matlab 图像处理霍夫变换检测四个圆,(输出四个圆的半径和坐标)

说明:
1、因为需要找到图片中的四个圆,刚开始我是直接在整张图片上找,可是发现周围的干扰因素太多了,调了一组参数,发现重复的圆太多了,还有其他我们不需要的误圆检测了出来。然后就想着分别检测,为了摆脱周围相似环境的影响,我将整张图片带圆的地方,剪裁了下来,分别剪裁了只带圆的正方形进行检测,这样就比较容易检测,找到准确位置。(提示一点,可能分别检测的时候,也可能在同一个圆的边界附近检测出了很多相似圆重叠在一起,也就是检测同一个圆出来了好几组相近的坐标数据。你又无法调一组只出来一组坐标的参数,但是最后你只需要一组坐标数据,这时候你可以对矩阵进行求平均,用mean()函数即可。代码里有)
2、分别找到四个圆的准确位置后,也只是相对位置,再加上剪裁的起始坐标就得到了绝对坐标。
这是原始图,我们要进行处理的图。
这是未进行校正的视频的某一帧  图1
通过检测进行了坐标标记 如下图:
霍夫变换检测圆操作后并进行了圆心标记
main.m文件

%%     main.m文件
clc;
clear;
% BW :二值图像;
% stepR:检测的圆半径步长 
% stepAngle:角度步长,单位为弧度
% minR:最小圆半径  
% maxR:最大圆半径 p:阈值 0,1之间的数,通过调节此值可以得到图中圆的圆心和半径
% 读取视频的第一帧进行如下操作:
%1)剪裁图片的四个角 
%2)利用霍夫变换检测圆,检测圆的之后得到圆的圆心并同时输出四个圆的坐标和半径。
%3)输出的有圆心的相对坐标和圆心的绝对坐标。
I = imread('image_supple\1.jpg');
for i = 1:4 % 连续剪裁图片的四个角
   switch (i)
       case {1}
           tlc= imcrop(I,[117 50 100 100]);% 左上角
           processpic(tlc,1);
           figure,imshow(tlc); 
       case {2}
           dlc= imcrop(I,[115 520 100 100]);% 左下角
           processpic(dlc,2);
           figure,imshow(dlc);
       case {3}
           trc = imcrop(I,[810 45 100 100]); % 右上角
           processpic(trc,3);
           figure,imshow(trc);
       case {4}
           drc = imcrop(I,[745 510 100 100]); % 右下角
           processpic(drc,4);
           figure,imshow(drc);
   end
end

processpic.m函数

对图片进行预处理
function processpic(t,h)   
grayI = rgb2gray(t);%图片灰度处理
BW = edge(grayI,'sobel');%边缘检测
imshow(t);
hold on;
switch (h)
    case {1}% 这是检测到的第一个圆
        parm = findcircle(BW,3,0.07,16,18,0.95);
        % 对于supple因为调参之后就出现了一组数据,所以不用再求均值。
        %disp(parm);
        %paraAvg = mean(parm);%对矩阵的每一列进行求均值
        % 输出的坐标是绝对坐标坐标形式是(y,x);
        %fprintf('CenterAvg %d %d  radiusAvg %d\n',round(paraAvg(1,1)+50),round(paraAvg(1,2)+117),paraAvg(1,3));
        fprintf('CenterAvg %d %d  radiusAvg %d\n',round(parm(1,1)+50),round(parm(1,2)+117),parm(1,3));
    case {2}%这是检测到的第二个圆
        parm = findcircle(BW,3,0.07,16,18,0.95);
       % paraAvg = mean(parm);%对矩阵的每一列进行求均值
        fprintf('CenterAvg %d %d  radiusAvg %d\n',round(parm(1,1)+520),round(parm(1,2)+115),parm(1,3));
    case {3}%这是检测的第三个圆
       parm = findcircle(BW,3,0.07,16,18,0.95);
       % paraAvg = mean(parm);%对矩阵的每一列进行求均值
       fprintf('CenterAvg %d %d  radiusAvg %d\n',round(parm(1,1)+45),round(parm(1,2)+810),parm(1,3));
    case {4}%这是检测的第四个圆
       parm = findcircle(BW,3,0.07,16,18,0.95);
       % paraAvg = mean(parm);%对矩阵的每一列进行求均值
       fprintf('CenterAvg %d %d  radiusAvg %d\n',round(parm(1,1)+510),round(parm(1,2)+745),parm(1,3));
