C++ opencv概率霍夫变换(HoughLinesP)直线检测

霍夫线变换

  1. 霍夫线变换是一种用于检测直线的变换。
  2. 为了应用变换,首先需要进行边缘检测预处理。

标准和概率霍夫线变换

OpenCV 实现了两种霍夫线变换:

标准霍夫变换

  • 提供了一个组合向量(θ,rθ)
  • 在 OpenCV 中,它是用函数HoughLines()实现的

HoughLines()

void cv::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 
)

#include

参数

image 8 位、单通道二进制源图像。该函数可以修改图像。
lines 线的输出向量。每条线由一个 2 或 3 元素向量表示( ρ , θ )或者( ρ , θ ,票数).ρ是到坐标原点的距离( 0 , 0 )(图像的左上角)。θ是以弧度为单位的线旋转角度(0 ∼垂直线, π/ 2∼水平线)。选票是累加器的值。
rho 累加器的距离分辨率(以像素为单位)。
theta 累加器的角度分辨率(以弧度为单位)。
threshold 累加器阈值参数。仅返回那些获得足够票数的线(>门槛)。
srn 对于多尺度霍夫变换,它是距离分辨率 rho 的除数。粗略的累加器距离分辨率为 rho ,准确的累加器分辨率为 rho/srn 。如果 srn=0 和 stn=0 ,则使用经典的霍夫变换。否则,这两个参数都应该是正数。
stn 对于多尺度霍夫变换,它是距离分辨率 theta 的一个除数。
min_theta 对于标准和多尺度霍夫变换,检查线的最小角度。必须介于 0 和 max_theta 之间。
max_theta 对于标准和多尺度霍夫变换,检查线的最大角度。必须介于 min_theta 和 CV_PI 之间。

例子:

样本/cpp/tutorial_code/ImgTrans/houghlines.cpp。

概率霍夫线变换

  • 霍夫线变换的更有效实现。它将检测到的线的极值作为输出(x0,y0,x1,y1)
  • 在 OpenCV 中,它是用函数HoughLinesP()实现的

HoughLinesP()

void cv::HoughLinesP	(	InputArray	image,
	OutputArray	lines,
	double 	rho,
	double 	theta,
	int 	threshold,
	double 	minLineLength = 0,
	double 	maxLineGap = 0 
	)	

参数

image 8 位、单通道二进制源图像。该函数可以修改图像。
lines 线的输出向量。每条线由一个 4 元素向量表示(X1,是的1,X2,是的2), 在哪里(X1,是的1)和(X2,是的2)是每个检测到的线段的终点。
rho 累加器的距离分辨率(以像素为单位)。
theta 累加器的角度分辨率(以弧度为单位)。
threshold 累加器阈值参数。仅返回那些获得足够票数的线(>门槛)。
minLineLength 最小线长。比这短的线段被拒绝。
maxLineGap 同一条线上的点之间连接它们的最大允许间隙。

也可以看看

线段检测器

例子:

样本/cpp/tutorial_code/ImgTrans/houghlines.cpp。

应用示例

目的:检测图片里道路和车的直线。

使用方法:mask掩膜,概率霍夫线变换。

实现过程:读取图片 转灰度图像 高斯降噪 边缘检测 掩膜 概率霍夫变换 保存图片

#include 
#include 
#include 
#include
#include 
#include 


using namespace std;
using namespace cv;

// MASK THE EDGE IMAGE
/**
*@brief Mask the image so that only the edges that form part of the lane are detected
*@param img_edges is the edges image 
*@return Binary image with only the desired edges being represented
*/
/*道路轮廓*/
Mat mask1(Mat img_edges) {
    Mat output;
    Mat mask = cv::Mat::zeros(img_edges.size(), img_edges.type());
    Point pts[4] = {
        Point(650, 500),
        Point(850, 500),
        Point(450, 800),
        Point(250, 800),
};
    // Create a binary polygon mask
    fillConvexPoly(mask, pts, 4, cv::Scalar(255, 0, 0));
    // Multiply the edges image and the mask to get the output
    bitwise_and(img_edges, mask, output);

    return output;
}

/*前面车辆的车身边缘的候选轮廓*/
Mat mask2(Mat img_edges) {
    Mat output;
    Mat mask = cv::Mat::zeros(img_edges.size(), img_edges.type());
    Point pts[4] = {
        Point(720, 250),
        Point(1300, 250),
        Point(1350, 830),
        Point(650, 830),
    };
    fillConvexPoly(mask, pts, 4, cv::Scalar(255, 0, 0));
    bitwise_and(img_edges, mask, output);

    return output;
}

int main()
{
    Mat image;
    Mat grayImage;
    Mat cannyImage;
    Mat img_mask1;
    Mat img_mask2;
    image = imread("C:\\Users\\10985\\source\\repos\\CVDemo01\\test02_original\\440.png");
    if (!image.data) {
         cout << "Image reading error !" << endl;
    }

    //将图像转换为灰度图
    cvtColor(image, grayImage, COLOR_BGR2GRAY);

    //高斯降噪
    GaussianBlur(grayImage, grayImage, Size(3, 3),0, 0, BORDER_DEFAULT);

    //边缘检测
    Canny(grayImage, cannyImage, 50, 150, 3, false);
    
    // Mask the image so that we only get the ROI
    /*道路轮廓*/
    img_mask1 = mask1(cannyImage);
    /*前面车辆的车身边缘的候选轮廓*/
    img_mask2 = mask2(cannyImage);

    /*Mat oneline(cannyImage.size(), CV_8U, Scalar(0));*/
    /* 将Hough变换应用于轮廓图像*/
    vector lines1;
    HoughLinesP(img_mask1, lines1, 1, 1, 10, 40, 20);
    for (int j = 0; j < lines1.size(); j++)
    {
         Vec4f hline = lines1[j];
		 line(image, Point(hline[0], hline[1]), Point(hline[2], hline[3]), Scalar(0, 255, 0), 2);
    }

    vector lines2;
    HoughLinesP(img_mask2, lines2, 1, 1, 10, 10, 40);
    for (int j = 0; j < lines2.size(); j++)
    {
        Vec4f hline = lines2[j];
        /*选择接近于垂直/水平的部分 
         - 前面车辆的车身边缘的候选人.*/
        if ((hline[1] - hline[3]) <= 1 & (hline[1] - hline[3]) >= -1 || (hline[0] - hline[2]) <= 1 & (hline[0] - hline[2]) >= -1) {
            line(image, Point(hline[0], hline[1]), Point(hline[2], hline[3]), Scalar(255, 0, 0), 2);
        }
    }

    //保存 
    stringstream str2;
    str2 << "C:/Users/10985/source/repos/CVDemo01/04_houghTest/" << "result.png";
    imwrite(str2.str(), image);

    return 0;
}

读取的原图C++ opencv概率霍夫变换(HoughLinesP)直线检测_第1张图片

结果图片 

C++ opencv概率霍夫变换(HoughLinesP)直线检测_第2张图片

 

 

你可能感兴趣的:(C++,opencv,opencv,c++,计算机视觉)