目录

  • 问题1 :颜色空间转换函数参数问题:CV_BGR2GRAY vs CV_GRAY2BGR
  • 问题2:cvRound()、cvFloor()、cvCeil()函数用法
  • 霍夫变换的含义
  • 标准霍夫直线变换
    • 霍夫线变换函数参数讲解
  • 累计概率霍夫变换
  • 霍夫变换圆变换
    • 原理和算法步骤:
    • 霍夫圆变换函数参数讲解
  • 霍夫变换总结
  • 参考链接

问题1 :颜色空间转换函数参数问题:CV_BGR2GRAY vs CV_GRAY2BGR

OpenCV的颜色空间转换函数:

void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0 )

dstCn现在已经改成COLOR_GRAY2BGR之类的以COLOR开头的。
CV_BGR2GRAY :将RGB图转换成GRAY图
CV_GRAY2BGR:将GRAY图转换成RGB图
浅墨源码
cvtColor(midImage, dstImage, COLOR_GRAY2BGR);
//将canny算子扫描后的二值图转化为RGB图,原因是后面你可视化霍夫变换效果时,画的曲线是彩色的。

问题2:cvRound()、cvFloor()、cvCeil()函数用法

cvRound():返回跟参数最接近的整数值,即四舍五入;
cvFloor():返回不大于参数的最大整数值,即向下取整;
cvCeil():返回不小于参数的最小整数值,即向上取整;

霍夫变换的含义

这个我在边缘的文章中有涉及过,直接贴链接:
https://blog.csdn.net/qq_42604176/article/details/104300287
还有我参考的一个链接:
https://blog.csdn.net/yuyuntan/article/details/80141392

标准霍夫直线变换

霍夫线变换函数参数讲解

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

理解:在XY平面,直线有两个参数:K、B(斜率和截距),可视化直线,需要构造x,y轴,假设XY轴的最小精度为1,则勾画出的直线其实是一系列离散的点。随着XY精度升高,所可视化出来的数据将越来越像一条线。
同理,在rho/theta平面,一条直线对应平面上以rho为横坐标,tehta为纵坐标的一个点。
rho/theta的精度越高,所表示的直线越精准。我想这边是第三参数和第四参数的含义。
我们一般以rho=1,theta=1度的精度来构造投票空间。

#include <opencv2/opencv.hpp>
#include <iostream>
#include "windows.h"
#include <stdio.h>
#define WINDOW_NAME "【程序窗口】"          //为窗口标题定义的宏using namespace cv;
using namespace std;
//==================================标准霍夫变换============================================
int main()
{SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);     //字体为绿色Mat srcImage = imread("D:\\opencv_picture_test\\霍夫变换.png");//判断图像是否加载成功if (srcImage.empty()){cout << "图像加载失败!" << endl;return -1;}elsecout << "图像加载成功!" << endl << endl;Mat midImage,dstImage;Canny(srcImage, midImage, 50, 200, 3);//进行一此canny边缘检测  //【3】进行霍夫线变换  vector<Vec2f> lines;//定义一个矢量结构lines用于存放得到的线段矢量集合  HoughLines(midImage, lines, 1, CV_PI / 180, 150, 0, 0);//【4】依次在图中绘制出每条线段  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(midImage, pt1, pt2, Scalar(255,255,255),1, LINE_AA);}//【5】显示原始图    imshow("【原始图】", srcImage);//【6】边缘检测后的图   imshow("【边缘检测后的图】", midImage);//【7】显示效果图    //imshow("【效果图】", dstImage);waitKey(0);return 0;
}

累计概率霍夫变换

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

第一个参数,InputArray类型的image,输入图像,即源图像,需为8位的单通道二进制图像,可以将任意的源图载入进来后由函数修改成此格式后,再填在这里。
第二个参数,InputArray类型的lines,经过调用HoughLinesP函数后后存储了检测到的线条的输出矢量,每一条线由具有四个元素的矢量(x_1,y_1, x_2, y_2) 表示,其中,(x_1, y_1)和(x_2, y_2) 是是每个检测到的线段的结束点。
第三个参数,double类型的rho,以像素为单位的距离精度。另一种形容方式是直线搜索时的进步尺寸的单位半径。
第四个参数,double类型的theta,以弧度为单位的角度精度。另一种形容方式是直线搜索时的进步尺寸的单位角度。
第五个参数,int类型的threshold,累加平面的阈值参数,即识别某部分为图中的一条直线时它在累加平面中必须达到的值。大于阈值threshold的线段才可以被检测通过并返回到结果中。
第六个参数,double类型的minLineLength,有默认值0,表示最低线段的长度,比这个设定参数短的线段就不能被显现出来。
第七个参数,double类型的maxLineGap,有默认值0,允许将同一行点与点之间连接起来的最大的距离。

