zoukankan      html  css  js  c++  java
  • opencvHough霍夫变换

    Hough变换是图像处理中从图像中识别几何形状的基本方法之一 

    原理看视频:

    https://www.bilibili.com/video/BV16i4y1R7kf?spm_id_from=333.999.0.0  

    霍夫直线检测

    1. 标准的霍夫变换 cv::HoughLines从平面坐标转换到霍夫空间,最终输出是  表示极坐标空间
    2. 霍夫变换直线概率 cv::HoughLinesP最终输出是直线的两个点

    霍夫线变换是一种用来寻找直线的方法. 在使用霍夫线变换之前, 首先要对图像进行边缘检测的处理,也即霍夫线变换的直接输入只能是边缘二值图像

    OpenCV支持三种不同的霍夫线变换,它们分别是:
    标准霍夫变换(Standard Hough Transform,SHT),
    多尺度霍夫变换(Multi-Scale Hough Transform,MSHT),
    累计概率霍夫变换(Progressive Probabilistic Hough Transform ,PPHT)

    在OpenCV中,我们可以用HoughLines函数来调用标准霍夫变换SHT和多尺度霍夫变换MSHT。
    而HoughLinesP函数用于调用累计概率霍夫变换PPHT。累计概率霍夫变换执行效率很高,所有相比于HoughLines函数,我们更倾向于使用HoughLinesP函数 

    HoughLinesP寻找直线

    10.jpg

    #include<opencv2/opencv.hpp>
    #include<iostream>
    
    int main(int argc, char** argv) {
    
        cv::Mat src = cv::imread("D:/bb/tu/10.jpg");
        if (!src.data)
        {
            printf("图像读取失败...\n");
            return -1;
        }
        cv::imshow("src", src);
        cv::Mat canny, dst;
        Canny(src, canny, 50, 255);  //获取边缘
        imshow("canny", canny);
        cvtColor(canny, dst, cv::COLOR_GRAY2BGR);//将二值图转换为RGB图颜色空间
        std::vector<cv::Vec4f> plines;//保存霍夫变换检测到的直线
        HoughLinesP(canny, plines, 1, CV_PI / 180, 10, 0, 10);//霍夫变换---寻找直线
        //提取边缘时,会造成有些点不连续,所以maxLineGap设大
        /*
        参数1:InputArray src 输入图像,必须8-bit的灰度边缘图像
        参数2:输出的极坐标来表示直线,经过调用HoughLinesP函数后后存储了检测到的线条的输出矢量,
                每一条线由具有四个元素的矢量(x_1,y_1, x_2, y_2) 表示,其中,(x_1, y_1)和(x_2, y_2) 是
                每个检测到的线段的起点和结束点。
        参数3:double rho 生成极坐标时的像素扫描步长,一般取值为1
        参数4:double theta 生成极坐标时的角度步长,一般取值CV_PI/180,即表示一度
        参数5:int threshold 阈值,只有获得足够交点的极坐标点才被看成是直线
        参数6:double minLineLength=0  最小直线长度,有默认值0,表示最低线段的长度,比这个
            设定参数短的线段就不能被显现出来
        参数7:double maxLineGap=0 最大间隔,有默认值0,允许将同一行点与点之间连接起来的最大的距离
            【间隔小于等于这个数,就认为是连续直线】
    
        */
        std::cerr << plines.size() << std::endl;//检测到的直线数量
        cv::Scalar color = cv::Scalar(0, 0, 255);//设置颜色
        for (size_t i = 0; i < plines.size(); i++) {
            cv::Vec4f hline = plines[i];//提取直线坐标
            line(dst, cv::Point(hline[0], hline[1]), cv::Point(hline[2], hline[3]), color, 1, cv::LINE_AA);//绘制直线
    
        }
        cv::imshow("检测到的直线", dst);
    
    
    
    
    
    
        cv::waitKey(0);
        return 0;
    }

    HoughLines寻找直线

    #include<opencv2/opencv.hpp>
    #include<iostream>
    
    int main(int argc, char** argv) {
    
        cv::Mat src = cv::imread("D:/bb/tu/10.jpg");
        if (!src.data)
        {
            printf("图像读取失败...\n");
            return -1;
        }
        cv::imshow("src", src);
        cv::Mat canny, dst;
        Canny(src, canny, 50, 255);  //获取边缘
        imshow("canny", canny);
        cvtColor(canny, dst, cv::COLOR_GRAY2BGR);//将二值图转换为RGB图颜色空间
        std::vector<cv::Vec4f> plines;//保存霍夫变换检测到的直线
        HoughLines(canny, plines, 1, CV_PI / 180, 10, 0, 0);//霍夫变换---寻找直线
    
        /*
        参数1:InputArray src 输入图像,必须8-bit的灰度边缘图像
        参数2:OutputArray lines 输出的极坐标来表示直线,经过调用HoughLines函数后储存了霍
            夫线变换检测到线条的输出矢量。每一条线由具有两个元素的矢量(ρ,θ)表示,其
            中,ρ是离坐标原点((0,0)(也就是图像的左上角)的距离。 θ是弧度线条旋转角度
            (0~ 垂直线,π/2~水平线)。
        参数3:double rho 生成极坐标时的像素扫描步长,一般取值为1,不要大于图像尺寸的一半
        参数4:double theta 生成极坐标时的角度步长,一般取值CV_PI/180,即表示一度
        参数5:int threshold 阈值,只有获得足够交点的极坐标点才被看成是直线,大于阈值的线段
            才可以被确认为直线
        参数6:double srn=0 是否应用多尺度的霍夫变换;设置0表示经典霍夫变换,
            多尺度表示的是使用图像金字塔,即多尺度图上进行霍夫变换
        参数7:stn,默认值为 0。也是多尺度霍夫线变换才会用到的参数。对于多尺度霍夫线变换,
            平面  -  中 θ 轴的单位长度 = theta / stn。如果 srn、stn 同时为 0,就表示使用
            经典霍夫变换,否则两个参数都应该为正数
    
        */
        std::cerr << plines.size() << std::endl;//检测到的直线数量
        cv::Scalar color = cv::Scalar(0, 0, 255);//设置颜色
        for (size_t i = 0; i < plines.size(); i++) {
            cv::Vec4f hline = plines[i];//提取直线坐标
            line(dst, cv::Point(hline[0], hline[1]), cv::Point(hline[2], hline[3]), color, 1, cv::LINE_AA);//绘制直线
    
        }
        cv::imshow("检测到的直线", dst);
    
    
    
    
    
    
        cv::waitKey(0);
        return 0;
    }

    寻找圆 

    2.jpg

      

    #include<opencv2/opencv.hpp>]
    #include<iostream>
    
    int main(int argc, char** argv) {
    
        cv::Mat src = cv::imread("D:/bb/tu/2.jpg");
        if (!src.data)
        {
            printf("图像读取失败...\n");
            return -1;
        }
        cv::imshow("src", src);
        cv::Mat gray_src, dst;
        medianBlur(src, dst, 5);//因为霍夫圆检测对噪声比较敏感,故须先做中值滤波
        cvtColor(dst, gray_src, cv::COLOR_BGR2GRAY);
        
    
        imshow("gray", gray_src);
        std::vector<cv::Vec3f> circles;//用Vec3f:一个圆需要三个数:圆心x y 半径r
        HoughCircles(gray_src, circles, cv::HOUGH_GRADIENT, 1, 10, 150, 50, 50, 100);//寻找圆
        /*
        参数1:输入图像 ,必须是8位的单通道灰度图像
        参数2:输出结果,发现的圆信息    
        参数3:目前opencv只有霍夫梯度法一种方法可用,该参数填HOUGH_GRADIENT即可
        参数4:double类型的dp,用来检测圆心的累加器图像的分辨率于输入图像之比的倒数,且此参数
            允许创建一个比输入图像分辨率低的累加器。上述文字不好理解的话,来看例子吧。例如,如
            果dp= 1时,累加器和输入图像具有相同的分辨率。如果dp=2,累加器便有输入图像一半那么大的宽度和高度
        参数5:为霍夫变换检测到的圆的圆心之间的最小距离
        参数6:它是第三个参数method设置的检测方法的对应的参数。对当前唯一的方法霍夫梯度法CV_HOUGH_GRADIENT,
            它表示传递给canny边缘检测算子的高阈值,而低阈值为高阈值的一半
        参数7:也是第三个参数method设置的检测方法的对应的参数,对当前唯一的方法霍夫梯度法HOUGH_GRADIENT,
            它表示在检测阶段圆心的累加器阈值。它越小的话,就可以检测到更多根本不存在的圆,而它越大的话,能
            通过检测的圆就更加接近完美的圆形了
        参数8:表示圆半径的最小值
        参数9:表示圆半径的最大值
        */
    
        std::cerr << circles.size() << std::endl;//找到的圆的数量
    
        //画出圆和圆心
        for (size_t i = 0; i < circles.size(); i++)
        {
            cv::Vec3f cc = circles[i];
            std::cout << "=" << std::endl << cc << std::endl;//查看图像中圆的信息
            circle(src, cv::Point(cc[0], cc[1]), cc[2], cv::Scalar(0, 0, 255), 2, cv::LINE_AA);//画圆
            circle(src, cv::Point(cc[0], cc[1]), 2, cv::Scalar(255, 0, 0), 2, cv::LINE_AA);//标记出圆心(这里把圆的半径设为2,并把标记线的粗细设为2,刚好画出一个实心的圆心)
        }
        imshow("result", src);
    
    
    
        cv::waitKey(0);
        return 0;
    }

     

  • 相关阅读:
    几个论坛上看到的2015小米笔试题
    Line(扩展欧几里得)
    MapReduce编程之倒排索引
    annotation(@Retention@Target)详解
    【JEECG技术文档】JEECG平台对外接口JWT应用文档V3.7.2
    jeecg 模糊查询
    jeecg下实现自动默认模糊查询
    The packaging for this project did not assign a file to the build artifact
    Maven添加本地Jar包
    maven 如何引入本地jar包
  • 原文地址:https://www.cnblogs.com/liming19680104/p/15735052.html
Copyright © 2011-2022 走看看