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…

宏定义和内联函数区别

内联函数是代码被插入到调用者代码处的函数。如同 #define 宏&#xff0c;内联函数通过避免被调用的开销来提高执行效率&#xff0c;尤其是它能够通过调用&#xff08;“过程化集成”&#xff09;被编译器优化。 宏定义不检查函数参数&#xff0c;返回值什么的&#xff0c;只是…

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…

智能车复工日记【3】:图像处理——基本扫线和基本特征提取和十字补线

博主联系方式: QQ:1540984562 QQ交流群:892023501 群里会有往届的smarters和电赛选手,群里也会不时分享一些有用的资料,有问题可以在群里多问问。 目录 1、系列文章2、前言3、基本扫线(除了进入环岛状态或者坡道或者十字路口的普通扫线)1.基本数据和初步特征4、进一步特征…

short 用equals_Java Short类equals()方法的示例

short 用equals短类equals()方法 (Short class equals() method) equals() method is available in java.lang package. equals()方法在java.lang包中可用。 equals() method is used to check equality or inequality of this Object against the given Object or in other wo…

图解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;一个数…

智能车复工日记【2】——普通PID、变结构PID、微分先行PID、模糊PID、专家PID

博主联系方式: QQ:1540984562 QQ交流群:892023501 群里会有往届的smarters和电赛选手,群里也会不时分享一些有用的资料,有问题可以在群里多问问。 目录 系列文章前言普通PID舵机参数:电机参数:变结构PI控制(电机控制,这里对公式进行修改采用正态分布公式)微分先行PID(…

爬动的蠕虫(C++)

问题描述&#xff1a; 一条虫子在n英寸深的井底&#xff0c;每次一分钟爬行u英寸&#xff0c;但是它再次爬行前必须先休息1分钟&#xff0c;在休息过程中它将滑落d英寸&#xff0c;在反复向上爬行和休息后&#xff0c;多长时间虫子能爬出这口井&#xff1f;在此过程中&#xf…

使用快捷键,快到极致

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

java反射对象赋值_Java反射详解

反射(Reflection)能够让运行于 JVM 中的程序检测和修改运行时的行为。Class类提供了以下方法四个public方法&#xff0c;用于获取某个类的构造方法&#xff1a;Constructor getConstructor(Class[] params)// 根据构造函数的参数&#xff0c;返回一个具体的具有public属性的构造…

Oracle装置后果

来历&#xff1a;网海拾贝 本日未来诰日装置Oracle后&#xff0c;出现了两个后果。 经过过程SQL Plus不竭无法连接长途数据库&#xff0c;提醒错误ORA-12514:TNS:监听过程不能解析在连接描绘符中给出的SERVICE_NAME。 厥后缔造用可视化的Net Configuration Assistant东西对监听…

Java Hashtable hashCode()方法及示例

Hashtable类hashCode()方法 (Hashtable Class hashCode() method) hashCode() method is available in java.util package. hashCode()方法在java.util包中可用。 hashCode() method is used to return the hash code value for this object in this Hashtable. hashCode()方法…

C---蝉、蜻蜓、蜘蛛

【问题描述】 已知 腿/条翅膀/对蝉61蜻蜓62蜘蛛80 现有小虫n只&#xff0c;共有X条腿和Y对翅膀&#xff0c;问蝉、蜻蜓、蜘蛛各有多少只&#xff1f;请使用循环的知识解决&#xff0c;数据确保有解。 【输入形式】三个用空格隔开的整数&#xff0c;依次为n、X、Y 【输出形式】…

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

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

python如何操作oracle数据库_python操作oracle数据库

搜索热词下面是编程之家 jb51.cc 通过网络收集整理的代码片段。编程之家小编现在分享给大家&#xff0c;也给大家做个参考。# -*- mode: python; coding: utf-8 -*-## python operate oracle,contain insert、delete、update、select.## author liyulin# date 2014-11-07import…

可能用得上的jquery 插件

Chosen (github) 是一个强大的增强下拉选择框的插件&#xff0c;支持自定义css样式。同时你可以使用ajax增加一些回调函数&#xff0c;插件会给hidden input复制&#xff0c;这样你可以在提交表单的时候获得正确的值。 Turn.js 是一个 JavaScript 库&#xff0c;使您的网页内容…

草根创业回忆录二: 都选择的是什么人?

草根创业回忆录二: 都选择的是什么人&#xff1f; 前言&#xff1a;选合伙人和投资就像在选女朋友一样&#xff0c;要谨慎&#xff0c;甚至有时候宁缺毋滥。 曾经以为有了钱&#xff0c;就会找到需要的人&#xff0c;后来发现不是这样的。 也以为&#xff0c;随便拉几个关系好的…