代码
#include "../common/common.hpp"
static int max_count = 255;
static int threshold_value = 100;
static const char* title = "Hough Lines";
static Mat src, roiImage, dst;
static void detectLines(int, void*);
static void morphologyLines(int, void*);
void main(int argc, char ** argv)
{
src = imread(getCVImagesPath("images/case3-2.png"), IMREAD_GRAYSCALE);
imshow("src3-2", src);
Rect roi = Rect(10, 10, src.cols - 20, src.rows - 20);
roiImage = src(roi); // 周边白线裁剪掉
//namedWindow(title, CV_WINDOW_AUTOSIZE);
//createTrackbar("Threshold:", title, &threshold_value, max_count, detectLines);
//detectLines(0, 0);
morphologyLines(0, 0);
waitKey(0);
}
void detectLines(int, void*) // 单纯的使用霍夫直线检测,得不到想要的结果
{
Canny(roiImage, dst, threshold_value, threshold_value * 2, 3, false);
//threshold(roiImage, dst, 0, 255, THRESH_BINARY | THRESH_OTSU); // 二值化
vector<Vec4i> lines; // 保存检测到的直线,Vec4i 保存线段两个点的四个坐标值
HoughLinesP(dst, lines, 1, CV_PI / 180.0, 30, 30.0, 0);
cout << "lines.size=" << lines.size() << endl;
cvtColor(dst, dst, COLOR_GRAY2BGR);
for (size_t t = 0; t < lines.size(); t++) {
Vec4i ln = lines[t];
line(dst, Point(ln[0], ln[1]), Point(ln[2], ln[3]), Scalar(0, 0, 255), 2, 8, 0);
}
imshow(title, dst);
}
void morphologyLines(int, void*) // 通过图像形态学操作来寻找直线,霍夫获取位置信息与显示
{
// binary image
Mat binaryImage, morhpImage;
threshold(roiImage, binaryImage, 0, 255, THRESH_BINARY_INV | THRESH_OTSU); // 二值化
imshow("binary", binaryImage);
// morphology operation
Mat kernel = getStructuringElement(MORPH_RECT, Size(30, 1), Point(-1, -1)); // 结构元素的选取非常重要
morphologyEx(binaryImage, morhpImage, MORPH_OPEN, kernel, Point(-1, -1)); // 开操作
imshow("morphology result", morhpImage); // 如果觉得此图的效果不够明显,可以膨胀一下此图,不膨胀对最终结果无影响
// dilate image
kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
dilate(morhpImage, morhpImage, kernel); // 膨胀,让二值图的直线更明显
imshow("morphology lines", morhpImage);
// hough lines
vector<Vec4i> lines; // 保存检测到的直线,Vec4i 保存线段两个点的四个坐标值
HoughLinesP(morhpImage, lines, 1, CV_PI / 180.0, 30, 20.0, 0);
cout << "mor lines.size=" << lines.size() << endl; // mor lines.size=32
Mat resultImage = roiImage.clone();
cvtColor(resultImage, resultImage, COLOR_GRAY2BGR);
for (size_t t = 0; t < lines.size(); t++) {
Vec4i ln = lines[t];
line(resultImage, Point(ln[0], ln[1]), Point(ln[2], ln[3]), Scalar(0, 0, 255), 2, 8, 0);
}
imshow("final img", resultImage);
}
效果图