在Linux上实现摄像头中的霍夫圆检测


一 霍夫变换的原理

       Hough变换的基本思想是利用点-线的对偶性。

     一条直线可以用两个元素来确定:在笛卡尔坐标系中用斜率和截距(k,b);在极坐标中用用极径和极角(r,θ)。由于在x-y坐标系中垂直直线的k值为无穷大,这将给计算带来麻烦,所以我们采用极坐标系来表示直线。即:

r=xcosθ+ysinθ

     显然对于固定的(x0,y0),(r,θ)将表示一条正弦曲线。也就是说x-y平面的一个点将对应r-θ平面的一条直线。将通过点(x0,y0)的一条直线上的另一些点再描绘到r-θ平面,会发现这些点对应的直线在r-θ平面交于一点,这一点即x-y平面的那些点所在的直线。

     这意味着一般来说, 一条直线能够通过在平面\theta-r寻找交于一点的曲线数量来检测. 越多曲线交于一点也就意味着这个交点表示的直线由更多的点组成. 一般来说我们可以通过设置直线上点的 阈值 来定义多少条曲线交于一点我们才认为 检测 到了一条直线.

     这就是霍夫线变换要做的. 它追踪图像中每个点对应曲线间的交点. 如果交于一点的曲线的数量超过了阈值, 那么可以认为这个交点所代表的参数对 (\theta, r_{\theta})在原图像中为一条直线.

      霍夫圆变换的原理类似于霍夫线变换。广义的霍夫圆变换中,圆的方程可写为:(x-a)^2+(y-b)^2=r^2
相对于图像空间,参数空间中以(x,y)为圆心,r为半径的圆的方程可写为:(a-x)^2+(b-y)^2=r^2
式中有三个参数a,b,r,所以需要在参数空间建立一个三维的累加数组。可见,这实际上是把输入图像圆边界上的点映射到三维的参数空间的锥面上。检测过程中,对参数空间的每一个(a,b,r)考虑图像中的每一个像素点(x,y)。

二  代码实现

#include "cv.h"
#include "highgui.h"
#include <stdio.h>

int main(int argc,char**argv){
   IplImage *pImage=NULL;   
   IplImage *pImg8u=NULL; 

   //打开摄像头
    CvCapture *capture=cvCaptureFromCAM(0);
    if(!capture)
    {
      printf("could not");
      return -1;
    }
    cvNamedWindow("demo",CV_WINDOW_AUTOSIZE);
    IplImage *frame;
    while(1){
      frame=cvQueryFrame(capture);
      if(!frame)
        break;
      char c=cvWaitKey(100);
      if(c==27)
        break;
   // cvShowImage("demo",frame);
   
   pImage=cvCloneImage(frame);
   pImg8u=cvCreateImage(cvGetSize(pImage),IPL_DEPTH_8U,1);
   //转化为灰度图
   if(frame->nChannels!=1)
      cvCvtColor(pImage,pImg8u,CV_BGR2GRAY);
   else
      cvCopy(pImage,pImg8u,NULL);
   
   cvSmooth(pImg8u,pImg8u,CV_GAUSSIAN,5,5,0,0); //平滑                                                                                                 
   CvMemStorage* storage=cvCreateMemStorage(0);//声明storage变量,用于存储检测到的线段
   CvSeq* circles=cvHoughCircles(pImg8u,storage,CV_HOUGH_GRADIENT,2,pImg8u->height/4,250,55,0,0);
   int i=0;
   for( i;i<circles->total;i++){
      float* p=(float *)cvGetSeqElem(circles,i);
      CvPoint pt=cvPoint(cvRound(p[0]),cvRound(p[1]));
      cvCircle(pImage,pt,cvRound(p[2]),CV_RGB(255,0,0),3,8,0);
   }
   cvShowImage("demo",pImage);
 }
   cvWaitKey(10); 
   cvReleaseCapture(&capture);
   cvReleaseImage(&frame);
   cvReleaseImage(&pImage);
   cvReleaseImage(&pImg8u);
   cvDestroyWindow("demo");
}






















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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值