8.13霍夫变换-直线检测

news2024/11/17 5:27:06

基本概念

霍夫变换(Hough Transform)是一种用于检测图像中特定形状(如直线、圆、椭圆等)的技术。在OpenCV中,霍夫变换主要用于检测直线和圆形。这里我们将详细介绍如何使用OpenCV中的霍夫变换来检测直线。

霍夫变换(Hough Transform)是一种在图像中检测特定形状的方法,最常用的就是检测直线。霍夫变换的核心思想是将图像空间中的边缘点映射到参数空间中的点,然后寻找这些点在参数空间中的集中区域,以此来检测图像中的直线或其他形状。

霍夫变换原理
霍夫变换的核心思想是从图像空间到参数空间的映射。对于直线检测,霍夫变换将图像空间中的点映射到极坐标系下的参数空间。一条直线可以用极坐标系中的两个参数表示:距离 𝜌和角度 𝜃。

霍夫变换基本原理

霍夫变换通常分为两种类型:标准霍夫变换(Standard Hough Transform)和概率霍夫变换(Probabilistic Hough Transform)。

标准霍夫变换

标准霍夫变换将图像中的每一个边缘点投影到参数空间中的一个曲线或曲面,然后寻找这些曲线或曲面的交点。对于直线,参数空间是一个二维空间,通常用极坐标系表示,其中一个维度表示距离原点的距离(ρ),另一个维度表示角度(θ)。

概率霍夫变换

概率霍夫变换是对标准霍夫变换的一种改进,它通过随机选取边缘点来减少计算量,同时仍然能够检测出直线。概率霍夫变换通常用于处理大图像或需要快速处理的情况。

霍夫变换的主要步骤如下:

1.初始化参数空间:建立一个二维数组,对应于所有可能的 (𝜌,𝜃)组合。

2.投票过程:对于图像空间中的每个点,计算所有可能的 (𝜌,𝜃)对,并在对应的参数空间中增加计数。

3.检测峰值:在参数空间中寻找局部最大值,这些峰值对应于图像空间中的直线。

OpenCV中的霍夫变换直线检测

在OpenCV中,可以使用标准霍夫变换HoughLines概率霍夫变换HoughLinesP函数来实现霍夫变换直线检测。前者用于检测无穷长的直线,后者用于检测有限长度的线段。

1. 使用HoughLines函数

HoughLines 函数是OpenCV中用于检测图像中的直线的一个重要函数。该函数利用霍夫变换来查找图像中的直线。

功能描述

HoughLines 函数通过对图像中的边缘点进行霍夫变换,在参数空间中找到那些累加器值高于给定阈值的位置,从而检测出直线。该函数返回一个包含直线参数的向量 Vec2f,其中每个元素表示一条直线,由两个值组成:直线到原点的距离(ρ)和直线的角度(θ)。


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

参数说明
•image:输入图像,通常是边缘检测后的图像(如Canny边缘检测的结果)。此图像应为单通道的8位灰度图像。 输入图像,通常为二值化后的边缘图像。
•lines:输出直线,是一个包含直线参数的向量 Vec2f。每条直线由两个参数表示:距离原点的最近距离(ρ)和角度(θ)。输出的直线集,每条直线由(𝜌,𝜃)表示。
•rho:距离分辨率,即在参数空间中的步长。通常选择为 1 或更小的值,以获得更高的精度。距离分辨率,单位为像素。
•theta:角度分辨率,通常以弧度表示。可以选择为 CV_PI / 180 来获得每度一个角度步长。角度分辨率,单位为弧度。
•threshold:累加器阈值,只有当累加器中的值大于等于这个阈值时,才认为找到了一条直线。较高的阈值可以减少误检,但也可能导致漏检。阈值,只有当计数器大于此阈值时,才认为存在一条直线。
•srn:标准霍夫变换中的累加器行数。通常情况下不需要修改,默认为 0。
•stn:标准霍夫变换中的累加器列数。通常情况下不需要修改,默认为 0。
srn 和 stn: 分别是𝜌和𝜃的累积计数器的分辨率。

示例代码1

