得到一条水平线,就需要把不是水平线的干扰元素去掉。就需要定义一个水平或垂直的结构,如果被这个结构元素覆盖,那就可以去掉这部分,然后将水平线分离出来。
adaptiveThreshold函数
void adaptiveThreshold( InputArray src, OutputArray dst, double maxValue, int adaptiveMethod, int thresholdType, int blockSize, double C );
adaptiveThreshold(
Mat src, // 输入的灰度图像
Mat dest, // 二值图像
double maxValue, // 二值图像最大值255
int adaptiveMethod // 自适应方法,只能其中之一 –
// ADAPTIVE_THRESH_MEAN_C局部邻域块的平均值 ,ADAPTIVE_THRESH_GAUSSIAN_C 局部邻域块的高斯加权和
int thresholdType,// 阈值类型.可选择THRESH_BINARY或者THRESH_BINARY_INV两种。(即二进制阈值或反二进制阈值)。
int blockSize, // 块大小,一般选择为3、5、7…奇数
double C // 常量C 可以是正数,0,负数
)
下列代码:
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
int main(int argc, char** argv) {
Mat src,gray_src,bin_src,dst,m1;
src = imread("d:/03.png");
if (!src.data) {
cout << "not load..." << endl;
return -1;
}
namedWindow("input", WINDOW_AUTOSIZE);
imshow("input", src);
//转换为灰度图像
cvtColor(src, gray_src, CV_BGR2GRAY);
imshow("gray", gray_src);
//转换为二值图像
adaptiveThreshold(~gray_src, bin_src, 255,ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 15, -2);
imshow("BIN", bin_src);
//进行开操作
//水平结构
Mat xline = getStructuringElement(MORPH_RECT, Size(src.cols/32, 1), Point(-1, -1));
//垂直结构
Mat yLine = getStructuringElement(MORPH_RECT, Size(1, src.rows/32), Point(-1, -1));
Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
erode(bin_src, m1, kernel);//腐蚀
dilate(m1, dst, kernel);//膨胀
//morphologyEx(bin_src, m1, CV_MOP_OPEN, xline); //开操作
//blur(m1, m1, Size(3, 3), Point(-1, -1)); //为了让结果更好看,模糊一下
bitwise_not(m1,m1);
imshow("最终", m1);
waitKey(0);
return 0;
}