【机器视觉与图像处理】基于MATLAB+Hough的圆检测

正文之前

没错,我回来了。十天没有更新了,感觉自己都不像自己了!今天开始狂更???可以的!!

正文

本次文章,没有太多好写的,就是最近做的一个机器视觉的课程设计作业,是要做一个流水线的生产线建模以及对于产品的检测识别,我个人承包了圆心半径检测的内容,熬了好几天,终于找到了一个好的算法可以比较迅速准确的找到圆了。天不负我!!

这是我要检测图片,因为我们的要求是检测大小接近的图,所以我把检测半径范围规定在很小的范围内,这样的话会极大地加快速度!!所以这才是致胜的关键!!

%%%%%%%%%%      main.m    %%%%%%%%%%%
% 文件2 main.m  
clc;
clear;  
circleParaXYR=[];  
I = imread('/Users/zhangzhaobo/program/MATLAB/Machine_vision/Picture/9.bmp');  

%取整张图的三维尺寸
[m,n,l] = size(I);  

% 通过判断对象类型来决定是否转化为灰度图
if l>1  
    I = rgb2gray(I);  
end  

%采用sobel算子来进行边缘检测
BW = edge(I,'sobel');  
[m,n]=size(BW);
% 步长为1,即每次检测的时候增加的半径长度
step_r = 1;  

%检测的时候每次转过的角度
step_angle = 0.1; 

% 对检测的圆的大小范围预估,在实际项目中因为产品大小固定,所以可以给定较小范围,提高运行速度 
minr = 508;  
maxr = 510;  

% 自动取最优的灰度阈值
thresh = graythresh(I);  

% 调用hough_circle函数进行霍夫变换检测圆
[hough_space,hough_circle,para] = hough_circle(BW,step_r,step_angle,minr,maxr,thresh);  
 figure(1),imshow(I),title('原图')  
 figure(2),imshow(BW),title('边缘')  
 figure(3),imshow(hough_circle),title('检测结果')  


circleParaXYR=para;  

%输出  
fprintf(1,'\n---------------圆统计----------------\n');  
[r,c]=size(circleParaXYR); % r=size(circleParaXYR,1);  
fprintf(1,'  检测出%d个圆\n',r); % 圆的个数  
fprintf(1,'  圆心     半径\n'); % 圆的个数  
for n=1:r  
%     x0=floor(circleParaXYR(n,1));
%     y0=floor(circleParaXYR(n,2));
%     if x0>0.25*m && x0<0.75*m && y0>0.25*n && y0<0.75*n
        fprintf(1,'%d (%d,%d)  %d\n',n,floor(circleParaXYR(n,1)),floor(circleParaXYR(n,2)),floor(circleParaXYR(n,3))); 
%    end
end  

%标出圆  
 figure(4),imshow(I),title('检测出图中的圆')  
%figure(1),imshow(I),title('检测出图中的圆')  
hold on;  

plot(circleParaXYR(:,2), circleParaXYR(:,1), 'r+');  
for k = 1 : r %size(circleParaXYR, 1)  
    t=0:0.01*pi:2*pi;  
    x=cos(t).*circleParaXYR(k,3)+circleParaXYR(k,2);
    y=sin(t).*circleParaXYR(k,3)+circleParaXYR(k,1);  
    plot(x,y,'r');  
end  


% R_max=maxr;  
% acu=zeros(R_max);  
% stor =[];  
% for j=1:R_max  
%     for n=1:r  
%         if  j == floor(circleParaXYR(n,3))  
%             acu(j)= acu(j)+1;  
%         end  
%     end  
%     stor=[stor;j,acu(j)];  
%     %fprintf(1,'%d,%d\n',j,acu(j));  
% end  

% fprintf(1,'\n------------粒子大小,数目统计---------\n');  
% fprintf(1,'粒子半径,粒子个数\n');  
% for j=1:R_max  
%     if acu(j) > 0  
%         fprintf(1,'%4d %8d\n',stor(j,1),stor(j,2));  
%     end  
% end  