下面是一个详细的示例代码,展示如何使用 HoughLines 函数检测图像中的直线:

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

using namespace std;
using namespace cv;

void detectLinesWithHough(const Mat &edges, vector<Vec2f> &lines, double rho, double theta, int threshold) 
{
	HoughLines(edges, lines, rho, theta, threshold);
}

int main(int argc, char** argv) 
{
	/*if (argc != 2) {
		cout << "Usage: ./HoughLines <Image Path>" << endl;
		return -1;
	}*/

	// 加载图像
	Mat img = imread("283.png", IMREAD_GRAYSCALE);
	if (!img.data) 
	{
		cout << "Error opening image" << endl;
		return -1;
	}

	// 边缘检测
	Mat edges;
	Canny(img, edges, 50, 150);

	// 初始化输出向量
	vector<Vec2f> lines;

	// 使用霍夫变换检测直线
	detectLinesWithHough(edges, lines, 1, CV_PI / 180, 50);

	// 在原图上绘制检测到的直线
	Mat result = img.clone();
	for (size_t i = 0; i < lines.size(); i++) 
	{
		float rho = lines[i][0], theta = lines[i][1];
		double cos_theta = cos(theta), sin_theta = sin(theta);
		double x0 = rho * cos_theta, y0 = rho * sin_theta;
		Point pt1, pt2;
		double alpha = 1000;  // 控制直线的长度
		pt1.x = cvRound(x0 + alpha*(-cos_theta));
		pt1.y = cvRound(y0 + alpha*(-sin_theta));
		pt2.x = cvRound(x0 - alpha*(-cos_theta));
		pt2.y = cvRound(y0 - alpha*(-sin_theta));
		line(result, pt1, pt2, Scalar(255, 0, 0), 3, LINE_AA);
	}

	// 显示结果
	namedWindow("Original Image", WINDOW_NORMAL);
	imshow("Original Image", img);
	namedWindow("Edges", WINDOW_NORMAL);
	imshow("Edges", edges);
	namedWindow("Detected Lines", WINDOW_NORMAL);
	imshow("Detected Lines", result);

	waitKey(0);
	destroyAllWindows();

	return 0;
}


代码解释
1. 加载图像:使用 imread 函数以灰度模式加载图像。
2. 边缘检测:使用Canny边缘检测算法检测图像的边缘。
3. 初始化输出向量:创建一个新的向量来存储检测到的直线信息。
4. 执行霍夫变换:使用 HoughLines 函数检测图像中的直线。
5. 绘制直线:在原图上绘制检测到的直线。
6. 显示结果:使用 imshow 函数显示原始图像、边缘检测结果以及检测到的直线。

参数详解
•rho:距离分辨率,表示在参数空间中的步长。选择较小的 rho 值可以获得更高的精度,但也会增加计算量。
•theta:角度分辨率,通常以弧度表示。选择较小的 theta 值可以获得更高的精度,但也会增加计算量。通常选择 CV_PI / 180 表示每度一个角度步长。
•threshold:累加器阈值,只有当累加器中的值大于等于这个阈值时,才认为找到了一条直线。较高的阈值可以减少误检,但也可能导致漏检。
•srn 和 stn:这两个参数用于控制累加器的大小,通常情况下不需要修改,默认为 0。

应用场景

•图像分割:检测图像中的直线可以帮助分割图像中的不同区域。
•文档分析:在文档扫描或OCR处理中,检测文档中的直线可以帮助校正倾斜或扭曲的文档。
•交通标志检测:在智能交通系统中,检测道路标志中的直线可以帮助识别交通标志。
•机器人导航:在机器人视觉系统中,检测环境中的直线可以帮助机器人识别障碍物和路径。

注意事项
•边缘检测:在进行霍夫变换之前,通常需要先对图像进行边缘检测,以减少计算量并提高检测精度。
•参数选择:rho、theta 和 threshold 等参数的选择会影响检测结果。较小的 rho 和 theta 值可以提高检测精度,但也会增加计算量;较大的 threshold 值可以减少误检,但也可能导致漏检。
•性能考虑:标准霍夫变换计算量较大,适用于小图像或对速度要求不高的场景;概率霍夫变换则适用于大图像或需要快速处理的场景。


