6e94c5269b19df216ffecea6b8050482
Learning OpenCV with iOS:掩膜(mask)操作

一、前言

上一篇我们简单讲解了OpenCV的概念和基础架构。本篇主要向大家介绍下图像处理中一个比较重要的概念 -- 掩膜操作。开始前我们先看下利用矩阵掩膜操作来加强图像对比度的效果。

增强对比度

增强对比度

二、开胃菜-Mat对象

Mat

Mat

我们用眼睛看到的是图像,而计算机却不认识。于是,人们使用数值的形式来记录图像,比如用RGB值记录图像的每个点,以此来表示图像。就如上图,我们看到的是一辆车,而计算机“看到”的是一个包含图像值的矩阵。OpenCV的Mat对象对应的就是矩阵。Mat提供了许多便捷的API来创建、操作矩阵。

Mat基础操作

Mat image = Mat(240, 320, CV_8UC3);

第一个参数是rows,该矩阵的行数;第二个参数是cols,该矩阵的列数;第三个参数是该矩阵元素的类型。这句话表示创建一个大小为240×320的矩阵,里面的元素为8位unsigned型,通道数(channel)有3个。

image.create(480, 640, CV_8UC3);

分配(或重新分配)image矩阵,把大小设为480×640,类型设为CV8UC3。

Mat image = Mat(3, 3, CV_32F, Scalar(5));

定义并初始化一个3×3的32bit浮点数矩阵,每个元素都设为5。

uchar* ptr = image.ptr(row);

指针操作,表示拿到image第row行的指针

uchar* output = image.ptr(row);
output[1] = value;

利用指针修改图像,表示修改image第row行的第2个数据为value。

Mat常用成员介绍

1、data
Mat对象中的一个指针,指向存放矩阵数据的内存(uchar* data)

2、dims
矩阵的维度,3 * 4的矩阵维度为2维,3 * 4 * 5的矩阵维度为3维

3、channels
矩阵通道,矩阵中的每一个矩阵元素拥有的值的个数,比如说 3 * 4 矩阵中一共 12 个元素,如果每个元素有三个值,那么就说这个矩阵是 3 通道的,即 channels = 3。常见的是一张彩色图片有红、绿、蓝三个通道。

4、rows
矩阵的行数

5、cols
矩阵的列数

Mat与IplImage

OpenCV1使用基于C接口定义的图像存储格式IplImage存储图像。IplImage直接暴露内存,如果忘记释放内存,就会造成内存泄漏。

从OpenCV2开始,开始使用Mat类存储图像,具有以下优势:

  • 图像的内存分配和释放由Mat类自动管理

  • Mat类由两部分数据组成:矩阵头(包含矩阵尺寸、存储方法、存储地址等)和一个指向存储所有像素值的矩阵(根据所选存储方法的不同,矩阵可以是不同的维数)的指针。Mat在进行赋值和拷贝时,只复制矩阵头,而不复制矩阵,提高效率。如果矩阵属于多个Mat对象,则通过引用计数来判断,当最后一个使用它的对象,则负责释放矩阵。

  • 可以使用clone和copyTo函数,不仅复制矩阵头还复制矩阵。

三、掩膜操作

数字图像处理中的掩膜的概念是借鉴于PCB制版的过程,在半导体制造中,许多芯片工艺步骤采用光刻技术,用于这些步骤的图形“底片”称为掩膜(也称作“掩模”),其作用是:在硅片上选定的区域中对一个不透明的图形模板遮盖,继而下面的腐蚀或扩散将只影响选定的区域以外的区域。
图像掩膜与其类似,用选定的图像、图形或物体,对处理的图像(全部或局部)进行遮挡,来控制图像处理的区域或处理过程。
光学图像处理中,掩模可以是胶片、滤光片等。数字图像处理中,掩模为二维矩阵数组,有时也用多值图像。

是不是概念看得一头雾水,没事的,我第一次看概念的也是一样样的。下面我以例子来辅助大家了解掩膜。

抠下铠的头

铠

接下来我们以代码角度分析下究竟什么是掩膜。

    // image为铠的图片
    Mat src;
    UIImageToMat(image, src);

    Mat mask = Mat::zeros(src.size(), CV_8UC1);
    Rect2i r = Rect2i(120, 80, 100, 100);
    mask(r).setTo(255);

    Mat dst;
    src.copyTo(dst, mask);

第一步建立与原图一样大小的mask图像,并将所有像素初始化为0,因此全图成了一张全黑色图。
第二步将mask图中的r区域的所有像素值设置为255,也就是整个r区域变成了白色。

 Mat mask = Mat::zeros(src.size(), CV_8UC1);
 mask(r).setTo(255);

mask图片

mask图片

top Created with Sketch.