OpenCV 形态学操作(开,闭,梯度,礼帽,黑帽)

文章目录

  • 形态学基本概念
  • 高级形态学变换函数:MorphologyEx
    • 形态学开运算
      • 开运算案例:
    • 形态学闭运算
      • 闭运算案例:
    • 形态学梯度运算
      • 形态学梯度运算案例:
    • 礼/顶帽(Top hat)
      • 礼帽案例:
    • 黑帽(Black hat)
      • 黑帽案例:

形态学基本概念

图像形态学即数学形态学(Mathematical morphology)是一门建立在格伦和拓扑学基础上的图像分析学科,是数学形态学图像处理的基本理论;常见图像形态学运算:腐蚀,膨胀,开运算,闭运算,骨架抽取,极线腐蚀,击中击不中变换,顶帽变换,颗粒分析,流域变换,形态学梯度等。

腐蚀和膨胀是最基本的形态学运算。

腐蚀和膨胀是针对白色部分(高亮部分)而言的。

膨胀(dilate)是对图像高亮部分进行“领域扩张”,领域扩张,效果图拥有比原图更大的高亮区域;

腐蚀(erode)是原图中的高亮区域被蚕食,领域缩减,效果图拥有比原图更小的高亮区域。

开运算先腐蚀再膨胀,用来消除小物体

闭运算先膨胀再腐蚀,用于排除小型黑洞

形态学梯度:就是膨胀图与俯视图之差,用于保留物体的边缘轮廓。

顶帽:原图像与开运算图之差,用于分离比邻近点亮一些的斑块。
OpenCV 形态学操作(开,闭,梯度,礼帽,黑帽)_第1张图片

黑帽:闭运算与原图像之差,用于分离比邻近点暗一些的斑块。
OpenCV 形态学操作(开,闭,梯度,礼帽,黑帽)_第2张图片

高级形态学变换函数:MorphologyEx

函数原型:

void morphologyEx( 
	InputArray src, 
	OutputArray dst,
	int op, 
	InputArray kernel,
	Point anchor = Point(-1,-1), 
	int iterations = 1,
	int borderType = BORDER_CONSTANT,
	const Scalar& borderValue = morphologyDefaultBorderValue()
)

参数:

  • src:源图像Mat对象

  • dst:目标图像Mat对象

  • op:操作的类型,通过源码我们得知总共有以下几种类型:

    enum MorphTypes{
           
        MORPH_ERODE    = 0, //腐蚀
        MORPH_DILATE   = 1, //膨胀
        MORPH_OPEN     = 2, //开操作
        MORPH_CLOSE    = 3, //闭操作
        MORPH_GRADIENT = 4, //梯度操作
        MORPH_TOPHAT   = 5, //顶帽操作
        MORPH_BLACKHAT = 6, //黑帽操作
        MORPH_HITMISS  = 7  
    };
    
  • kernel:用于膨胀操作的结构元素,如果取值为Mat(),那么默认使用一个3 x 3 的方形结构元素,可以使用getStructuringElement()来创建结构元素

  • anchor:参考点,其默认值为(-1,-1)说明位于kernel的中心位置。

  • borderType:边缘类型,默认为BORDER_CONSTANT。

  • borderValue:边缘值,用它的默认值即可。

形态学开运算

开操作(先腐蚀后膨胀)可以平滑物体轮廓,断开狭窄的间断和消除细小的突出物。

它具有消除细小物体,在纤细处分离物体和平滑较大物体边界的作用。

函数使用:

morphologyEx(src, dst, MORPH_OPEN, kernel);

开运算案例:

OpenCV 形态学操作(开,闭,梯度,礼帽,黑帽)_第3张图片

#include
#include
#include
using namespace cv;
using namespace std;

int main()
{
     
	Mat img = imread("./morphologyEx.jpg");
	cout << img.size() << endl;
	imshow("原图", img);

	Mat dst;
	//获取自定义核
	Mat element = getStructuringElement(MORPH_RECT, Size(10, 10));
	//形态学开操作
#if 1
	morphologyEx(img, dst, MORPH_OPEN, element);
#else
	erode(img, dst, element);
	dilate(dst, dst, element);
#endif
	imshow("形态学开操作", dst);
	waitKey();
	return 0;
}

