『OpenCV3』霍夫变换

Posted hellcat

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了『OpenCV3』霍夫变换相关的知识,希望对你有一定的参考价值。

霍夫变换常用于检测直线特征,经扩展后的霍夫变换也可以检测其他简单的图像结构。

在霍夫变换中我们常用公式

ρ = x*cosθ + y*sinθ

表示直线,其中ρ是圆的半径(也可以理解为原点到直线的距离),θ是直线与水平线所成的角度(0~180°),确定了它们,也就确定一条直线了,和下图略有出入的是实际的原点定在图片左上角。

技术分享图片

原理是对于输入的二值图像中的像素点(有值的),按照步长(参数三参数四对应rho和theta的步长)分别计算出每个点上的所有可能的直线。记录下每条直线经过的点数(即存在多个点计算出的直线有交集),按照阈值(参数五)筛选符合条件的图像。

霍夫变换

霍夫变换接收二值化的输入,即已经进行初步的轮廓检测之后,才进行直线检测;输出一组cv::Vec2f,通常用vector<CV::Vec2f>接收,所以我们通常使用Canny检测之后进行霍夫变换

输出的两个float数字表示(rho, theta),使用cv::line绘图,因其参数需要的是线段的两个端点,所以我们不得不进行还原操作。

void hough() {
	cv::Mat image = cv::imread("road.png");
	cv::Mat midImage;
	cv::Canny(image, midImage, 50, 200, 3);
	std::vector<cv::Vec2f> lines;
	cv::HoughLines(midImage, lines, 1, CV_PI / 180, 150);  // 输入的时二值图像,输出vector向量
	for (size_t i=0; i < lines.size(); i++) {
		float rho = lines[i][0]; //就是圆的半径r
		float theta = lines[i][1]; //就是直线的角度
		cv::Point pt1, pt2;
		double a = cos(theta), b = sin(theta);
		double x0 = a*rho, y0 = b*rho;
		pt1.x = cvRound(x0 + 1000 * (-b));
		pt1.y = cvRound(y0 + 1000 * (a));
		pt2.x = cvRound(x0 - 1000 * (-b));
		pt2.y = cvRound(y0 - 1000 * (a));

		cv::line(image, pt1, pt2, cv::Scalar(55, 100, 195), 1); //Scalar函数用于调节线段颜色,就是你想检测到的线段显示的是什么颜色

		cv::imshow("边缘检测后的图", midImage);
		cv::imshow("最终效果图", image);
	}
}

技术分享图片

概率霍夫变换

概率霍夫变换输出Vec4i,直接输出了每一条线段的首尾,绘图更加方便。它是霍夫变换的改进版,由于算法的改进(会沿着搜寻到的直线扫描图像),可以进一步检测到线段的长度,除了最小投票数(参数五)外,可以额外限制最小线段长度(参数六)和同一线段最大像素间距(参数七)。

void houghp() {
	cv::Mat image = cv::imread("road.png");
	cv::Mat midImage;
	cv::Canny(image, midImage, 50, 200, 3);
	std::vector<cv::Vec4i> lines;
	cv::HoughLinesP(midImage, lines, 1, CV_PI / 180, 50);  // 输入的时二值图像,输出vector向量
	for (int i=0; i < lines.size(); i++) {
		cv::Point pt1(lines[i][0], lines[i][1]);
		cv::Point pt2(lines[i][2], lines[i][3]);
		cv::line(image, pt1, pt2, cv::Scalar(0, 255, 255));
	}
	cv::imshow("概率霍夫变换", image);
}

技术分享图片

以上是关于『OpenCV3』霍夫变换的主要内容,如果未能解决你的问题,请参考以下文章

MATLAB中用霍夫变换检测出了直线之后怎么求斜率

使用霍夫变换检测圆

OpenCV 霍夫变换——圆

opencv识别车道线(霍夫线变换)

pyhton—opencv直线检测(HoughLines)找到最长的一条线

pyhton—opencv直线检测(HoughLines)找到最长的一条线