Opencv——霍夫变换以及遇到的一些问题

目录

    • 问题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
浅墨大神博客

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

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

相关文章

java ssm如何上传图片_ssm整合-图片上传功能(转)

本文介绍 ssm (SpringSpringMVCMybatis)实现上传功能。以一个添加用户的案例介绍(主要是将上传文件)。一、需求介绍我们要实现添加用户的时候上传图片(其实任何文件都可以)。文件名&#xff1a;以 博客名日期的年月日时分秒毫秒形式命名如 言曌博客2017082516403213.png路径&am…

24-光流估计

光流是空间运动物体在观测成像平面上的像素运动的“瞬间速度”&#xff0c;根据各个像素点的速度矢量特征&#xff0c;可以对图像进行动态分析&#xff0c;例如目标跟踪 亮度恒定&#xff1a;同一点随着时间的变化&#xff0c;其亮度不会发生改变 小运动&#xff1a;随着时间的…

java公平索非公平锁_java中的非公平锁不怕有的线程一直得不到执行吗

首先来看公平锁和非公平锁&#xff0c;我们默认使用的锁是非公平锁&#xff0c;只有当我们显示设置为公平锁的情况下&#xff0c;才会使用公平锁&#xff0c;下面我们简单看一下公平锁的源码&#xff0c;如果等待队列中没有节点在等待&#xff0c;则占有锁&#xff0c;如果已经…

mybatis.net - 5 嵌入资源与引用资源

在SqlMap.config文件中可以有两种方式引入外部的文件。 一种是通过资源的方式&#xff0c;在文件中表现为 resource&#xff0c;就是引用外部的文件&#xff0c;这里需要保证文件的路径正确。 <sqlMaps><sqlMap resource"Maps/ProductMap.xml"/><sqlM…

图解MySQL数据库的陈列和把持-4

泉源&#xff1a;网海拾贝 填入一些测试数据&#xff1a; 封闭“MySQL Query Browser”&#xff0c;再从头翻开它&#xff0c;切换到testtable表&#xff0c;看到了没有&#xff1f;刚刚输出的中文变成了“&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;&am…

非常好友(C++)

Bessie和其他的所有奶牛的耳朵上都戴有一个射频识别&#xff08;RFID&#xff09;序列号码牌。因此农夫John可以机械化地计算他们的数量。很多奶牛都有一个“牛友”。如果奶牛A的序列号的约数之和刚好等于奶牛B的序列号&#xff0c;那么A的牛友就是B。在这里&#xff0c;一个数…

使用快捷键,快到极致

前段时间曾经写过一篇文章&#xff0c;《优秀程序员无他-善假于物也》。其中谈到一点是优秀的程序员必须要能灵活的掌握常用软件的快捷键。对于程序员来说&#xff0c;每天使用时间最长的软件恐怕就是IDE&#xff08;Integrated Development Environment&#xff09;了。如果你…

轮廓(查找和绘制轮廓、轮廓的表达与组织、轮廓的特性)

目录1、轮廓的定义2、如何在图像中找到轮廓opencv自带的查找轮廓函数:findContours()3、轮廓的表达方式1.顶点的序列2.Freeman链码4、轮廓之间的组织方式5、轮廓的特点&#xff08;这部分可以展开来详细探讨&#xff0c;这里不做过多解释&#xff09;6、轮廓的匹配7、绘制轮廓d…

01-基本配置与测试

一、开发环境 使用的是Anaconda 3&#xff0c;其中Python版本为3.6.3 首先&#xff0c;在Anaconda下的Scripts文件夹下打开命令框 使用pip install -U selenium安装selenium 打开Jupiter Notebook&#xff0c;输入from selenium import webdriver进行测试 不报错即安装成功 …

Opencv——查找并绘制凸包、凸包与轮廓的关系

定义 给定二维平面上的点集&#xff0c;凸包就是将最外层的点连接起来构成的凸多边型。 理解物体形状或轮廓的一 种比较有用的方法便是计算一个物体的凸包&#xff0c;然后计算其凸缺陷(convexity defects)。 检测凸包 opencv自带函数&#xff1a;convexHull() 参数解释&a…

java接口并发衡量_java 后端设计高并发接口总结

