案例背景:将答题卡中的直线提取出来
方案思路:二值化后利用霍夫直线检测,效果特别差;canny边缘检测后利用霍夫直线检测效果也很差,有些线检测不出来。这里采用的方法是基于形态学的直线提取,再利用霍夫直线检测。
#include<opencv2\opencv.hpp>
using namespace cv;
using namespace std;
int main(int arc, char** argv) {
Mat src = imread("1.jpg");
namedWindow("input", CV_WINDOW_AUTOSIZE);
imshow("input", src);
cvtColor(src, src, CV_BGR2GRAY);
Mat binaryImg, morphImg;
Rect roi = Rect(10, 10, src.cols - 20, src.rows - 20);
Mat roiImg = src(roi);
threshold(roiImg, binaryImg, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
imshow("binaryImg", binaryImg);
//定义水平直线结构元素,开操作进行水平直线的提取
Mat kernel = getStructuringElement(MORPH_RECT, Size(30, 1), Point(-1, -1));
morphologyEx(binaryImg, morphImg, MORPH_OPEN, kernel);
imshow("morphImg", morphImg);
//膨胀加强直线
kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
dilate(morphImg, morphImg, kernel);
imshow("dilateImg", morphImg);
//霍夫直线检测
vector<Vec4i>lines;
HoughLinesP(morphImg, lines, 1, CV_PI / 180, 30, 20.0,0);
Mat resultImg = roiImg.clone();
cvtColor(resultImg, resultImg, CV_GRAY2BGR);
for (int i = 0; i < lines.size(); i++) {
Vec4i ln = lines[i];
line(resultImg, Point(ln[0], ln[1]), Point(ln[2], ln[3]), Scalar(0, 0, 255));
}
imshow("result", resultImg);
printf("%d", lines.size());
waitKey(0);
return 0;
}