二十、霍夫圆检测

1、霍夫圆检测原理

  • 从平面坐标到极坐标转换3个参数C(opencv检测标定板上圆形并按固定方向排序 opencv检测圆弧_中值滤波,opencv检测标定板上圆形并按固定方向排序 opencv检测圆弧_ci_02,opencv检测标定板上圆形并按固定方向排序 opencv检测圆弧_中值滤波_03),其中opencv检测标定板上圆形并按固定方向排序 opencv检测圆弧_中值滤波opencv检测标定板上圆形并按固定方向排序 opencv检测圆弧_ci_02是圆心。
  • 假设平面坐标的任意一个圆上的点,转换到极坐标中:C(opencv检测标定板上圆形并按固定方向排序 opencv检测圆弧_中值滤波,opencv检测标定板上圆形并按固定方向排序 opencv检测圆弧_ci_02,opencv检测标定板上圆形并按固定方向排序 opencv检测圆弧_中值滤波_03)处有最大值,霍夫变换正是利用这个原理实现圆的检测。

opencv检测标定板上圆形并按固定方向排序 opencv检测圆弧_#include_09


霍夫圆检测先检测边缘,将非边缘处都变为零值。遍历所有非零值,将其投影为(a,b,r)空间的一个圆,笛卡尔坐标中同一个圆上的所有点投影到(a,b,r)空间将交于一点,这一点为笛卡尔坐标中这个圆的圆心。(a,b,r)中空间中每一个点有一个累加器,有一条线经过该点,累加器加1,根据阈值(大于某一个阈值)找到所有可能的圆心。

opencv检测标定板上圆形并按固定方向排序 opencv检测圆弧_中值滤波_10xopencv检测标定板上圆形并按固定方向排序 opencv检测圆弧_中值滤波_11aopencv检测标定板上圆形并按固定方向排序 opencv检测圆弧_中值滤波_12+opencv检测标定板上圆形并按固定方向排序 opencv检测圆弧_中值滤波_10yopencv检测标定板上圆形并按固定方向排序 opencv检测圆弧_中值滤波_11bopencv检测标定板上圆形并按固定方向排序 opencv检测圆弧_中值滤波_12 = opencv检测标定板上圆形并按固定方向排序 opencv检测圆弧_中值滤波_16

opencv检测标定板上圆形并按固定方向排序 opencv检测圆弧_中值滤波_10aopencv检测标定板上圆形并按固定方向排序 opencv检测圆弧_中值滤波_11xoopencv检测标定板上圆形并按固定方向排序 opencv检测圆弧_中值滤波_12+opencv检测标定板上圆形并按固定方向排序 opencv检测圆弧_中值滤波_10bopencv检测标定板上圆形并按固定方向排序 opencv检测圆弧_中值滤波_11yoopencv检测标定板上圆形并按固定方向排序 opencv检测圆弧_中值滤波_12 = opencv检测标定板上圆形并按固定方向排序 opencv检测圆弧_中值滤波_16

2、相关APIcv::HoughCircles

  • 因为霍夫圆检测对噪声比较敏感,所以首先要对图像做中值滤波。
  • 基于效率考虑,opencv中实现的霍夫圆检测是基于图像梯度的实现,分为两步:
    (1)检测边缘,发现可能的圆心
    (2)基于第一步的基础上从候选圆心开始计算最佳半径大小
HoughCircles(
InputArray image,//输入图像,必须是8位的单通道灰度图像
OutputArray circles,//输出结果,发现的圆信息,为三元向量组,存储每个可能的圆心坐标和半径信息(a,b,r)
int method,//方法-HOUGH_GRADIENT,求梯度,得到可能的边缘值,其余为零值
double dp,//取dp = 1,代表在原图的尺度下寻找,0.5为在原图的一半尺度上寻找
double mindist,//最短距离可以分辨是两个圆的,否则认为是同心圆
double param1,//canny edge detection low threshold
double param2,//中心点累加器阈值,候选圆心
int minradius,//最小半径
int maxradius//最大半径
)

示例代码:(霍夫圆检测)

#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>

using namespace cv;
using namespace std;

int main(int argc, char* argv) {
    Mat src, dst;
    src = imread("添加图片路径");
    if (!src.data) {
  	cout << "could not load image..." << endl;
 	return -1;
    }
    char INPUT_WIN[] = "input image";
    char OUTPUT_WIN[] = "Hough Demo";
    namedWindow(INPUT_WIN, WINDOW_AUTOSIZE);
    namedWindow(OUTPUT_WIN, WINDOW_AUTOSIZE);
    imshow(INPUT_WIN, src);
    
    //中值滤波
    Mat moutput;
    medianBlur(src, moutput, 3);
    cvtColor(moutput, moutput, COLOR_BGR2GRAY);
    
    //霍夫圆检测
    vector<Vec3f> pcircles;//定义存储潜在的圆心坐标和半径(a,b,r)的向量组
    HoughCircles(moutput, pcircles, HOUGH_GRADIENT, 1, 30, 100, 25, 2 ,50);
    src.copyTo(dst);
    for (size_t i = 0; i < pcircles.size(); i++) {//将圆心和圆做标记
  	Vec3f cc = pcircles[i];//提取第i个潜在圆的信息
  	circle(dst, Point(cc[0], cc[1]), cc[2], Scalar(0, 0, 255), 2, LINE_AA);//画出圆的边界,(cc[0],cc[1])存储的是圆心坐标,cc[2]存储的是半径
  	circle(dst, Point(cc[0], cc[1]), 2, Scalar(0, 255, 0), 2, LINE_AA);
    }//画出圆心
    imshow(OUTPUT_WIN, dst);
    
    waitKey(0);
    return 0;
}

输出结果显示如下:

opencv检测标定板上圆形并按固定方向排序 opencv检测圆弧_opencv_24