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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
8 I7 J) a) g2 H7 I" d. R& [6 L3 M
1.二值化图像+ h, D1 `9 t% I& ?; w2 V) g
​ 用于处理的图像,一般都是为二值图像。这里也不例外,因为要调用那些图像处理函数,传入的图像都是二值化后的图像。, u1 N8 A6 [# |

$ Y1 b6 s5 X" K* F' G+ A0 R2 B二值化操作代码:
0 w( k/ s" P- P0 S9 R1 F4 y; v
2 v! f/ S8 L% X- C* A
  • 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);  x$ O2 G3 {5 }1 V# ?; J
" M* a. N% C2 o- b7 C  f3 l% J
运行结果:
# e. J( _. b* z; b) S
, h9 _  s' b) S
, \0 p$ W3 B8 t$ J
% l7 |( }  R$ @! O$ j. K4 J" ?8 o4 h  v0 M1 W
2.统计标注连通域
/ V# M9 W* @6 C+ @2 M& m- \& d
  N0 v! p. J) j1 d参考网址:7 [' _  m) P% X/ p! c9 }- w# N

$ ]$ ?) ~8 h% U5 Z5 TMatlab中bwlabel函数的使用
  I* X7 o6 ?6 h6 t/ l: T3 G( D
2 V# y* [! D0 _0 }matlab的Regionprops详解
, b) Z& y  C* m/ f6 O! g% Q. q, M3 R  T. I

' p" l# @- c" \- F4 q6 q4 y+ \bwlabel函数& c1 I4 x* Y0 Q# C

# H, P) n  r0 \& t( I
* g( b5 Z: ]2 h) L! ^L = bwlabel(BW,n)/ i9 O) S* e0 q9 I5 l- L' X& ]! Z
返回一个和BW大小相同的L矩阵,包含了标记了BW中每个连通区域的类别标签,这些标签的值为1、2、num(连通区域的个数)。n的值为4或8,表示是按4连通寻找区域,还是8连通寻找,默认为8。
8 Q6 [" i' O. T1 H4连通或8连通是图像处理里的基本感念:而8连通,是说一个像素,如果和其他像素在上、下、左、右、左上角、左下角、右上角或右下角连接着,则认为他们是联通的;4连通是指,如果像素的位置在其他像素相邻的上、下、左或右,则认为他们是连接着的,连通的,在左上角、左下角、右上角或右下角连接,则不认为他们连通。请注意“或”字的含义,就是满足其中一个条件就认为是连通的。3 Q5 P9 z$ |8 N( l
[L,num] = bwlabel(BW,n)这里num返回的就是BW中连通区域的个数。
6 g  p9 @2 n, k" v0 A通俗的说,这个函数的作用是用来找这个二值图像中的连通区域的,对于不同的符合条件的连通区域(4连通,8连通)分别用不同的标号加以区别,结果保存在L这个矩阵里,而num里保存的是输入图像中连通区域的总数。
* i2 X9 T7 ?. i! S4 X8 r) H. H6 J. O3 b. L6 H
3 s3 O7 \( V: }* c  h2 G
Regionprops函数4 \7 K1 M& @8 O& ?- m& D' y

8 |! e7 {& ]* [  P" m
) F" x4 [+ z$ {8 WRegionprops:用途是get the properties of region,即用来度量图像区域属性的函数。
: ]( O- P: S$ V" q: G: f1 I! u
, O7 E; H  f( P& r9 {语法:STATS = regionprops(image,properties)+ k5 U+ k. w( }6 R4 R" s9 S' O

1 h# I* T0 {! l! X+ Nimage是为传入的是bwlabel函数传出的,经过标记后的图像数据。: ~, z; ~4 U1 e9 ]" V
' W0 a4 s7 d0 V8 ~+ o, A
properties:这个则是你需要传入的参数。
- \7 }$ M1 r! n- b# ?
9 A- S! O, x, @  w比如我们需要求面积,则传入Area参数。
# r3 e! F) s; g: e3 B- T& c% z
2 |% |4 _5 ~) u9 @) J! g) m2 {求周长,则传入Perimeter参数。
' z$ w- I7 g# Q5 L0 m  V: E* @* z6 r$ H$ q; \" p
求离心率,则传入Eccentricity参数。$ H$ f: A+ |( ]5 m* `3 V

