Hough变换检测椭圆

 由椭圆的公式(1)可得,确定一个椭圆需要5个参数,a,b 为椭圆的长轴和段轴,P,Q 为椭圆中心坐标,θ为椭圆的旋转角度。如果用传统的Hough变换方法,参数空间需要五维。这种方法在计算过程中所耗费的时间和空间资源是惊人的,根本无法应用于实际。为此,人们提出了很多新的改进算法。

改进算法主要分为两种:

  • 1)随机Hough变换(RHT),采用多到一的映射,但是随机采样会带来大量无效的计算,当点数很大时,算法的性能急剧下降。
  • 2)利用椭圆的几何特征降低参数的维度。

本文所提出的椭圆检测方法也是基于第二种方法。在讲该方法之前,先引入椭圆的一个几何定理:

定理 设平面上有一个椭圆,点 c 为椭圆中心,任取平面上一点 p(不同于点 c),点 p 距椭圆上点的最大距离一 定大于点 c 距椭圆上点的最大距离。

该定理是该方法的核心思想,也可表达为:椭圆中心(P,Q)是平面上所有点中,距离椭圆轮廓上点最大距离最小的点

利用这一几何性质,降低Hough 参数空间的维度。这句话听起来比较别扭,意思很简单。

通俗的说,就是计算 图像中每一点与椭圆(椭圆边界)最远的距离L,其中,L最小的点就是椭圆的中心,L就是椭圆的短轴a .

算法的具体步骤:

  • 1)首先对图像进行边缘检测,得到二值化的边缘轮廓图,将边缘图上的点坐标存入数组 A。
  • 2)对图像上的每一点, 计算与上一步所得数组 A 中点的距离,得到每一点距数组 A 中点的最大距离,所有点中最大距离最小的点,即是椭圆中心(p, q),该最大距离即是椭圆长轴长度 a。
  • 3)将数组A中每一点的数值和刚才得到的3个椭圆参数p、q、a 代入椭圆方程 (1)。
  • 4)在二维参数空间上对参数 b、θ 进行统计,得到峰值超过一定阈值的一组参数即为椭圆。  

实验结果:

结果分析:本文运用了椭圆的几何性质,把hough参数空间减少到2维。减少了运算量。由于第一步要得到椭圆的轮廓图,如果,图像中几个椭圆有重叠部分,无法保证提取的轮廓是一个椭圆,则无法检测出椭圆。

Matlab代码:

clc
clear all
I = imread(‘22.png‘);
[m,n,L] = size(I); %m图像的高度,n图像的宽度,L通道数
if L>1
I = rgb2gray(I);
end
BW1 = edge(I,‘sobel‘); %自动选择阈值用Sobel算子进行边缘检测(二值化)

figure(1)
subplot(121)
imshow(BW1); title(‘边缘检测‘);
se = strel(‘square‘,2);
BW=imdilate(BW1,se);%图像A1被结构元素B膨胀

hough_circle=zeros(m,n,3);
[Limage, num] = bwlabel(BW,8); %num 连通区域个数
for N=1:num

%[rows,cols] = find(BW); % 找出二值图中的所有非零元素,并将这些元素的线性索引值返回到[rows,cols] 即找出边缘
[rows,cols] = find(Limage==N); % 找出二值图中的所有非零元素,并将这些元素的线性索引值返回到[rows,cols] 即找出边缘
pointL=length(rows); %非零元素个数,椭圆的周长

max_distan=zeros(m,n);
distant=zeros(1,pointL);
for i=1:m
for j=1:n
for k=1:pointL
distant(k)=sqrt((i-rows(k))^2+(j-cols(k))^2); %计算所有点 到椭圆边界的点的距离
end
max_distan(i,j)=max(distant); %(i,j)点到椭圆边界的最大距离
end
end
min_distan=min(min(max_distan)); %图像中所有的点到椭圆边界最大距离 的最小值,这个最小值对应的坐标位置 就是椭圆的中心。

