OpenCV图像处理实际案例(二)---直线检测

本博客算法及代码参考自贾志刚老师的《OpenCV图像处理-小案例实战》,若涉及侵权问题,望通知,会第一时间删除。

功能要求:

从如下图片中找出所有直线。

OpenCV图像处理实际案例(二)---直线检测_第1张图片

 解决方案一:

         直接进行霍夫直线检测

代码实现:

/*=======================
========直线检测========
========================*/
#include 
#include 

using namespace cv;
using namespace std;

void detectHoughP(Mat&);


int main(int argc, char** argv)
{
	Mat src = imread("D:/VS2015_Projects/opencv_workspace/img/img_lines2.jpg",1);
	if (src.empty())
	{
		printf("load src img failed!\n");
		return -1;
	}
	imshow("src", src);
	detectHoughP(src);

	waitKey(0);
	return 0;
}

//统计概率霍夫线变换HoughLinesP()
void detectHoughP(Mat& src)
{
	Mat src_gray, binaryImg;
	cvtColor(src, src_gray, CV_BGR2GRAY);
	threshold(src_gray, binaryImg, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
	imshow("bin image", binaryImg);

	vector lines;  //储存着检测到的直线的参数对 (X1, Y1, X2, Y2) 的容器,也就是线段的两个端点
	HoughLinesP(binaryImg, lines, 1, CV_PI / 180, 30, 30, 0);

	Mat img_line = src.clone();
	//绘制直线
	for (size_t t = 0; t < lines.size(); t++) {
		Vec4i ln = lines[t];//Vec4i 就是Vec,里面存放4个int
		line(img_line, Point(ln[0], ln[1]), Point(ln[2], ln[3]), Scalar(0, 0, 255), 2, 8, 0);
	}

	imshow("line image", img_line);
}

处理效果

OpenCV图像处理实际案例(二)---直线检测_第2张图片 

从运行结果可看出,部分直线并未检测出来。

解决方案二:

        先进行形态学操作,然后再进行霍夫直线检测。

代码实现:

/*=======================
========直线检测========
========================*/
#include 
#include 

using namespace cv;
using namespace std;

void morhpologyLines(Mat&);


int main(int argc, char** argv)
{
	Mat src = imread("D:/VS2015_Projects/opencv_workspace/img/img_lines2.jpg",1);
	if (src.empty())
	{
		printf("load src img failed!\n");
		return -1;
	}
	imshow("src", src);
	morhpologyLines(src);

	waitKey(0);
	return 0;
}

//形态学处理+霍夫直线检测
void morhpologyLines(Mat& src)
{
	Mat src_gray, binaryImg;
	cvtColor(src, src_gray, CV_BGR2GRAY);
	threshold(src_gray, binaryImg, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
	//imshow("bin image", binaryImg);

	//形态学开运算
	Mat morhpImage;
	//结构元素:关键点在于窗口的选择,此处选择类直线扁平矩形,即可筛选出水平直线
	Mat kernel = getStructuringElement(MORPH_RECT, Size(20, 1), Point(-1, -1));
	morphologyEx(binaryImg, morhpImage, MORPH_OPEN, kernel, Point(-1, -1));
	//imshow("morphology result", morhpImage);

	//图像膨胀
	kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
	dilate(morhpImage, morhpImage, kernel);
	//imshow("dilate lines", morhpImage);

	vector lines;
	double rho = 1.0;
	double theta = CV_PI / 180.0;
	int threshold = 10;  //累加平面的阈值参数,int类型,超过设定阈值才被检测出线段。
	                     //值越大,基本上意味着检出的线段越长,检出的线段个数越少。
	HoughLinesP(morhpImage, lines, rho, theta, threshold, 10.0);

	//绘制直线
	Mat resultImage = src.clone();
	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("result image", resultImage);
}

运行效果:

OpenCV图像处理实际案例(二)---直线检测_第3张图片

从运行结果可看出,通过预先的形态学操作,使我们的处理效果得到了很好的提升,所以应该学会合理使用和搭配各种图像处理操作。

你可能感兴趣的:(OPENCV,计算机视觉)