OpenCV-霍夫变换

OpenCV-霍夫变换


author@jason_ql
http://blog.csdn.net/lql0716/


  • 标准霍夫变换(Standard Hough Transform, SHT)
  • 多尺度霍夫变换(Multi—Scale Hough Transform, MSHT)
  • 累计概率霍夫变换(Progressive Probabilistic Hough Transform,PPHT)

相关函数

  • HoughLines()直线检测
    该函数对应标准霍夫变换(SHT)、多尺度霍夫变换(MSHT)。

C++: void HoughLines(InputArray image, OutputArray lines, double rho, double theta, int threshold, double srn=0, double stn=0)

第一个参数:InputaArray类型的image,原图像,8位单通道二进制。
第二个参数:InputArray类型的lines,经过调用HoughLines函数后储存了霍夫变换检测到线条的输出矢量。每一条线由具有两个元素的矢量(rou,theta)表示,其中rou为到座标原点(0,0)(原点为图像的左上角)的距离,theta是弧度线条旋转角度(0度表示垂直线,pi/2度表示水平线)。
第三个参数:double类型的rho,以像素为单位的距离精度。另一种表述方式是直线搜索时的进步尺寸的单位角度。
第四个参数:double类型的theta,以弧度为单位的角度精度。另一种表述方式是直线搜索时的进步尺寸的单位角度。
第五个参数:int类型的threshold,累加平面的阈值参数,即识别某部分为图中的一条直线时它在累加平面中必须达到的值。大于阈值threshold的线段才可以被检测通过并返回到结果中。
第六个参数:double类型的srn,默认值为0.对于多尺度的霍夫变换,这是第三个参数进步尺寸rho的除数距离。粗略的累加器进步尺寸直接是第三个参数rho,而精确的累加器进步尺寸为rho/srn。
第七个参数:double类型的stn,默认值为0.对于多尺度霍夫变换,srn表示第四个参数进步尺寸的单位角度theta的除数距离。且如果srn和stn同时为0,就表示使用经典的霍夫变换,否则这两个参数应该都为正数。

  • HoughLinesP() 直线检测
    该函数对应累计概率霍夫变换PPHT。

  • HoughCircles() 圆检测

  • 霍夫变换示例代码

#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
//    String path = "/home/jason/jason2/photo/cylinder/target_cylinder.jpg";
    String path = "/home/jason/jason2/photo/cylinder/01.jpg";
    cv::Mat img1, img2, gray1, gray2;
    img1 = cv::imread(path);
    cv::cvtColor(img1, gray1, cv::COLOR_BGR2GRAY);

    cv::Canny(img1, img2, 50, 100);
//    cv::cvtColor(img2, gray2, cv::COLOR_BGR2GRAY);

    cv::vector<Vec2f> lines;
    cv::HoughLines(img2, lines, 1, CV_PI/180, 150, 0, 0);

    cv::Point v0;
    v0.x = 0;
    v0.y = 1;

    for(size_t i = 0; i < lines.size(); i++)
    {
        float rho = lines[i][0], theta = lines[i][1];
        cv::Point pt1, pt2, v1;
        double a = cos(theta), b = sin(theta);
        double x0 = a*rho, y0 = b*rho;

        pt1.x = round(x0 + 1000 * (-b));
        pt1.y = round(y0 + 1000 * a);
        pt2.x = round(x0 - 1000 * (-b));
        pt2.y = round(y0 - 1000 * a);

        v1 = pt1 - pt2;

        if( (v0.x * v1.y + v0.y * v1.x) == 0)
        {
            line(img1, pt1, pt2, Scalar(0, 255, 0), 2, CV_AA);
        }

    }

    cv::namedWindow("原图", cv::WINDOW_NORMAL);
    cv::namedWindow("直线", cv::WINDOW_NORMAL);
    cv::imshow("原图", img1);
    cv::imshow("直线", img2);

    cv::waitKey(0);
    return 0;

}
#霍夫变换圆检测

#include <cv.h>
#include <highgui.h>
#include <math.h>

using namespace cv;

int main(int argc, char** argv)
{
    Mat img, gray;
    if( argc != 2 && !(img=imread(argv[1], 1)).data)
        return -1;
    cvtColor(img, gray, CV_BGR2GRAY);
    // smooth it, otherwise a lot of false circles may be detected
    GaussianBlur( gray, gray, Size(9, 9), 2, 2 );
    vector<Vec3f> circles;
    HoughCircles(gray, circles, CV_HOUGH_GRADIENT,
                 2, gray->rows/4, 200, 100 );
    for( size_t i = 0; i < circles.size(); i++ )
    {
         Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
         int radius = cvRound(circles[i][2]);
         // draw the circle center
         circle( img, center, 3, Scalar(0,255,0), -1, 8, 0 );
         // draw the circle outline
         circle( img, center, radius, Scalar(0,0,255), 3, 8, 0 );
    }
    namedWindow( "circles", 1 );
    imshow( "circles", img );
    return 0;
}

  • 相关文章
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章