您的位置:首页 > 运维架构

OpenCV的霍夫变换(Hough Transform)圆检测

2017-10-20 20:17 585 查看

Hough变换检测圆

霍夫变换也可以用于检测其他几何形体,事实上,可以用参数方程表示的几何体都可以尝试用霍夫变换进行检测。

比如圆形,它对应的参数方程为:r2=(x-x0)2+(y-y0)2

该函数包含三个参数,分别是圆心的坐标和圆的半径,这意味着需要三维的累加器。

OpenCV中实现的霍夫圆检测算法通常是两个步骤:

1. 二维累加器用于寻找可能为圆的位置。由于在圆周上的点的梯度应该指向半径的方向,因此对于每一个点,只有沿着梯度方向的项才得到增加(需要预先设定最大和最小的半径);

2. 若找到了圆心,则构建一维的半径的直方图,这个直方图的峰值对应的是检测到的圆的半径。

OpenCV中的霍夫变换圆检测函数 cv::HoughCircles

它整合了Canny检测和霍夫变换,输出是cv::Vec3f向量,每个元素包含检测圆的圆心坐标和半径(cx, cy, radius)。

另外,在进行霍夫变换之前,先对操作图像进行平滑,以减少可能引起误检测的噪声点。

#include "opencv2/highgui.hpp"
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"

class CircleFinder{
private:
std::vector<cv::Vec3f> circles;
double dp;       // 累加器的分辨率(图像尺寸/2)
double minDist;  // 两个圆之间的最小距离
double th;       // Canny中的高阈值
double minVote;  // 最小投票数
int minR;
int maxR;        // 有效半径的最小值和最大值
public:
CircleFinder() {
dp = 1.0, minDist = 1.0;
th = 300;
minVote = 80;
minR = 1, maxR = 100;
}
void setDPandThreshold(double dp, double th) {
dp = dp;
th = th;
}
void setMinVote(double minv) {
minVote = minv;
}
void setCircleParams(double minD, int minR, int maxR) {
minDist = minD;
minR = minR;
maxR = maxR;
}

// Hough变换检测圆
void findCircles(cv::Mat& imageBlur) {
circles.clear();
cv::HoughCircles(imageBlur, circles, CV_HOUGH_GRADIENT, dp, minDist, th, minVote, minR, maxR);
}

void drawDetectedCircles(cv::Mat &image, cv::Scalar color = cv::Scalar(255)) {
std::vector<cv::Vec3f>::const_iterator itc = circles.begin();
while (itc != circles.end()) {
cv::Point pt((*itc)[0], (*itc)[1]);
cv::circle(image, pt, int((*itc)[2]), cv::Scalar(255), 2); //画圆
++itc;
}
}
};

int main(int argc, char *argv[])
{
cv::Mat image = cv::imread("D:/VS_exercise/images/coin3.jpg");
cv::Mat imageGray;
cv::cvtColor(image, imageGray, cv::COLOR_RGB2GRAY);

// 在调用cv::HoughCircles函数前对图像进行平滑,减少误差
cv::Mat imageBlur;
cv::GaussianBlur(imageGray, imageBlur, cv::Size(5, 5), 1.5);

// Hough变换检测
CircleFinder finder;
finder.setDPandThreshold(2, 300);
finder.setMinVote(25);
finder.setCircleParams(20, 5, 100);
finder.findCircles(imageBlur);
finder.drawDetectedCircles(image);

// 显示
cv::namedWindow("Detected Lines with Hough");
cv::imshow("Detected Lines with Hough", image);
cv::waitKey(0);
return 0;
}



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++ opencv 霍夫变换