% fprintf(1,'----------------------------------------\n');  
% figure(5),plot(stor(:,1),stor(:,2),'-k','LineWidth',2),title('粒径谱');  
% xlabel('粒子大小');  
% ylabel('粒子个数');  
% grid on;  

% z=[0,10,20,30,40,50,60,70,80,90,11,35,25,42,48,40,20,75,88,94,23,10,20,30,40,78,60,76,84,95,58,10,20,30,40,50,60,70,80,90,100];%给出z的坐标  
% Z=z(:);  
% S=floor(abs(Z)*1);  
% C=floor(abs(Z)*0.5);  
% figure(6),scatter3(circleParaXYR(:,1),circleParaXYR(:,2),Z,circleParaXYR(:,3)*7,'filled'),title('构建三维粒子场');

上面是?main函数,也就是最终的直接调用的函数,下面是hough_circle的m函数,在main中要调用这个函数的!

%%%%%%%%%%      hough_circle.m    %%%%%%%%%%%
% 文件1---hough_circle.m  

function [hough_space,hough_circle,para] = hough_circle(BW,step_r,step_angle,r_min,r_max,p)  

% ***************************************************** 
% 参数输入  
  % BW:二值图像;  
  % step_r:检测的圆半径步长  
  % step_angle:角度步长,单位为弧度  
  % r_min:最小圆半径  
  % r_max:最大圆半径  
  % p:阈值,0,1之间的数 通过调此值可以得到图中圆的圆心和半径

% ***************************************************** 
% 参数返回 
  % hough_space:参数空间,h(a,b,r)表示圆心在(a,b)半径为r的圆上的点数  
  % hough_circl:二值图像,检测到的圆  
  % para:检测到的圆的圆心、半径  

circleParaXYR=[];  
para=[];  

[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);%非零坐标的个数  

% Hough变换  
% 将图像空间(x,y)对应到参数空间(a,b,r)  

% a = x-r*cos(angle)  
% b = y-r*sin(angle)  

for i=1:ecount  
    for r=1:size_r %半径步长数  
        for k=1:size_angle %按一定弧度把圆几等分  
            a = 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.35*m&a<=0.7*m&b>0.35*n&b<=0.7*n)  
                hough_space(a,b,r) = hough_space(a,b,r)+1;%h(a,b,r)的坐标,圆心和半径  
            end  
        end  
    end  
end  


% 搜索超过阈值的聚集点。对于多个圆的检测,阈值要设的小一点!通过调此值,可以求出所有圆的圆心和半径  
max_para = max(max(max(hough_space)));%返回值就是这个矩阵的最大值  
index = find(hough_space>=max_para*p);%一个矩阵中,想找到其中大于max_para*p数的位置  
length = size(index);%符合阈值的个数  
hough_circle = false(m,n);  
%hough_circle = zeros(m,n);  
%通过位置求半径和圆心。  
for i=1:ecount  
    for k=1:length  
        par3 = 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;   %检测的圆  
        end  
    end  
end                 

% 从超过峰值阈值中得到  
for k=1:length  
    par3 = 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;  
    circleParaXYR = [circleParaXYR;par1,par2,par3];  
    hough_circle(par1,par2)= true; %这时得到好多圆心和半径,不同的圆的圆心处聚集好多点,这是因为所给的圆不是标准的圆  
    %fprintf(1,'test1:Center %d %d \n',par1,par2);  
end  

