本章内容:

1. HoughLines直线检测
2. HoughLinesP直线检测
3. 圆检测

1. HoughLines直线检测

opencv 霍夫变换、直线检测,圆检测

输出结果:

opencv 霍夫变换、直线检测,圆检测

2. HoughLinesP直线检测

opencv 霍夫变换、直线检测,圆检测

输出结果

opencv 霍夫变换、直线检测,圆检测


3. 圆检测

opencv 霍夫变换、直线检测,圆检测

输出结果:

opencv 霍夫变换、直线检测,圆检测

源码


#include <ostream>
#include <opencv.hpp>
#include <math.h>

int main(int argc, char *argv[])
{
    /*
     本章内容:
        1. HoughLines直线检测
        2. HoughLinesP直线检测
        3. 圆检测
    */
    cv::String fileName = "/home/wang/dev/Image/c10.tif";
    cv::String fileName1 = "/home/wang/dev/Image/pingpang.jpeg";
    cv::Mat src = cv::imread(fileName);
    cv::Mat src2 = cv::imread(fileName1);
    if(src.data == NULL){
        printf("图像读入失败\n");
        return -1;
    }
    /*1. HoughLines直线检测
        CV_EXPORTS_W void HoughLines( InputArray image, OutputArray lines,
                                      double rho, double theta, int threshold,
                                      double srn = 0, double stn = 0,
                                      double min_theta = 0, double max_theta = CV_PI );
        参数分析:
            @param lines Output vector of lines. Each line is represented by a 2 or 3 element vector
            @param rho Distance resolution of the accumulator in pixels. //rho分辨率
            @param theta Angle resolution of the accumulator in radians. // 旋转角度分辨率
            @param threshold Accumulator threshold parameter. // 阈值
    */
    cv::Mat gray;
    cv::cvtColor(src,gray,cv::COLOR_BGR2GRAY);
    cv::Mat src1 = src.clone();
    cv::Mat dstCanny;
    cv::Canny(gray,dstCanny,50,100); // 计算边缘
    std::vector<cv::Vec2f> lines1;
    cv::HoughLines(dstCanny,lines1,1,CV_PI/180,150);
    // vector<cv::Vec2f> 的索引
    /* 直线转换过程
        1. 获取rho,theta值,
        2. 计算直线的(x0,y0)中心点
        3. 根据斜率和中心点定义直线,
       总结:这种条件下无法获取直线的真实长度,值保留了直线的趋势
    */
    std::cout <<"直线数目: " << lines1.size() << std::endl;
    for(int i=0; i < lines1.size();i++){
        float rho = lines1[i][0],theta = lines1[i][1];
        float a = cos(theta), b=sin(theta);
        int x0 = rho*a, y0= rho*b;
        cv::Point pt1,pt2;
        float lineLen = 1000;
        pt1.x = cvRound(x0 - lineLen*b);
        pt1.y = cvRound(y0 + a*lineLen);
        pt2.x = cvRound(x0 + lineLen*b);
        pt2.y = cvRound(y0 - a*lineLen);
        cv::line(src,pt1,pt2,cv::Scalar(0,0,255),4);
    }

    cv::imshow("gray", gray);
    cv::imshow("HoughLines", dstCanny);
    cv::imshow("src", src);

    /* 2. HoughLinesP直线检测
        api接口: CV_EXPORTS_W void HoughLinesP( InputArray image, OutputArray lines,
                               double rho, double theta, int threshold,
                               double minLineLength = 0, double maxLineGap = 0 );
      参数分析:
            @param lines Output vector of lines. // 4-元素 Vector,(x1,x2,y1,y2)
            @param minLineLength Minimum line length. 构成一条直线所需要的最小点数
            @param maxLineGap  同一直线上的点允许的最大距离
    */
    std::vector<cv::Vec4f> lines2;
    cv::HoughLinesP(dstCanny,lines2,1,CV_PI/180,100,100,50);
    std::cout << "lines2: " << lines2.size() << std::endl;

    for(int i=0; i < lines2.size(); i++){
        cv::Point pt1(lines2[i][0],lines2[i][1]),pt2(lines2[i][2],lines2[i][3]);
        cv::line(src1,pt1,pt2,cv::Scalar(0,0,255),4);
    }
    cv::imshow("src1", src1);

    /* 3.圆检测
      api接口:CV_EXPORTS_W void HoughCircles( InputArray image, OutputArray circles,
                               int method, double dp, double minDist,
                               double param1 = 100, double param2 = 100,
                               int minRadius = 0, int maxRadius = 0 );
      简单参数分析:
           @param circles Output vector : // 输出类型:(x, y, radius)or (x, y, radius, votes)
           @param method Detection method, see #HoughModes. The available methods are #HOUGH_GRADIENT and #HOUGH_GRADIENT_ALT.
           @param dp  霍夫空间分辨率,反比与输入图像分辨率
           @param minDist : 圆心与圆心之间的最小距离
           @param param1 Canny检测算子高阈值
           @param param2 霍夫空间阈值
           @param minRadius 检测圆最小距离
           @param maxRadius 检测圆最大距离
     // 不同版本实现的方法有差异,
     enum method{
            HOUGH_GRADIENT      = 3,
            HOUGH_GRADIENT_ALT  = 4,
        }
    */
    cv::Mat gray1;
    cv::cvtColor(src2,gray1,cv::COLOR_BGR2GRAY);
    std::vector<cv::Vec3f> circles;
    cv::HoughCircles(gray1,circles,cv::HOUGH_GRADIENT,1,10,100,50,0,0);
    std::cout << "的个数:"<<circles.size() << std::endl;
    // 画圆
    for(int i=0;i<circles.size();i++){
        cv::Vec3f c=circles[i];
        cv::circle(src2,cv::Point(c[0],c[1]),c[2],cv::Scalar(0,0,255),4);
    }
    cv::imshow("gray1",gray1);
    cv::imshow("src2",src2);
    cv::waitKey(0);
    return 1;
}

 

 

相关文章: