首页 > 编程语言 >OpenCV C++ 霍夫直线变换-Hough Line Transform

OpenCV C++ 霍夫直线变换-Hough Line Transform

时间:2024-08-12 11:51:51浏览次数:15  
标签:直线 变换 Transform 霍夫 OpenCV C++ theta cv result

使用 OpenCV 在 C++ 中实现霍夫直线变换(Hough Line Transform)可以通过以下步骤完成。我们将首先进行边缘检测,然后应用霍夫直线变换来检测图像中的直线。

步骤概述

  1. 读取图像:使用 cv::imread 读取图像。
  2. 灰度转换:将图像转换为灰度图。
  3. 边缘检测:使用 Canny 边缘检测器。
  4. 霍夫直线变换:使用 cv::HoughLinescv::HoughLinesP 进行霍夫直线变换。
  5. 绘制检测到的直线:将检测到的直线绘制在原图或边缘图上。

示例代码

以下是一个完整的示例,展示了如何在 C++ 中使用 OpenCV 实现霍夫直线变换。

标准霍夫直线变换 (cv::HoughLines)
#include <opencv2/opencv.hpp>
#include <iostream>

int main() {
    // 读取图像
    cv::Mat image = cv::imread("example.jpg", cv::IMREAD_GRAYSCALE);
    if (image.empty()) {
        std::cerr << "Error opening image" << std::endl;
        return -1;
    }

    // 边缘检测
    cv::Mat edges;
    cv::Canny(image, edges, 50, 150, 3);

    // 霍夫直线变换
    std::vector<cv::Vec2f> lines;
    cv::HoughLines(edges, lines, 1, CV_PI / 180, 200);

    // 将检测到的直线绘制在原图上
    cv::Mat result;
    cv::cvtColor(edges, result, cv::COLOR_GRAY2BGR);

    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;
        cv::Point pt1(cvRound(x0 + 1000 * (-b)), cvRound(y0 + 1000 * (a)));
        cv::Point pt2(cvRound(x0 - 1000 * (-b)), cvRound(y0 - 1000 * (a)));
        cv::line(result, pt1, pt2, cv::Scalar(0, 0, 255), 2, cv::LINE_AA);
    }

    // 显示结果
    cv::imshow("Detected Lines - Standard Hough Transform", result);
    cv::waitKey(0);

    return 0;
}
概率霍夫直线变换 (cv::HoughLinesP)
#include <opencv2/opencv.hpp>
#include <iostream>

int main() {
    // 读取图像
    cv::Mat image = cv::imread("example.jpg", cv::IMREAD_GRAYSCALE);
    if (image.empty()) {
        std::cerr << "Error opening image" << std::endl;
        return -1;
    }

    // 边缘检测
    cv::Mat edges;
    cv::Canny(image, edges, 50, 150, 3);

    // 概率霍夫直线变换
    std::vector<cv::Vec4i> linesP;
    cv::HoughLinesP(edges, linesP, 1, CV_PI / 180, 50, 50, 10);

    // 将检测到的直线绘制在原图上
    cv::Mat result;
    cv::cvtColor(edges, result, cv::COLOR_GRAY2BGR);

    for (size_t i = 0; i < linesP.size(); i++) {
        cv::Vec4i l = linesP[i];
        cv::line(result, cv::Point(l[0], l[1]), cv::Point(l[2], l[3]), cv::Scalar(0, 255, 0), 2, cv::LINE_AA);
    }

    // 显示结果
    cv::imshow("Detected Lines - Probabilistic Hough Transform", result);
    cv::waitKey(0);

    return 0;
}

参数解释

  • cv::HoughLines

    • image:输入的边缘检测图像。
    • lines:输出的直线参数。
    • rho:参数空间中 (\rho) 的分辨率。
    • theta:参数空间中 (\theta) 的分辨率。
    • threshold:累加平面中投票数阈值,超过该值的点被认为是一条直线。
  • cv::HoughLinesP

    • image:输入的边缘检测图像。
    • lines:输出的直线段。
    • rho:参数空间中 (\rho) 的分辨率。
    • theta:参数空间中 (\theta) 的分辨率。
    • threshold:累加平面中投票数阈值,超过该值的点被认为是一条直线段。
    • minLineLength:线段的最小长度,线段长度小于此值的线段会被丢弃。
    • maxLineGap:线段之间的最大间隔,如果线段间的间隔小于此值,则认为它们是同一条线段。

总结