%集中在各个圆的圆心处的点取平均,得到针对每个圆的精确圆心和半径!  
while size(circleParaXYR,1) >= 1  
    num=1;  
    XYR=[];  
    temp1=circleParaXYR(1,1);  
    temp2=circleParaXYR(1,2);  
    temp3=circleParaXYR(1,3);  
    c1=temp1;  
    c2=temp2;  
    c3=temp3;  
    temp3= r_min+(temp3-1)*step_r;  
    if size(circleParaXYR,1)>1       
        for k=2:size(circleParaXYR,1)  
          if (circleParaXYR(k,1)-temp1)^2+(circleParaXYR(k,2)-temp2)^2 > temp3^2  
             XYR=[XYR;circleParaXYR(k,1),circleParaXYR(k,2),circleParaXYR(k,3)];  %保存剩下圆的圆心和半径位置  
          else    
            c1=c1+circleParaXYR(k,1);  
            c2=c2+circleParaXYR(k,2);  
            c3=c3+circleParaXYR(k,3);  
            num=num+1;  
          end   
        end  
    end   
    %fprintf(1,'sum %d %d radius %d\n',c1,c2,r_min+(c3-1)*step_r);  
    c1=round(c1/num);  
    c2=round(c2/num);  
    c3=round(c3/num);  
    c3=r_min+(c3-1)*step_r;  
    %fprintf(1,'num=%d\n',num)  
    %fprintf(1,'Center %d %d radius %d\n',c1,c2,c3);     
    para=[para;c1,c2,c3]; %保存各个圆的圆心和半径的值  
    circleParaXYR=XYR;  
end

通过上面两个函数,会有下面的结果!

Warning: Image is too big to fit on screen; displaying at 67% 
> In images.internal.initSize (line 71)
  In imshow (line 332)
  In main (line 33) 
Warning: Image is too big to fit on screen; displaying at 67% 
> In images.internal.initSize (line 71)
  In imshow (line 332)
  In main (line 34) 
Warning: Image is too big to fit on screen; displaying at 67% 
> In images.internal.initSize (line 71)
  In imshow (line 332)
  In main (line 35) 

---------------圆统计----------------
  检测出1个圆
  圆心     半径
1 (528,728)  509
Warning: Image is too big to fit on screen; displaying at 67% 
> In images.internal.initSize (line 71)
  In imshow (line 332)
  In main (line 54) 
>>

然后我还有另外的类似的一个,是在一本书的附赠代码里面的,因为觉得图片很美,所以也放上来吧!!

下面是代码?,代码之后是原图,按照代码中的名字设置名字即可!

clear all; 
close all;
i=imread('yanjing.bmp'); 
imshow(i); 
iii=i; 
%把输入图象二值化,用canny算法返回阈值
sigma=3.0;
thresh=[0.03,0.09];
bw_1=i>70;
edgerm=edge(bw_1,'canny',thresh,sigma); 
figure,imshow(edgerm);
t1=280;
s=0;
while t1>10
t2=1;
while t2<310
%查找第一个边缘点
if edgerm(t1,t2)==1 
         u1=t1;
         u2=t2;
         s=1;
end
if s==1
   break;
end
  t2=t2+1;  
end
t1=t1-1;
end
po=1;
sum2=0;
%第一个边缘点
o1=u1; 
o2=u2;
hang=zeros(0,0);
lie=zeros(0,0);
while (po==1)
   while (po==1)
         sum1=0;
         for t3=1:5
            for t4=1:5
               % 第一个边缘点的左上方5个像素内有边缘点
               if edgerm(u1-t3+1,u2+t4-1)==1                  
% 第一个边缘点周围的边缘点个数
sum1=sum1+1; 
                  sum2=sum2+1;
                  % 第sum1个边缘点位置x
hang(sum1,1)=u1-t3+1;
                  % 第sum1个边缘点位置y
hang(sum1,2)=u2+t4-1;
                  lie(sum2,1)=u1-t3+1;
                  lie(sum2,2)=u2+t4-1;
               end
            end
         end
         % 边缘点只有一个
if sum1==1 
            po=0;
         % 没有边缘点
elseif sum1==0 
            po=0;
         else
            % 以最后的边缘点为起点,进行下一轮搜索
u1=hang(sum1,1); 
            u2=hang(sum1,2);
            po=1;
         end
      end
      % 边缘点个数小于30个
