OpenCV24霍夫直线变换API介绍_3.1.0

/*OpenCV24霍夫直线变换API介绍
by txwtech

霍夫变换(Hough Transform)于1962年由Paul Hough 首次提出,后于1972年由Richard Duda和Peter Hart推广使用,是图像处理领域内从图像中检测几何形状的基本方法之一。经典霍夫变换用来检测图像中的直线,后来霍夫变换经过扩展可以进行任意形状物体的识别,例如圆和椭圆。
霍夫变换运用两个坐标空间之间的变换,将在一个空间中具有相同形状的曲线或直线映射到另一个坐标空间的一个点上形成峰值,从而把检测任意形状的问题转化为统计峰值问题。

霍夫直线检测(Hough Line Detection)
Hough直线检测的基本原理在于利用点与线的对偶性,在我们的直线检测任务中,即图像空间中的直线与参数空间中的点是一一对应的,参数空间中的直线与图像空间中的点也是一一对应的。这意味着我们可以得出两个非常有用的结论:
1)图像空间中的每条直线在参数空间中都对应着单独一个点来表示;
2)图像空间中的直线上任何一部分线段在参数空间对应的是同一个点。
因此Hough直线检测算法就是把在图像空间中的直线检测问题转换到参数空间中对点的检测问题,通过在参数空间里寻找峰值来完成直线检测任务。
————————————————
参考资料:
https://blog.csdn.net/leonardohaig/article/details/87907462

给定一幅图像(一般为二值图像)中的点集合,如何检测直线?
一种解决方法:任选一对点,决定一条线,然后测试所有其他点是否接近这条线,从而得出接近这条特殊线的所有点的子集。该方法比较复杂。另外一种方法便是采用霍夫变换。

霍夫变换是图像处理必然接触到的一个算法,它通过一种投票算法检测具有特定形状的物体,该过程在一个参数空间中通过计算累计结果的局部最大值得到一个符合该特定形状的集合作为霍夫变换结果,该方法可以进行圆,直线,椭圆等形状的检测。在车道线检测中,当初考虑的一个方案便是采用霍夫变换检测直线进行车道线提取。
————————————————


Hough Line Transform用来做直线检测
前提条件 – 边缘检测已经完成
平面空间到极坐标空间转换
对于任意一条直线上的所有点来说
变换到极坐标中,从[0~360]空间,可以得到r的大小
属于同一条直线上点在极坐标空(r, theta)必然在一个点上有最强的信号出现,根据此反算到平面坐标中就可以得到直线上各点的像素坐标。从而得到直线

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


cv::HoughLines(
InputArray src, // 输入图像,必须8-bit的灰度图像
OutputArray lines, // 输出的极坐标来表示直线
double rho, // 生成极坐标时候的像素扫描步长
double theta, //生成极坐标时候的角度步长,一般取值CV_PI/180
int threshold, // 阈值,只有获得足够交点的极坐标点才被看成是直线
double srn=0;// 是否应用多尺度的霍夫变换,如果不是设置0表示经典霍夫变换
double stn=0;//是否应用多尺度的霍夫变换,如果不是设置0表示经典霍夫变换
double min_theta=0; // 表示角度扫描范围 0 ~180之间, 默认即可
double max_theta=CV_PI
) // 适用于有经验的开发者使用,需要自己反变换到平面空间


cv::HoughLinesP(
InputArray src, // 输入图像,必须8-bit的灰度图像
OutputArray lines, // 输出的极坐标来表示直线
double rho, // 生成极坐标时候的像素扫描步长
double theta, //生成极坐标时候的角度步长,一般取值CV_PI/180
int threshold, // 阈值,只有获得足够交点的极坐标点才被看成是直线
double minLineLength=0;// 最小直线长度
double maxLineGap=0;// 最大间隔
)


*/

#include <iostream>
#include <opencv2\opencv.hpp>

using namespace std;
using namespace cv;
Mat src;
Mat src_gray;
Mat dst;

int main(int argc, char *argv[])
{
    //src = imread("e:\\pictures\\霍夫变换直线.jpg",CV_LOAD_IMAGE_COLOR);
    src = imread("e:\\pictures\\交叉垂直线.jpg", CV_LOAD_IMAGE_COLOR);
    
    if (!src.data)
    {
        printf("failed to load image");
        return -1;
    }
    
    char input_name[] = "原图";
    char output_name[] = "霍夫直线结果";
    namedWindow(input_name, CV_WINDOW_AUTOSIZE);
    imshow(input_name, src);
    namedWindow(output_name,CV_WINDOW_AUTOSIZE);

    cvtColor(src, src_gray,CV_BGR2GRAY);
    //边缘提取
    Canny(src_gray, src_gray,120,220);
    cvtColor(src_gray,dst,CV_GRAY2BGR);
    imshow("canny image", src_gray);

    vector<Vec4f> plines;
    //霍夫直线API,提取直线像素,最后一个参数大小影响线的平滑度,10改为0,会有锯齿.因为有间隔不会看成直线
    HoughLinesP(src_gray,plines,1,CV_PI/180.0,10,0,10);
    Scalar color = Scalar(0,0,255);
    for (size_t i = 0; i < plines.size(); i++)
    {
        Vec4f h_line = plines[i];
        //绘制直线
        line(dst,Point(h_line[0], h_line[1]), Point(h_line[2], h_line[3]),color,LINE_AA);
    }
    imshow(output_name,dst);
    waitKey(0);
    return 0;
}

 

posted @ 2021-04-25 21:20  txwtech  阅读(106)  评论(1编辑  收藏  举报