找回密码
 注册
关于网站域名变更的通知
查看: 1888|回复: 1
打印 上一主题 下一主题

这是一篇关于集Matlab的形状识别与计算图形周长、面积、圆周率的文章

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2020-1-15 09:32 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x

  R$ H% }3 {- a7 k1.二值化图像
  W+ ^% U4 f! Y& B' D: E4 |' }. M1 d​ 用于处理的图像,一般都是为二值图像。这里也不例外,因为要调用那些图像处理函数,传入的图像都是二值化后的图像。) ~0 o1 I( ^- d6 u1 M

7 u* D/ |2 Q; {. i8 B7 U) F' y- G8 c二值化操作代码:3 e8 Z9 b1 v& x3 V" o8 V
" B" S3 B8 d! k- g5 |9 k) F
  • clc;
  • close all;
  • clear all;
  • img=imread('test.bmp'); %读取原图像
  • figure;
  • imshow(img);
  • grayimg = rgb2gray(img);
  • BWimg = grayimg;
  • [width,height]=size(grayimg);
  • figure;
  • imshow(grayimg);
  • %二值化
  • T1=80;
  • for i=1:width
  •     for j=1:height
  •         if(grayimg(i,j)<T1)
  •             BWimg(i,j)= 255;
  •         else
  •             BWimg(i,j)= 0;
  •         end
  •     end
  • end
  • figure;
  • imshow(BWimg);
  • %先闭运算 再开运算
  • se=strel('disk',5);
  • BWimg = imclose(BWimg,se);
  • BWimg = imopen(BWimg,se);
  • figure;
  • imshow(BWimg);8 d  w3 _7 P' y: R; j% y+ q" a% \* |0 a) L
3 @; J0 J0 U; I
运行结果:
* s- W  e8 a7 O
. w  Z) q/ x+ Q) C
4 e/ u! z6 _9 j9 Z& w& k4 W  e( p+ P, L

. s" b: G* V( h" I+ L2.统计标注连通域
  Q1 o) }; s1 e/ {( }: b- h; e6 n) u7 A& m0 N' ?