if sum2<30 
         u1=o1;
         u2=o2+1;
         po=1;
         sum2=0;
      % 横坐标不变,改变纵坐标值得到边缘点
while (edgerm(u1,u2)~=1)   
         while (edgerm(u1,u2)~=1)&(u2<310)
            % 不是边缘点,纵坐标加1
u2=u2+1; 
         end 
         % 没有得到边缘点
if u2==310 
            u1=u1-1;
            u2=1;
         end
      end
      % x不变,改变y重新得到边缘点
o1=u1; 
      o2=u2;
      else
         break;
      end  
   end 
% 边缘点个数
a1=size(lie); 
w1=lie(a1(1),1);
w2=lie(a1(1),2);
po1=1;
      while (po1==1)
         sum1=0;
         for t1=1:3
            for t2=1:5
               % 边缘点向左方3个像素,上方5个像素
if edgerm(w1-t1+1,w2-t2+1)==1 
                  sum1=sum1+1;
                  sum2=sum2+1;
                  lie(sum2,1)=w1-t1+1;
                  lie(sum2,2)=w2-t2+1;
                  hang(sum1,1)=w1-t1+1;
                  hang(sum1,2)=w2-t2+1;
               end
            end
         end   
         % 边缘点只有一个
if sum1==1 
            po1=0;
         else
            po1=1;
            w1=hang(sum1,1);
            w2=hang(sum1,2);
         end
      end

 po2=1;
 while (po2==1)
         sum1=0;
         for t1=1:7
            for t2=1:15
               if edgerm(w1+t1-1,w2-t2+1)==1 
                  sum1=sum1+1;
                  sum2=sum2+1;
                  lie(sum2,1)=w1+t1-1;
                  lie(sum2,2)=w2-t2+1;
                  hang(sum1,1)=w1+t1-1;
                  hang(sum1,2)=w2-t2+1;
               end
            end
         end   
         if sum1==1
            po2=0;
         else
            po2=1;
            w1=hang(sum1,1);
            w2=hang(sum1,2);
         end       
      end
%不止一个边缘点
while (w1~=lie(1,1))&(w2~=lie(1,2)) 
         sum1=0;
         for t1=1:5
            for t2=1:5
               %向右向上5个像素搜索边缘点
if edgerm(w1+t1-1,w2+t2-1)==1 
                  sum1=sum1+1;
                  sum2=sum2+1;
                  lie(sum2,1)=w1+t1-1;
                  lie(sum2,2)=w2+t2-1;
                  hang(sum1,1)=w1+t1-1;
                  hang(sum1,2)=w2+t2-1;
               end
            end
         end   
            w1=hang(sum1,1);
            w2=hang(sum1,2);
end      
for t1=1:280
   for t2=1:320
      % 初始化Hough矩阵
e(t1,t2)=0; 
   end
end
% 边缘点个数
for t1=1:size(lie) 
   % 将是边缘点的位置设为1
e(lie(t1,1),lie(t1,2))=1;
end
%确定瞳孔的边缘的上下限
minl=320;
maxl=1;
minh=280;
maxh=1;
for t1=1:280
   for t2=1:320
      if (e(t1,t2)==1)&(t2<minl)
         minl=t2;
      end
      if (e(t1,t2)==1)&(t2>maxl)
         maxl=t2;
      end
      if (e(t1,t2)==1)&(t1<minh)
         minh=t1;
      end
      if (e(t1,t2)==1)&(t1>maxh)
         maxh=t1;
      end       
   end
end
% 采用二值化的方法求得瞳孔的面积sum3
sum3=0;
t1=minh;
while t1<=maxh
   t2=minl;
   while t2<=maxl
      if (bw_1(t1,t2)==0) 
         sum3=sum3+1;
      end
      t2=t2+1;
   end
   t1=t1+1;
