|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
MATLAB源程序代码分享:MATLAB图像处理实现螺纹的识别
$ r+ E* `/ ^; t0 `. @& ?: N6 d5 ~ u
%% 读入原始的螺纹图片, 并显示
' x, z1 c4 R% p8 C2 r {. `* v& hclear;clc;close all1 _2 W- a* w5 }$ M7 B
I=imread('screw.bmp');4 ^* H t9 ~3 `0 L" V
I=rgb2gray(I);6 c" ^& i& w, y* X
9 V% g/ U: A( g) qfigure7 ?" v7 J2 C9 u H- P: w7 h# [( P7 A- Y
subplot(1,3,1)
3 Y9 W4 S& ]$ }$ U( Ximshow(I)( ]0 y0 J# n. \8 b- J
title('螺纹原图')7 W! K1 D p- Q7 J; ?8 s7 I
" V: a& {4 {+ o
set(gcf,'units','normalized','position',[0.2 0.2 0.6 0.6]); % 设置 figure 窗口的位置和尺寸, g2 M3 i$ I. s* X6 D7 O
& L/ \5 J' Z. V# ?+ v4 ^%% 对螺纹图片进行滤波处理, 并执行边缘检测; B7 K* i. B- J; b, J' R2 q
I=wiener2(I,[5 5]); % 把原图里的噪声点滤去
6 x6 @0 z2 N$ {3 R9 e% K8 n5 |$ [6 r
I=edge(I,'canny'); % 边缘检测, 得到螺纹的轮廓波形
1 z7 L1 S( ?1 |% | A. ][m,n]=size(I); % 计算图像的尺寸
2 B$ i8 t, q9 y4 Z
% V* \4 e. P5 L- [: Y; ]3 M* i& C( `I=I(20:m-20,20:n-20); % 把图像的边角去掉, 仅留下有用的部分- N6 i, u; V! J) r+ f7 B
[m,n]=size(I); % 计算去掉边角之后的图像尺寸
2 X, C3 _* f8 a8 K V7 y8 p& R3 ]# ]- G! v& g
subplot(1,3,2)2 U' `8 g1 S7 w6 S$ x- u; x( o
imshow(I) % 显示去掉边角之后的图像
( b" Q2 V. `5 U" k( K& Otitle('螺纹波形')+ V( o9 N6 L7 k, {( O9 l
; V" f; T7 {1 \- l
%% 查找白色像素点的位置, 将螺纹轮廓的坐标点提取出来
d, {) [' R1 b5 nN=1; % 计数器7 ~2 J& U: h( u0 A% b. L9 U
for i=1:m
7 q1 }( A5 W- ~5 d. `$ { for j=1:n# I8 A+ F1 U) d6 K5 ]' g* N
if I(i,j)==1 1 _ A& q+ \9 N) Z1 d2 ~2 t
x(N)=i; % 保存白色像素的横坐标 x
/ L( X0 q2 F/ P/ j, E2 k2 }) _0 n y(N)=j; % 保存白色像素的纵坐标 y: G' f/ [7 e }& t2 Y: k
N=N+1; % 计数器 +1! D A1 z4 Q! C! U! L9 g3 n
end
" I% {2 W* p T# C) G4 ~ end( i, q2 f6 S4 G' l1 w" x- ~) g+ r# k
end
2 O6 U U7 A& ^7 j& X- f' \* q, Y% E0 A( k9 l K7 F. z
[x,IX]=sort(x); % 将 x 按升序排列
- g b8 ~$ b% g! r6 v" @y=y(IX); % 对应的 y 顺序依次和 x 对应" _* B. g4 Z6 l. V: ^( L+ }# {
+ e1 x# I5 b/ s7 x
subplot(1,3,3)- V& w! u5 {4 c7 w$ r
plot(x,y) % 绘制出螺纹轮廓波形
* G2 `. [' O4 K& f: G% exlabel('横轴 x')
1 h5 a# F; G1 x7 Tylabel('纵轴 y'). a4 k* j0 G( ~, v3 R
title('螺纹识别结果')" ?6 q1 z$ Z z3 H1 X2 J8 \
view([90 90])6 `$ Q1 T: S/ D9 L5 t
hold on% W( r* B) ^( A8 j0 e7 v
axis equal
8 T. j+ |; r/ Z& |axis([1 m 1 n])
5 y, t9 }! Y" v/ P5 w8 t" [: C. Y) C* J. ]/ P8 G- m. c* k5 T! o
%% 查找螺纹轮廓上的波峰点和波谷点% a( {# w/ t* o
M=14; % 设置螺纹的分段数6 x0 A& E+ D! k4 p( H. P' R5 p2 Y
lengthxy=length(x); % 数据点的个数
2 Y5 y. V" O' M8 n4 kdlength=floor(lengthxy/M); % 将螺纹轮廓波形等分成 M 段, 每一段的长度* q. J0 \/ M! i7 o5 a
+ z5 v& {2 P( X3 C$ ~
for k=1:M
+ U' o8 s( ~8 r% S! j xx{k}=x((k-1)*dlength+1:k*dlength); % 保存每一段的 x 值( V( f1 J% C- g7 B( r7 E
yy{k}=y((k-1)*dlength+1:k*dlength); % 保存每一段的 y 值) Y% Z& X* C0 W3 @" H) d
end
8 Y# t3 M9 {4 e3 ?) D- ^1 ~8 }7 {# e( e L( K, X( p( t0 W$ K
for k=1:M' z% ?) A/ R5 n% F
[bofengy(k),index1]=max(yy{k}); % 寻找每一段里 y 的最大值
# N( N# ?: @9 S4 e9 F% T bofengx(k)=xx{k}(index1); % 得到与波峰对应的横坐标 x0 J6 U, `5 j8 ~0 ]9 E9 M T
[boguy(k),index2]=min(yy{k}); % 寻找每一段里 y 的最小值
5 n, G: e j- m4 s/ B' @5 u bogux(k)=xx{k}(index2); % 得到与波谷对应的横坐标 x
# O3 R* x7 k( {6 \. tend
/ z/ H! z5 S) g! @. c P6 e* |4 Qscatter(bofengx,bofengy) % 绘制波峰点7 P7 L$ G" @! v; u' B2 F
scatter(bogux,boguy,'k') % 绘制波谷点
, b* e, W$ f: \) U" K# O/ E z" f0 r7 n c
%% 分别对波峰点和波谷点, 执行直线拟合, 得到螺纹轮廓的两条包络线
! ?# {9 q% i. S7 _: v( p/ j% 对波峰点进行直线拟合
6 P7 X7 Q* _6 g' T: e9 p/ nA1=[bofengx',ones(length(bofengx),1)]; % c s2 i- p. M8 g
kb1=A1\bofengy';8 R! ]2 l3 h! o" U; F% p4 Y5 T
k1=kb1(1);& B* F( n* b2 O0 s' F# M2 W q3 \4 u
b1=kb1(2);+ b& P P) T; Y3 Z' t
7 v1 O; v9 A$ ` {5 s4 e7 _% v% 绘制出波峰点的拟合直线6 x3 V6 X+ U# h' f ^% ~. Z9 p Q$ v
x0=[1 m];
' t+ n; ~6 t2 e$ L" \Y1=k1*x0+b1;
) e; @7 ^2 B u( u( |0 xplot(x0,Y1,'m');* }/ J$ K) Y$ ^6 b- _- H5 I
7 E2 D7 h* v, j5 c
% 对波谷点进行直线拟合
3 D% {4 n. N/ N' d! }( x/ z! {1 k9 wA2=[bogux',ones(length(bogux),1)];# V9 D& M, x: L, ?! D* z( r4 j) B c
kb2=A2\boguy';" L6 k' b. N% c P
k2=kb2(1);- R p$ R8 g5 a) m! b
b2=kb2(2);
, D; E# E# Y5 X9 x: E0 O0 J8 |& ?; D3 g8 `4 @8 \
% 绘制出波谷点的拟合直线
7 q# D+ Q$ i& s4 ex0=[1 m];
5 `6 J( b7 b" N! V8 C+ XY2=k2*x0+b2;
/ Y" m4 i% L8 ^ i9 `: z9 |plot(x0,Y2,'r')# D) ?) Y. c+ S* ]5 g
|
|