通过设定直线长度阈值,对过长或过短的直线不予理会。

//==================================累计概率霍夫变换============================================
int main()
{//读取原图片Mat Image = imread("D:\\opencv_picture_test\\霍夫变换.png");//显示原图片namedWindow("【原图】");imshow("【原图】", Image);Mat srcImage = Image.clone();Mat midImage, dstImage;//进行边缘检测和转化为将灰度图转为RGB图Canny(srcImage, midImage, 50, 200, 3);cvtColor(midImage, dstImage, COLOR_GRAY2BGR);//定义矢量结构lines用于存放得到的线段矢量集合vector<Vec4i> lines;//进行霍夫变换HoughLinesP(midImage, lines, 1, CV_PI / 180, 80, 50, 10);//依次在图中绘制每条线段for (size_t i = 0;i < lines.size();i++) {Vec4i l = lines[i];line(dstImage, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0, 0, 255), 1, LINE_AA);}imshow("【边缘检测后的图】", midImage);imshow("【效果图】", dstImage);waitKey(0);return 0;
}

霍夫变换圆变换

原理和算法步骤:

霍夫圆变换函数参数讲解

cvHoughCircles( CvArr* image, void* circle_storage, int method, double dp, double min_dist, double param1=100, double param2=100, int min_radius=0, int max_radius=0 );

输入:输入 8-bit、单通道灰度图像. circle_storage:检测到的圆存储仓. 可以是内存存储仓 (此种情况下,一个线段序列在存储仓中被创建,并且由函数返回)或者是包含圆参数的特殊类型的具有单行/单列的CV_32FC3型矩阵(CvMat*).矩阵头为函数所修改,使得它的 cols/rows 将包含一组检测到的圆。如果 circle_storage是矩阵,而实际圆的数目超过矩阵尺寸,那么最大可能数目的圆被返回。 每个圆由三个浮点数表示:圆心坐标(x,y)和半径.
method:Hough 变换方式,目前 只支持HOUGH_GRADIENT
dp:累加器图像的分辨率。这个参数允许创建一个比输入图像分辨率低的累加器。(这样做是因为有理由认为图像中存在的圆会自然降低到与图像宽高相同数量的范畴)。如果dp设置为1,则分辨率是相同的;如果设置为更大的值(比如2),累加器的分辨率受此影响会变小(此情况下为一半)。dp的值不能比1小。
min_dist:该参数是让算法能明显区分的两个不同圆之间的最小距离。
param1:用于Canny的边缘阀值上限,下限被置为上限的一半。
param2:累加器的阀值。
min_radius:最小圆半径。
max_radius:最大圆半径。


==================================霍夫变换圆变换============================================int main()
{//载入原始图和Mat变量定义     Mat srcImage = imread("D:\\opencv_picture_test\\形态学操作\\孔洞.png");Mat midImage, dstImage;//显示原始图  imshow("【原始图】", srcImage);//转为灰度图,进行图像平滑  cvtColor(srcImage, midImage, COLOR_BGR2GRAY);//转化边缘检测后的图为灰度图  GaussianBlur(midImage, midImage, Size(9, 9), 2, 2);        //模糊去噪//进行霍夫圆变换  vector<Vec3f> circles;       //圆存储器,存储圆的数量,圆心坐标和半径HoughCircles(midImage, circles,HOUGH_GRADIENT, 1.5, 10, 200, 100, 0, 0);//inputImage  circle_storage 霍夫变换的方式 累加器图像的分辨率 两个不同圆之间的距离 //依次在图中绘制出圆  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]);//绘制圆心  circle(srcImage, center, 3, Scalar(0, 0, 255), 3, 8, 0);//绘制圆轮廓  circle(srcImage, center, radius, Scalar(0, 0, 255), 3, 8, 0);}//显示效果图    imshow("【效果图】", srcImage);while ((char)waitKey(1) != 'q') {}return 0;
}

霍夫变换总结

1、为什么在霍夫变换求直线方程时,要用极坐标的形式
斜截式不能表示垂直于x轴的直线,而极坐标形式可以表达。
2、霍夫变换求直线方程,和使用最小二乘法求直线最小方程相比,有什么优缺点
优点:当出现离群采样点时最小二乘法会有很大误差而霍夫变换不会
缺点:时间复杂度和空间复杂度都很高,只能检测线段的方向,而不能确定线段的长度

参考链接

https://blog.csdn.net/timidsmile/article/details/9342855

https://blog.csdn.net/OliverkingLi/article/details/54754814?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522158565498519724835852132%2522%252C%2522scm%2522%253A%252220140713.130056874…%2522%257D&request_id=158565498519724835852132&biz_id=0&utm_source=distribute.pc_search_result.none-task