end
% 得到瞳孔r1半径向上取整,sum3表示瞳孔的面积
r1=ceil(sqrt(sum3/pi)); 
% 向下取整 估算出瞳孔圆心x坐标
c(1,1)=floor((maxh-minh)/2+minh); 
c(1,2)=ceil((maxl-minl)/2+minl);
r2=ceil(r1/3);
r3=2*r2;
for t1=1:ceil(r1/6)*2
   for t2=1:ceil(r1/6)*2
       pu(t1,t2)=0;
   end
end 
 %pu中存放有相同圆心点的个数,以下找一个最大的pu认为是瞳孔的圆心
 t1=minh;
 while t1<=maxh
    t2=minl;
    while t2<=maxl
      if (e(t1,t2)==1)
            for a=1:2*ceil(r1/6)
                for b=1:2*ceil(r1/6)
                  if (((t1-(c(1,1)+ceil(r1/6)-a))^2+(t2-(c(1,2)-ceil(r1/6)+b))^2-r1^2)>-10)&(((t1-(c(1,1)+ceil(r1/6)-a))^2+(t2-(c(1,2)-ceil(r1/6)+b))^2-r1^2)<10)
                      % 以a,b为圆心的圆累加个数
pu(a,b)=pu(a,b)+1; 
                  end
              end
          end
       end
       t2=t2+1;
    end
    t1=t1+1;
end
ma=pu(1,1);        
% 选取同心圆最多的圆心
for a=1:2*ceil(r1/6) 
   for b=1:2*ceil(r1/6)
      if (ma<pu(a,b))
         ma=pu(a,b);
         row=a;
         col=b;
      end
   end
end
% 圆心坐标
c(1,1)=c(1,1)+ceil(r1/6)-row; 
c(1,2)=c(1,2)-ceil(r1/6)+col;
j=double(i);
for t1=1:280
   for t2=1:320
%虹膜内边缘设为白色
     if ((t1-c(1,1))^2+(t2-c(1,2))^2-r1^2<80)&((t1-c(1,1))^2+(t2-c(1,2))^2-r1^2>-80)         
i(t1,t2)=255;
      end
   end
end

row1=c(1,1);
col1=c(1,2);
%以上找到圆心(row1,col1),半径r1;
ha=row1;
li=col1;
sh1=1;
zong=0;
while sh1<=3
   sh2=1;
   while sh2<=3
      zong=zong+1;
      % 圆心向左、不变、向右移动2
row1=ha-4+sh1*2;
      col1=li-4+sh2*2;
      j1=double(i);    
      u=zeros(0,0);
        for t1=1:row1
            t2=col1;
               while t2<=310
                  %第一像限的图像对角变换
u(row1-t1+1,t2-col1+1)=j1(t1,t2); 
                  t2=t2+1;
               end
       end
u1=double(u);
%第一像限图像的行列数
yy=size(u); 
%瞳孔半径r1
rr=r1+40; 
l1=r1+40;
l2=1;
ll1=0;
n1=l1;
sq1=0;
%yy(1,2)表示第一像限的矩阵列数,yy(1,1)行数
while (l2<l1)&(l1<yy(1,2))&(l2<yy(1,1))
   pk=(l1-1/2)^2+(l2+1)^2-rr^2;
%半径在rr+40范围内
if pk<0 
      %沿着l1方向灰度值累加
sq1=sq1+u1(l2+1,l1); 
      %记录sql的个数
ll1=ll1+1; 
      l1=l1;
      l2=l2+1;
   else sq1=sq1+u1(l2+1,l1-1);
      ll1=ll1+1;
      l1=l1-1;
      l2=l2+1;
   end
end
%灰度平均值
sq=sq1/ll1; 
for t1=r1+40:126
   sr1(t1)=0;
