pythonopencv圆形检测
❶ opencv代码详解(探测红色圆形 并标注)
CvSize//定义640*480大小区域
CvCapture//从摄像头中获取视频
if(!capture)//如果获取失败
fprintf//输出错误信息
getchar();//获取一个输入字猜启符
return-1;//返回-1
cvNamedWindow//命名一个窗口,原始大小
CvScalar//定义2个数组
IplImage//新建2幅图像,大小为640*480,一穗搏如幅3通银码道彩色,一幅灰度
while(1)//循环
IplImage*frame//获取摄像头的一帧画面
if条件语句同上
cvCvtColorCV_BGR2HSV获取的图像由BGR模式转换为HSV颜色模式
cvInRangeS检测转换后HSV图像灰度是否在定义的2个数组范围内
❷ OpenCv判断某个轮廓是否为圆[100分]
方法1:现有轮廓拟合亏枝一个圆,计算拟合标旅启准圆与现有轮廓的距离。
方法2:直接拆空如给定标准轮廓,计算轮廓距离。
仅供参考
❸ python OpenCV 霍夫(Hough Transform)直线变换检测原理,图像处理第 33 篇博客
霍夫变换(Hough Transform)是图像处理领域中,从图像中识别几何形状的基本方法之一。主要识别具有某些相同特征的几何形状,例如直线,圆形,本篇博客的目标就是从黑白图像中识别出直线。
翻阅霍夫直线变换的原理时候,橡皮擦觉得原理部分需要先略过,否则很容易在这个地方陷进去,但是问题来了,这个原理略过了,直接应用函数,里面有些参数竟然看不懂。例如极坐标,角度扫描范围,这种函数就属于绕不过去的知识点了,所以本文转移方向,死磕原理,下面的博文将语无伦次的为你展示如何学习原理知识。
因为数学知识的贫乏,所以在学习阶段会涉及到很多基础概念的学习,一起来吧。
首先找到相对官方的资料,打开该 地址
下面是一个数学小白对原理的学习经验。
教材说:众所周知,一条直线在图像二维空间可由两个变量表示。
抱歉,小白还真不知道……即使学习过,这些年也早已经还给老师了。
一开始难道要学习笛卡尔坐标系,不,你低估小白的能力了,我第一个查询的是 θ 读作 西塔 ,是一个希腊字母。
什么是笛卡尔坐标系?
这个比较简单,直角坐标系。
斜率和截距
斜率,亦称“角系数”,表示一条直线相对于横坐标轴的倾斜程度。
一条直线与某平面直角坐标系横坐标轴正半轴方向的夹角的正切值即该直线相对于该坐标系的斜率。
如果直线与 x 轴互相垂直,直角的正切直无穷大,故此直线不存在斜率。
对于一次函数 y=kx+b , k 就是该函数图像的斜率。
在学习的时候,也学到如下内容:
截距:对 x 的截距就是 y=0 时, x 的值,对 y 的截距就是 x=0 时, y 的值,
截距就是直线与坐标轴的交点的横(纵)坐标。 x 截距为 a , y 截距 b ,截距式就是: x/a+y/b=1(a≠0且b≠0) 。
斜率:对于任意函数上任意一点,其斜率等于其切线与 x 轴正方向所成的角,即 k=tanα 。 ax+by+c=0中,k=-a/b 。
什么是极坐标系?
关于极坐标系,打开 网络 学习一下即可。
重点学到下面这个结论就行:
找资料的时候,发现一个解释的比较清楚的 博客 ,后续可以继续学习使用。
继续阅读资料,看到如下所示的图,这个图也出现在了很多解释原理的博客里面,但是图下面写了一句话
在这里直接蒙掉了,怎么就表示成极坐标系了?上面这个公式依旧是笛卡尔坐标系表示直线的方式呀,只是把 k 和 b 的值给替换掉了。
为何是这样的,具体原因可以参照下图。
<center>chou 图</center>
继续寻找关于霍夫变换的资料,找到一个新的概念 霍夫空间 。
在笛卡尔坐标系中,一条直线可以用公式 表示,其中 k 和 b 是参数,表示的是斜率和截距。
接下来将方程改写为 ,这时就建立了一个基于 k - b 的笛卡尔坐标系。
此时这个新的方程在 k - b 坐标系也有一个新的直线。
你可以在纸上画出这两个方程对应的线和点,如下图所示即可。
<center>chou 图</center>
新的 k - b 坐标系就叫做霍夫空间,这时得到一个结论,图像空间 x - y 中的点 对应了 霍夫空间 k - b 中的一条直线 ,即图像空间的点与霍夫空间的直线发生了对应关系。
如果在图像空间 x - y 中在增加一个点 ,那相应的该点在霍夫空间也会产生相同的点与线的对应关系,并且 A 点与 B 点产生的直线会在霍夫空间相交于一个点。而这个点的坐标值 就是直线 AB 的参数。
如果到这里你掌握了,这个性质就为我们解决直线检测提供了方法,只需要把图像空间的直线对应到霍夫空间的点,然后统计交点就可以达到目的,例如图像空间中有 3 条直线,那对应到霍夫空间就会有 3 个峰值点。
遍历图像空间中的所有点,将点转换到霍夫空间,形成大量直线,然后统计出直线交会的点,每个点的坐标都是图像空间直线方程参数,这时就能得到图像空间的直线了。
上述的内容没有问题,但是存在一种情况是,当直线趋近于垂直时,斜率 k 会趋近于无穷大,这时就没有办法转换了,解决办法是使用法线来表示直线。
上文提及的斜截式如下:
通过第二个公式,可以得到下述公式:
此时,我们可以带入一些数值进行转换。
图像空间有如下的几个点:
转换后的函数,都可以在霍夫空间 θ - ρ (横坐标是 θ ,纵坐标是 ρ )进行表示。
原理这时就比较清晰了:
除了一些数学知识以外,经典的博客我们也有必要记录一下,方便后面学习的时候,进行复盘。
本部分用于记录本文中提及的相关数学原理,后续还要逐步埋坑。
今天涉及了一点点数学知识,能力限制,大家一起学习,有错误的地方,可以在评论区指出,不胜感激。
希望今天的 1 个小时(今天内容有点多,不一定可以看完),你有所收获,我们下篇博客见~
相关阅读
技术专栏
逗趣程序员
❹ opencv中检测圆的方法
我采集了一幅JPG图片,想检测里面的圆,楼主有简单的例程么,我想学一学。
❺ python使用opencv进行圆检测的时候出现"Nonetype" object has no attribute "rint" 是什么问题
这个提示的意思是None类型对象没有rint属性,也就是说,你宴逗散上一步操作后返回晌氏的是一个None值,而不是你在题目里说到的圆,所以才会有这个提示,你应该检查一下上一步操作的结果。
如果上一步的返回结果是一个圆,那就是一个circle对象。你可以使用type方法检测返回结果。
不知道我说清楚了没有指拿,希望可以帮助到你。
❻ 用android opencv判断圆形
先进行边缘提取,比如用cvCanny, 然后用Hough变换,但是opencv的hough圆检测,不洞唯是太实用,罩笑和参数设置关系很大,很难检测出所有的圆信息, 最好根据具体纳闷培问题,自己编写该模块
❼ 用opencv函数HoughCircles为什么检测不到圆
//圆形检测代码demo
//载入数张包含各种形凯谨状的图片,检测出其中的圆形
#include "cv.h"
#include "highgui.h"
#include <math.h>
#include <string.h>
#include <iostream>
int thresh = 50;
IplImage* img =NULL;
IplImage* img0 = NULL;
IplImage * pImg8u=NULL;
CvMemStorage* storage =NULL;
const char * wndname = "圆形检测 Demo";
char* names[] = { "aa.png","bb.png","pic8.png"尘磨,"pic7.png","pic3.png","pic9.png","pic10.png",
"pic11.png","pic12.png","pic13.png","pic14.png",0};
void HoughCircle()
{
CvSeq * circles=NULL;
pImg8u=cvCreateImage(cvGetSize(img),8,1);
CvMemStorage* storage = cvCreateMemStorage(0);
cvCvtColor(img,pImg8u,CV_BGR2GRAY);
//最好先cvSmooth一下,再调用cvHoughCircles
cvSmooth(pImg8u,pImg8u,CV_GAUSSIAN,7,7);
circles=cvHoughCircles(pImg8u,storage,CV_HOUGH_GRADIENT,
2, //最小分辨率,应当>=1
pImg8u->height/4, //该参数是让算法能明显区分的两个不同圆之间的最小距离
140, //用于Canny的边缘阀值上限,下派孙斗限被置为上限的一半
118, //累加器的阀值
2, //最小圆半径
120 //最大圆半径
);
int k;
for (k=0;k<circles->total;k++)
{
float *p=(float*)cvGetSeqElem(circles,k);
//cvCircle( img, cvPoint(cvRound(p[0]),cvRound(p[1])), 3, CV_RGB(0,255,0), -1, 8, 0 );
cvCircle(img,cvPoint(cvRound(p[0]),cvRound(p[1])),cvRound(p[2]),CV_RGB(0,0,0),3,CV_AA,0);
}
cvClearMemStorage( storage );
}
int main(int argc, char** argv)
{
int i, c;
// create memory storage that will contain all the dynamic data
for( i = 0; names[i] != 0; i++ )
{
img0 = cvLoadImage( names[i], 1 );
if( !img0 )
{
cout<<"不能载入"<<names[i]<<"继续下一张图片"<<endl;
continue;
}
img = cvCloneImage( img0 );
HoughCircle();
cvNamedWindow( wndname, 1 );
cvShowImage(wndname,img);
c = cvWaitKey(0);
cvReleaseImage( &img );
cvReleaseImage( &img0 );
cvReleaseImage(&pImg8u);
if( (char)c == 27 )
break;
}
cvDestroyWindow( wndname );
return 0;
}
❽ 在opencv中使用cvHoughCircles检测圆,提到这是一种改进的方法,请问这种“改进的方法”改进的地方是哪里
单纳御纯的hough变兆旅换检测速度太慢,特别是园,是一到多映射,因而计算量急剧增大,需占用大量内存空间,改进的方法很多,你可以看它洞猜岩的源代码。个人估计用的是随机Hough变换(RHT)