1.概述
1.1原理方法
图像形态学操作的时候,可以通过自定义的结构元素实现结构元素对输入图像一些对象敏感、另外一些对象不敏感,这样就会让敏感的对象改变而不敏感的对象保留输出。通过使用两个最基本的形态学操作-膨胀与腐蚀,是哟个不同的结构元素实现对输入图像的操作、得到想要的结果。
-膨胀:输出的像素值是结构元素覆盖下输入图像的最大像素值
-腐蚀:输出的像素值是结构元素覆盖下输入图像的最小像素值
1.2结构元素
- 膨胀和腐蚀过程可以使用任意的结构元素
- 常见的形状:矩形、圆、直线、磁盘形状、砖头形状等等各种自定义的形状
1.3提取步骤
- 输入图像彩色图像-imread
- 转换为灰度图像-cvtColor
- 转换为二值图像-adaptiveThreshold
- 定义结构元素
- 开操作(腐蚀+膨胀)提取水平与垂直线
adaptiveThreshold{
- Mat src,
- Mat dst,
- double maxValue,//二值图像的最大值
- int adaptiveMethd//自适应方法,只能选择其中之一,ADAPTIVA_THRESH_MEAN_C,ADAPTIVE_THRESH_GAUSSIAN_C
- int thresholdType,//阈值类型
- int blocksize,//块大小
- double C //C是常量可以是正数也可以负数或0
}
2 提取垂直线案例
void MyApi::extract_hLine_vLine(Mat& image)
{
Mat gray_image;
cvtColor(image, gray_image, COLOR_BGR2GRAY);
imshow("gray_image", gray_image);
//将灰度图像转化为二值图像,只有灰度图像才可以变为二值图像
Mat binImage;
//~表示取反操作,我们想把图像的白黑互换,也可以不做。
adaptiveThreshold(~gray_image, binImage, 255,
ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 15, -2);
imshow("binary_image", binImage);
//开操作
Mat hline = getStructuringElement(MORPH_RECT, Size(image.cols / 16, 1), Point(-1, -1));//水平结构元素
Mat vline = getStructuringElement(MORPH_RECT, Size(1, image.rows / 16), Point(-1, -1));//垂直结构元素
Mat kernel = getStructuringElement(MORPH_RECT, Size(5, 5), Point(-1, -1));//矩形结构
//提取水平线
//Mat h_temp, h_dst;
//erode(binImage, h_temp, hline);
//dilate(h_temp, h_dst, hline);
////bitwise_not(dst, dst);//输出的背景黑白互换
//imshow("Final Result", h_dst);
//提取垂直线 也可以直接使用APImorphologyEx(binImg,dst,MOP_OPEN,vline)
Mat v_temp,v_dst;
erode(binImage, v_temp, vline);
dilate(v_temp, v_dst, vline);
//bitwise_not(dst, dst);//输出的背景黑白互换
imshow("Final Result", v_dst);
}
原图和灰度图
二值图和提取垂直线后的图
如果要提取水平的线只需要把vline换成hline即可。
3.案例二提取字母
void MyApi::extract_hLine_vLine(Mat& image)
{
Mat gray_image;
cvtColor(image, gray_image, COLOR_BGR2GRAY);
imshow("gray_image", gray_image);
//将灰度图像转化为二值图像,只有灰度图像才可以变为二值图像
Mat binImage;
//~表示取反操作,我们想把图像的白黑互换,也可以不做。
adaptiveThreshold(~gray_image, binImage, 255,
ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 15, -2);
imshow("binary_image", binImage);
//开操作
Mat hline = getStructuringElement(MORPH_RECT, Size(image.cols / 16, 1), Point(-1, -1));//水平结构元素
Mat vline = getStructuringElement(MORPH_RECT, Size(1, image.rows / 16), Point(-1, -1));//垂直结构元素
Mat kernel = getStructuringElement(MORPH_RECT, Size(5, 5), Point(-1, -1));//矩形结构
//提取水平线
//Mat h_temp, h_dst;
//erode(binImage, h_temp, hline);
//dilate(h_temp, h_dst, hline);
////bitwise_not(dst, dst);//输出的背景黑白互换
//imshow("Final Result", h_dst);
//提取垂直线 也可以直接使用APImorphologyEx(binImg,dst,MOP_OPEN,vline)
Mat v_temp,v_dst;
erode(binImage, v_temp, kernel);
dilate(v_temp, v_dst, kernel);
//bitwise_not(dst, dst);//输出的背景黑白互换
imshow("Final Result", v_dst);
}
补充:
getStructuringElement函数会返回指定形状和尺寸的结构元素。
Mat getStructuringElement(int shape, Size esize, Point anchor = Point(-1, -1));
这个函数的第一个参数表示内核的形状,有三种形状可以选择。
矩形:MORPH_RECT;
交叉形:MORPH_CROSS;
椭圆形:MORPH_ELLIPSE;
第二和第三个参数分别是内核的尺寸以及锚点的位置。一般在调用erode以及dilate函数之前,先定义一个Mat类型的变量来获得getStructuringElement函数的返回值。对于锚点的位置,有默认值Point(-1,-1),表示锚点位于中心点。element形状唯一依赖锚点位置,其他情况下,锚点只是影响了形态学运算结果的偏移。