霍夫变换同样可以检测图像中是否存在圆形,其检测方法与检测直线的方式相同,都是将图像空间x-y直角坐标系中的像素投影到参数空间中,之后寻找是否存在交点。在检测圆形的霍夫变换中圆形的数学描述形式如式(7.7)所示。

python 霍夫变换寻找图片中的矩形 matlab霍夫变换找圆心_ci

假设图像上中心像素点和圆的半径已知,根据已知量和式(7.7)可以将图像空间x-y直角坐标系中的像素投影到参数空间中,图7-12给出了这种霍夫变换的示意图。



python 霍夫变换寻找图片中的矩形 matlab霍夫变换找圆心_python 霍夫变换寻找图片中的矩形_02


图7-12 圆形霍夫变换示意图

OpenCV 4中提供了利用霍夫变换检测图像中是否存在圆形的HoughCircles()函数,该函数的函数原型在代码清单7-9中给出。

代码清单7-9 HoughCircles()函数原型void cv::HoughCircles(InputArray  image,                        OutputArray  circles,                         int  method,                         double  dp,                         double  minDist,                         double  param1 = 100,                         double  param2 = 100,                         int  minRadius = 0,                         int  maxRadius = 0                          )
  • image:待检测圆形的输入图像,数据类型必须是CV_8U的单通道灰度图像。
  • circles:检测结果的输出量,每个圆形用三个参数描述,分别是圆心的坐标和圆的半径
  • method:检测圆形的方法标志,目前仅支持HOUGH_GRADIENT方法。
  • dp:离散化时分辨率与图像分辨率的反比。
  • minDist:检测结果中两个圆心之间的最小距离。
  • param1:使用HOUGH_GRADIENT方法检测圆形时,传递给Canny边缘检测器的两个阈值的较大值。
  • param2:使用HOUGH_GRADIENT方法检测圆形时,检测圆形的累加器阈值,阈值越大检测的圆形越精确。
  • minRadius:检测圆的最小半径
  • maxRadius:检测圆的最大半径。

该函数可以检测灰度图像中是否存在圆形,与前面介绍的霍夫变换相关函数不同,该函数会调用Canny边缘检测进行边缘检测,因此在检测圆形时不需要对灰度图像进行二值化,直接输入灰度图像即可。函数中第一个参数是输入图像,图像的数据类型必须是CV_8UC1。函数第二个参数是圆形的检测结果,存放在vector类型的变量中,每个圆形的检测结果变量类型是Vec3f,其中前2个参数是圆形的中心坐标,第3个参数是圆形的半径。第三个参数是检测圆形的方法标志,目前仅支持HOUGH_GRADIENT方法。第四个参数是离散化时分辨率与图像分辨率的反比。例如,如果dp = 1,则图像离散化后具有与输入图像相同的分辨率,如果dp = 2,则图像离散化后宽度和高度都是原图像的一半。第五个参数是检测结果中两个圆心之间的最小距离,如果参数太小,除了真实的圆形之外,可能错误地检测到多个相邻的圆圈;如果参数太大,可能会遗漏一些圆形。第六个参数是Canny检测边缘时两个阈值的较大值,较小阈值默认为较大值的一半。第七个参数是累加器阈值,阈值越大检测的圆形越精确。最后两个参数是检测圆形半径的取值范围,半径的最小值需要大于等于0,默认值为0;半径的最大值可以任意取值,当取值小于等于0时圆形半径的最大值为图像尺寸的最大值,并且检测结果只输出圆形的中心,不输出圆形的半径。

为了了解该函数的使用方法以及圆形的检测结果,在代码清单7-10中给出了利用HoughCircles()函数检测图像中是否存在圆形的示例程序,程序的输出结果在图7-13给出。

代码清单7-10 myHoughCircles.cpp圆形检测  #include   #include   #include     using namespace cv;  using namespace std;    int main(){    Mat img = imread("coins.jpg");    if (img.empty())    {      cout << "请确认图像文件名称是否正确" << endl;      return -1;    }    imshow("原图", img);    Mat gray;    cvtColor(img, gray, COLOR_BGR2GRAY);    GaussianBlur(gray, gray, Size(9, 9), 2, 2);  //平滑滤波      //检测圆形  vector circles;  double dp = 2; //  double minDist = 10;  //两个圆心之间的最小距离  double  param1 = 100;  //Canny边缘检测的较大阈值  double  param2 = 100;  //累加器阈值  int min_radius = 20;  //圆形半径的最小值  int max_radius = 100;  //圆形半径的最大值    HoughCircles(gray, circles, HOUGH_GRADIENT, dp, minDist, param1, param2,      min_radius, max_radius);    //图像中标记出圆形  for (size_t i = 0; i < circles.size(); i++)  {    //读取圆心    Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));      //读取半径    int radius = cvRound(circles[i][2]);    //绘制圆心    circle(img, center, 3, Scalar(0, 255, 0), -1, 8, 0);    //绘制圆    circle(img, center, radius, Scalar(0, 0, 255), 3, 8, 0);    }    //显示结果    imshow("圆检测结果", img);    waitKey(0);  return 0;  }



python 霍夫变换寻找图片中的矩形 matlab霍夫变换找圆心_python 霍夫变换寻找图片中的矩形_03


图7-13 myHoughCircles.cpp程序中圆形检测结果