图像处理(八)——霍夫变换

版权声明: https://blog.csdn.net/Godsolve/article/details/83867815

霍夫变换是一种特征检测(feature extraction),被广泛应用在图像分析(image analysis)、电脑视觉(computer vision)以及数位影像处理(digital image processing)。
霍夫变换是用来辨别找出物件中的特征,例如:线条。他的算法流程大致如下,给定一个物件、要辨别的形状的种类,算法会在参数空间(parameter space)中执行投票来决定物体的形状,而这是由累加空间(accumulator space)里的局部最大值(local maximum)来决定。

而本次实验我要做的就是使用霍夫变换进行图像圆的检测。

霍夫变换的过程可以分为以下几步:

  1. 对输入图像进行边缘检测,获取边界点,即前景点。
  2. 假如图像中存在圆形,那么其轮廓必定属于前景点(此时请忽略边缘提取的准确性)。
  3. 同霍夫变换检测直线一样,将圆形的一般性方程换一种方式表示,进行坐标变换。由x-y坐标系转换到a-b坐标系。写成如下形式(a-x)²+(b-y)²=r²。那么x-y坐标系中圆形边界上的一点对应到a-b坐标系中即为一个圆。
  4. 那x-y坐标系中一个圆形边界上有很多个点,对应到a-b坐标系中就会有很多个圆。由于原图像中这些点都在同一个圆形上,那么转换后a,b必定也满足a-b坐标系下的所有圆形的方程式。直观表现为这许多点对应的圆都会相交于一个点,那么这个交点就可能是圆心(a, b)。
  5. 统计局部交点处圆的个数,取每一个局部最大值,就可以获得原图像中对应的圆形的圆心坐标(a,b)。一旦在某一个r下面检测到圆,那么r的值也就随之确定。

在实际实现中,只需要注意输入的是灰度图,以及霍夫变换中的参数问题,就可以较好地实现图像中圆的检测。

结果如下图:
在这里插入图片描述

不过我的实现中还存在一些问题,例如图像如果是不完全连通的,有时候就不能识别。
在这里插入图片描述
在这张图例,第二行第二个圆就没有识别出来,而且第二行第一个图识别出了两个圆。

此外,对于边缘粗细不一样的图形,我的实现中会出现识别出n多个圆的情况。
在这里插入图片描述
可能是因为对于不同像素的位置,而识别出了不同的圆。


代码自取:

#include "stdafx.h"
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;
using namespace cv;

int main()
{
	//【1】载入原始图和Mat变量定义   
	Mat srcImage = imread("E:/C++/CVE7/1.jpg");  //工程目录下应该有一张名为1.jpg的素材图
	Mat midImage, dstImage;//临时变量和目标图的定义

						   //【2】显示原始图
	imshow("【原始图】", srcImage);

	//【3】转为灰度图,进行图像平滑
	cvtColor(srcImage, midImage, CV_BGR2GRAY);//转化边缘检测后的图为灰度图
	GaussianBlur(midImage, midImage, Size(9, 9), 2, 2);

	//【4】进行霍夫圆变换
	vector<Vec3f> circles;
	HoughCircles(midImage, circles, CV_HOUGH_GRADIENT, 1.5, 10, 200, 100, 0, 0);

	//【5】依次在图中绘制出圆
	for (size_t i = 0; i < circles.size(); i++)
	{
		Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
		int radius = cvRound(circles[i][2]);
		//绘制圆心
		circle(srcImage, center, 3, Scalar(0, 255, 0), -1, 8, 0);
		//绘制圆轮廓
		circle(srcImage, center, radius, Scalar(155, 50, 255), 3, 8, 0);
	}

	//【6】显示效果图  
	imshow("【效果图】", srcImage);

	waitKey(0);

	return 0;
}




猜你喜欢

转载自blog.csdn.net/Godsolve/article/details/83867815