通过这些示例和详细解释,你应该能够理解如何在OpenCV中使用C++实现霍夫变换直线检测。如果有任何问题或需要进一步的帮助,请随时提问。

运行结果1

示例代码2

以下是一个完整的C++示例程序,展示了如何使用HoughLines函数来检测图像中的直线:

步骤一:包含必要的头文件
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;

步骤二:加载图像并进行预处理
int main(int argc, char** argv)
{
    // 加载图像
    Mat src = imread("path_to_your_image.jpg", IMREAD_GRAYSCALE);
    if (src.empty())
    {
        cout << "Error: Image cannot be loaded!" << endl;
        return -1;
    }

    // 进行Canny边缘检测
    Mat edges;
    Canny(src, edges, 50, 150);

步骤三:应用霍夫变换直线检测
    // 定义存储检测到的直线的容器
    vector<Vec2f> lines;

    // 使用HoughLines函数检测直线
    HoughLines(edges, lines, 1, CV_PI / 180, 100);  // 参数分别为:输入图像、输出直线、距离分辨率、角度分辨率、阈值

步骤四:绘制检测到的直线
    // 创建一个彩色图像来绘制直线
    Mat dst;
    cvtColor(src, dst, COLOR_GRAY2BGR);

    // 遍历检测到的每条直线并绘制
    for (size_t i = 0; i < lines.size(); i++)
    {
        float rho = lines[i][0], theta = lines[i][1];
        Point pt1, pt2;
        double a = cos(theta), b = sin(theta);
        double x0 = a * rho, y0 = b * rho;
        pt1.x = cvRound(x0 + 1000 * (-b));
        pt1.y = cvRound(y0 + 1000 * (a));
        pt2.x = cvRound(x0 - 1000 * (-b));
        pt2.y = cvRound(y0 - 1000 * (a));
        line(dst, pt1, pt2, Scalar(0, 0, 255), 3, LINE_AA);
    }

步骤五:显示结果
    // 显示原始图像和检测到的直线
    namedWindow("Source Image", WINDOW_AUTOSIZE);
    imshow("Source Image", src);

    namedWindow("Detected Lines", WINDOW_AUTOSIZE);
    imshow("Detected Lines", dst);

    waitKey(0);
    return 0;
}

参数解释
rho: 直线到原点的距离。
theta: 直线与水平线的夹角。
a 和 b: 极坐标系中的方向余弦。
x0 和 y0: 直线到原点的垂足坐标。
pt1 和 pt2: 用于绘制直线的两个端点。

注意事项
Canny边缘检测: 在应用HoughLines之前,通常需要先进行边缘检测。这里我们使用了Canny边缘检测器。
参数调整: HoughLines函数中的参数(如距离分辨率、角度分辨率和阈值)可以根据具体需求进行调整,以获得更好的检测效果。
直线绘制: HoughLines函数返回的直线是以极坐标形式表示的,需要将其转换为笛卡尔坐标系下的两点来绘制。

通过上述步骤,你可以使用OpenCV的HoughLines函数来检测图像中的直线,并将检测结果绘制在原始图像上。这种方法适用于检测图像中的无穷长直线,对于检测短直线或线段,可以考虑使用HoughLinesP函数。

完整代码

//步骤一:包含必要的头文件
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;

