opencv直线检测

#include 
#include
#include 
#include
#include
#include
using namespace std;
using namespace cv;

int max_count = 255;
int threshold_value = 100;
const char* output_lines = "Hough Lines";
Mat dst, src,roiImage;
void detectLines(int, void*);
void morhpologyLines(int, void*);
int main()
{
	src = imread("E:\\Users\\opencvCoder\\image\\exam.png", IMREAD_GRAYSCALE);
	if (src.empty())
	{
		printf("could not load image...\n");
		return -1;
	}

	namedWindow("input image", WINDOW_AUTOSIZE);
	imshow("imput image", src);
	Rect roi = Rect(10, 10, src.cols - 20, src.rows - 20);
	roiImage = src(roi);
	namedWindow("ROI image", WINDOW_AUTOSIZE);
	imshow("ROI image", roiImage);
	namedWindow(output_lines, WINDOW_AUTOSIZE);
	//常规直线检测,
	/*createTrackbar("threshold:", output_lines, &threshold_value, max_count, detectLines);
	detectLines(0, 0);*/

	//通过图像形态学操作来寻找直线,霍夫获取位置信息并显示
	morhpologyLines(0, 0);



	waitKey(0);
	return 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;
	HoughLinesP(dst, lines, 1, CV_PI / 180.0, 30, 30.0, 0);
	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(output_lines, dst);
}
//通过图像形态学操作来寻找直线,霍夫获取位置信息并显示
void morhpologyLines(int, void*)
{
	//binary image
	Mat binaryImage, morhpImage;
	//二值化图像
	threshold(roiImage, binaryImage, 0, 255, THRESH_BINARY_INV| THRESH_OTSU);
	imshow("binary image:", binaryImage);

	//morphology operation掩码
	Mat kernel = getStructuringElement(MORPH_RECT, Size(25, 1), Point(-1, -1));
	//形态学处理morphologyEx函数
	/*
	第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可。图像位深应该为以下五种之一:
	CV_8U, CV_16U,CV_16S, CV_32F 或CV_64F。

    第二个参数,OutputArray类型的dst,即目标图像,函数的输出参数,需要和源图片有一样的尺寸和类型。
    第三个参数,int类型的op,表示形态学运算的类型,可以是如下之一的标识符: 
          MORPH_OPEN – 开运算(Opening operation

          MORPH_CLOSE – 闭运算(Closing operation)

          MORPH_GRADIENT -形态学梯度(Morphological gradient)

          MORPH_TOPHAT - “顶帽”(“Top hat”)

          MORPH_BLACKHAT - “黑帽”(“Black hat“)
第四个参数,InputArray类型的kernel,形态学运算的内核。若为NULL时,表示的是使用参考点位于中心3x3的核。
我们一般使用函数 getStructuringElement配合这个参数的使用。getStructuringElement函数会返回指定形状和尺寸的结构元素(内核矩阵)。
关于getStructuringElement我们上篇文章中讲过了,这里为了大家参阅方便,再写一遍:
       其中,getStructuringElement函数的第一个参数表示内核的形状,我们可以选择如下三种形状之一: 

            矩形: MORPH_RECT

           交叉形: MORPH_CROSS

            椭圆形: MORPH_ELLIPSE

   而getStructuringElement函数的第二和第三个参数分别是内核的尺寸以及锚点的位置。

  我们一般在调用erode以及dilate函数之前,先定义一个Mat类型的变量来获得getStructuringElement函数的返回值。对于锚点的位置,有默认值Point(-1,-1),
  表示锚点位于中心。且需要注意,十字形的element形状唯一依赖于锚点的位置。而在其他情况下,锚点只是影响了形态学运算结果的偏移。
	
	
	*/
	morphologyEx(binaryImage, 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("morphology lines", morhpImage);

	 //hough lines
	 vector<Vec4i>lines;
	 /*
	 * 此函数在HoughLines的基础上末尾加了一个代表Probabilistic(概率)的P,表明它可以采用累计概率霍夫变换(PPHT)来找出二值图像中的直线。
	   第一个参数,InputArray类型的image,输入图像,即源图像,需为8位的单通道二进制图像,可以将任意的源图载入进来后由函数修改成此格式后,再填在这里。

		第二个参数,InputArray类型的lines,经过调用HoughLinesP函数后后存储了检测到的线条的输出矢量,每一条线由具有四个元素的矢量(x_1,y_1, x_2, y_2) 表示,
		其中,(x_1, y_1)和(x_2, y_2) 是是每个检测到的线段的结束点。

		第三个参数,double类型的rho, 以像素为单位的距离精度。 另一种形容方式是直线搜索时的进步尺寸的单位半径。

		第四个参数,double类型的theta,以弧度为单位的角度精度。另一种形容方式是直线搜索时的进步尺寸的单位角度。

		第五个参数,int类型的threshold,累加平面的阈值参数,即识别某部分为图中的一条直线时它在累加平面中必须达到的值。 
		大于阈值 threshold 的线段才可以被检测通过并返回到结果中。

		第六个参数,double类型的minLineLength,有默认值0,表示最低线段的长度,比这个设定参数短的线段就不能被显现出来。

		第七个参数,double类型的maxLineGap,有默认值0,允许将同一行点与点之间连接起来的最大的距离。

	 */
	 HoughLinesP(morhpImage, lines, 1, CV_PI / 180.0, 30, 20, 0.0);
	 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(output_lines, resultImage);

}

opencv直线检测_第1张图片

你可能感兴趣的:(C/C++,图像处理,算法,opencv,计算机视觉,人工智能)