zoukankan      html  css  js  c++  java
  • hough圆检测

    方法1:

    1. 如下图所示,确定一个圆需要3个参数:半径,圆心的横坐标,圆心的纵坐标

      2.所以我们可以以如下方式进行投票:

     

     遍历图像上的所有像素点,选取不同的半径进行投票,选择投票数超过阈值的那个像素点作为圆心,如下图所示:

     缺点:计算量太大

    方法二:霍夫梯度法

    原理:

    如下图所示:

    圆的边缘点切线的垂直方向,也就是梯度方向过圆点,所以我们可以遍历图像的所有点,对每个像素点计算梯度,比如Sobel算子,对该直线上的所有像素点进行投票,最后选取超过阈值的某个像素点,为了避免选取过多的圆心,可以把一个像素点周围相差不大的像素点看做成一个圆心,确定圆心后再计算以改点为圆心的最佳半径,结果如下:

     该方法优点:速度快

    缺点:圆心可能会有偏差,这个方法对噪声比较敏感,所以可以先做中值滤波,做完之后再用hough圆变换

     

     原图直接处理的代码:

    #include <opencv2/opencv.hpp>
    #include <iostream>
    #include <math.h>
    #include <vector>
    using namespace cv;
    using namespace std;
    
    Mat src, dst,dst2,gray_src;
    char* INPUT_WIN = "input image";
    char* OUTPUT_WIN = "binary image";
    int t1_value = 50;
    int max_value = 255;
    
    
    
    
    int main()
    {
    
        src = imread(".//pic//0.jpg");
    
        namedWindow(INPUT_WIN, CV_WINDOW_AUTOSIZE);
        imshow(INPUT_WIN, src);
    
        
        Mat moutput;
        //转成灰度图
        cvtColor(src, moutput, CV_BGR2GRAY);
    
        //霍夫圆检测
        vector<Vec3f> pcircles;
        HoughCircles(moutput, pcircles, CV_HOUGH_GRADIENT, 1, 30, 100, 30, 110, 200);
    
        src.copyTo(dst);
        for (size_t i = 0; i < pcircles.size(); i++)
        {
            Vec3f cc = pcircles[i];
            circle(dst, Point(cc[0], cc[1]), cc[2], Scalar(0, 0, 2), 2, LINE_AA);
            circle(dst, Point(cc[0], cc[1]), cc[2], Scalar(0, 255, 0), 2, LINE_AA);
        }
        imshow("Hough检测后", dst);
    
        waitKey(0);
        return 0; 
    }

     转成灰度图再处理的代码:

    #include <opencv2/opencv.hpp>
    #include <iostream>
    #include <math.h>
    #include <vector>
    using namespace cv;
    using namespace std;
    
    Mat src, dst,dst2,gray_src;
    char* INPUT_WIN = "input image";
    char* OUTPUT_WIN = "binary image";
    int t1_value = 50;
    int max_value = 255;
    
    
    
    
    int main()
    {
    
        src = imread(".//pic//0.jpg");
    
        namedWindow(INPUT_WIN, CV_WINDOW_AUTOSIZE);
        imshow(INPUT_WIN, src);
    
        
        Mat moutput;
        //转成灰度图
        cvtColor(src, moutput, CV_BGR2GRAY);
        //中值滤波
        medianBlur(moutput, moutput, 3);
        imshow("中值滤波后", moutput);
        //边缘检测
        Canny(moutput, dst2, 100, 100 * 2, 3, false);
        imshow("canny", dst2);
    
        //霍夫圆检测
        vector<Vec3f> pcircles;
        HoughCircles(dst2, pcircles, CV_HOUGH_GRADIENT, 1, 10, 100, 30, 110, 200);
    
        src.copyTo(dst);
        for (size_t i = 0; i < pcircles.size(); i++)
        {
            Vec3f cc = pcircles[i];
            circle(dst, Point(cc[0], cc[1]), cc[2], Scalar(0, 0, 2), 2, LINE_AA);
            circle(dst, Point(cc[0], cc[1]), cc[2], Scalar(0, 255, 0), 2, LINE_AA);
        }
        imshow("Hough检测后", dst);
    
        waitKey(0);
        return 0; 
    }
  • 相关阅读:
    基于AVPlayer的音乐播放器
    java中关于正则一些基础使用
    随笔08.09
    我的Android笔记--我对安卓系统的一些了解
    2016/06/16
    Objective-C(iOS)严格单例模式正确实现
    Swift轻松入门——基本语法介绍和详细地Demo讲解(利用WebView打开百度、新浪等网页)
    GCD学习之dispatch_barrier_async
    iOS自学之NSOperation、NSOperationQueue、Background
    docker run mysql
  • 原文地址:https://www.cnblogs.com/xiaochi/p/12028544.html
Copyright © 2011-2022 走看看