霍夫直线和圆检测

在图像处理中,图像的特征提取是一大关键,今天学习的霍夫变换就是用来提取图像中的直线和圆的。

对于霍夫的直线检测,步骤如下:

(1)利用Canny边缘提取获取图像边缘的灰度图

(2)利用函数HoughLinesP(源Mat对象,存放结果的向量,以像素为单位的距离精度,以弧度为单位的角度精度,阈值,最短距离,最大间断距离)//存放结果的向量是一个n x 4的二维数组,每个单元有四个值,分别代表直线两端的坐标,以像素为单位的距离精度一般取1,以弧度为单位的角度精度一般取CV_PI / 180,阈值是指累加平面的参数,根据原理,累加次数越多,越可能是直线,所以阈值越高,检测到的直线越少,最短距离是指一条直线的最短长度,最大间断距离是指两个间断点能否被认定在一条直线上的最大jian'du。

(3)利用line函数和存放结果的向量生成直线。

对于霍夫的圆检测,步骤如下:

(1)利用滤波对图像进行降噪操作,并把图像转换成灰度图。

(2)利用函数HoughCircles(源Mat对象,存放结果的向量,检测方法,累加器图像的分辨率与输入图像的分辨率之比的倒数,判断是否为同心圆的最小距离,Canny算子的高阈值,累加器阈值,最小半径,最大半径)//存放结果的向量与直线类似,只不过每个单元只有3个值,分别为圆心坐标和半径,检测方法只有一种,HOUGH_GRADIENT,累加器分辨率与输入图像分辨率之比的倒数一般取1,是否为同心圆的最小距离如果太小会检测错误,太大会漏掉一些圆。因为该算法中包含了Canny处理,所以需要提供Canny算子的高阈值,低阈值为其一半,累加器阈值与直线的类似,阈值越高越准确,但是检测到的越少,最大半径和最小半径确定检测范围,默认都是0,即无限制。

(3)利用circle函数和结果向量生成圆。

演示代码:

扫描二维码关注公众号,回复: 3039464 查看本文章
#include<opencv2\opencv.hpp>
#include<iostream>
#include<math.h>
#include<algorithm>
#include<stdlib.h>

using namespace std;
using namespace cv;

Mat src, dst_line, src_gray, dst_gray, dst_cir;

int main()
{
	src = imread("2.jpg", 1);
	if (src.empty())
	{
		printf("cannot load!!\n");
		system("pause");
		return -1;
	}
	namedWindow("原图");
	imshow("原图", src);

	//先进行Canny边缘提取
	cvtColor(src, src_gray, CV_BGR2GRAY);
	Canny(src_gray, dst_gray, 100, 200);
	namedWindow("Canny");
	imshow("Canny", dst_gray);

	//霍夫直线检测
	src.copyTo(dst_line);
	vector<Vec4f>plines;//结果向量的建立,每个单位是个Vec4f,即4个浮点数
	HoughLinesP(dst_gray, plines, 1, CV_PI / 180, 80, 50, 10);
	for (int i = 0; i < plines.size(); i++)
	{
		Vec4f p = plines[i];
		line(dst_line, Point(p[0], p[1]), Point(p[2], p[3]), Scalar(255, 0, 0), 1, LINE_AA);
	}
	namedWindow("Lines Result");
	imshow("Lines Result", dst_line);

	src = imread("2.png", 1);
	cvtColor(src, src_gray, CV_BGR2GRAY);

	//先进行高斯滤波或者中值滤波,圆检测不用Canny边缘提取了,因为圆检测的函数中已经包含了
	GaussianBlur(src_gray, src_gray, Size(5, 5), 0, 0);
	namedWindow("高斯滤波");
	imshow("高斯滤波", src_gray);

	//霍夫圆检测
	src.copyTo(dst_cir);
	vector<Vec3f>pc;
	HoughCircles(src_gray, pc, HOUGH_GRADIENT,1,10,100,30);
	for (int i = 0; i < pc.size(); i++)
	{
		Vec3f p = pc[i];
		circle(dst_cir, Point(p[0], p[1]), p[2], Scalar(255, 0, 0),2);
	}
	namedWindow("Circle Result");
	imshow("Circle Result", dst_cir);

	waitKey(0);
	return 0;
}
演示效果:








猜你喜欢

转载自blog.csdn.net/ZouCharming/article/details/70717774