! U% h1 T  C0 wregionprops 函数具体有哪些参数可以参考Matlab官方文档。
! i( ]7 ~# O! C4 L
* E+ J7 J2 N; X* ?+ y在Matlab右上角查询regionprops函数,点开,则会有最官方的使用方法和参数含义。
! G4 X- s; j6 a5 [2 r
8 v5 n+ d$ `& m' x; A; {8 y; R
3 i: E% n6 ]# b6 N; L- @3 n( `0 g
, y6 T/ [- r1 l这个函数非常强大,不止这个教程中的三个功能。/ m6 S! A: q% l5 L* s/ Z) T
% K" w+ Y$ w5 L# E9 ]
( f$ p5 F+ j, Q5 s8 G7 l

' ]) }+ I" c6 U4 y! g2 \- C
* ^* C) Q5 m4 @9 @. N# R5 y. S* Y( s统计连通域代码:
8 e+ o3 K+ x; I( d4 {
8 l5 r+ H0 p2 L  C  L- k
  • %先闭运算 再开运算
  • 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');
    ) H3 s  h3 f3 n- j: Y% F8 a4 X
  
3 O- s( Q/ I6 M! P8 Z1 f" F
$ N2 d; j: P6 a6 p" w, j标记图像各个图形,进行图形编号代码
4 Q6 k2 Q/ @' V8 P( n1 p1 \
& N. C* V! \3 o* \5 R, K9 x
  • 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')
  •     %这个是为绘制出来的矩形框图标记数字
  • end8 p# Y# c1 G7 k; R  g  l
5 T) B% I# g4 U$ L* ^7 {
运行结果图像:
: z: g2 Z* z' x/ d9 k
7 G0 f7 P/ }* r " T4 F) y7 _/ F$ O7 v8 p' P' m; K
+ T4 u6 y( Y, N( N+ Y
- ~2 b: c7 r  k# o; Y+ q  H: E
3.计算周长,面积与离心率* [3 m- E9 ?7 g

- a/ g* d6 i& C( E' P0 c$ O, B; w* h8 Y% t. O
接上一次的题目:计算出图像左上角绿色方块的面积和周长,计算出右下角红色椭圆的离心率7 O$ I% K: A+ G

3 D* R& r8 q$ a8 r​ 要计算出左上角和右下角图像的值,首先,你要先识别出那个图形,你才能对其进行计算。这里就需要使用到前面bwlabel函数标记的矩阵。
. {, D. \; W# C, e- @. S4 `
& d) |! U3 g1 M* H ; H! u  x5 R  x5 R, E+ O9 p
8 _! K9 h4 T4 X; A# z" Z) x
代码即:
. F( ?) i8 _# z  {
6 A- t& K3 W" k" c! n# `8 R$ ]
  • image_part3 = (copy_mark_image == 3);
    ' ]. E! V3 [4 h1 w6 p5 c8 M

- ~- W9 l+ ?. G5 X" P4 J% D; n' s! P) `5 K7 m# }
根据标记的数值,来判断是不是那个区域,然后将那个标记的区域取出,并显示出来。, D  q9 w8 w" v2 K+ V6 k* B, W

+ z( Z/ j! t5 Y7 d; l6 q效果图:注意,使用regionprops函数计算周长和面积,计算的是白色区域的周长和面积。黑白颜色颠倒,那个计算出来的数值则不正确。7 V) v: V) _7 n4 v

. h& L) u: g1 ?% B, m
* Q7 O$ G, @# I0 Q5 }$ L& E
/ `8 u% l/ @8 g; i3 g+ H
) Y' o3 X; r5 U计算代码:
2 K' T% \" y7 i3 D" m+ {! s5 e
2 l$ C# C/ z$ T, f
  • 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);
    ( T# E. ]. X* D9 }- d
   
: L, U4 \! b- y1 B
' \" Q7 i% P: d1 O计算结果将在matlab的命令行窗口打印出来:: ?6 @5 w& ~, w2 g

' V/ x6 o( E8 tround_area = 7044.000000   —— 周长. r  D" G8 D# r$ b
s.Perimeter = 320.200000     ——面积
& T" ^* q! `$ l& `* |/ s3 xoval.Eccentricity = 0.915874  ——离心率
# g4 ^, R9 w5 M8 e/ _& J
$ Y, Z7 l) n1 H9 w - Z( `8 F7 i7 h; {0 q
' S8 _: q) k: V" C2 J* x
) O+ j0 f; T4 D5 A! q" P

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-7-21 05:48 , Processed in 0.140625 second(s), 26 queries , Gzip On.

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

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

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