7.1 引言
图像的形态学处理通常作用于图像预处理、图像增强、目标分割等场景。数字图像的形态学利用点集的性质、拓扑学理论等对物体像素进行变换。形态学变化只能再二值图像上处理。形态学处理可分为:腐蚀、膨胀、开运算、闭运算、形态学梯度运算、顶帽运算、黑帽运算等。
7.2 形态学操作
7.2.1 腐蚀
腐蚀的作用是清除物体边界噪点,缩小目标结构,以及消除游离在外的小的噪声点。
集体实现形式如下图所示,定义一个腐蚀结构元结构B,用结构B去扫描图像结构A的像素,每个重叠的像素点做与操作,如果均为1,则该像素为1,否则为0。
opencv中腐蚀的API为 CV::erode
void cv::erode(InputArray src, OutputArray dst, InputArray kernel, Point anchor=Point(-1,-1), int iteration=1, int borderType=BORDER_DEFAULT,const Scalar& borderValue=morphologyDefaultB-orderValue())
参数 | 含义 | |
作用 | 形态学腐蚀 | |
输入 | src | 原图 |
dst | 腐蚀后的图像 | |
kernel | 腐蚀结构元 | |
anchor | 锚点,默认(-1,-1)为核中心 | |
iteration | 迭代次数,可以选择对图像进行多次形态学运算 | |
borderType | 边框模式用于推断图像外部的像素(一般默认) | |
borderValue | 边界值,一般采用默认值。 | |
返回值 | void | 无 |
7.2.2 膨胀
膨胀可以实现了对目标像素点进行扩展,使目标增大,可填充目标中的孔洞。
opencv中腐蚀的API为 CV::dilate
void cv::dilate(InputArray src, OutputArray dst, InputArray kernel, Point anchor=Point(-1,-1), int iteration=1, int borderType=BORDER_DEFAULT,const Scalar& borderValue=morphologyDefaultB-orderValue())
参数 | 含义 | |
作用 | 形态学腐蚀 | |
输入 | src | 原图 |
dst | 腐蚀后的图像 | |
kernel | 腐蚀结构元 | |
anchor | 锚点,默认(-1,-1)为核中心 | |
iteration | 迭代次数,可以选择对图像进行多次形态学运算 | |
borderType | 边框模式用于推断图像外部的像素(一般默认) | |
borderValue | 边界值,一般采用默认值。 | |
返回值 | void | 无 |
7.2.3 腐蚀和膨胀代码示例
Mat src, erodeImg, dilateImg;
char OutputWin[] = "output img";
int nKeenelSize = 1;
int nMaxSize = 21;
//设置腐蚀跟踪条的回调函数
void CallbackErodeBar(int, void*)
{
int nSize = nKeenelSize * 2 + 1;
Mat structElement = getStructuringElement(MORPH_RECT, Size(nSize, nSize), Point(-1, -1));//获取一个矩形的卷积核
erode(src, erodeImg, structElement, Point(-1, -1), 1);
imshow(OutputWin, erodeImg);
}
//设置膨胀跟踪条的回调函数
void CallbackDilateBar(int, void*)
{
int nSize = nKeenelSize * 2 + 1;
Mat structElement = getStructuringElement(MORPH_RECT, Size(nSize, nSize), Point(-1, -1));//获取一个矩形的卷积核
dilate(src, dilateImg, structElement, Point(-1, -1), 1);
imshow(OutputWin, dilateImg);
}
int main(int argc,char** argv)
{
src = imread("D:\\testimg\\CSet12\\Butterfly.png");
if (src.empty())
{
printf("Could not load the image...\n");
return -1;
}
else;
cvtColor(src,src,COLOR_BGR2GRAY);
//二值化
threshold(src, src,120,255,THRESH_BINARY);
//显示窗口
char input_win[] = "srcImg";
namedWindow(input_win, WINDOW_AUTOSIZE);
imshow(input_win, src);
namedWindow(OutputWin,WINDOW_AUTOSIZE);
createTrackbar("erode size:",OutputWin,&nKeenelSize,nMaxSize,CallbackErodeBar);
CallbackErodeBar(0, 0);
createTrackbar("dilate size:", OutputWin, &nKeenelSize, nMaxSize, CallbackDilateBar);
CallbackDilateBar(0,0);
waitKey(0);
return 0;
}
可通过跟踪条来测试腐蚀和膨胀的效果
7.2.4 开操作
开操作其实就是先腐蚀后膨胀;可以消除小区域并分离物体。消除噪点和小的干扰块,而不影响原来的图像。
7.2.5 闭操作
开操作其实就是先膨胀后腐蚀;可以填充目标区域内的离散小空间和分散部分。它有助于填充物体内部的小孔,或去除物体上的小黑点,还可以将不同的前景图像进行连接。
7.2.6 形态学梯度
形态学梯度运算(基本梯度)等价于图像的膨胀图像减腐蚀图像的操作,该操作可以获取原始图像中前景图像的边缘。
7.2.7顶帽
顶帽(Top Hat)等价于原始图像-开运算图像,能够获取图像的噪声信息,或者得到比原始图像的边缘更亮的边缘信息。
7.2.8 黑帽
顶帽(Black Hat)等价于闭运算图像-原始图像,黑帽运算能够获取图像内部的小孔,或前景色中的小黑点,或者得到比原始图像的边缘更暗的边缘部分。
7.2.9 形态学操作API
在opencv中,对形态学处理有一个统一的API接口:CV::morphologyEx
void cv::morphologyEx(InputArray src, OutputArray dst, int op, InputArray kernel, Point anchor=Point(-1,-1), int iteration=1, int borderType=BORDER_DEFAULT,const Scalar& borderValue=morphologyDefaultB-orderValue())
参数 | 含义 | |
作用 | 形态学腐蚀 | |
输入 | src | 原图 |
dst | 腐蚀后的图像 | |
op | 形态学操作算子类型: MORPH_OPEN-开操作 MORPH_CLOSE-闭操作 MORPH_GRADIENT-梯度操作 MORPH_TOPHAT-顶帽操作 MORPH_BLACKHAT-黑帽操作 | |
kernel | 腐蚀结构元 | |
anchor | 锚点,默认(-1,-1)为核中心 | |
iteration | 迭代次数,可以选择对图像进行多次形态学运算 | |
borderType | 边框模式用于推断图像外部的像素(一般默认) | |
borderValue | 边界值,一般采用默认值。 | |
返回值 | void | 无 |
代码示例
int main(int argc, char** argv)
{
Mat src = imread("D:\\testimg\\CSet12\\Butterfly.png");
if (src.empty())
{
printf("Could not load the image...\n");
return -1;
}
else;
cvtColor(src, src, COLOR_BGR2GRAY);
//二值化
threshold(src, src, 120, 255, THRESH_BINARY);
//显示窗口
char input_win[] = "srcImg";
namedWindow(input_win, WINDOW_AUTOSIZE);
imshow(input_win, src);
Mat openImg, closeImg, gradImg, topHatImg, blackHatImg;
Mat structElemet = getStructuringElement(MORPH_RECT,Size(11,11),Point(-1,-1));
//开操作
morphologyEx(src, openImg,MORPH_OPEN,structElemet);
//闭操作
morphologyEx(src, closeImg, MORPH_CLOSE, structElemet);
//梯度操作(膨胀-腐蚀)
morphologyEx(src, gradImg, MORPH_GRADIENT, structElemet);
//顶帽操作(原图-开操作)
morphologyEx(src, topHatImg, MORPH_TOPHAT, structElemet);
//黑帽操作(闭操作-原图)
morphologyEx(src, blackHatImg, MORPH_BLACKHAT, structElemet);
char OutputWin[] = "openImg";
namedWindow(OutputWin, WINDOW_AUTOSIZE);
imshow(OutputWin, openImg);
imshow("closeImg", closeImg);
imshow("gradImg", gradImg);
imshow("topHatImg", topHatImg);
imshow("blackHatImg", blackHatImg);
waitKey(0);
return 0;
}