//步骤二:加载图像并进行预处理
int main(int argc, char** argv)
{
	// 加载图像
	Mat src = imread("02.png", IMREAD_GRAYSCALE);
	if (src.empty())
	{
		cout << "Error: Image cannot be loaded!" << endl;
		return -1;
	}

	// 进行Canny边缘检测
	Mat edges;
	Canny(src, edges, 50, 150);

	//步骤三:应用霍夫变换直线检测
		// 定义存储检测到的直线的容器
		vector<Vec2f> lines;

	// 使用HoughLines函数检测直线
	HoughLines(edges, lines, 1, CV_PI / 180, 100);  // 参数分别为:输入图像、输出直线、距离分辨率、角度分辨率、阈值

	//步骤四:绘制检测到的直线
		// 创建一个彩色图像来绘制直线
		Mat dst;
	cvtColor(src, dst, COLOR_GRAY2BGR);

	// 遍历检测到的每条直线并绘制
	for (size_t i = 0; i < lines.size(); i++)
	{
		float rho = lines[i][0], theta = lines[i][1];
		Point pt1, pt2;
		double a = cos(theta), b = sin(theta);
		double x0 = a * rho, y0 = b * rho;
		pt1.x = cvRound(x0 + 1000 * (-b));
		pt1.y = cvRound(y0 + 1000 * (a));
		pt2.x = cvRound(x0 - 1000 * (-b));
		pt2.y = cvRound(y0 - 1000 * (a));
		line(dst, pt1, pt2, Scalar(0, 0, 255), 3, LINE_AA);
	}

	//步骤五:显示结果
		// 显示原始图像和检测到的直线
	namedWindow("Source Image", WINDOW_NORMAL);
	imshow("Source Image", src);

	namedWindow("Detected Lines", WINDOW_NORMAL);
	imshow("Detected Lines", dst);

	waitKey(0);
	return 0;
}

运行结果2

2. 使用HoughLinesP函数

HoughLinesP 函数是OpenCV中用于检测图像中直线段的一个函数,它是概率霍夫变换(Probabilistic Hough Transform)的一个实现。与标准霍夫变换相比,概率霍夫变换通过随机选择边缘点来减少计算量,同时仍能有效地检测直线。

功能描述

HoughLinesP 函数通过对图像中的边缘点进行概率霍夫变换,在参数空间中找到那些累加器值高于给定阈值的位置,并且根据 minLineLength 和 maxLineGap 参数过滤掉不符合条件的线段,从而检测出直线段。

void HoughLinesP(
    InputArray image,
    OutputArray lines,
    double rho,
    double theta,
    int threshold,
    double minLineLength = 0,
    double maxLineGap = 0
);
参数说明
•image:输入图像,通常是边缘检测后的图像(如Canny边缘检测的结果)。此图像应为单通道的8位灰度图像。输入图像,通常为二值化后的边缘图像。
•lines:输出直线段,是一个包含直线段参数的向量 Vec4i。每个直线段由四个值表示:起始点的x坐标、起始点的y坐标、终止点的x坐标和终止点的y坐标。输出的直线集,每条直线由起点和终点坐标表示。
•rho:距离分辨率,即在参数空间中的步长。通常选择为 1 或更小的值,以获得更高的精度。距离分辨率,单位为像素。
•theta:角度分辨率,通常以弧度表示。可以选择为 CV_PI / 180 来获得每度一个角度步长。角度分辨率,单位为弧度。
•threshold:累加器阈值,只有当累加器中的值大于等于这个阈值时,才认为找到了一条直线段。较高的阈值可以减少误检,但也可能导致漏检。阈值,只有当计数器大于此阈值时,才认为存在一条直线。
•minLineLength:最小线段长度,只有比这个值长的线段才会被保留。最小线段长度,小于此长度的线段将被忽略。
•maxLineGap:两个线段间的最大允许间隙,如果两个线段之间的距离小于这个值,则认为它们属于同一直线。最大允许的线段间隙,小于此间隙的线段将被视为一条直线。

示例代码3

下面是一个基于C++的OpenCV示例程序,展示如何使用HoughLinesP函数来检测图像中的直线。

步骤一:包含必要的头文件
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;

步骤二:加载图像并进行预处理
int main(int argc, char** argv)
{
    Mat src = imread("path_to_your_image.jpg", IMREAD_GRAYSCALE);
    if (src.empty())
    {
        cout << "Error: Image cannot be loaded!" << endl;
        return -1;
    }

    // Canny边缘检测
    Mat edges;
    Canny(src, edges, 50, 150);

步骤三:应用霍夫变换直线检测
    vector<Vec4i> lines;  // 存储检测到的直线
    HoughLinesP(edges, lines, 1, CV_PI / 180, 50, 50, 10);  // CV_PI / 180 表示1度的角度分辨率

    // 绘制检测到的直线
    Mat dst = Mat::zeros(src.size(), CV_8UC3);
    for (size_t i = 0; i < lines.size(); i++)
    {
        Vec4i l = lines[i];
        line(dst, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0, 0, 255), 3, LINE_AA);
    }

