初学OpenCV学习记录(七)

以下内容摘自OpenCV2 计算机视觉编程手册

引言

书中本章介绍了运用形态学运算的几种算法,对图像的腐蚀、膨胀、开闭运算,以及利用上面的几种算法对图像进行边缘检测和角点检测,除此之外,还介绍了分水岭算法进行图像分割和GrabCut算法完成对图片前景和背景的分割。

腐蚀、膨胀、开闭运算

  • 腐蚀:cv::erode()
  • 膨胀:cv::dilate()
  • 开闭运算:cv::morphologyEx()

形态学滤波通常运用于二值图像,因此首先应该生成二值图像,形态学的惯例是用白色像素表示前景物体,黑色像素表示背景,如果你转化的二值图像不是这样,就要转化成它的负片。
腐蚀和膨胀是最基本的形态学运算,运算的工具是结构元素,结构元素实际上就是一个由像素构成的特定形状,并且指定形状中的一个像素为原点(锚点),在进行滤波时,类似于卷积滤波的方法,对图片中的每一个像素都应用这个结构进行运算,即将结构元素的锚点和像素对齐,然后结构元素与图像的相交像素进行某种运算。
举一个例子:

cv::Mat element(5,5,CV_8U,cv::Scalar(1));
cv::erode(image,eroded,element,cv::Point(-1,-1),3);

我们首先创建了一个Mat矩阵,大小为5 * 5,并将其所有的像素值初始化为1,那么将其作为结构元素时,结构元素就是一个5 * 5的矩阵,通过设置像素值为1或0,我们可以用Mat矩阵表示任意形状,比如我们需要的结构形状是长方形4* 5,那么就可以将最后一行像素置为0。参数cv::Point(-1,-1)表示原点为与矩阵中心,3表示进行3次腐蚀运算,运算次数越多,效果越强烈。
膨胀运算的用法与其基本一致,腐蚀的基本原理是当结构元素应用于某个像素时,用结构元素与图片相交的元素集合中最小的像素值替代锚点处的像素值,膨胀运算相反,它替换的是最大值。因此,腐蚀后的图像尺寸会减小,可以移除图片中的一些细小和物体(通常被认为是噪音),而膨胀后的图像会使尺寸变大,可以填满一些物体内部的“洞”。
开闭运算就是基于膨胀和腐蚀进行的:

  • 闭运算:先膨胀、后腐蚀
  • 开运算:先腐蚀、后膨胀
    到底用那种运算由函数的参数控制。
    上面这四种运算通常在物体检测中使用,通常我们对二值图像先进行闭运算,再进行开运算,如果你想更好地剔除噪点,可以先进行开运算,再进行闭运算,但是有可能去除一些分散的物体。

检测边缘与角点

利用上述的算法完成边缘和角点检测,当然边缘和角点检测算法还有很多,这里只是使用形态学的方法。
边缘检测:

  • 阈值化得到图片的二值图像
  • 使用cv::morphologyEx()函数,方法要选择cv::MORPH_GRADIENT

检测原理:由于膨胀和腐蚀后的图像不同点主要在边缘处,计算膨胀后的图像与腐蚀后图像的差值就可以得到图像的边缘,函数给定的结构元素尺寸越大,检测出的边缘越厚,当然只使用膨胀后的图像减去原图像或者原图像减去腐蚀后的图像也能够得到边缘,但是效果没那么好。
角点检测:
只使用膨胀和腐蚀的算法,但要取特殊形状的结构元素

  • 得到图像的灰度图
  • 创建结构元素(Mat矩阵),通过对矩阵元素赋值的方式创建十字形元素、菱形元素、X形元素和方形元素。
  • 对原图使用十字形膨胀,再使用菱形腐蚀,得到输出图像1
  • 对原图使用X形膨胀,在使用方形腐蚀,得到输出图像2
  • 图像2减去图像1得到输出图像,输出图像不为0的像素值都是角点
    这里省略详细的代码

使用分水岭进行图像分割

使用GrabCut算法提取前景物体

猜你喜欢

转载自blog.csdn.net/weixin_42411702/article/details/123868866