原理方法
图像形态学操作时候,可以通过自定义的结构元素实现结构元素对输入图像一些对象敏感、另外一些对象不敏感,这样就会让敏感的对象改变而不敏感的对象保留输出。
通过使用两个最基本的形态学操作 – 膨胀与腐蚀,使用不同的结构元素实现对输入图像的操作、得到想要的结果。
- 膨胀,输出的像素值是结构元素覆盖下输入图像的最大像素值
- 腐蚀,输出的像素值是结构元素覆盖下输入图像的最小像素值
比如开操作,先腐蚀后膨胀,将白色的小块去掉了
结构元素
- 膨胀与腐蚀过程可以使用任意的结构元素
- 常见的形状:矩形、园、直线、磁盘形状、砖石形状等各种自定义形状。
假如原图像是矩形,那么矩形的结构元素就不会影响它本来的形状
如果原图是圆形,那么就要选择圆形的结构元素
提取步骤
- 输入图像彩色图像 imread
- 转换为灰度图像 – cvtColor
- 转换为二值图像 – adaptiveThreshold
- 定义结构元素
- 开操作 (腐蚀+膨胀)提取 水平与垂直线
- 最后一步根据二值图像来决定
相关API
转换二值图像
adaptiveThreshold(
Mat src, // 输入的灰度图像
Mat dest, // 二值图像
double maxValue, // 二值图像最大值(255)
int adaptiveMethod // 自适应方法,只能其中之一 –
// ADAPTIVE_THRESH_MEAN_C , ADAPTIVE_THRESH_GAUSSIAN_C
int thresholdType,// 阈值类型
int blockSize, // 块大小
double C // 常量C 可以是正数,0,负数
)
如
adaptiveThreshold(~gray, binImg, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 15, -2);
定义结构元素
Mat getStructuringElement(
int shape,
Size ksize,
Point anchor = Point(-1,-1)
);
(1)int类型的shape,元素形状,可以是cv::MorphShapes之一。
(2)Size类型的ksize,结构化元素的大小。
(3)Point类型的anchor,默认值(-1,-1),表示锚定位于中心。请注意,只有十字形元素的形状取决于锚定位置。在其他情况下,锚只是调节形态学操作结果的移动量。
第一个参数有这几种选项
-(1)MORPH_RECT:矩形结构区域。
-(2)MORPH_CROSS,十字形结构区域。
-(3)MORPH_ELLIPSE,椭圆结构区域,内接于矩形Rect(0,0,esize.width,0.esize.height)的填充椭圆。
代码
#include<opencv2\opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
int main()
{
Mat src;
src = imread("C:/Users/86176/Pictures/pics/lines.png");
if (!src.data)
{
printf("fail to read the pic\n");
}
namedWindow("src", CV_WINDOW_AUTOSIZE);
imshow("src", src);
/*转化为灰度图*/
Mat gray;
if (src.channels() == 3)
{
cvtColor(src, gray, CV_BGR2GRAY);
}
else
{
gray = src;
}
imshow("gray pic ", gray);
//转化为二值图像
Mat binImg;
adaptiveThreshold(~gray, binImg, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 15, -2);
imshow("binImg", 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 xdst;
Mat ydst;
morphologyEx(binImg, xdst, CV_MOP_OPEN, hline);
morphologyEx(binImg, ydst, CV_MOP_OPEN, vline);
//优化后输出
Mat dsty, dstx;
blur(ydst, dsty, Size(3,3), Point(-1,-1));
blur(ydst, dstx, Size(3, 3), Point(-1, -1));
imshow("xline", xdst);
imshow("yline", ydst);
waitKey(0);
return 0;
}
现象