步骤四:显示结果
    namedWindow("Source Image", WINDOW_AUTOSIZE);
    imshow("Source Image", src);

    namedWindow("Detected Lines", WINDOW_AUTOSIZE);
    imshow("Detected Lines", dst);

    waitKey(0);
    return 0;
}

注意事项

预处理: 在应用霍夫变换之前,通常需要对图像进行边缘检测,如使用Canny边缘检测器。
参数调整: rho 和 theta 的分辨率、阈值 threshold、最小线段长度 minLineLength 和最大线段间隙 maxLineGap 都需要根据具体应用场景调整,以获得最佳的检测效果。
性能: 霍夫变换在检测复杂场景中的直线时可能会比较耗时,尤其是当参数空间很大时。可以通过适当调整参数来优化性能。

通过上述步骤,你可以使用OpenCV的HoughLinesP函数来检测图像中的直线,并绘制出检测结果。

完整代码


//下面是一个基于C++的OpenCV示例程序,展示如何使用HoughLinesP函数来检测图像中的直线。

//步骤一:包含必要的头文件
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;

//步骤二:加载图像并进行预处理
int main(int argc, char** argv)
{
	Mat src = imread("23.png", IMREAD_GRAYSCALE);
	if (src.empty())
	{
		cout << "Error: Image cannot be loaded!" << endl;
		return -1;
	}

	// Canny边缘检测
	Mat edges;
	Canny(src, edges, 50, 150);

	//步骤三:应用霍夫变换直线检测
		vector<Vec4i> lines;  // 存储检测到的直线
	HoughLinesP(edges, lines, 1, CV_PI / 180, 50, 50, 10);  // CV_PI / 180 表示1度的角度分辨率

	// 绘制检测到的直线
	Mat dst = Mat::zeros(src.size(), CV_8UC3);
	for (size_t i = 0; i < lines.size(); i++)
	{
		Vec4i l = lines[i];
		line(dst, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0, 0, 255), 3, LINE_AA);
	}

	//步骤四:显示结果
		namedWindow("Source Image", WINDOW_NORMAL);
	imshow("Source Image", src);

	namedWindow("Detected Lines", WINDOW_NORMAL);
	imshow("Detected Lines", dst);

	waitKey(0);
	return 0;
}

运行结果3

示例代码4

下面是一个详细的示例代码,展示如何使用 HoughLinesP 函数检测图像中的直线段:

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

using namespace std;
using namespace cv;

void detectLinesWithHoughP(const Mat &edges, vector<Vec4i> &lines, double rho, double theta, int threshold, double minLineLength, double maxLineGap) {
    HoughLinesP(edges, lines, rho, theta, threshold, minLineLength, maxLineGap);
}

int main(int argc, char** argv) {
    if (argc != 2) {
        cout << "Usage: ./HoughLinesP <Image Path>" << endl;
        return -1;
    }

    // 加载图像
    Mat img = imread(argv[1], IMREAD_GRAYSCALE);
    if (!img.data) {
        cout << "Error opening image" << endl;
        return -1;
    }

    // 边缘检测
    Mat edges;
    Canny(img, edges, 50, 150);

    // 初始化输出向量
    vector<Vec4i> lines;

    // 使用概率霍夫变换检测直线段
    detectLinesWithHoughP(edges, lines, 1, CV_PI/180, 50, 50, 10);

    // 在原图上绘制检测到的直线段
    Mat result = img.clone();
    for (size_t i = 0; i < lines.size(); i++) {
        Vec4i l = lines[i];
        line(result, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(255, 0, 0), 3, LINE_AA);
    }

    // 显示结果
    imshow("Original Image", img);
    imshow("Edges", edges);
    imshow("Detected Line Segments", result);

    waitKey(0);
    destroyAllWindows();

    return 0;
}


