目录
3、形态学梯度(Morphological Gradient)
前言
1、了解图像形态学
2、图像形态学主要包括腐蚀(Erosion)、膨胀(Dilation)、开运算(Opening)、闭运算(Closing)等操作。
除了以上基本操作,还有其他形态学操作,如击中击不中变换(Hit-or-Miss Transform)、顶帽运算(Top Hat Transform)和黑帽运算(Black Hat Transform)等。
这些图像形态学操作可以通过OpenCV库中的函数进行实现,例如cv::erode
、cv::dilate
、cv::morphologyEx
等函数。
3、膨胀与腐蚀是图像处理中最常用得形态学手段。
一、膨胀(Dilation)与 腐蚀(Erosion)
1、膨胀含义:
跟卷积操作类似,假设有图像A和结构元素B,结构元素B在A上面移动,其中B定义其中心为锚点,计算B覆盖下A的最大像素值用来替换锚点的像素,其中B作为结构体可以是任意形状。
2、腐蚀含义:
腐蚀跟膨胀操作的过程类似,唯一不同的是以最小值替换锚点重叠下图像的像素值。
3、相关的API:
(1)getStructuringElement(int shape, Size ksize, Point anchor)
- 形状 (MORPH_RECT \MORPH_CROSS \MORPH_ELLIPSE)
- 大小
- 锚点 默认是Point(-1, -1)意思就是中心像素
(2)dilate(src, dst, kernel)
(3)erode(src, dst, kernel)
4、相关代码演示
#include<opencv2\opencv.hpp>
#include<iostream>
using namespace cv;
Mat src, dst;
char OUTPUT_WIN[] = "output image";
int element_size = 3;
int max_size = 21;
void CallBack_Demo(int, void*);
int main(int argc, char** argv) {
src = imread("test.jpg");
if (!src.data) {
printf("could not load image...\n");
return -1;
}
namedWindow("input image", CV_WINDOW_AUTOSIZE);
imshow("input image", src);
namedWindow(OUTPUT_WIN, CV_WINDOW_AUTOSIZE);
createTrackbar("Element Size :", OUTPUT_WIN, &element_size, max_size, CallBack_Demo);
CallBack_Demo(0, 0);
waitKey(0);
return 0;
}
void CallBack_Demo(int, void*) {
int s = element_size * 2 + 1;
Mat structureElement = getStructuringElement(MORPH_RECT, Size(s, s), Point(-1, -1));
// 膨胀
// dilate(src, dst, structureElement, Point(-1, -1), 1);
// 腐蚀
erode(src, dst, structureElement);
imshow(OUTPUT_WIN, dst);
return;
}
效果展示:
二、形态学操作
1、开操作(Opening)
(1)先腐蚀后膨胀
(2)可以去掉小的对象,假设对象是前景色,背景是黑色
2、闭操作(Closing)
(1)先膨胀后腐蚀(bin2)
(2)可以填充小的洞(fill hole),假设对象是前景色,背景是黑色
3、形态学梯度(Morphological Gradient)
(1)膨胀减去腐蚀
(2)又称为基本梯度(其它还包括-内部梯度、方向梯度)
4、顶帽 ( top hat)
顶帽 是原图像与开操作之间的差值图像
5、黑帽 ( black hat)
黑帽是闭操作图像与源图像的差值图像
6、相关的API
morphologyEx(src, dest, CV_MOP_BLACKHAT, kernel);
7、代码演示
三、形态学操作应用-提取水平与垂直线
1、原理方法
(1)膨胀,输出的像素值是结构元素覆盖下输入图像的最大像素值
二值图像与灰度图像上的膨胀操作:
(2)腐蚀,输出的像素值是结构元素覆盖下输入图像的最小像素值
二值图像与灰度图像上的腐蚀操作
(3)结构元素
1)上述膨胀与腐蚀过程可以使用任意的结构元素
2)常见的形状:矩形、园、直线、磁盘形状、砖石形状等各种自定义形状。
2、实现步骤
(1)输入图像彩色图像 imread
(2)转换为灰度图像 – cvtColor
(3)转换为二值图像 – adaptiveThreshold
(4)定义结构元素
(5)开操作 (腐蚀+膨胀)提取 水平与垂直线
后处理
3、代码演示
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
int main(int argc, char** argv) {
Mat src, dst;
src = imread("D:/vcprojects/images/chars.png");
if (!src.data) {
printf("could not load image...\n");
return -1;
}
char INPUT_WIN[] = "input image";
char OUTPUT_WIN[] = "result image";
namedWindow(INPUT_WIN, CV_WINDOW_AUTOSIZE);
imshow(INPUT_WIN, src);
Mat gray_src;
cvtColor(src, gray_src, CV_BGR2GRAY);
imshow("gray image", gray_src);
Mat binImg;
adaptiveThreshold(~gray_src, binImg, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 15, -2);
imshow("binary image", binImg);
// 水平结构元素
Mat hline = getStructuringElement(MORPH_RECT, Size(src.cols / 16, 1), Point(-1, -1));
// 垂直结构元素
Mat vline = getStructuringElement(MORPH_RECT, Size(1, src.rows / 16), Point(-1, -1));
// 矩形结构
Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
Mat temp;
erode(binImg, temp, kernel);
dilate(temp, dst, kernel);
// morphologyEx(binImg, dst, CV_MOP_OPEN, vline);
// 背景变色
bitwise_not(dst, dst);
// 结果更加圆滑些
//blur(dst, dst, Size(3, 3), Point(-1, -1));
imshow("Final Result", dst);
waitKey(0);
return 0;
}
效果展示:
(1)水平结构元素:
先腐蚀后膨胀,相当于一开始把垂直的元素擦掉,所以就保留了水平的线。
(2)垂直结构元素
先腐蚀后膨胀,相当于一开始把水平的元素擦掉,所以就保留了垂直的线。
(3)矩形结构
矩形大小的干扰项都去掉。