通过使用 OpenCV 提供的霍夫直线变换函数,可以方便地从图像中检测直线。标准霍夫变换适用于简单场景,而概率霍夫变换更适合复杂图像,因为它可以显著减少计算量并提高检测效率。根据具体应用场景调整参数,可以得到更好的直线检测效果。

标签:直线,变换,Transform,霍夫,OpenCV,C++,theta,cv,result
From: https://blog.csdn.net/qq_43689451/article/details/141116599

相关文章

  • 使用BatchNorm替代LayerNorm可以减少Vision Transformer训练时间和推理时间
    以VisionTransformer(ViT)的发现为先导的基于transformer的架构在计算机视觉领域引发了一场革命。对于广泛的应用,ViT及其各种变体已经有效地挑战了卷积神经网络(CNN)作为最先进架构的地位。尽管取得了一些成功,但是ViT需要更长的训练时间,并且对于小型到中型输入数据大小,推理......
  • 排序算法 内省排序(STL sort) IntroSort --C/C++
    内观排序/内省排序内省排序-维基百科,自由的百科全书(wikipedia.org)内省排序(英语:Introsort)是由大卫·穆塞尔在1997年设计的排序算法。这个排序算法首先从快速排序开始,当递归深度超过一定深度(深度为排序元素数量的对数值)后转为堆排序。采用这个方法,内省排序既能在常规数据集......
  • 使用API Monitor探测QQ安装包在创建桌面快捷方式时都调用了哪些API及COM接口,去解决C++
    目录1、通过代码制作安装包程序,不再使用专用的打包工具2、问题说明3、为啥路径中包含环境变量%ProgramFiles%会报找不到路径呢?4、使用APIMonitor监测QQ安装包在创建桌面快捷方式时都调用哪些COM组件的接口5、同时勾选IShelllinkDatalist接口类的接口,重新开启监测6、最后......
  • C++部分知识点总结
    动态规划:  01背包(每件物品只有1个)    不装:dp[i][j]=dp[i-1][j]    装: dp[i][j]=max(dp[i][j],dp[i-1][j-w[i]]+c[i])  完全背包    不装:dp[i][j]=dp[i-1][j]    装: dp[i][j]=max(dp[i][j],dp[i][j-w[i]]+c[i])  多重......
  • vs2022 x64 C/C++和汇编混编 遇到的坑
    vs2022x64C/C++和汇编混编遇到的坑遇到的问题二、问题复现1.出错代码2.问题分析2.1堆栈对齐问题3.解决方案总结奇数和偶数个寄存器的影响为什么`subrsp,8`对奇数个寄存器有用?结论遇到的问题0x00007FFFFAE24A29(msvcp140.dll)处(位于TestCompileConsol......
  • 【全网独家】OpenCV 面部识别系统
    OpenCV面部识别系统面部识别是计算机视觉中的一项重要应用,广泛用于安防监控、身份验证等领域。本文将详细介绍OpenCV中的面部识别系统,包括其应用场景、原理解释、算法流程、代码示例实现及部署测试场景。目录介绍应用使用场景原理解释算法原理流程图及解释应用场景代码......
  • C++写文件
    写文件的具体步骤:其中文件打开方式有下面几种:代码实现示例:#include<iostream>usingnamespacestd;#include<fstream>voidtest01(){ ofstreamofs; ofs.open("练习生.txt",ios::out);//这里选择打开自己文件,没有会自己创建 ofs<<"鸡你太美"<<endl; ofs.cl......
  • C++对象的创建(堆和栈的区别)
    在C++中,对象的创建可以在两种不同的内存区域进行:堆(heap)和栈(stack)。这两种内存区域在管理方式、生命周期、性能和使用场景上有所不同。以下是堆和栈上对象创建的主要区别:栈上对象创建:自动内存管理:栈上的对象在创建时自动分配内存,在离开作用域时自动销毁,无需手动管理内存。生命......
  • C++初阶
      目录一.命名空间1.命名空间定义2.命名空间使用二.C++输入&输出三.缺省参数四.函数重载五.引用1.常引用2.传值、传引用效率比较3.引用和指针的区别4.引用和指针的不同点:小知识点:六.内联函数七.auto关键字(C++11)1.auto的使用细则八.基于范围的for循环(C+......
  • C++《类和对象》(上)
    在之前的C++入门基础知识中我们了解了C++的发展过程已经重要性,还初步了解了C++中一些相比C语言特有的知识点,例如命名空间、缺少参数、函数重载、引用等,接下来在本篇中我们将开始C++整个体系中非常重要的一个知识章节——类和对象,类和对象时之后我们更加深入学习C++所必须要学习......