opencv 简单的实现霍夫变换(改进版)

//霍夫变换  输入单通道二值图像 检测直线数量
void HoughLines(Mat &img,int n)
{
	int i,j;
	//行列
	int row = img.rows;
	int col = img.cols;

	//极径最大值为 对角线+宽
	int max_r = col + cvCeil (sqrt(double(row*row+col*col)));

	//累加器 三角函数
	int *line_cnt[180];
	double sin_[180],cos_[180],rad_ = CV_PI/180;
	for(i = 0; i < 180; i++)
	{
		//初始化累加器为0
		line_cnt[i] = new int[max_r]();
		//初始化三角函数
		sin_[i] = sin(i*rad_);
		cos_[i] = cos(i*rad_);
	}

	//极径 极角
	int r = 0;
	int theta = 0;

	//遍历图像 判断并进行累加
	uchar *p;  
    for( i = 0; i < row; i++)  
    {  
        p = img.ptr<uchar>(i);  
        for ( j = 0; j < col; j++)  
        {
            if(p[j] != 0) 
			{
				for( theta =0; theta < 180 ; theta++)
				{
					//极坐标 直线方程
					r =cvRound(j*cos_[theta]+i*sin_[theta]);
					//偏移 无负值
					r = r + col;
					line_cnt[theta][r]++;
				}
			}
        }  
    } 

	//存放取出最长的n条直线   
	int *line_n[3];
	line_n[0] = new int[n]();//极角
    line_n[1] = new int[n]();//极径
	line_n[2] = new int[n]();//共点数量
	int tt = 0,rr = 0,cnt = 0;
	for(theta = 0; theta < 180; theta++)
	{
		for( r = 0; r < max_r; r++)
		{
			//最少共点 < 这条直线的共点 则替换 并尝试进行冒泡
			if(line_n[2][n-1] < line_cnt[theta][r])
			{
				line_n[0][n-1] = theta;
				//累计的时候偏移过 这里再偏移回来
				line_n[1][n-1] = r - col;
				line_n[2][n-1] = line_cnt[theta][r];
				//冒泡排序
				for(i = n - 1;i > 0; i--)
				{
					//如果大于 则交换
					if(line_n[2][i] > line_n[2][i-1])
					{
						tt = line_n[0][i];
						rr = line_n[1][i];
						cnt = line_n[2][i];
						line_n[0][i] = line_n[0][i-1];
						line_n[1][i] = line_n[1][i-1];
						line_n[2][i] = line_n[2][i-1];
						line_n[0][i-1] = tt;
						line_n[1][i-1] = rr;
						line_n[2][i-1] =cnt;
					}
					else
						break;
				}
			}
		}
	}

	//为了画绿线 单通道转换为三通道
    cvtColor(img, img, CV_GRAY2BGR);

	//画出线段
	for(i = 0; i < n; i++ )  
    {
		Point pt1, pt2;  
		double a = cos_[line_n[0][i]], b = sin_[line_n[0][i]];  
		double x0 = a* line_n[1][i], y0 = b* line_n[1][i];  
		pt1.x = cvRound(x0 + max_r*(-b));  
		pt1.y = cvRound(y0 + max_r*(a));  
		pt2.x = cvRound(x0 - max_r*(-b));  
		pt2.y = cvRound(y0 - max_r*(a)); 
		//绿线
		line(img, pt1, pt2, Scalar(0,255,0), 1, CV_AA); 
    } 

	//-------------------释放内存------------------------
	for(i = 0; i < 180; i++)
	{
		delete []line_cnt[i];
	}
	delete []line_n[0];
	delete []line_n[1];
	delete []line_n[2];
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大米粥哥哥

感谢认可!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值