end
   
% 绘制所有的圆 
for i = 1:size(parm,1)
    x0 = parm(i,1); y0 = parm(i,2);  r0 = parm(i,3);
    xi=[-r0:0 0:r0];
    yi=round((r0^2-xi.^2).^0.5);
    plot(yi+y0,xi+x0,'Color','g','LineWidth',3); % 下半圆
    plot(-yi+y0,xi+x0,'Color','g','LineWidth',3); % 上半圆
    % plot(y0,x0,'x','LineWidth',2,'Color','red');
end
end

findcircle.m函数

% 霍夫检测圆的主要代码
function [para] = findcircle(BW,stepR,stepAngle,minR,maxR,p)
%circleParaXYR = [];
[m,n] = size(BW);% BW:二值图像;
cntR = round((maxR-minR)/stepR)+1;% stepR:检测的圆半径步长, minR:最小圆半径, maxR:最大圆半径
cntAngle = round(2*pi/stepAngle);% stepAngle:角度步长,单位为弧度
hough_space = zeros(m,n,cntR);
% hough_space:参数空间,h(a,b,r)表示圆心在(a,b)半径为r的圆上的点数
[rows,cols] = find(BW);
cntPoints = size(rows,1); 
% Hough变换将图像空间(x,y)对应到参数空间(a,b,r)
% a = x-r*cos(angle), b = y-r*sin(angle)
for i=1:cntPoints
    for r=1:cntR
        for k=1:cntAngle
            a = round(rows(i)-(minR+(r-1)*stepR)*cos(k*stepAngle));
            b = round(cols(i)-(minR+(r-1)*stepR)*sin(k*stepAngle));
            if(a>0 && a<=m && b>0 && b<=n)
                hough_space(a,b,r) = hough_space(a,b,r)+1;
            end
        end
    end
end
 
% 寻找满足阈值的圆的参数
max_para = max(max(max(hough_space)));
index = find(hough_space>=max_para*p); % p:以p*hough_space的最大值为阈值,p取0,1之间的数
length = size(index,1);
hough_circle=zeros(m,n);
for i=1:cntPoints
    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<(minR+(par3-1)*stepR)^2+5 && (rows(i)-par1)^2+(cols(i)-par2)^2>(minR+(par3-1)*stepR)^2-5)
            hough_circle(rows(i),cols(i)) = 1;% hough_circl:二值图像,检测到的圆
        end
    end
end
 
for k=1:length
    par3 = floor(index(k)/(m*n))+1;     
    par2 = floor((index(k)-(par3-1)*(m*n))/m)+1;    % 圆心y坐标
    par1 = index(k)-(par3-1)*(m*n)-(par2-1)*m;      % 圆心x坐标
    par3 = minR+(par3-1)*stepR;                    % 圆的半径
    fprintf(1,'Center %d %d radius %d\n',par1,par2,par3);
    para(k,:) = [par1,par2,par3];% para:检测到的圆的圆心、半径
    plot(par2,par1,'x','LineWidth',5,'Color','red');%用红的的X对圆心位置进行标记
        
end


注:本人处理的就是上面显示图片,第一张是原始图片,第二张是处理之后的图片。因为我要处理的是视频,所以里面做了循环和选择。具体实现还是根据自己的需求进行修改。

  • 13
    点赞
  • 76
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值