end
rr=rr+2;
l1=n1+2;
l2=1;
while (rr<=126)&(rr<sqrt(2)*yy(1,2))&(rr<sqrt(2)*yy(1,1))&(l1>l2)&(l1<yy(1,2))&(l2<yy(1,1))
   n1=l1;
   ll2=0;
   sq2=0;
   while (l1>l2)&(l1<yy(1,2))&(l2<yy(1,1))
      pk=(l1-1/2)^2+(l2+1)^2-rr^2;
      if pk<0
         sq2=sq2+u1(l2+1,l1);
         ll2=ll2+1;
         l1=l1;
         l2=l2+1;
      else sq2=sq2+u1(l2+1,l1-1);
         ll2=ll2+1;
         l1=l1-1;
         l2=l2-1;
      end
   end
   sqq=sq2/ll2;
   sr1(rr)=abs(sqq-sq);
   sq=sqq;
   rr=rr+2;
   l1=n1+2;
   l2=1;
end
ma1=sr1(r1+40);
t1=r1+40;
while t1<=126
   if sr1(t1)>ma1
      % 找出灰度值变化最大点
ma1=sr1(t1); 
      % 半径
rad1=t1; 
   end
   t1=t1+1;
end

q1=zeros(0,0);
t1=row1;
while t1<280
   t2=col1;
   while t2<310
      q1(t1-row1+1,t2-col1+1)=j1(t1,t2);
      t2=t2+1;
   end
   t1=t1+1;
end
yy1=double(q1);
ys1=size(yy1);
rr1=r1+40;
l21=r1+40;
l22=1;
ll3=0;
n2=l21;
sq3=0;
while (l22<l21)&(l21<ys1(1,2))&(l22<ys1(1,1))
   pk1=(l21-1/2)^2+(l22+1)^2-rr1^2;
   if pk1<0
      sq3=sq3+yy1(l22+1,l21);
      ll3=ll3+1;
      l21=l21;
      l22=l22+1;
   else sq3=sq3+yy1(l22+1,l21-1);
      ll3=ll3+1;
      l21=l21-1;
      l22=l22+1;
   end
end
sq=sq3/ll3;
for t1=r1+40:126
   sr2(t1)=0;
end
rr1=rr1+2;
l21=n2+2;
l22=1;
while (rr1<=126)&(rr1<sqrt(2)*ys1(1,2))&(rr1<sqrt(2)*ys1(1,1))&(l21>l22)&(l21<ys1(1,2))&(l22<ys1(1,1))
   n2=l21;
   ll4=0;
   sq4=0;
   while (l21>l22)&(l21<ys1(1,2))&(l22<ys1(1,1))
      pk1=(l21-1/2)^2+(l22+1)^2-rr1^2;
      if pk1<0
         sq4=sq4+yy1(l22+1,l21);
         ll4=ll4+1;
         l21=l21;
         l22=l22+1;
       else sq4=sq4+yy1(l22+1,l21-1);
         ll4=ll4+1;
         l21=l21-1;
         l22=l22+1;
       end
   end
   sqq=sq4/ll4;
   sr2(rr1)=abs(sqq-sq);
   sq=sqq;
   rr1=rr1+2;
   l21=n2+2;
   l22=1;
end

ma2=sr2(r1+40);
t1=r1+40;
while t1<=126
   if sr2(t1)>ma2
      ma2=sr2(t1);
      rad2=t1;
   end
   t1=t1+1;
end
%以上是第四向限
q2=zeros(0,0);
for t1=1:row1
   for t2=1:col1
      q2(row1+1-t1,col1+1-t2)=j1(t1,t2);
   end
end
yy2=double(q2);
ys2=size(yy2);
rr2=r1+40;
l31=r1+40;
l32=1;
ll5=0;
n3=l31;
sq5=0;
while (l32<l31)&(l31<ys2(1,2))&(l32<ys2(1,1))
   pk2=(l31-1/2)^2+(l32+1)^2-rr2^2;
   if pk2<0
      sq5=sq5+yy2(l32+1,l31);
      ll5=ll5+1;
      l31=l31;
      l32=l32+1;
   else sq5=sq5+yy2(l32+1,l31-1);
      ll5=ll5+1;
      l31=l31-1;
      l32=l32+1;
   end
