Opencv--霍夫变换-直线

Hough Line变换

目标

  • 使用OpenCV函数cv :: HoughLines和cv :: HoughLinesP来检测图像中的行。

理论

注意

下面的解释属于Bradski和Kaehler 的“ 学习OpenCV ”一书。

Hough Line变换

  1. Hough Line变换是用于检测直线的变换。
  2. 为了应用变换,首先需要边缘检测预处理。

它是如何工作的?

  1. 如你所知,图像空间中的一行可以用两个变量表示。例如:在笛卡尔坐标系中:参数:(m,b);在极坐标系中:参数:(r,θ)

Opencv--霍夫变换-直线_第1张图片

对于Hough 变换,我们将在极地系统中表达线条。因此,线性方程可以写为:Hough Line变换

Hough Line变换

排列术语:r=xcosθ+ysinθ

  • 通常,对于每个点(x0,y0),我们可以定义通过该点的行给出如下公式:

Hough Line变换

意思是每一对的 (rθ,θ)表示通过每一排的 (x0,y0)

 

  • 如果对于给定的 (x0,y0)我们绘制通过它的线族,我们得到一个正弦曲线,例如,对于x0=8和y0=6 ,我们得到以下图(在平面 θ - r)

Opencv--霍夫变换-直线_第2张图片

我们只需考虑这样的情况: r>0 和 0<θ<2π.

  • 我们可以对图像中的所有点执行上述相同的操作。如果两个不同点的曲线在平面θ - r相交,那意味着两个点都属于同一行。例如,按照上面的例子,并绘制两个点的x1=4, y1=9 和 x2=12, y2=3,,我们得到:

Opencv--霍夫变换-直线_第3张图片

三个曲线在一个点(0.925,9.6)相交,这些坐标是参数 ( θ,r) 或其中(x0,y0), (x1,y1) 和 (x2,y2) lay.

  • 上面所有的东西是什么意思?这意味着一般来说,通过找到曲线之间的交点数可以检测到一条线。更多的相交曲线意味着由该交点表示的线具有更多的点。通常,我们可以定义检测线路所需的最小交点数的阈值。
  • 这就是Hough Line变换所做的。它跟踪图像中每个点的曲线之间的交点。如果交叉点的数量高于某个阈值,则它将其声明为具有交点的参数(θ,rθ)的行。

标准和概率Hough Line变换

OpenCV实现了两种Hough线变换:

一个。标准Hough变换

  • 它几乎包含在上一节中我们刚刚解释的内容。它给你一个向量的结果(θ,rθ)
  • 在OpenCV中,它使用函数cv :: HoughLines实现

湾 概率霍夫线变换

  • 更有效地实现Hough Line变换。它给出检测出的行的极值(x0,y0,x1,y1)
  • 在OpenCV中,它使用函数cv :: HoughLinesP来实现

Code

加载图像应用标准Hough Line变换或概率线变换。在两个窗口中显示原始图像和检测到的线:

//#include "opencv2/imgcodecs.hpp"
//#include "opencv2/highgui.hpp"
//#include "opencv2/imgproc.hpp"

#include 
#include 
#include 

using namespace cv;
using namespace std;
Mat src, cdst, dst;
int main(int argc, char** argv) {
	src = imread("C:/usr/opencv-test/Testpictures/sight.jpg");
	if (!src.data) {
		printf("could not load image...\n");
		return -1;
	}

	char INPUT_TITLE[] = "input image";
	namedWindow(INPUT_TITLE, CV_WINDOW_AUTOSIZE);
	//imshow(INPUT_TITLE, src);

	Canny(src, dst, 50, 200, 3);
	cvtColor(dst, cdst, COLOR_GRAY2BGR);

	vector lines;
	HoughLinesP(dst, lines, 1, CV_PI / 180.0, 10, 0, 0);
	for (size_t i = 0; i < lines.size(); i++)
	{
		Vec4f l = lines[i];
		line(cdst, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0, 0, 255), 3, LINE_AA);
	}
	imshow(INPUT_TITLE, src);
	imshow("detected lines", cdst);

	waitKey(0);
	return 0;
}

说明

  • 加载图像
  • 使用Canny检测器检测图像的边缘
Canny(src,dst,50,200,3);

 

  • 标准霍夫线变换

首先,你应用变换:

vector lines;
HoughLines(dst, lines, 1, CV_PI/180, 10, 0, 0 );

具有以下参数:

  1. dst:边缘检测器的输出。它应该是一个灰度图像(尽管事实上它是二进制的)
  2. 行:一个向量,将存储检测到的行的参数(r,θ)
  3. rho:参数的分辨率(以像素为单位)。我们使用1像素。r
  4. theta:以弧度表示的参数的分辨率。我们使用1度(CV_PI / 180)θ
  5. threshold:将“* detect *”一行的最小交点数
  6. srn和stn:默认参数为零。 

然后通过绘制线条显示结果。

for( size_t i = 0; i < lines.size(); i++ )
{
  Vec4i l = lines[i];
  line( cdst, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0,0,255), 3, LINE_AA);
}

效果图如下:

Opencv--霍夫变换-直线_第4张图片

Opencv--霍夫变换-直线_第5张图片

 

你可能感兴趣的:(嵌入式)