注:形态学操作可使用高级函数morphologyEx。

形态学闭运算

闭操作(先膨胀后腐蚀)可以消弭狭窄的间断,消除小的孔洞。先膨胀后腐蚀的操作称之为闭操作。

它具有填充物体内细小空洞,连接邻近物体和平滑边界的作用。

函数使用:

morphologyEx(src, dst, MORPH_CLOSE, kernel);

闭运算案例:

OpenCV 形态学操作(开,闭,梯度,礼帽,黑帽)_第4张图片

#include
#include
#include
using namespace cv;
using namespace std;

int main()
{
     
	Mat img = imread("./morphologyEx.jpg");
	cout << img.size() << endl;
	imshow("原图", img);

	Mat dst;
	//获取自定义核
	Mat element = getStructuringElement(MORPH_RECT, Size(10, 10));
	//形态学闭操作
	morphologyEx(img, dst, MORPH_CLOSE, element);

	imshow("形态学闭操作", dst);
	waitKey();
	return 0;
}

形态学梯度运算

形态学梯度操作能描述图像亮度变化的剧烈程度;当我们想要突出高亮区域的外围时,则可以选用形态学梯度来突出边缘,可以保留物体的边缘轮廓。

形态学梯度运算案例:

OpenCV 形态学操作(开,闭,梯度,礼帽,黑帽)_第5张图片

#include
#include
#include
using namespace cv;
using namespace std;

int main()
{
     
	Mat img = imread("./morphologyEx.jpg");
	cout << img.size() << endl;
	imshow("原图", img);

	Mat dst;
	//获取自定义核
	Mat element = getStructuringElement(MORPH_RECT, Size(10, 10));
	//形态学梯度运算
	morphologyEx(img, dst, MORPH_GRADIENT, element);

	imshow("形态学梯度运算", dst);
	waitKey();
	return 0;
}

礼/顶帽(Top hat)

顶帽是原图与原图的开运算的差值图像。

开运算放大了裂缝或者局部低亮度的区域,所以,从原图中减去开运算后的图,得到的结果突出了比原图轮廓周围的区域更明亮的区域,这个操作与选择的核的大小有关。TopHat运算一般用来分离比邻近点亮一些的斑块,可以使用这个运算提取背景。

礼帽案例:

OpenCV 形态学操作(开,闭,梯度,礼帽,黑帽)_第6张图片

#include
#include
#include
using namespace cv;
using namespace std;

int main()
{
     
	Mat img = imread("./morphologyEx.jpg");
	cout << img.size() << endl;
	imshow("原图", img);

	Mat dst,dst_open;
	// 获取自定义核
	Mat element = getStructuringElement(MORPH_RECT, Size(5, 5));
	// 形态学礼帽
	morphologyEx(img, dst_open, MORPH_OPEN, element);
	morphologyEx(img, dst, MORPH_TOPHAT, element);

	imshow("开运算", dst_open);
	imshow("形态学礼帽", dst);
	waitKey();
	return 0;
}

黑帽(Black hat)

黑帽是闭运算结果与原图的差值图像。

黑帽运算的结果突出了比原图轮廓周围区域更暗的区域,所以黑帽运算用来分离比邻近点暗一些的斑块。

黑帽案例:

OpenCV 形态学操作(开,闭,梯度,礼帽,黑帽)_第7张图片

#include
#include
#include
using namespace cv;
using namespace std;

int main()
{
     
	Mat img = imread("./morphologyEx.jpg");
	cout << img.size() << endl;
	imshow("原图", img);

	Mat dst, dst_close;
	// 获取自定义核
	Mat element = getStructuringElement(MORPH_RECT, Size(5, 5));
	// 形态学黑帽
	morphologyEx(img, dst_close, MORPH_CLOSE, element);
	morphologyEx(img, dst, MORPH_BLACKHAT, element);

	imshow("闭运算", dst_close);
	imshow("形态学黑帽", dst);
	waitKey();
	return 0;
}

你可能感兴趣的:(#,OpenCV,opencv,计算机视觉,图像处理)