opencv 简单的实现霍夫变换

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_38204686/article/details/79314080
//霍夫变换  输入单通道二值图像  大小640x480 
void hough(Mat &img)
{
	//累积和 可以根据图片大小来定 这里就随意了
	//注意r 和 theta 的取值范围就好 注意堆栈溢出 我这里调整了默认堆栈大小
	int line_cnt[1500][180] = {0};
	int r = 0;
	int theta = 0;

	//行列
	int row = img.rows;
	int col = img.cols;
	//遍历图像
	int i,j,k=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 = x*cos(theta)+y*sin(theta)
					r =cvRound(j*cos(theta*CV_PI/180)+i*sin(theta*CV_PI/180));
					r = r + 640; //偏移   r有可能是负值 下面计算再 - 640
					line_cnt[r][theta]++;
				}
			}
        }  
    } 
	//取出最长的n条直线
	const int n = 10;
	double line_n[n][2];
	int rr = 0,tt = 0;
	for(i = 0; i < n; i++)
	{
		for( r = 0; r < 1500; r++)
		{
			for(theta = 0; theta < 180; theta++)
			{
				if(line_cnt[rr][tt] < line_cnt[r][theta])
				{
					rr = r;
					tt = theta;
				}
			}
		}
		//累加器清零  将直线的 r theta 放入数组
		line_cnt[rr][tt] = 0;
		line_n[i][0] = double(rr -640);
        line_n[i][1] = tt*CV_PI/180;
	}

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

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

猜你喜欢

转载自blog.csdn.net/qq_38204686/article/details/79314080