参考网址:' G$ y8 D; {6 b: D  k
9 v; z7 T+ _1 t% A/ j& r6 O
Matlab中bwlabel函数的使用
# M2 n' N+ C% m% R# w
% s7 z$ _+ K  s: j# q. T: P7 D8 Zmatlab的Regionprops详解* ?3 z4 f" o6 K6 B$ [$ v5 f
) z, w' |1 D( Q/ G6 M$ o
  ], f( u" b0 J+ H3 X5 [
bwlabel函数
1 [6 m( H* x2 @$ q/ x, O! Z! N: _
* N2 u# |( w  b5 v" k: Q7 z6 K, y: T
L = bwlabel(BW,n)9 L7 D. n) G3 A0 C8 G
返回一个和BW大小相同的L矩阵,包含了标记了BW中每个连通区域的类别标签,这些标签的值为1、2、num(连通区域的个数)。n的值为4或8,表示是按4连通寻找区域,还是8连通寻找,默认为8。4 g: R' k2 q( c
4连通或8连通是图像处理里的基本感念:而8连通,是说一个像素,如果和其他像素在上、下、左、右、左上角、左下角、右上角或右下角连接着,则认为他们是联通的;4连通是指,如果像素的位置在其他像素相邻的上、下、左或右,则认为他们是连接着的,连通的,在左上角、左下角、右上角或右下角连接,则不认为他们连通。请注意“或”字的含义,就是满足其中一个条件就认为是连通的。# ]+ c! Y, {! g2 f# o8 D
[L,num] = bwlabel(BW,n)这里num返回的就是BW中连通区域的个数。! i1 a0 W2 `$ ?
通俗的说,这个函数的作用是用来找这个二值图像中的连通区域的,对于不同的符合条件的连通区域(4连通,8连通)分别用不同的标号加以区别,结果保存在L这个矩阵里,而num里保存的是输入图像中连通区域的总数。# B3 z' ~7 _1 t
  g, {8 R) l# N" K) f

2 H0 T. g$ x6 d9 l0 hRegionprops函数
5 {4 f* R1 s$ T6 w/ z) x( K: v+ ]( J$ H$ b; f6 D  A

9 Z% o. E( m+ ?0 zRegionprops:用途是get the properties of region,即用来度量图像区域属性的函数。4 t+ o& z3 w) D9 T

1 P+ @' l; G& `语法:STATS = regionprops(image,properties)! {/ U! _- ?& I1 I/ Q/ }
: s/ k# \1 O: o0 ^5 F: d. X7 t
image是为传入的是bwlabel函数传出的,经过标记后的图像数据。
8 R, Z; F' V5 x( V+ f
& H, U7 @' X6 x% uproperties:这个则是你需要传入的参数。
9 K$ C7 f# y" _9 }+ h& `" H7 v
( [, v% J/ a% n6 k) H  n; P# x比如我们需要求面积,则传入Area参数。5 [& v2 ^2 f/ Q2 ?3 U, K* Y

  S% R  o' b3 |6 I求周长,则传入Perimeter参数。
# f; Z, t$ c% Y0 k, p4 L& H* u* F2 m# J! P  L0 j
求离心率,则传入Eccentricity参数。# X$ @4 ~3 r- g" }5 x/ {6 j

8 B% C  Z# G, ?% Y) W9 `2 w; rregionprops 函数具体有哪些参数可以参考Matlab官方文档。
3 V# w! l" k' K' g) q1 y' |! p8 C9 M8 K
在Matlab右上角查询regionprops函数,点开,则会有最官方的使用方法和参数含义。7 B- x& I& C0 F! x+ {2 n" K& i  z
  e3 \  K) z* Q! B

( {: A  D( G! }  F! C. l# U3 u# N3 l+ L
, {1 L: C' }: T7 s& l6 t这个函数非常强大,不止这个教程中的三个功能。$ n% \* G) G: J3 v% r- c
3 m  X4 d) A' c

% T) m4 y2 X3 |" Z/ t6 t7 \6 q* S; E5 e2 N8 k/ e8 d3 [
( f6 S( o" [" I8 W
统计连通域代码:1 ]: R/ N# F! h: |; C/ V

% Z& R+ l4 s$ [( P3 G: L
  • %先闭运算 再开运算
  • se=strel('disk',5);
  • BWimg = imclose(BWimg,se);
  • BWimg = imopen(BWimg,se);
  • % figure;
  • subplot(2,2,4);imshow(BWimg);title('形态学操作后的图像');
  • %统计标注连通域
  • %使用外接矩形框选连通域,并使用形心确定连通域位置
  • [mark_image,num] = bwlabel(BWimg,4); %参考博客https://blog.csdn.net/wanrenwangxuejing/article/details/25108191
  • %bwlabel 寻找连通区域,    4连通是指,如果像素的位置在其他像素相邻的上、下、左或右,则认为他们是连接着的
  • %num 表示连通区域的个数
  • %l是大小和BWing一样的图像数组,里面存放着对bwing图像的标签值(即判定为连通后,在L矩阵中标记出来)
  • %regionprops 介绍
  • %参考 :https://blog.csdn.net/langb2014/article/details/49886787
  • %返回值STATS是一个长度为max(L(:))的结构数组,结构数组的相应域定义了每一个区域相应属性下的度量
  • status=regionprops(mark_image,'BoundingBox');
  • centroid = regionprops(mark_image,'Centroid');, q+ _. ~5 g3 u  e% I' I
  
& X: x4 ]# Q5 ~6 h( n4 U% l: q5 P; }0 n- h
标记图像各个图形,进行图形编号代码
* Q& C0 u& h, u) x' c" s
* C+ z0 `. B3 ]
  • figure;
  • imshow(mark_image);title('标记后的图像');
  • for i=1:num
  •     rectangle('position',status(i).BoundingBox,'edgecolor','r');%参考https://blog.csdn.net/zr459927180/article/details/51152094
  •     %参数说明:position绘制的为二维图像(他是通过对角的两点确定矩形框)
  •     %edgecolor 指边缘图像,r表示变换为红色。
  •     %facecolor 指内部填充颜色。
  •     text(centroid(i,1).Centroid(1,1)-15,centroid(i,1).Centroid(1,2)-15, num2str(i),'Color', 'r')
  •     %这个是为绘制出来的矩形框图标记数字
  • end
    / [/ c; r& m" ^/ y' z1 I. N% ^$ F1 W; R

- V, w7 [: ~6 w, W$ i. _运行结果图像:( u1 h) k0 Z) [- t. P2 s
1 |3 D. R1 x# ]4 h  t
. L. t/ H* y. Z; M" D
: B- f( c- M0 A9 B5 Q2 r
& y' Z" I5 X5 l8 n: D2 d
3.计算周长,面积与离心率/ I' Z: X1 _4 D! ]  V* v

+ ~; U0 I1 a# p3 e0 k/ V7 l- E9 @% a+ |+ P' d  j- b4 R: z
接上一次的题目:计算出图像左上角绿色方块的面积和周长,计算出右下角红色椭圆的离心率( F+ O/ x1 b6 `
0 h3 _( h/ Z/ F* W! H
​ 要计算出左上角和右下角图像的值,首先,你要先识别出那个图形,你才能对其进行计算。这里就需要使用到前面bwlabel函数标记的矩阵。/ V2 Y5 |: p& I8 e  M

$ L1 o% ^, L  }) D $ |; s# V! c8 o5 ]

9 B; X/ [; U: c3 k: z代码即:2 W: {! y9 ?! w3 o0 |
( K) a8 g' r: L* P' O# Q
  • image_part3 = (copy_mark_image == 3);4 C2 u: D& f- n& O" ]- ~
6 V' P5 Y$ h* D: f
7 E* S8 B$ }7 E' ^. S
根据标记的数值,来判断是不是那个区域,然后将那个标记的区域取出,并显示出来。# T6 |1 m# E1 W9 D6 E$ R3 e* L
5 L: c- P6 Q2 X8 q/ q+ b; t( |4 E& L
效果图:注意,使用regionprops函数计算周长和面积,计算的是白色区域的周长和面积。黑白颜色颠倒,那个计算出来的数值则不正确。
& f% G6 ~( Y" Y1 h
+ @0 t# r9 k6 A' A$ h7 G - \2 y7 L0 }& y9 s# e
- ~% g5 R# I+ T

/ Z  F! o" V. ?. D计算代码:9 z+ a& p7 x% k. ^' k) a

! o2 Z7 G, o8 H1 E
  • copy_mark_image = mark_image;
  • image_part3 = (copy_mark_image == 3); %%这边进行区域的选择,例如只保留3
  • % image_part3 = (mark_image ~= 3);
  • figure;
  • imshow(image_part3);
  • %求面积
  • % total = bwarea(image_part3);
  • % fprintf('total = %f\n', total);
  • round_area = regionprops(image_part3,'Area');
  • fprintf('round_area = %f\n', round_area.Area);
  • %求周长
  • girth = regionprops(image_part3,'Perimeter');
  • % girth.Perimeter
  • fprintf('s.Perimeter = %f\n', girth.Perimeter);
  • %这边进行区域的选择,例如只保留10
  • image_part10 = (mark_image == 10);
  • figure;
  • imshow(image_part10);
  • %求红色椭圆的离心率
  • oval = regionprops(image_part10,'Eccentricity');%离心率 0 < e < 1之间,e越小,越像圆。
  • % oval.Eccentricity
  • fprintf('oval.Eccentricity = %f\n', oval.Eccentricity);
    % L5 L4 l. H" t$ m% }( T
    2 X2 e6 ^6 |) Z$ z( m3 j3 z) {
8 s( R) H+ z/ m4 a
计算结果将在matlab的命令行窗口打印出来:
8 I$ J5 X+ r; u* g; Z/ Q% |! t8 p+ ?4 h; Y3 D3 o
round_area = 7044.000000   —— 周长9 H( C3 P7 |3 G1 J
s.Perimeter = 320.200000     ——面积5 t% X2 H6 [+ I) B
oval.Eccentricity = 0.915874  ——离心率
" E) @+ R; [; D% a% ^5 Q$ ?8 U" X. K8 {9 m6 E
$ v; u; p7 `8 n% \

+ }. s0 T6 b( ~7 g9 L; y, `6 W& P
( [& p. t. D  u

该用户从未签到

2#
发表于 2020-1-15 17:56 | 只看该作者
集Matlab的形状识别与计算图形周长、面积、圆周率
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-10-5 21:19 , Processed in 0.140625 second(s), 26 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表