Hough变换实例

合集下载

膨胀与腐蚀radonhough变换(1)

膨胀与腐蚀radonhough变换(1)

(a) 图像3-16(a)的一部分,即有字母b的那部分,图3-17左边的一部分数据
(b) 图(a)使用Q膨胀后的部分结果,即3-18(d)的放大。 图3-19 二值图像膨胀运算规则
其他算子的运算规则都与上面所述相同。运算结果与原图像有关,算子形状与图像的邻域情况决定了运算结果。 另外,从上面描述情况看,二值图像膨胀运算本质上是逻辑运算。 数学上,二值图像膨胀运算可以用集合定义如下:
(a) 原图像 (b) 腐蚀后的图像 (c) 膨胀后的图像 图3-21 二值图像腐蚀与膨胀比较
函数strel是专门用来生成算子模板的,strel('diamond',3)生成的算子模板为: 0 0 0 1 0 0 0 0 0 1 1 1 0 0 0 1 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1 1 1 1 0 0 0 1 1 1 0 0 0 0 0 1 0 0 0 函数strel还可以生成‘square’、‘line’、‘disk’、‘periodicline’、‘pair’、‘octagon’等模板。
图3-20 二值图像腐蚀运算
程序中的函数imerode是用来进行腐蚀运算的。腐蚀运算后,原来图像一般会变细变小。
【例3-18】对二值图像实施腐蚀运算,并且与膨胀运算进行比较。 设计下面程序: A = imread('0370.bmp'); B=im2bw(A); B=~B; M=strel('diamond',3); C1=imerode(B,M); C2=imdilate(B,M); subplot(1,3,1); imshow(B) subplot(1,3,2); imshow(C1) subplot(1,3,3); imshow(C2) 程序运行结果如图3-21所示。

Hough变换

Hough变换
2)对边界上的每一个点(xi,yi),将 的所有量化 值代入式(8-71),计算相应的,并且将累加器加1, M(,)=M(,)+1。
3)将全部(xi,yi)处理后,分析M(,),如果 M(,)T,就认为存在一条有意义的线段,是该线段
的拟合参数。T是一个非负整数,由图像中景物的先 验知识决定。
y

(xi,yi)
图8-14 点的Houghx变换的极坐标形式
y
0=xcos0+ysin0 (xi,yi)
(0,0)
图8-15 共线点Houxgh变换的极坐标形式
数字图像处理与分析基础
算法
1)将(,)空间量化,得到二维矩阵M(,), M(,)是一个累加器,初始值为0,M(,)=0。
直线。对于(x,y)空间的任意一点(xi,yi),采用
极坐标(,)作为变换空间,其变换方程为:
=xicos+y间的一点(xi,yi)对应于(,)空
间的一条正弦曲线,其相位和幅值由xi、yi决定。
数字图像处理与分析基础
(x,y)空间的同一条直线上的点在(,)空间的正弦 曲线都会相交于点(0, 0),0为这条直线到原点的 距离, 0为直线的法线与轴的夹角,
边缘连接——Hough变换
Hough变换[Hough,1962]是一种基于图像全局分割 结果的边缘连接技术,它抗干扰能力强,能检测出 任意形状的曲线,即使线上有许多的断裂,因此在 图像分析的预处理中获得广泛应用。下面只介绍检 测直线的经典方法。
设图像空间(x,y)中的一条直线的方程为:
y=u0x+v0 式中u0为斜率,v0为截距。那么对于直线上的任意 一点pi(xi,yi),它在由斜率和截距组成的变换空间
(u,v)中将满足方程式:

Hough变换检测直线

Hough变换检测直线

Hough 变换检测直线实验报告一,实验要求用hough 算法检测图像中的直线算法。

使用这一算法来求一幅图像中的所有大于规定长度的直线段,设规定的长度为20点。

二,Hough 变换简介Hough 变换是图像处理中从图像中识别几何形状的基本方法之一。

Hough 变换的基本原理在于利用点与线的对偶性,将原始图像空间的给定的曲线通过曲线表达形式变为参数空间的一个点。

这样就把原始图像中给定曲线的检测问题转化为寻找参数空间中的峰值问题。