end
sq=sq5/ll5;
for t1=r1+40:126
   sr3(t1)=0;
end
rr2=rr2+2;
l31=n3+2;
l32=1;
while (rr2<=126)&(rr2<sqrt(2)*ys2(1,2))&(rr2<sqrt(2)*ys2(1,1))&(l31>l32)&(l31<ys2(1,2))&(l32<ys2(1,1))
   n3=l31;
   ll6=0;
   sq6=0;
   while (l31>l32)&(l31<ys2(1,2))&(l32<ys2(1,1))
      pk2=(l31-1/2)^2+(l32+1)^2-rr2^2;
      if pk2<0
         sq6=sq6+yy2(l32+1,l31);
         ll6=ll6+1;
         l31=l31;
         l32=l32+1;
      else sq6=sq6+yy2(l32+1,l31-1);
         ll6=ll6+1;
         l31=l31-1;
         l32=l32+1;
      end
   end
   sqq=sq6/ll6;
   sr3(rr2)=abs(sqq-sq);
   sq=sqq;
   rr2=rr2+2;
   l31=n3+2;
   l32=1;
end
ma3=sr3(r1+40);
t1=r1+40;
while t1<=126
   if sr3(t1)>ma3
      ma3=sr3(t1);
      rad3=t1;
   end
   t1=t1+1;
end
%以上是第二向限
j1=double(i);
q3=zeros(0,0);
t1=row1;
while t1<280
   for t2=1:col1
      q3(t1-row1+1,col1+1-t2)=j1(t1,t2);
   end
   t1=t1+1;
end
yy3=double(q3);
ys3=size(yy3);
rr3=r1+40;
l41=r1+40;
l42=1;
ll7=0;
n4=l41;
sq7=0;
while (l42<l41)&(l41<ys3(1,2))&(l42<ys3(1,1))
   pk3=(l41-1/2)^2+(l42+1)^2-rr3^2;
   if pk3<0
      sq7=sq7+yy3(l42+1,l41);
      ll7=ll7+1;
      l41=l41;
      l42=l42+1;
   else sq7=sq7+yy3(l42+1,l41-1);
      ll7=ll7+1;
      l41=l41-1;
      l42=l42+1;
   end
end
sq=sq7/ll7;
for t1=r1+40:126
   sr4(t1)=0;
end
rr3=rr3+2;
l41=n4+2;
l42=1;
while (rr3<=126)&(rr3<sqrt(2)*ys3(1,2))&(rr3<sqrt(2)*ys3(1,1))&(l41>l42)&(l41<ys3(1,2))&(l42<ys3(1,1))
   n4=l41;
   ll8=0;
   sq8=0;
   while (l41>l42)&(l41<ys3(1,2))&(l42<ys3(1,1))
      pk3=(l41-1/2)^2+(l42+1)^2-rr3^2;
      if pk3<0
         sq8=sq8+yy3(l42+1,l41);
         ll8=ll8+1;
         l41=l41;
         l42=l42+1;
      else sq8=sq8+yy3(l42+1,l41-1);
         ll8=ll8+1;
         l41=l41-1;
         l42=l42+1;
      end
   end
   sqq=sq8/ll8;
   sr4(rr3)=abs(sqq-sq);
   sq=sqq;
   rr3=rr3+2;
   l41=n4+2;
   l42=1;
end
ma4=sr4(r1+40);
t1=r1+40;
while t1<=126
   if sr4(t1)>ma4
      ma4=sr4(t1);
      rad4=t1;
   end
   t1=t1+1;
end
% 以上是第三向限
% 四个像限的半径平均值
ra(zong)=(rad1+rad2+rad3+rad4)/4; 
% 圆心位置
xin(zong,1)=row1; 
xin(zong,2)=col1;
sh2=sh2+1;
% 4个像限最大灰度差值和
ma(zong)=ma1+ma2+ma3+ma4; 
end
sh1=sh1+1;
end
max1=ma(1);
for t1=1:zong 
   if max1<=ma(t1)
      % 最大值是第t1次循环
