美文网首页职场牢骚派计算机杂谈程序员
【机器视觉与图像处理】基于MATLAB+Hough的圆检测

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

作者: 张照博 | 来源:发表于2017-12-20 23:11 被阅读1097次

    正文之前

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

    正文

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

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

    %%%%%%%%%%      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);
    
    yanjing.bmp

    正文之后

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

    相关文章

      网友评论

      • Lolitamy:大神 请问后面那个求瞳孔的代码为啥运行出错了呀
        张照博:@Lolitamy 。。或许你写错了?、、、、我这儿貌似没出问题啊
        Lolitamy:@HustWolf :sob: 心痛
        张照博:@Lolitamy 没道理啊。。这是书上的模板
      • 653a6fedacb4:大佬大佬 我是一个连函数都不懂的傻缺
        张照博:@Weshion 没。。这个主要是算法麻烦了一点。。没别的了
      • 叶止__:好美,虽然看不懂代码
      • 小泰熊:MATLAB看见这么多循环,好难受
        小泰熊:@HustWolf 哈哈。。懂得懂得
        张照博:@小泰熊 :sweat: :sweat: :sweat: 霍夫变换就这样子。。

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

      本文链接:https://www.haomeiwen.com/subject/rkonwxtx.html