图1 Hough 变换)sin(sin cos 00θαθθρ+=+=A y x如上图所示,在图像空间,直线上一点),(00y x 转换到参数空间就是一条曲线,而且,图像空间同一直线上的点转换到参数空间的曲线一定相交于一点,即参数空间各曲线的交点对应着图像空间的一条直线,这样,检测参数空间曲线交点就检测出了图像空间的直线。

三,实验过程和结果分析用Hough 变换之前, 首先要对图像进行边缘检测的处理,也即霍夫线变换的直接输入只能是边缘二值图像。

本实验基于VS2008和OPENCV 来实现。

实验的步骤如下:(1)读入图像,转换成灰度图像OPENCV 中用cvLoadImage 函数来读取图像,函数原型:IplImage* cvLoadImage( const char* filename, int flags=CV_LOAD_IMAGE_COLOR );filename :要被读入的文件的文件名(包括后缀);flags :指定读入图像的颜色和深度;例如:cvLoadImage( fileame, -n1 ); //默认读取图像的原通道数cvLoadImage( filename, 0 ); //强制转化读取图像为灰度图 cvLoadImage( filename, 1 ); //读取彩色图(2)进行边缘检测本实验选择Canny算子的边缘检测,OPENCV中用Canny函数来进行Canny 算子的边缘检测,函数原型为:void cvCanny( const CvArr* image, CvArr* edges, double threshold1, double threshold2, int aperture_size=3 );image:单通道输入图像edges:单通道存储边缘的输出图像threshold1 :第一个阈值threshold2 :第二个阈值aperture_size :算子内核大小3,对检测出的二值图像进行Hough变换OPENCV中用cvHoughLines2函数来进行Hough变换,函数原型为:CvSeq* cvHonghLines2(CvArr* image,void* line_storage,int mehtod,double rho,double theta,int threshold,double param1 =0,double param2 =0);Image:输入8-比特、单通道(二值)图像line_storage:检测到的线段存储仓Method:Hough 变换变量,是下面变量的其中之一CV_HOUGH_STANDARD ——传统或标准Hough 变换CV_HOUGH_PROBABILISTIC——概率Hough 变换CV_HOUGH_MULTI_SCALE ——传统Hough 变换多尺度变种Rho:以象素为单位的距离精度,一般取1Theta:以弧度为单位角度精度,一般取CV_PI/180Threshold:阈值参数,当在一条直线上的像素点数大于threshold时,才将该直线作为检测结果显示出来,该值越大,得到直线越少。

用Hough变换检测二值图像中的圆

用Hough变换检测二值图像中的圆

用Hough变换检测二值图像中的圆Hough 变换简介Hough变换是实现图像边缘检测的一种有效方法,其基本思想是将测量空间的一点变换到参量空间中的一条曲线或一个曲面,而具有同一参量特征的点交换后在参量空间中相交,通过判断交点处的积累程度来完成特征曲线的检测,基于参量性质的不同,Hough变换可以检测直线、圆、椭圆、双曲线、抛物线等。

同时,将概率论、模糊集理论、分层迭代的思想和级联的方法应用于Hough变换的过程中,大大地提高了Hough变换的效率,改善了Hough变换的性能。

实验主要使用的函数MATLAB内部常数pi:圆周率p(=3.1415926...)MATLAB常用基本数学函数:abs(x):纯量的绝对值或向量的长度;round(x):四舍五入至最近整数;floor(x):地板函数,即舍去正小数至最近整数;MATLAB常用三角函数sin(x):正弦函数cos(x):余弦函数;向量的常用函数max(x):向量x的元素的最大值。

MATLAB图像类型转换函数:rgb2gray:将一副真彩色图像转换成灰度图像;im2bw:通过设定高度阈值将真彩色,索引色,灰度图转换成二值图像;MATLAB图形图像文件的读取和显示函数imread(filename);MATLAB二进制图像及其显示imshow(f1)。

用double对二值图像双精度化图形处理:sobel算子检测边缘hough变换检测圆分别显示灰度图像:figure;subplotSobel:算子边缘检测图像hough变换检测后的图像实验相关代码I=imread('*.jpg');f=rgb2gray(I);f1=im2bw(f,200/255);BW1=double(f1);BW=edge(BW1,'sobel',0.4);r_max=50;r_min=10;step_r=10;step_angle=pi/12;p=0.7;[m,n]=size(BW);size_r=round((r_max-r_min)/step_r)+1;size_angle=round(2*pi/step_angle);hough_space=zeros(m,n,size_r);[rows,cols]=find(BW);ecount=size(rows);for i=1:ecountfor r=1:size_rfor k=1:size_anglea=round(rows(i)-(r_min+(r-1)*step_r)*cos(k*step_angle));b=round(cols(i)-(r_min+(r-1)*step_r)*sin(k*step_angle));if(a>0&&a<=m&&b>0&&b<=n)hough_space(a,b,r)=hough_space(a,b,r)+1;endendendendmax_para=max(max(max(hough_space)));index=find(hough_space>=max_para*p);length=size(index);hough_circle=false(m,n);for i=1:ecountfor k=1:lengthpar3=floor(index(k)/(m*n))+1;par2=floor((index(k)-(par3-1)*(m*n))/m)+1;par1=index(k)-(par3-1)*(m*n)-(par2-1)*m;if((rows(i)-par1)^2+(cols(i)-par2)^2<(r_min+(par3-1)*step_r)^2+5&&...(rows(i)-par1)^2+(cols(i)-par2)^2>(r_min+(par3-1)*step_r)^2-5)hough_circle(rows(i),cols(i))=true;endendendfor k=1:lengthpar3=floor(index(k)/(m*n))+1;par2=floor((index(k)-(par3-1)*(m*n))/m)+1;par1=index(k)-(par3-1)*(m*n)-(par2-1)*m;par3=r_min+(par3-1)*step_r;fprintf(1,'Center%d%d radius%d\n',par1,par2,par3);para(:,k)=[par1,par2,par3];endsubplot(221),imshow(f);subplot(222),imshow(BW);subplot(223),imshow(hough_circle)图像读取图像处理的第一步就是对所采集的图像进行读入,本次研究采集的图像是24位真彩色的JPG 格式的图像。

OpenCV函数cvHoughLines2进行Hough变换

OpenCV函数cvHoughLines2进行Hough变换

OpenCV函数cvHoughLines2进行Hough变换OpenCV函数cvHoughLines2进行Hough变换霍夫变换(Hough Transform)是图像处理中的一种特征提取技术,它通过一种投票算法检测具有特定形状的物体。

该过程在一个参数空间中通过计算累计结果的局部最大值得到一个符合该特定形状的集合作为霍夫变换结果。

霍夫变换于1962年由Paul Hough 首次提出[53],后于1972年由Richard Duda和Peter Hart推广使用[54],经典霍夫变换用来检测图像中的直线,后来霍夫变换扩展到任意形状物体的识别,多为圆和椭圆。

Hough变换用来在图象中查找直线。

它的原理很简单:假设有一条与原点距离为s,方向角为θ的一条直线,如图7.6所示。

直线上的每一点都满足方程我们知道,一条直线在直角坐标系下可以用y=kx+b表示, 霍夫变换的主要思想是将该方程的参数和变量交换,即用x,y作为已知量k,b作为变量坐标,所以直角坐标系下的直线y=kx+b在参数空间表示为点(k,b),而一个点(x1,y1)在直角坐标系下表示为一条直线y1=x1·k+b,其中(k,b)是该直线上的任意点。

为了计算方便,我们将参数空间的坐标表示为极坐标下的s和θ。

因为同一条直线上的点对应的(s,θ)是相同的,因此可以先将图片进行边缘检测,然后对图像上每一个非零像素点,在参数坐标下变换为一条直线,那么在直角坐标下属于同一条直线的点便在参数空间形成多条直线并内交于一点。

因此可用该原理进行直线检测。

在Opencv中已经有了利用Hough变换在二值图中找到直线的接口了,这里就直接调用,下面是我的实例:[cpp] view plaincopy#include<cv.h>#include<highgui.h><P> </P><P>#pragma comment(lib, "cv.lib") #pragmacomment(lib, "cxcore.lib")#pragma comment(lib, "highgui.lib")</P>int main(){IplImage* pImgSrc = NULL; //源图像IplImage* pImg8u = NULL; //灰度图IplImage* pImgCanny = NULL; //边缘检测后的图IplImage* pImgDst = NULL; //在图像上画上检测到的直线后的图像CvSeq* lines = NULL;CvMemStorage* storage = NULL;/*边缘检测*/pImgSrc = cvLoadImage ("1.jpg", 1);pImg8u = cvCreateImage (cvGetSize(pImgSrc),IPL_DEPTH_8U, 1);pImgCanny = cvCreateImage (cvGetSize(pImgSrc),IPL_DEPTH_8U, 1);pImgDst = cvCreateImage (cvGetSize(pImgSrc),IPL_DEPTH_8U, 1);cvCvtColor (pImgSrc, pImg8u, CV_BGR2GRAY);cvCanny (pImg8u, pImgCanny, 20, 200, 3);/*检测直线*/storage = cvCreateMemStorage (0);lines = cvHoughLines2 (pImgCanny, storage,CV_HOUGH_PROBABILISTIC, 1, CV_PI/180, 80, 200, 10);pImgDst = cvCreateImage (cvGetSize(pImgSrc),IPL_DEPTH_8U, 3);cvCvtColor (pImg8u, pImgDst, CV_GRAY2BGR);/*在pImgDst上画出检测到的直线*/for (int i = 0; i < lines->total; i++){CvPoint* line = (CvPoint*)cvGetSeqElem (lines, i); cvLine (pImgDst, line[0], line[1], CV_RGB(255,0,0), 3, 8);}cvNamedWindow ("src",1);cvNamedWindow ("canny", 1);cvNamedWindow ("hough", 1);cvShowImage ("src", pImgSrc);cvShowImage ("canny", pImgCanny);cvShowImage ("hough", pImgDst);cvWaitKey (0);cvReleaseImage (&pImgSrc);cvReleaseImage (&pImg8u);cvReleaseImage (&pImgCanny);cvReleaseImage (&pImgDst); cvReleaseMemStorage (&storage);return 0;}结果如下:源图:Canny算子进行边缘检测结果:Hough变换检测直线:。

hough变换 matlab例程

hough变换 matlab例程

以下是一个简单的MATLAB例程,演示如何使用Hough变换来检测图像中的直线。

假设你已经有一个名为`image.jpg`的图像文件,你可以使用以下代码来进行Hough变换:读取图像I = imread('image.jpg');将图像转换为灰度图Igray = rgb2gray(I);执行边缘检测BW = edge(Igray, 'canny');执行Hough变换[H,theta,rho] = hough(BW);找到峰值P = houghpeaks(H,5,'threshold',ceil(0.3*max(H(:))));找到直线lines = houghlines(BW,theta,rho,P,'FillGap',5,'MinLength',7);绘制图像和检测到的直线figure, imshow(I), hold onfor k = 1:length(lines)xy = [lines(k).point1; lines(k).point2];plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','green');% 为每条直线绘制端点plot(xy(1,1),xy(1,2),'x','LineWidth',2,'Color','yellow');plot(xy(2,1),xy(2,2),'x','LineWidth',2,'Color','red');end在这个例程中,我们首先读取图像,然后将其转换为灰度图像,并执行Canny边缘检测。

接下来,我们使用Hough变换来检测直线,并找到其中的峰值。

最后,我们使用`houghlines`函数找到图像中的直线,并将其绘制在原始图像上。

Hough变换算法及过程

Hough变换算法及过程

Hough 变换Hough 变换是1962年由Hough 提出来的,用于检测图像中直线、圆、抛物线、椭圆等且其形状能够用一定函数关系描述的曲线,它在影像分析、模式识别等很多领域中得到了成功的应用:其基本原理是将影像空间中的曲线(包括直线)变换到参数空间中,通过检测参数空间中的极值点,确定出该曲线的描述参数,从而提取影像中的规则曲线。

直线Hough 变换通常采用的直线模型为θθρsin cos y x +=其中ρ是从原点引到直线的垂线长度;θ是垂线与x 轴正向的夹角(如图)。

对于影像空间直线上任一点(x ,y),Hough 变换将其映射到参数空间()ρθ,的一条正弦曲线上。

由于影像空间内的一条直线由一对参数()00ρθ,唯一地确定,因而该直线上的各点变换到参数空间的各正弦曲线必然都经过点()00ρθ,,在参数平面(或空间)中的这个点的坐标就代表了影像空间这条直线的参数。

这样,检测影像中直线的问题就转换为检测参数空间中的共线点的问题。

由于存在噪声及特征点的位置误差,参数空间中所映射的曲线并不严格通过一点,而是在一个小区域中出现一个峰,只要检测峰值点,就能确定直线的参数。

其过程为(1)对影像进行预处理,提取特征并计算其梯度方向;(2)将()ρθ,参数平面量化,设置二维累计矩阵()j i H ρθ,;(3)边缘细化,即在边缘点的梯度方向上保留极值点,剔除那些非极值点;(4)对每一边缘点,以其梯度方向ψ为中心,设置一小区间[]00,θψθψ+-,其中0θ为经验,一般可取 10~5,在此小区间上以θ∆为步长,按式(2—3—37)对每一个区间中的θ量化值计算相应的ρ值,并给相应的累计矩阵元素增加一个单位值;(5)对累计矩阵进行阈值检测,将大于阈值的点作为备选点;(6)取累计矩阵(即参数空间)中备选点中的极大值点为所需的峰值点,这些点所对应的参数空间的坐标即所检测直线的参数。

利用Hough 变换也可以提取圆和抛物线:()()222R r y c x =-+- c bx ax y ++=2但此时参数空间是三维空间,因而计算量相当大。

hough变换

hough变换

什么是hough变换Hough变换利用图像空间和Hough参数空间的点-线对偶性,把图像空间中的检测问题转换到参数空间。

通过在参数空间里进行简单的累加统计,然后在Hough参数空间寻找累加器峰值的方法检测直线。

例如,图1(a)中的九条线段对应于如图1(b)所示的其Hough参数空间的九个累加器峰值。

图1(b)中,Hough参数空间的横纵坐标分别为直线极坐标方程:ρ=x×cos(θ) + y×sin(θ) 的两个参数ρ和θ。

九个峰值的ρ和θ值唯一的确定其对应线段所在直线的两个参数。

并且线段的长度决定坐标(ρ,θ)处的累加值的大小。

应用领域理论与实践向来是形影不离,相辅相成,Hough变换之所以有如此长足的发展,主要原因还是在于实践应用上的广泛需求;而在实践中所暴露出的不足又进而促进了它的发展,循环往复,就如同生命的演化。

现枚举其主要应用领域如下:生物医学Hough变换已被成功应用于基于人工智能的专家诊断系统;X射线人体照片和CT图像的处理和判读;光学显微镜和电子显微镜中的细胞核自动分析系统;从超声波诊断中提取三维动脉特征,等等。

自动化、机器人视觉Hough变换已被用于产品部件的自动监视、缺陷诊断、生产过程的自动监控、计算机辅助制造(CAM)等。

例如基于Hough变换的机械零件检测和定位系统;基于Hough变换采用直线、圆弧等作为基本特征的工业产品检查系统。

空间技术、军事防御Hough变换已被用于运动目标轨迹的检测与识别,高空侦察机、间谍卫星和军事雷达等目标自动识别系统的特征提取。

例如应用Hough变换对战斗机的外形特征进行提取和自动识别;应用Hough变换辅以信号检测理论解决并行多运动目标的跟踪问题。

办公自动化Hough变换在许多应用系统中得到了很好的应用。

例如采用Hough变换进行英文字符特征提取并自动识别,其对印刷体字符识别率为99.6%,对手写体字符的平均识别率也达到了86.9%,并已成功应用于邮政信件的自动分拣、文件处理等。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验内容1.拍摄一张包含硬币、橡皮等物品的照片,通过Hough 变换检测出圆形的硬币个数并区分不同半径的硬币。

最终计算出照片中的总钱数。

解:Hough 变换的实质是对图像进行坐标的变换,将图像空间的线条变为参数空间的聚集点,从而将原始图像中检测给定形状的曲线问题,变成寻找参数空间中的峰点的问题。

它不仅可以检测直线,而且可以很方便地检测圆、椭圆和抛物线等形状。

由于这里需要检测圆形的硬币,所以下面给出检测圆的具体方法:因为圆的图像空间方程为:222()()x a y b r -+-=,我们需要通过Hough 变换,将图像空间(,)x y 对应到参数空间(,,)a b r ,然后对其进行累加完成检测。

但是显然这种方法的计算量是非常大的,所以一般都是先对灰度图像进行边缘提取,利用边界像素的灰度梯度信息估计出下式中的角度θ,以此来降低计算量:cos cos a x r b y r θθ=-*⎧⎨=-*⎩ (1)一般在检测过程中需要对图像进行预处理,使得检测更加准确和容易。

检测过程如下所示:○1真彩色图像转为灰度图像; ○2去除噪声,进行中值滤波; ○3转为二值图像,利用边缘算子进行图像边缘提取; ○4最后进行图像的平滑和填充。

这里处理的图像并没有太多噪声,所以处理的时候略去了中值滤波的步骤,直接对边缘提取后的图像进行Hough 变换检测圆形。

根据式(1),我们需要对半径r 和角度θ进行搜索,所以这里应该首先设置半径和角度方向的搜索步长step_r 和step_angle ,接着给出半径搜索的最大和最小值,当然这两个数值需要根据经验来自己确定。

最后就可以根据这些确定半径和角度的最大搜索次数。

由于Hough 变换需要用到稀疏矩阵,也即首先得找到图像矩阵中的非零量,针对这些非零量进行进一步的处理。

这个操作可以直接通过Matlab 中的find 语句来实现:>> [rows, cols] = find(BW); %找出矩阵中的非零值接着只需要根据式(1)计算出对应参数空间的参数a b和,根据,a b的范围确定hough空间累加器hough_adder是否自增。

由于这里的图像中不止一个圆形,所以不能直接利用hough_adder中的最大值来确定半径,需要设置一定的阈值thre来确定一定半径的圆,当阈值设置合理后才可以找出图像中的圆。

接着对阈值范围内的点进行搜索,当满足圆周内外各5个像素点时,该点可以认为是我们搜寻的圆上的点。

对其相应的坐标赋1即可。

经过上述的步骤,便通过hough变换的思想将图像的中的圆给检测出来了。

并且可以将圆心坐标和圆的半径都显示出来。

那接下来按照题目的意思是需要我们计算总的钱数,所以首先需要区分一元和五角的硬币,也就是区分圆的半径。

由于这里我们设置搜索出来的圆的半径是逐渐递增的,所以只需要判断在两个相邻点之间圆的半径是否存在跳变即可。

因为如果是不同的一元硬币,那么他们的半径即使相差一点也不会很多。

这样我们便可以得出首先将圆分成两类(这里只考虑一元和五角的两种情况),然后在每一类中再寻找半径相似的圆位于不同坐标的个数,也就是同样面值的硬币的个数了。

可以通过如下代码实现:是不同的硬币了。

接着在相同的硬币中,通过循环搜索当前半径和之前像素点的半径,当横纵坐标相差都小于10的时候可以认为是同一个点,也即是同一个硬币,否则将硬币数加一。

最后通过统计得到的总硬币数计算出总钱数。

下面先给出具体代码:clc,clear allImage = imread('final.bmp');imshow(Image),title('原始图像');Gray = rgb2gray(Image);bw = im2bw(Gray); % 先转为二值图像BW = edge(bw); % 然后提取边缘figureimshow(BW),title('图像边缘);step_r = 1; % 设定半径搜索步长step_angle = 0.1; % 设定角度搜索步长r_min = 50; % 最小半径和最大半径,确定搜索范围r_max = 100;thre = 0.8; % 设定阈值%***************hough变换*********************************[m, n] = size(BW);Count_r = round((r_max-r_min)/step_r)+1; % °半径最大搜索次数hough_adder = zeros(m, n, Count_r);Count_angle = round(2*pi/step_angle); % 角度最大搜索次数[rows, cols] = find(BW); % 找出矩阵中的非零值count = size(rows); % 计算非零值的个数for Count_Num = 1 : countfor Count_R = 1 : Count_rfor Count_Angle = 1 : Count_anglea =round(rows(Count_Num)-(r_min+(Count_R-1)*step_r)*cos(Count_Angle*step_angle ));b =round(cols(Count_Num)-(r_min+(Count_R-1)*step_r)*sin(Count_Angle*step_angle) );isTrue = (a>0 && a<=m && b>0 && b<=n);if(isTrue)hough_adder(a,b,Count_R) = hough_adder(a,b,Count_R) + 1;% 参数空间累加器加1endendendendmax_hough_adder = max(max(max(hough_adder))); % 计算最大值index = find(hough_adder >= max_hough_adder * thre); % 设定阈值length = size(index);hough_circle=zeros(m,n);for Count_Num = 1 : countfor Count_Length = 1 : lengthpar3 = floor(index(Count_Length)/(m*n));par2 = floor((index(Count_Length)-par3*(m*n))/m);par1 = index(Count_Length)-par3*(m*n)-par2*m;isTrue =(rows(Count_Num)-par1)^2+(cols(Count_Num)-par2-1)^2<(r_min+par3*step_r)^2+5 &&(rows(Count_Num)-par1)^2+(cols(Count_Num)-par2-1)^2>(r_min+par3*step_r)^2-5 ;if(isTrue)hough_circle(rows(Count_Num),cols(Count_Num)) = 1;endendendfigureimshow(hough_circle),title('圆形检测结果');for Count_Length = 1 : lengthpar3 = floor(index(Count_Length)/(m*n));par2 = floor((index(Count_Length)-par3*(m*n))/m);par1 = index(Count_Length)-par3*(m*n)-par2*m;par3 = r_min+par3*step_r;para(:,Count_Length) = [par1,par2,par3]; % 存储符合条件的圆坐标以及半径end%***************计算总钱数*********************************total_wu = 0;for idx = 1 : length-1total_wu = total_wu + para(3,idx);if (para(3,idx+1) - para(3,idx) > 5)break;endendtotal_yi = sum(para(3,:)) - total_wu;Ave_wu = total_wu / idx;Ave_yi = total_yi / (length(1,1)-idx);% 计算五角硬币的个数count_wu = 1;j = 1;for i = 2 : idxif j<= i-1if abs(para(1,i) - para(1,j)) < 10 && abs(para(2,i) - para(2,j)) < 10count_wu = count_wu;elsecount_wu = count_wu + 1;break ;endendend% 计算一元硬币的个数count_yi = 1;j = idx+1;for i = (idx+2) : lengthif j <= i-1if abs(para(1,i) - para(1,j)) < 10 && abs(para(2,i) - para(2,j)) < 10 count_yi = count_yi;elsecount_yi = count_yi + 1;break ;endendendtotal_money = count_wu * 0.5 + count_yi * 1 % 计算总钱数下面给出处理的图像:原始图像图1 原始图像图像边缘最后给出检测出的图像如下:从图3可以看出此时检测结果还是很准确的,当然这个和我们所选取的阈值thre 有关,如果thre 选择偏大,则无法将三个圆都检测出来,相反,如果thre 偏小,那么可能检测出来图形中其他的圆(比如该图像中的U 盘上的圆圈)。

所以说这里的关键就是阈值的选择,我是通过不断调试得出这个比较理想的结果的。

最后,在屏幕上打印总的钱数为:>> total_money =2.5000一、 实验小结由于老师上课只讲述了直线的hough 变换,所以在一开始做这题的时候感觉有点无从下手。

后来查阅了冈萨雷斯的图像处理书对hough 变换有了一个更深刻图2 提取的图像边缘检测结果图3 检测出圆轮廓的了解。

其实质是将图像空间转为参数空间,然后进行累加计数,累加的最大值便是所求的半径。

相关文档
最新文档