//霍夫变换 输入单通道二值图像 大小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);
}
}
opencv 简单的实现霍夫变换
最新推荐文章于 2021-05-11 16:29:57 发布