1.原理方法
通过自定义的结构元素,实现结构元素对输入图像的一些对象敏感,另一些对象不敏感,从而就可以让敏感的对象改变而不敏感的对象保留。通过两个最基本的形态学操作——膨胀与腐蚀,使用不同的结构元素对输入图像的进行操作,得到想要的结果。
2.步骤
- 输入图像彩色图像——imread();
- 转化为灰度图像——cvtColor();
- 转化为二值图像——adaptiveThreshold();
- 定义结构元素——getStructuringElement();
- 开操作(腐蚀 膨胀)提取水平与垂直线morphologyEX(CV_MOP_OPEN);
- 后处理(根据实际情况考虑是否添加):像素取反操作bitwise_not()和模糊blur()
2.1输入彩色图像
2.2 转化为灰度图像
2.3 转化为二值图像
adaptiveThreshold();
- Mat src, // 输入的灰度图像
- Mat dest, // 二值图像
- double maxValue, // 二值图像最大值
- int adaptiveMethod // 自适应方法,只能其中之一 –
// ADAPTIVE_THRESH_MEAN_C , ADAPTIVE_THRESH_GAUSSIAN_C - int thresholdType,// 阈值类型(THRESH_BINARY)
- int blockSize, // 块大小
- double C // 常量C 可以是正数,0,负数
2.3 定义结构元素
定义两个结构元素,分别为了提取水平线和垂直线:
- 一个像素宽的水平线 - 水平长度 width/30,垂直长度为1;
- 一个像素宽的垂直线 –水平长度为1, 垂直长度 height/30。
2.4 开操作(腐蚀 膨胀)
开操作实现有两种方法:
- 先进行腐蚀erode(),再膨胀dilate()
- 直接使用morphology(),然后给一个开操作的形参CV_MOP_OPEN
两种方法的效果相同,使用第二种只用一个方法(函数),较为简便一些。
2.5 后处理
- 像素取反操作,即255-SrcPixel,为了将背景改为黑色或白色,使结果更专业更好看。
bitwise_not(Mat bin,Mat dst);
- 使用模糊是结果更好看,常用均值模糊blur():
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;
}