待处理图片:
看到直线检测,首先想到的就是霍夫线变换,先试一下,看一下效果:
Mat img_gray;
cvtColor(srcmat,img_gray,CV_BGR2GRAY);
Mat img_bin;
//int pos = otsu(img_gray);
int threshold_value = 100;
Canny(img_gray, img_bin, threshold_value, threshold_value * 2, 3, false);
vector<Vec4i> lines;
HoughLinesP(img_bin,lines,1,CV_PI/180.0,20,20.0,0);
for (size_t t = 0; t < lines.size(); t++)
{
Vec4i In = lines[t];
line(srcmat,Point(In[0],In[1]), Point(In[2],In[3]),Scalar(0,0,255),2,8,0);
}
namedWindow("dst",WINDOW_NORMAL);
imshow("dst",srcmat);
霍夫线变换检测效果:
效果很差,边缘也出现了很多检测错误的地方。
下面学习一下,使用基本的形态学滤波,使用巧妙的element设置,可以很好的找出只有答题线的位置:
部分代码:
Mat img_gray;
cvtColor(srcmat,img_gray,CV_BGR2GRAY);
Mat img_bin;
threshold(img_gray,img_bin,0,255,THRESH_BINARY_INV | THRESH_OTSU); //大津算法二值化
Mat img_morph;
Mat kernel = getStructuringElement(MORPH_RECT,Size(20,1),Point(-1,-1));
morphologyEx(img_bin,img_morph,MORPH_OPEN,kernel,Point(-1,-1));
kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
dilate(img_morph, img_morph, kernel);
vector<Vec4i> lines;
HoughLinesP(img_morph, lines, 1, CV_PI / 180.0, 30, 25.0, 0);
for (size_t t = 0; t < lines.size(); t++) {
Vec4i ln = lines[t];
line(srcmat, Point(ln[0], ln[1]), Point(ln[2], ln[3]), Scalar(0, 0, 255), 2, 8, 0);
}
检测效果:
效果很好地将答题线地部分检测到了。
代码中地二值化依旧使用了大津算法,这次使用地是opencv里面自带地函数。