理论
图像在进行形态学操作的时候, 可以通过自定义的结构元素实现结构元素对输入图像的一些对象敏感丶对另外一些对象不敏感, 这样就会让敏感的对象改变而不敏感的对象保留输出。 通过使用两个最基本的形态学操作 - 膨胀 与 腐蚀 , 使用不同的结构元素实现对输入图像的操作,从而得到想要的结果。
这里再简单介绍一下 膨胀 与 腐蚀 操作:
上述中, 通过 膨胀 与 腐蚀 来进行提取的操作, 其中的自定义结构元素, 也就是我们说的kernel(核), 常见的核的形状:矩形丶圆丶直线丶磁盘形状丶钻石形状以及各种自定义形状。
提取水平线与垂直线的操作流程:
相关API
转换为二值图像 - 通过adaptiveThreshold这个接口去转换
代码示例
Mat src,dst;
src = imread(...);
// 先显示原图
namedWindow("input image", CV_WINDOW_AUTOSIZE);
imshow("input image", src);
// 再显示灰度图
Mat gray_dst;
cvtColor(src, gray_dst, CV_BGR2GRAY);
namedWindow("gray image", CV_WINDOW_AUTOSIZE);
imshow("gray image", gray_dst);
// 再显示二值图
Mat binImg_dst;
adaptiveThreshold(~gray_dst, binImg_dst, 255, ADAPTIVE_THRESH_MEAN_C, THRSH_BINARY, 15, -2); //注意这个gray_dst有个取反符号,表示先取反再进行二值转换, 如果是白色背景的图, 就会变为黑色
namedWindow("binary image", CV_WINDOW_AUTOSIZE);
imshow("binary image", binImg_dst);
// 再显示开操作之后的图
Mat hline = getStructuringElement(MORPH_RECT, Size(src.cols / 16, 1), Point(-1, -1)); //横线, 核的y轴为1
Mat vline = getStructuringElement(MORPH_RECT, Size(1, src.rows / 16), Point(-1, -1)); //纵线, 核的x轴为1
// 提取水平线
// Mat temp;
// erode(binImg_dst, temp, hline); // 先腐蚀
// dilate(temp, dst, hline); // 再膨胀
// bitwise_not(dst, dst); // 图像取反操作, 将黑色背景再转为白色
// namedWindow("hline image", CV_WINDOW_AUTOSIZE);
// imshow("hline image", dst);
// 提取垂直线
// morphologyEx(binImg, dst, CV_MOP_OPEN, vline); // 直接进行开操作
// bitwise_not(dst, dst);
// namedWindow("vline image", CV_WINDOW_AUTOSIZE);
// imshow("vline image", dst);
// 提取水平线, 并使用均值滤波对结果进行优化显示
Mat temp;
erode(binImg_dst, temp, hline); // 先腐蚀
dilate(temp, dst, hline); // 再膨胀
bitwise_not(dst, dst); // 图像取反操作, 将黑色背景再转为白色
blur(dst, dst, Size(3, 3), Point(-1, -1)); // 均值滤波,进行边缘处理, 使图像更和谐一些
namedWindow("hline image", CV_WINDOW_AUTOSIZE);
imshow("hline image", dst);
效果截图:
原图:
灰度图:
取反过后的二值图:
提取水平线(再取反将背景变为白色):
提取垂直线(同上都是取反了的,背景一样变回为白色, 右下边那个几个短线是文字A的垂直部分,也被提取了)):
使用均值滤波过后的水平线提取