shh=t1; 
      % 循环后的最大灰度差值
max1=ma(t1); 
   end
end
jing=0;
for t1=1:zong 
   jing=jing+ra(t1);
end
% 虹膜半径
jing=floor(jing/zong); 
% 虹膜的圆心
row2=xin(shh,1); 
col2=xin(shh,2);
for t1=1:280
   for t2=1:320
      if ((t1-row2-2)^2+(t2-col2+4)^2-jing^2<200)&((t1-row2-2)^2+(t2-col2+4)^2-jing^2>-200) 
 %设置虹膜外边缘为白色
i(t1,t2)=255;
      end
   end
end
for t1=1:280
   for t2=1:320
      if ((t1-c(1,1))^2+(t2-c(1,2))^2<=r1^2)|((t1-c(1,1))^2+(t2-c(1,2))^2>=jing^2)         
%把虹膜以外的部分设为白色
iii(t1,t2)=255;
      end
   end
end
figure,imshow(i);
figure,imshow(iii);

正文之后

没错,我回来了,再次宣布!!!溜了溜了。大后天就开始考研了,我把房子借给好朋友的青梅竹马但是不是女朋友的考研人了!所以明天出去住宾馆去~~ 权当是旅游咯!!

原文发布于微信公众号 - 工科狗和生物喵(gh_3507b116a1f8)

原文发表时间:2018-05-02

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Spring相关

Css权重解析

关于CSS权重,我们需要一套计算公式来去计算,这个就是 CSS Specificity,我们称为CSS 特性或称非凡性,它是一个衡量CSS值优先级的一个标准 具...

16320
来自专栏HTML5学堂

一步步教你弹性框架-上篇

HTML5学堂:本系列主要在于跟大家分享弹性运动框架的制作方式。弹性运动框架的运动方式类似于弹簧,有一种回弹的效果,在网站中的一些特效当中还是有一些应用的。实现...

37680
来自专栏数据小魔方

创意雷达图(Round Rador Chart)

今天给大家分享的图表是创意雷达图! ▽▼▽ 既然是创意雷达图,肯定是有难度的啦,单纯的雷达图太没有挑战了! 首先看成品,怎么样,还不错吧,想不想自己也做一个,如...

85350
来自专栏章鱼的慢慢技术路

OpenGL透明与混色效果

24160
来自专栏顶级程序员

阿里巴巴公司根据截图查到泄露信息的具体员工的技术是什么?

? 在月饼事件中的新闻中提到。阿里对员工访问的界面做了一定的处理。貌似这不是简单的水印。这种处理是什么,是怎么做到的呢? =====第三次更新===== 评论...

57190
来自专栏游戏杂谈

关于坐标旋转

在看<Flash actionscript动画教程>(中文版)的第十章的第二节,它提到“高级坐标旋转”,书中只给出了一个基本公式:

34320
来自专栏前端那些事

过渡与动画 - 逐帧动画&steps调速函数

写在前面 上一篇中我们熟悉五种内置的缓动曲线和(三次)贝塞尔曲线,并且基于此完成了缓动效果. 但是如果我们想要实现逐帧动画,基于贝塞尔曲线的调速函数就显得有些无...

27270
来自专栏王磊的博客

基于python的图片修复程序-可用于水印去除

77530
来自专栏前端那些事

过渡与动画 - 逐帧动画&steps调速函数

上一篇中我们熟悉五种内置的缓动曲线和(三次)贝塞尔曲线,并且基于此完成了缓动效果.

10400
来自专栏贾志刚-OpenCV学堂

OpenCV中泛洪填充算法解析与应用

泛洪填充(Flood Fill)很多时候国内的开发者称它为漫水填充,该算法在图形填充与着色应用程序比较常见,属于标配。在图像处理里对二值图像的Hole可以通过泛...

534100

扫码关注云+社区

领取腾讯云代金券