霍夫(Hough)变换

霍夫变换一种特征提取技术,是从图像中识别几何形状的基本方法之一
霍夫变换的三种形态:
1.标准霍夫变换(SHT),由HoughLines函数调用
2.多尺度霍夫变换(MSHT),由HoughLines函数调用
3.累计概率霍夫变换(PPHT),由HoughLinesP函数调用
在霍夫变换中,采用极坐标系表示直线
总结一下:霍夫变换的实质是,寻找通过图像中某一点的所有直线,再寻找通过图像另一点的所有直线,并绘制出曲线图,两个曲线图的交点就是通过这两点的那条直线。
程序:
在程序中会用到的函数:
函数 cvRound, cvFloor, cvCeil 用一种舍入方法将输入浮点数转换成整数。 cvRound 返回和参数最接近的整数值。 cvFloor 返回不大于参数的最大整数值。cvCeil 返回不小于参数的最小整数值。

line()函数

void MyLine( Mat img, Point start, Point end )
{
  int thickness = 2;
  int lineType = 8;
  line( img,
        start,
        end,
        Scalar( 0, 0, 0 ),
        thickness,
        lineType );
}
标准霍夫变换:
int main()
{
   Mat src=imread("lou.jpg",0);
   blur(src,src,Size(3,3));  //滤波去噪
   Mat dst;
   Canny(src,dst,50,150,3); //取边缘,输出边缘二值图像
   vector<Vec2f> lines;     //存储线段
   HoughLines(dst,lines,1,CV_PI/180,150);   //第三个是p的步进,第四个参数是theta的步进,最后一个是阈值
   for(int i=0;i<lines.size();i++)
   {
double p=lines[i][0];            //lines的第一维存储线段,第二维存储线段的属性
double theta=lines[i][1];
Point pot1,pot2;
double a,b;
a=sin(theta);
b=cos(theta);
pot1.x=cvRound((p+2)*b);    //这里加2减2是为了让一个点扩散成一个线
pot1.y=cvRound((p+2)*a);
pot2.x=cvRound((p-2)*b);
                pot2.y=cvRound((p-2)*a);  
line(dst,pot1,pot2,Scalar(100,200,10));
   }
   imshow("a",dst);
   waitKey(0);
}
累计概率霍夫变换:
int main()
{
   Mat src=imread("lou.jpg",0);
   blur(src,src,Size(3,3));
   Mat dst;
   Canny(src,dst,50,150,3);//取边缘,输出边缘二值图像
   vector<Vec4i> lines;   //vector内可以存结构体的
   HoughLinesP(dst,lines,1,CV_PI/180,150,20,10);   //150是阈值,20是最小线段长度,10是最大间隔
   for(int i=0;i<lines.size();i++)
   {
  Vec4i ln=lines[i];
  line(dst,Point(ln[0],ln[1]),Point(ln[2],ln[3]),Scalar(100,200,20),1);
   }
   imshow("a",dst);
   waitKey(0);
}
比标准霍夫变换的优势在于可以自动控制线的长度,不至于将物体边缘所在的直线全部绘制出来。
霍夫圆变换
跟上述两个函数比,不需要用二值图像进行霍夫圆变换

可以检测灰度图像中的圆形

int main()
{
   Mat src=imread("yuan2.jpg",0);
   GaussianBlur(src,src,Size(3,3),1,1);
  // imshow("a",src);
 //  waitKey(0);
   Mat dst;
   vector<Vec3f> circles;
   HoughCircles(src,circles,CV_HOUGH_GRADIENT,1,10,100,50,0,0);  //第四个参数=1,累加器与输入图像有相同分辨率
   //=2,累加器有图像一半的宽度和高度
   //第五个参数10是圆心的最小距离,参数太小多个相邻圆会变成一个。
   //第六七个参数200,100是两个阈值参数,高阈值是低阈值的2倍,阈值越小表明检测的圆越多,越大检测的圆越准,也少。
   cout<<circles.size()<<endl;
   for(int i=0;i<circles.size();i++)
   {
  Vec3f c=circles[i];
  Point center(cvRound(c[0]),cvRound(c[1]));
  int r=cvRound(c[2]);
  circle(src,center,3,Scalar(255,0,0),-1,8,0); //线粗定义为 thickness = -1, 因此次圆将被填充
       circle(src,center,r,Scalar(0,255,0),3,8,0);
  cout<<i<<endl;
   }
   
   imshow("b",src);
   waitKey(0);
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值