OpenCV(六)——Hough检测圆原理及算法实现

 hough检测圆的思路:

(1)图像中取出圆的轮廓(灰度值为255)

(2)根据圆的极坐标公式:

x = x_{0} + r * cos(\Theta )

y = y_{0} + r * sin(\Theta )

现在已知的是圆上的点,则x,y已知,反推出x0 和 y0(圆心的位置)。

\Theta的范围是0~360度,不过注意要转化成弧度。

(3)投票机制:

每次根据(2)公式得到的点,都在数组相应坐标+1

(4)归一化:

得到最大投票数的点,生成的图像在该点的像素灰度置为255。

(5)画圆。

根据搜索的半径,画圆。

#include 
#include 
#include 

using namespace std;
using namespace cv;


bool range(Mat &im, int x, int y)//判定是否在图片区域内
{
	if(x >= 0 && x < im.cols && y >= 0 && y < im.rows)
		return true;
	return false;
}
void houghCircle(Mat &image, int r)
{
	int mat_size = image.cols * image.rows;
	int *p_map = new int[mat_size];
	memset(p_map, 0, 4 * mat_size);
	int max_value = 0;
	for(int i = 0; i < image.cols; i++)
	{
		for(int j = 0; j < image.rows; j++)
		{
			if(image.at(j,i) == 255)
				for(int a = 0; a < 360; a++)
				{
					double theta = a * CV_PI / 180;//转成弧度制
					int x = i - r * cos(theta);//得到理想圆心x坐标
					int y = j - r * sin(theta);//得到理想圆心y坐标
					if(range(image, x, y))
					{
						p_map[y * image.cols + x]++;
						int value_ = p_map[y * image.cols + x];
						max_value = max_value < value_ ? value_ : max_value;//记录最大投票数
						
					}
				}

		}
	}
	
	for(int i = 0; i < image.cols; i++)
	{
		for(int j = 0; j < image.rows; j++)
		{
			p_map[j * image.cols + i] = p_map[j * image.cols + i] * 255 / max_value;//归一化

		}

	}

	Mat dst_mat = Mat::zeros(image.size(), CV_8UC1);
	Point center;
	for(int i = 0; i < dst_mat.cols; i++)
	{
		for(int j = 0; j < dst_mat.rows; j++)
		{
			uchar * color_ptemp = dst_mat.ptr(j);
			color_ptemp[i] = p_map[j * image.cols + i];
			if(color_ptemp[i] == 255)
				center = Point(i, j);//记录投票数最大的为圆心

		}

	}
	circle(dst_mat, center, r, Scalar(255),1);
	delete []p_map;
	imshow("dst_mat",dst_mat);


}


int main()
{
	Mat image = imread("c.jpg",IMREAD_GRAYSCALE);
	imshow("image",image);
	houghCircle(image,50);
	waitKey();
	return 0;
}

原图:

OpenCV(六)——Hough检测圆原理及算法实现_第1张图片

hough检测圆:

OpenCV(六)——Hough检测圆原理及算法实现_第2张图片

你可能感兴趣的:(opencv算法实现)