代码解释
1. 加载图像:使用 imread 函数以灰度模式加载图像。
2. 边缘检测:使用Canny边缘检测算法检测图像的边缘。
3. 初始化输出向量:创建一个新的向量来存储检测到的直线段信息。
4. 执行概率霍夫变换:使用 HoughLinesP 函数检测图像中的直线段。
5. 绘制直线段:在原图上绘制检测到的直线段。
6. 显示结果:使用 imshow 函数显示原始图像、边缘检测结果以及检测到的直线段。

参数详解
•rho:距离分辨率,表示在参数空间中的步长。选择较小的 rho 值可以获得更高的精度,但也会增加计算量。
•theta:角度分辨率,通常以弧度表示。选择较小的 theta 值可以获得更高的精度,但也会增加计算量。通常选择 CV_PI / 180 表示每度一个角度步长。
•threshold:累加器阈值,只有当累加器中的值大于等于这个阈值时,才认为找到了一条直线段。较高的阈值可以减少误检,但也可能导致漏检。
•minLineLength:最小线段长度,只有比这个值长的线段才会被保留。这有助于去除短的、可能是噪声的线段。
•maxLineGap:两个线段间的最大允许间隙,如果两个线段之间的距离小于这个值,则认为它们属于同一直线。这有助于合并接近的线段。

应用场景
•图像分割:检测图像中的直线段可以帮助分割图像中的不同区域。•文档分析:在文档扫描或OCR处理中,检测文档中的直线段可以帮助校正倾斜或扭曲的文档。
•交通标志检测:在智能交通系统中,检测道路标志中的直线段可以帮助识别交通标志。
•机器人导航:在机器人视觉系统中,检测环境中的直线段可以帮助机器人识别障碍物和路径。


注意事项
•边缘检测:在进行概率霍夫变换之前,通常需要先对图像进行边缘检测,以减少计算量并提高检测精度。
•参数选择:rho、theta、threshold、minLineLength 和 maxLineGap 等参数的选择会影响检测结果。较小的 rho 和 theta 值可以提高检测精度,但也会增加计算量;较高的 threshold 值可以减少误检,但也可能导致漏检;较大的 minLineLength 可以去除短的线段,但可能会丢失细节;较小的 maxLineGap 可以帮助合并接近的线段,但也可能会合并不应合并的线段。
•性能考虑:概率霍夫变换相比于标准霍夫变换更适合处理大图像或需要快速处理的情况。


通过这些示例和详细解释,你应该能够理解如何在OpenCV中使用C++实现概率霍夫变换直线段检测。

运行结果4

示例代码5


/* This is a standalone program. Pass an image name as the first parameter
of the program.  Switch between standard and probabilistic Hough transform
by changing "#if 1" to "#if 0" and back */
#include <opencv2/opencv.hpp>
#include <iostream>
#include <cv.h>
#include <highgui.h>
#include <math.h>

using namespace cv;
using namespace std;


int main(int argc, char** argv)
{
	Mat src, dst, color_dst;
	if (!(src = imread("56.jpeg", 0)).data)
		return -1;

	Canny(src, dst, 50, 200, 3);
	cvtColor(dst, color_dst, CV_GRAY2BGR);

#if 0
	vector<Vec2f> lines;
	HoughLines(dst, lines, 1, CV_PI / 180, 100);

	for (size_t i = 0; i < lines.size(); i++)
	{
		float rho = lines[i][0];
		float theta = lines[i][1];
		double a = cos(theta), b = sin(theta);
		double x0 = a*rho, y0 = b*rho;
		Point pt1(cvRound(x0 + 1000 * (-b)),
			cvRound(y0 + 1000 * (a)));
		Point pt2(cvRound(x0 - 1000 * (-b)),
			cvRound(y0 - 1000 * (a)));
		line(color_dst, pt1, pt2, Scalar(0, 0, 255), 3, 8);
	}
#else
	vector<Vec4i> lines;
	HoughLinesP(dst, lines, 1, CV_PI / 180, 80, 30, 10);
	for (size_t i = 0; i < lines.size(); i++)
	{
		line(color_dst, Point(lines[i][0], lines[i][1]),
			Point(lines[i][2], lines[i][3]), Scalar(0, 0, 255), 3, 8);
	}
#endif
	//namedWindow("Source", 1);
	namedWindow("Source", WINDOW_NORMAL);
	imshow("Source", src);

	namedWindow("Detected Lines", WINDOW_NORMAL);
	//namedWindow("Detected Lines", 1);
	imshow("Detected Lines", color_dst);

	waitKey(0);
	return 0;
}

