加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

(MATLAB)轴承尺寸内外径的检测方法及代码

(2014-06-19 13:03:39)
标签:

杂谈

it

图片

教育

文化

http://s1/mw690/002jY1Ccgy6JNi4phkI40&690

     毕业设计做的是轴承内外径尺寸的检测,和表面缺陷的识别,从最开始对MATLAB一窍不通,到现在,对MATLAB及图像处理,已经有了一定的了解,答辩结束了,还好有惊无险,现在,把自己这段时间所学习到的知识和大家分享一下,希望能和大家交流一下。

 

   (像素尺寸→真实尺寸)相机标定方面,看了一些资料,但是对棋盘格的标定还是不太理解,标记出来了相机的内外参数,但是还不知道怎么校正相机畸变。

 

 

如上图所示,需要求圆环内径、外径,(面积法,hough直线检测、hough圆检测)

 

1,可以通过求圆形的面积,根据面积,来求轴承的直径。

首先要提取内圆与外圆,然后再扫描面积,最后求半径,具体代码如下

clc;

clear all;

close all;

warning off all;

I = imread('f:\10mm\1.bmp');  %读取原始图像

imshow(I)                    %显示原始图像

c=1.0e+03 *[ 0.7705 1.6865 1.6865 0.7585 0.7705];

r =1.0e+03 *[0.4945 0.4945 1.4545 1.4545 0.4945];

J = roifill(I,c,r);             %特定区域填充

figure,imshow(J);

figure,imhist(J);                     %进行直方图均匀化

Q=im2bw(I,150/255);            %二值化阈值分割

figure,imshow(Q);

M=im2bw(J,150/255);            %二值化阈值分割 

figure,imshow(M);            

N=~M;                                  %图像取反

figure,imshow(N);

n=bitand(N,Q);

figure,imshow(n)                 %位与运算

arae1=bwarea(n);                %内圆面积

arae2=bwarea(N);               %外圆面积

arae3=bwarea(N)-bwarea(n);     %圆环面积

r1=sqrt(arae1/pi);             %求内圆半径r1

r2=sqrt(arae2/pi);            %求外圆半径r2

fprintf(1,'r1=%d\nr2=%d\n',r1,r2);   %输出r1、r2

 

2 hough直线检测

通过检测圆内的最长线段来检测圆的直径和圆心,具体代码如下:

clc;clf;clear all;close all;warning off all;

I = imread('f:\10mm\1.bmp');   %读取原始图像

figure,imshow(I) ;            %显示原始图像             

c=1.0e+03 *[ 0.7705 1.6865 1.6865 0.7585 0.7705];

r =1.0e+03 *[0.4945 0.4945 1.4545 1.4545 0.4945];

J = roifill(I,c,r);                     %特定区域填充

figure,imshow(J);

figure,imhist(J);                     %进行直方图均匀化

BW1=im2bw(I,150/255);             %二值化阈值分割

figure,imshow(BW1);title('BW1');

BW2=im2bw(J,150/255);              %二值化阈值分割 

figure,imshow(BW2); title('BW2');           

N=~BW2;                          %图像取反

figure,imshow(N);title('N');

n=bitand(N,BW1);                   %位与运算

figure,imshow(n);title('n');

%检测外圆直径及坐标

[H, theta, rho]=hough(N);              %对二值图像BW进行Hough变换

peaks=houghpeaks(H,2);               %获取两个峰值点

lines=houghlines(N,theta, rho,peaks);     %检测直线

figure,imshow(N),hold on;

max_len1 = 0;

for k=1:length(lines)                        %绘制直线

    xy=[lines(k).point1;lines(k).point2];

    len1=norm(lines(k).point1-lines(k).point2);  %获取最长直线坐标

    plot(xy(:,1),xy(:,2));                     %找出线段的起止点

    if ( len1 > max_len1)

        max_len1 = len1;

        xy_long = xy;

    end

    len1

end

title('外径hough直线检测')

plot(xy_long(:,1),xy_long(:,2),'LineWidth',2,'Color','green');

max_len1                                %输出最长线段长度,即直径

lines(1)

lines(2)

[xy]

a1=(xy(1)+xy(3))/2;

b1=(xy(2)+xy(4))/2;

para1=[a1,b1]                             %显示圆心坐标                            

%检测内圆直径及圆心坐标

[h,t,r]=hough(n);

peaks=houghpeaks(h,2);

lines=houghlines(n,t,r,peaks);

figure,imshow(n),hold on

max_len2 = 0;

