OpenCV形态学相关的运算包含腐蚀(MORPH_ERODE),膨胀(MORPH_DILATE),开运算(MORPH_OPEN),闭运算(MORPH_CLOSE),梯度运算(MORPH_GRADIENT),顶帽运算(MORPH_TOPHAT),黑帽运算(MORPH_BLACKHAT),击中击不中变换(MORPH_HITMISS)。
erode()函数
erode()函数执行的是腐蚀运算,其原型如下:
erode()通过使用特定的结构元素(如矩形、圆形等)来处理图像。在某个像素上应用结构元素时,结构元素的锚点与该像素对齐,所有与结构元素相交的像素就包含在当前集合中,腐蚀就是把当前像素替换成所定义像素集合中的最小像素值。即:
因此,腐蚀可去除图像中小的噪点,用于图像滤波,腐蚀后物体尺寸会缩小。
函数参数:
src 输入图像;通道的数量可以是任意的,但深度应为CV_8U、CV_16U、CV_36S、CV_32F或CV_64F之一。
dst 输出图像其大小与类型与源图像相同。
kernel 用于腐蚀操作的结果元素(内核),如果element=Mat(),则使用3 x 3矩形结构元素。内核可以使用getStructuringElement创建。
anchor 锚点在结构元素(kernel)内的位置;默认值(-1,-1)表示锚点位于元素中
心。
iteration 应用腐蚀操作的次数。
borderType 像素外推方法,请参见边界类型。不支持BORDER_WRAP。边界类型如下:
borderValue 恒定边界情况下的边界值。
dilate()函数
dilate()函数执行膨胀操作,其原型如下:
dilate()也是通过使用特定的结构元素(如矩形、圆形等)来处理图像。在某个像素上应用结构元素时,结构元素的锚点与该像素对齐,所有与结构元素相交的像素就包含在当前集合中,腐蚀就是把当前像素替换成所定义像素集合中的最大像素值。即:
膨胀操作,物体尺寸会变大,可使物体中的小减小填满。
函数参数:
src 输入图像;通道的数量可以是任意的,但深度应为CV_8U、CV_16U、CV_36S、CV_32F或CV_64F之一。
dst 输出图像其大小与类型与源图像相同。
kernel 用于膨胀操作的结构元素(内核),如果element=Mat(),则使用3 x 3矩形结构元素。内核可以使用getStructuringElement创建。
anchor 锚点在结构元素(kernel)内的位置;默认值(-1,-1)表示锚点位于元素中心。
iteration 应用膨胀操作的次数。
borderType 像素外推方法,请参见边界类型。不支持BORDER_WRAP。边界类型如下:
borderValue 恒定边界情况下的边界值。
图像的开运算/闭运算
开运算和闭运算的定义只与基本的腐蚀和膨胀运算有关:闭合的定义是对图像先膨胀后腐蚀,开启的定义是对图像先腐蚀后膨胀。要实现开运算/闭运算可分别调用腐蚀与膨胀函数,也可以调用OpenCV形态学函数morphologyEx(),morphologyEx()的原型如下:
函数morphology Ex()使用侵蚀和膨胀作为基本操作来执行高级形态转换。
函数参数:
src 输入图像;通道的数量可以是任意的,但深度应为CV_8U、CV_16U、CV_36S、CV_32F或CV_64F之一。
dst 输出图像其大小与类型与源图像相同。
Op 形态学操作的类型,请参见MorphTypes:
kernel 用于膨胀操作的结构元素(内核),如果element=Mat(),则使用3 x 3矩形结构元素。内核可以使用getStructuringElement创建。
anchor 锚点在结构元素(kernel)内的位置;默认值(-1,-1)表示锚点位于元素中心。
iteration 应用膨胀操作的次数。
borderType 像素外推方法,请参见边界类型。不支持BORDER_WRAP。边界类型如下:
borderValue 恒定边界情况下的边界值。
梯度运算
形态学梯度运算实质上是膨胀与腐蚀结果相减:
顶帽/黑帽
顶帽运算的实质是源图像与开运算结果相减:
黑帽运算实质是闭运算的结果减去与图像:
示例:
新建一个控制台应用程序Project,在源程序中加入如下代码:
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
Mat src = imread("2.bmp");
if (src.empty())
{
cout << "Cann't open image!" << endl;
return -1;
}
imshow("Src", src);
Mat src1 = src;
Mat src2 = src;
Mat tem;
Mat element(5, 5, CV_8U, Scalar(1));
//erode
erode(src, tem, element,Point(-1,-1),1);
imshow("Erode Result", tem);
//dilate
dilate(src, tem, element, Point(-1, -1), 1);
imshow("Dilate Result", tem);
//erode +dilate
erode(src, tem, element, Point(-1, -1), 1);
dilate(tem, tem, element, Point(-1, -1), 1);
imshow("Erode + dilate Result", tem);
//dilate + erode
dilate(src1, tem, element, Point(-1, -1), 1);
erode(tem, tem, element, Point(-1, -1), 1);
imshow("Dilate + erode Result", tem);
//open
morphologyEx(src1, tem, MORPH_OPEN, element);
imshow("Open Result", tem);
//close
morphologyEx(src1, tem, MORPH_CLOSE, element);
imshow("CLOSE Result", tem);
src2 = imread("3.bmp");
if (src.empty())
{
cout << "Cann't open image!" << endl;
return -1;
}
imshow("Src2", src2);
//top hat
morphologyEx(src2, tem, MORPH_TOPHAT, element);
imshow("Top hat", tem);
//Black hat
morphologyEx(src2, tem, MORPH_BLACKHAT, element);
imshow("Black hat", tem);
waitKey(0);
}
试运行,结果如下: