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 <opencv2/opencv.hpp>
#include <iostream>
#include <vector>

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<uchar>(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<uchar>(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;
}

原图:

hough检测圆:

  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值