如何设置高并发接口一、并发队列的选择二、请求接口的合理设计三、高并发下的数据安全3.1 超发的原因3.2 悲观锁思路3.3 FIFO队列思路3.4 乐观锁思路一、并发队列的选择Java的并发包提供了三个常用的并发队列实现&#xff0c;分别是&#xff1a;ArrayBlockingQueue、Concurrent…

JAVA 取得当前目录的路径

在写java程序时不可避免要获取文件的路径...总结一下,遗漏的随时补上 1.可以在servlet的init方法里 String path getServletContext().getRealPath("/"); 这将获取web项目的全路径 例如 :E:/eclipseM9/workspace/tree/ tree是我web项目的根目录 2.你也可以随时在任意…

02.1-元素定位(find)

常用的一些方法 一、导包 from selenium import webdriver二、打开火狐&#xff08;空白页&#xff09; b webdriver.Firefox()三、跳转到指定的网站 b.get(https://www.baidu.com/)四、将浏览器页面最大化 b.maximize_window()五、通过F12可查看当前的贴吧为超链接形式 …

快速傅里叶变换(FFT)——按时间抽取DIT的基

目录【1】前言1、DIF计算量2、利用性质改善【2】公式推导1、N 到 2*N/2a、分解原序列b、分解后的DFT变换c、一系列化简操作之后d、蝶形信号流e、计算量总结2、N/2 到 2*N/4a、分解X2(k)序列b、蝶形信号流&#xff08;2列&#xff09;3、N/4 到 2*N/8a、蝶形信号流&#xff08;3…

快速傅里叶变换(FFT)——按频率抽取DIF的基

目录【1】回顾DIT【2】算法原理【3】运算特点【1】回顾DIT https://blog.csdn.net/qq_42604176/article/details/105559756 【2】算法原理 设序列点数&#xff1a;N2^M,M为正整数。将输入序列按照前一半、后一半分开。&#xff08;并非按照奇偶分&#xff09; 由于&#xf…

莫比乌斯函数---C++

【问题描述】 莫比乌斯函数&#xff0c;数论函数&#xff0c;由德国数学家和天文学家莫比乌斯(Mobius&#xff0c;1790-1868)提出。梅滕斯(Mertens)首先使用μ(n)作为莫比乌斯函数的记号。而据说&#xff0c;高斯(Gauss)比莫比乌斯早三十年就曾考虑过这个函数。莫比乌斯函数在数…

Opencv——findContours函数再探(由轮廓联想连通域)

目录关于调参的一些思考分析图像的一些角度面积、周长、矩形度、圆形度、宽长比例1&#xff1a;找出汽车轮毂圆孔&#xff08;从轮廓和连通域两个角度&#xff09;例2&#xff1a;找出芯片中间正方形物体例3&#xff1a;桌面上橘色物体总结关于调参的一些思考 合理的参数设置&…

modelsim 编译 xilinx库

1.为单个工程加入库 在某一个目录建立工程 然后 vlib unisim vcom -work unsim *.vhd 然后就加入了unisim库 如果是windows的话&#xff0c;工程文件mpf应该是记录了这个库的信息&#xff0c;所以重新打开这个工程时&#xff0c;依然有这个库 linux&#xff0c;不用gui界面…

php 载入css就可以显示,如何在进度条加载后显示页面

1.思路&#xff1a;加入很多图片&#xff0c;以延迟加载时间&#xff0c;实现加载完后显示图片。定义一个外层p&#xff0c;覆盖住图片&#xff0c;在内层p中引入加载时显示的图片&#xff0c;让内层p居中在页面上&#xff0c;利用setInterval定时器设置3秒后将外层p隐藏&#…

如何获取轮廓(连通域)的面积、周长、矩形度、圆形度、宽长比、周径比等形状描述符?

博主联系方式&#xff1a; QQ:1540984562 QQ交流群&#xff1a;892023501 群里会有往届的smarters和电赛选手&#xff0c;群里也会不时分享一些有用的资料&#xff0c;有问题可以在群里多问问。 目录前言1、轮廓面积获取函数2、轮廓周长获取函数3、轮廓圆形度计算4、矩形度计算…