[center_yy,center_xx] = find(min_distan==max_distan); %检索出椭圆中心的位置,
center_y=(min(center_yy)+max(center_yy))/2; %由于计算误差,椭圆中心可能是一簇点,所以选择中心点
center_x=(min(center_xx)+max(center_xx))/2; %center_x,center_y为椭圆的中心
a=min_distan; %a为椭圆的长轴
%% 下面进行Hough变换 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
hough_space = zeros(round(a+1),180); %Hough空间
for k=1:pointL
   for w=1:180 %theta
      G=w*pi/180; %角度转换为弧度
      XX=((cols(k)-center_x)*cos(G)+(rows(k)-center_y)*sin(G))^2/(a^2);
      YY=(-(cols(k)-center_x)*sin(G)+(rows(k)-center_y)*cos(G))^2;
      B=round(sqrt(abs(YY/(1-XX)))+1);
     if(B>0&&B<=a) % 计算时,B的值可能很大,这里进行异常处理
         hough_space(B,w)=hough_space(B,w)+1;
     end
  end
end

%% 搜索超过阈值的聚集点
max_para = max(max(max(hough_space))); % 找出累积最大值

[bb,ww] = find(hough_space>=max_para); %找出累积最大值在hough_space位置坐标(坐标值就是b和 theta)
if(max_para<=pointL*0.33*0.25) % 如果累积最大值 不足一定的阈值 则判断不存在椭圆
disp(‘No ellipse‘);
return ;
end
b=max(bb); % b为椭圆的短轴
W=min(ww); % %theta
theta=W*pi/180;

%% 标记椭圆

for k=1:pointL
      XXX=((cols(k)-center_x)*cos(theta)+(rows(k)-center_y)*sin(theta))^2/(a^2);
      YYY=(-(cols(k)-center_x)*sin(theta)+(rows(k)-center_y)*cos(theta))^2/(b^2);
    if((XXX+YYY)<=1) %实心椭圆
   %if((XXX+YYY)<=1.1&&(XXX+YYY)>=0.99) % 椭圆轮廓
      hough_circle(rows(k),cols(k),1) = 255;
     end
end

end
subplot(122)
imshow(hough_circle);title(‘检测结果‘);title(‘检测结果‘);

参考文献:

[1] 周 祥,孔晓东,曾贵华.一种新的基于 Hough 变换的椭圆轮廓检测方法

时间: 2024-12-20 14:12:33

Hough变换检测椭圆的相关文章

hough变换检测直线

hough变换检测直线原理: 假设在图像中存在一条直线y=k*x+b(此时k,b未知).取直线上的任意两点进行说明,设为(x0,y0),(x1,y1). 所有经过点(x0,y0)的直线满足:-x0*k+y0=b ---式1,那么以k.b为直角坐标轴做式1对应直线: 所有经过点(x1,y1)的直线满足:-x1*k+y1=b ---式2,那么以k.b为直角坐标轴做式2对应直线: 两直线交于一点(kk,bb),此时该交点对应的直线y=kk*x+bb就是(x0,y0),(x1,y1)所确定的直线. 在h

Python下opencv使用笔记(十一)(详解hough变换检测直线与圆)

在数字图像中,往往存在着一些特殊形状的几何图形,像检测马路边一条直线,检测人眼的圆形等等,有时我们需要把这些特定图形检测出来,hough变换就是这样一种检测的工具. Hough变换的原理是将特定图形上的点变换到一组参数空间上,根据参数空间点的累计结果找到一个极大值对应的解,那么这个解就对应着要寻找的几何形状的参数(比如说直线,那么就会得到直线的斜率k与常熟b,圆就会得到圆心与半径等等). 关于hough变换,核心以及难点就是关于就是有原始空间到参数空间的变换上.以直线检测为例,假设有一条直线L,

Matlab实现Hough变换检测图像中的直线