https://www.opencv.org.cn/opencvdoc/2.3.2/html/search.html?q=HoughLines&check_keywords=ye0s&area=default运行

运行结果5

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2162802.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux 基础IO(个人笔记)

Linux基础 IO 1.C文件IO操作1.1 hello.c写文件1.2 hello.c读文件1.3 stdin&stdout&stderr 2.系统文件I/O2.1 hello.c写文件2.2 hello.c读文件2.3 open函数介绍2.4 文件描述符 fd2.4.1 文件描述符的分配规则2.4.2 重定向2.4.3 dup2系统调用2.4.4 C文件结构体FILE2.4.5 C…

文件上传、amrkdown编辑器

一、文件上传 这里我以图片为例&#xff0c;进行上传&#xff0c;上传到阿里云oss&#xff08;对象存在中&#xff09; 首先&#xff0c;我们先梳理一下&#xff0c;图片上传的流程 1、前端选择文件&#xff0c;提交文件 前端提交文件&#xff0c;我们可以使用ElementUI中的…

python如何实现日期加减

首先通过import datetime&#xff0c;导入日期处理库。 然后把日期转化成datetime标准格式&#xff0c;使用datetime.datetime.strptime()方法将字符串格式的时间转化为标准格式。 其中"%Y/%m/%d %H:%M:%S"为time字符串的时间格式&#xff1a;Y为年&#xff0c;m为月…

思维导图在线工具哪家强?2024年最新评测

你用过思维导图工具吗&#xff1f;如果品尝需要对事情进行逻辑理顺操作或者需要增强记忆点那我比较推荐使用思维导图在线工具来解决这些问题。这篇文章我将介绍几款思维导图工具来提高我们的效率。 1.福晰思维导图 链接一下&#xff1a;https://www.pdf365.cn/naotu/ 这款思…

JVM的基本组成

一、JDK\JRE\JVM JDK: 全称 "Java Development Kit" &#xff0c;Java 开发工具包&#xff0c;提供 javac 编译器、jheap、jconsole 等监控工具;JRE: 全称"Java Runtime Environment"&#xff0c;Java 运行环境&#xff0c;提供Class Library 核心类库 JV…

【leetcode练习·二叉树】用「遍历」思维解题 I

本文参考labuladong算法笔记[【强化练习】用「遍历」思维解题 I | labuladong 的算法笔记] 257. 二叉树的所有路径 | 力扣 | LeetCode | 给你一个二叉树的根节点 root &#xff0c;按 任意顺序 &#xff0c;返回所有从根节点到叶子节点的路径。 叶子节点 是指没有子节点的节点…

spring-boot、spring-cloud、spring-cloud-alibaba的常用依赖的依赖声明及pom文件

copy自若依 父工程pom文件&#xff0c;主要定义了依赖的版本号 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:sch…

什么是电商云手机?可以用来干什么?

随着电商行业的迅速发展&#xff0c;云手机作为一种创新工具正逐渐进入出海电商领域。专为外贸市场量身定制的出海电商云手机&#xff0c;已经成为许多外贸企业和出海电商卖家的必备。本文将详细介绍电商云手机是什么以及可以用来做什么。 与国内云手机偏向于游戏场景不同&…

什么是启发式过滤(Heuristic Filtering)?

定义 启发式过滤是一种技术方法&#xff0c;利用解决问题的技术和算法来识别数据中的模式、趋势或特征。 这种方法通常涉及使用预测分析和近似方法&#xff0c;以便快速做出决策或对信息进行分类。 启发式过滤通常应用于反垃圾邮件软件、防病毒程序和人工智能等领域&#xff0…

openeuler22.03 LTS 源码编译安装nginx1.22.1