http://www.manongjc.com/article/42132.html
https://stackoverflow.com/questions/5929125/opencv-houghcircles-param1-param2
https://blog.csdn.net/yuyuntan/article/details/80141392
浅墨大神博客

Opencv——霍夫变换以及遇到的一些问题相关推荐

  1. OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑

    本篇文章中,我们一起探讨了OpenCV中霍夫变换相关的知识点,以及了解了OpenCV中实现霍夫线变换的HoughLines.HoughLinesP函数的使用方法,实现霍夫圆变换的HoughCircle ...

  2. OpenCV霍夫变换的演示代码(附完整代码)

    OpenCV霍夫变换的演示代码 OpenCV霍夫变换的演示代码 OpenCV霍夫变换的演示代码 #include "opencv2/imgcodecs.hpp" #include ...

  3. OpenCV霍夫变换查找圆的实例(附完整代码)

    OpenCV霍夫变换查找圆的实例 OpenCV霍夫变换查找圆的实例 OpenCV霍夫变换查找圆的实例 #include "opencv2/imgcodecs.hpp" #inclu ...

  4. 【OpenCV新手教程之十四】OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/26977557 作者:毛星云(浅墨) ...

  5. opencv霍夫变换检测圆cvHoughCircles和直线cvHoughLines2的应用

    opencv霍夫变换检测圆cvHoughCircles和直线cvHoughLines2的应用 1)cvHonghLines2:直线 2)cvHoughCircles:该函数用Hough变换在二值图像中 ...

  6. 【OpenCV入门教程之十四】OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/26977557 作者:毛星云(浅墨) ...

  7. hough变换检测圆周_Python OpenCV 霍夫变换

    霍夫变换(Hough Transform)是图像处理中的一种特征提取技术,它通过一种投票算法检测具有特定形状的物体.Hough变换是图像处理中从图像中识别几何形状的基本方法之一.Hough变换的基本原 ...

  8. opencv 霍夫变换检测直线和圆

    霍夫变换 霍夫变换原理及python实现 opencv 霍夫直线变换 OpenCV中用cv.HoughLines()在二值图上实现霍夫变换,函数返回的是一组直线的(r,θ)数据: 函数中: 参数1:要 ...

  9. OpenCV 霍夫变换

    文章目录 一.霍夫直线变换 1. cv2.HoughLines() 1. cv2.HoughLinesP() 二.霍夫圆环变化 霍夫变化是一种在图像中寻找直线.圆形以及其他简单形状的方法.霍夫变换采用 ...

最新文章

  1. greenplum 存储过程_如何使用Greenplum提升PB级数据处理能力
  2. torch topk
  3. setfacl命令_一名合格的Linux运维人员应该掌握哪些命令?
  4. ajax html例子,AJAX实例
  5. C# 对Outlook联系人的增、删、查
  6. 小米获京东自营安卓平板销量冠军 小米平板5 Pro全版本闪降100元
  7. 新站如何迅速提高流量和被百度收录的技巧绝版
  8. Android开发网络连接超时
  9. java上课签到如何写_java签到程序怎么设置?学生考勤程序怎么写?
  10. C#基础知识(收藏)
  11. 一周3篇顶刊!颜宁团队今年已发5篇Science/PNAS等顶级论文
  12. 回答cad转pdf格式的简易方法
  13. 计算机进行定理的自动证明属于,使用计算机进行定理的自动证明,属于计算机在()应用领域的应用...
  14. OpenStack基金会更名,开源基础设施开启新十年
  15. 90°光混频器原理分析
  16. MP4文件格式的相关内容
  17. 计算机只存在于计算机硬盘上,计算机病毒只存在于计算机硬盘上。
  18. u盘中毒文件为html文档,U盘u盘中毒,文件被隐藏了怎么办 – 手机爱问
  19. babylon101| 08. Cameras, Mesh Collisions and Gravity(相机、碰撞和重力)
  20. 罗斯蒙特248温度变送器248HANANONS

热门文章

  1. odbc连接oracle失败,大神解答win7系统ODBC无法连接ORACLE的处理方案
  2. springboot mysql时区设置_java/springboot/mysql时区问题解决方案
  3. js 判断一个字符在字符串中出现的次数
  4. bootbox.js
  5. FROONT – 超棒的可视化响应式网页设计工具
  6. Sequence.js 实现带有视差滚动特效的图片滑块
  7. 行内元素,块级元素,各自特点及其相互转化
  8. 控制元素的div属性
  9. less学习三---父选择器
  10. 设置QtreeWidget水平滚动条