for k=1:length(lines)

    xy=[lines(k).point1;lines(k).point2];

    len2=norm(lines(k).point1-lines(k).point2);  %获取最长直线坐标

    plot(xy(:,1),xy(:,2));

    if ( len2 > max_len2)

        max_len2 = len2;

        xy_long = xy;

    end

    len2

end

title('内径huogh直线检测')

plot(xy_long(:,1),xy_long(:,2),'LineWidth',2,'Color','green');

max_len2

lines(1)

lines(2)

[xy]

a2=(xy(1)+xy(3))/2;

b2=(xy(2)+xy(4))/2;

para2=[a2,b2]

 

3 hough圆变换,具体代码如下

clc;                       %清空命令行

clear all;                   %清除工作空间的所有变量

close all;                   %关闭所有的图形窗口

clf;                        %清空当前图象窗口中的内容。

I=imread('f:\10mm\1.bmp');    %读取图像

J=medfilt2(I,[3,3]);           %进行中值滤波

%迭代法求阈值

ZMax=max(max(J));         %最后用min和max函数找到途中最小灰度值和最大灰度值

ZMin=min(min(J));

TK=(ZMax+ZMin)/2;        %求出初始阈值T,为最大值和最小值的平均值

bCal=1;

iSize=size(J);

while(bCal)                 % 迭代最佳阈值分割算法

    iForeground=0;

    iBackground=0;

    ForegroundSum=0;

    BackgroundSum=0;

    for i=1:iSize(1)

        for j=1:iSize(2)

            tmp=I(i,j);

            if(tmp>=TK)

              iForeground=iForeground+1;

               ForegroundSum= ForegroundSum+double(tmp);

            else

              iBackground=iBackground+1;

              BackgroundSum=BackgroundSum+double(tmp);

            end

        end

    end

    ZO=ForegroundSum/iForeground;

    ZB=BackgroundSum/iBackground;

    TKTmp=double((ZO+ZB)/2);

    if(TKTmp==TK)

        bCal=0;

    else

        TK=TKTmp;

    end

end

disp(strcat('迭代后的阈值:',num2str(TK)));  %确定阈值 

BW=im2bw(I,double(TK)/255);             %图像二值化阈值分割 

ED=edge(BW,'canny');                    %边缘检测

%霍夫变化检测圆

step_r = 1;                              % 设定半径搜索步长

step_angle = 0.1;                         % 设定角度搜索步长

r_min=250;

r_max=300;        % 最小半径和最大半径,确定搜索范围

%注意半径范围的选取,直接影响到你想要检测的圆。

% r_min=900;

% r_max=950;

p = 0.7;                  % 设定阈值

[hough_space,hough_circle,para]=hough_circle1(ED,step_r,step_angle,r_min,r_max,p);

subplot(231),imshow(I),title('原图')

subplot(232),imshow(J),title('中值滤波')

subplot(233),imshow(BW),title('二值化图像')

subplot(234),imshow(ED),title('边缘检测')

subplot(235),imshow(hough_circle),title('检测结果')

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

%------------------------------算法概述-----------------------------

% 该算法通过a = x-r*cos(angle),b = y-r*sin(angle)将圆图像中的边缘点

% 映射到参数空间(a,b,r)中,由于是数字图像且采取极坐标,angle和r都取

% 一定的范围和步长,这样通过两重循环(angle循环和r循环)即可将原图像

% 空间的点映射到参数空间中,再在参数空间(即一个由许多小立方体组成的

% 大立方体)中寻找圆心,然后求出半径坐标。

%------------------------------输入参数-----------------------------

% BW:二值图像;

% step_r:检测的圆半径步长

% step_angle:角度步长,单位为弧度

% r_min:最小圆半径

% r_max:最大圆半径

% p:以p*hough_space的最大值为阈值,p取0,1之间的数

%------------------------------输出参数-----------------------------

% hough_space:参数空间,h(a,b,r)表示圆心在(a,b)半径为r的圆上的点数

% hough_circl:二值图像,检测到的圆

% 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);%返回一个m乘n乘p...的元素为零的数组。

[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&&a<=m&&b>0&&b<=n)

                hough_space(a,b,r) = hough_space(a,b,r)+1;

                % 参数空间累加器加1

            end

        end

    end

end

%检索完毕,寻找最大值,求出圆心坐标与半径,保存

max_para = max(max(max(hough_space)));   % 计算最大值

index = find(hough_space>=max_para*p);   % 设定阈值

length = size(index);

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)) = 1;

        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;

    par3 = r_min+(par3-1)*step_r;

    fprintf(1,'Center %d %d radius %d\n',par1,par2,par3);

    para(:,k) = [par1,par2,par3];

end

 

代码大部分都是自己写的,或许有些不太规范,希望大家交流指正

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有