Hough变换的原理: 将图像从图像空间变换至参数空间,变换公式如下: 变换以后,图像空间与参数空间存在以下关系: 图像空间中的一点在参数空间是一条曲线,而图像空间共线的各点对应于参数空间交于一点的各条曲线. 下面使用Matlab实现Hough变换对图像中的直线划痕进行检测. close all; clear all; I = imread('scratch.tif'); figure; subplot(1,3,1); imshow(I); BW = edge(I,'canny');%Canny

Hough变换检测圆(附:MATLAB程序) - mhjerry的专栏(子水) - 博客频道 - CSDN.NET

来源:http://blog.csdn.net/mhjerry/article/details/7061819#1536434-hi-1-45330-42d97150898b1af15ddaae52f91f09c2 Hough变换很好玩,以前在学校写过一些检测圆圈.椭圆.双曲线等图像,同时也可以检测多个圆形.

Opencv图像识别从零到精通(22)-----hough变换检测直线与圆

今天要看的是霍夫变换,常用用来检测直线和圆,这里是把常见的笛卡尔坐标系转换成极坐标下,进行累计峰值的极大值,确定.HoughLines,HoughLinesP,HoughCircles,三个函数,首先先看看原理,最后会用漂亮的matlab图,来回归一下,霍夫直线变换. 霍夫线变换: 众所周知, 一条直线在图像二维空间可由两个变量表示. 例如: 在 笛卡尔坐标系: 可由参数:  斜率和截距表示. 在 极坐标系: 可由参数:  极径和极角表示 对于霍夫变换, 我们将用 极坐标系 来表示直线. 因此,

Python-Anaconda练习candy算子用于边缘提取,再用hough变换检测直线边缘

img: 待检测的图像. threshold: 阈值,可先项,默认为10 line_length: 检测的最短线条长度,默认为50 line_gap: 线条间的最大间隙.增大这个值可以合并破碎的线条.默认为10 返回: lines: 线条列表, 格式如((x0, y0), (x1, y0)),标明开始点和结束点. 下面,我们用canny算子提取边缘,然后检测哪些边缘是直线? import skimage.transform as st import matplotlib.pyplot as pl

python hough变换检测直线的实现方法 - python

文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 1 原理  2 检测步骤 将参数空间(ρ,θ) 量化成m*n(m为ρ的等份数,n为θ的等份数)个单元,并设置累加器矩阵,初始值为0: 对图像边界上的每一个点(x,y)带入ρ=xcosθ+ysinθ,求得每个θ对应的ρ值,并在ρ和θ所对应的单元,将累加器加1,即:Q(i,j)=Q(i,j)+1: 检验参数空间中每个累加器的值,累加器最大的单元所对应的ρ和θ即为直角坐标系中直线方程的参数.  3 接口 image:二值图

hough变换是如何检测出直线和圆的?

(I)直线篇 1 直线是如何表示的?对于平面中的一条直线,在笛卡尔坐标系中,常见的有点斜式,两点式两种表示方法.然而在hough变换中,考虑的是另外一种表示方式:使用(r,theta)来表示一条直线.其中r为该直线到原点的距离,theta为该直线的垂线与x轴的夹角.如下图所示. 2 如果坐标系中有多个点,又怎样识别出哪些点在一条直线上呢?使用hough变换来检测直线的思想就是:为每一个点假设n个方向的直线,通常n=180,此时检测的直线的角度精度为1°,分别计算这n条直线的(r,theta)坐标

hough变换是如何检测出直线和圆的

(I)直线篇 1 直线是如何表示的? 对于平面中的一条直线,在笛卡尔坐标系中,常见的有点斜式,两点式两种表示方法.然而在hough变换中,考虑的是另外一种表示方式:使用(r,theta)来表示一条直线.其中r为该直线到原点的距离,theta为该直线的垂线与x轴的夹角.如下图所示. 2 如果坐标系中有多个点,又怎样识别出哪些点在一条直线上呢? 使用hough变换来检测直线的思想就是:为每一个点假设n个方向的直线,通常n=180,此时检测的直线的角度精度为1°,分别计算这n条直线的(r,theta)