openeuler22.03 LTS 源码编译安装nginx1.22.1 下载安装包 #官网下载nginx1.22.1 wget http://nginx.org/download/nginx-1.22.1.tar.gz安装依赖包 #安装依赖包&#xff0c;NGINX是C语言写的&#xff0c;pcre-devel支持正则表达式&#xff0c;openssl 开启加密 [rootproxy ~]…

Java面向对象(类和对象)(自己学习整理的资料)

目录 一.面向对象思想 二.类和对象 三&#xff1a;定义类的步骤 四.创建对象 五.用Java代码写一个简单的登录系统 练习 六.关于类的方法 七.类的无参无返回值方法 八.方法的返回值 练习 关于方法调用问题 九.全局变量和局部变量 十.笔记 一.面向对象思想 就只关注参…

科研绘图系列:R语言分组堆积图(stacked barplot)

文章目录 介绍加载R包导入数据数据预处理画图导出数据系统信息介绍 堆积图是一种数据可视化图表,它通过将不同类别的数据以堆叠的形式展现在同一个图表中,来展示各个类别之间的相对大小和它们之间的总和。堆积图可以是柱状图、条形图或面积图的形式,其中每个堆叠的块或区域…

西门子S7-1200 PLC的配方功能

配方相关指令介绍工控人加入PLC工业自动化精英社群 配方功能主要使用4个指令&#xff0c;READ_DBL和WRIT_DBL用于对配方数据块的读写&#xff0c;RecipeExport和RecipeImport用于配方数据块和CSV文件之间的转化&#xff0c;下面分别介绍这4个指令的使用。 READ_DBL / / / / …

MMD模型及动作一键完美导入UE5-Blender方案(三)

1、下载并安装blender_mmd_tools插件 1、下载并安装Blender,Blender,下载Blender3.6,下载太新的版本可能会跟blender_mmd_tools不匹配 2、github下载blender_mmd_tools:https://github.com/UuuNyaa/blender_mmd_tools/ 3、Edit->Preference->Add ons->Install F…

【LinuxC高级】汇总

ls ls -l&#xff1a;显示文件的详细信息 ls -a&#xff1a;显示隐藏文件 ls -lh&#xff1a;文件大小单位显示 ls -i&#xff1a;显示文件的inode号 修改密码 passwd 用户名 su 用户名 -----> 用户名 su ----> 如果不加用户名&#xff0c;默认切换到超级用户 cd cd 路径…

Windows 10 on ARM, version 22H2 (updated Aug 2024) ARM64 AArch64 中文版、英文版下载

Windows 10 on ARM, version 22H2 (updated Aug 2024) ARM64 AArch64 中文版、英文版下载 基于 ARM 的 Windows 10 请访问原文链接&#xff1a;https://sysin.org/blog/windows-10-arm/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;s…

MyBatis—Plus 快速上手【后端 22】

MyBatis-Plus 使用入门指南 前言 在Java的持久层框架中&#xff0c;MyBatis因其灵活性和易用性而广受欢迎。然而&#xff0c;随着项目规模的扩大&#xff0c;MyBatis的一些重复性工作&#xff08;如CRUD操作&#xff09;开始显得繁琐。为了解决这一问题&#xff0c;MyBatis-Pl…

Flink 高可用原理

Flink 高可用原理 Flink JobManager 高可用 加强了 Flink 集群防止 JobManager 故障的能力。 此特性确保了 Flink 集群将始终持续执行你提交的作业。 JobManager 高可用一般概念是指&#xff0c;在任何时候都有 一个领导者 JobManager&#xff0c;如果领导者出现故障&#xff…

失踪人口回归(明天开始继续更新学习内容)

从明天开始继续更新个人学习经验及收获&#xff0c;可能会直接从C入门开始&#xff0c;总结一下C在C的基础上增加的新语法。这篇就当作水贴算了&#xff0c;大家别点赞&#xff0c;留点赞给明天的文章&#xff0c;哈哈 我是安姐的修沟...........

html TAB、table生成

1. 代码 <!DOCTYPE html> <head> <meta charset"UTF-8"> <title>Dynamic Tabs with Table Data</title> <style> /* 简单的样式 */ .tab-content { display: none; border: 10px solid #ccc; padding: 30px; mar…