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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x

8 ^7 y; d* {8 P" K4 \1.二值化图像
* d) P8 M' g! t: m0 x. t' h: j; N​ 用于处理的图像,一般都是为二值图像。这里也不例外,因为要调用那些图像处理函数,传入的图像都是二值化后的图像。
: H) x. \8 p9 x# s2 K
7 d" d$ m) G: ^8 ]: D1 A& I二值化操作代码:" _6 ]" \& V( Y- z2 O
+ M! G$ _" q  o1 T5 v
  • 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);
    + w/ p. S% s+ X( y0 L

3 e5 R1 E( v7 A/ s运行结果:: N! o) g0 T3 z( h" u1 i
! Y# e. b- k. Y. i/ U

. u5 U" l& ?2 |8 Y
; Q" n& m; i4 L' a) K, |) S  P! T: u4 ]
2.统计标注连通域) y- D- L) l! R# L8 c

$ g% I1 w2 T* x9 w+ l2 h. U! w参考网址:0 ?" f6 O9 H2 T$ t. Y$ ]+ E7 u* K

/ @  j: |( O, u, SMatlab中bwlabel函数的使用% P' v: y! L6 V- q+ z% w3 U
+ ?3 g; x) `5 F) z9 s. `
matlab的Regionprops详解1 o, ^/ d2 F* u0 x7 G" D4 y
$ u& e" s4 I/ c% W% M
5 |& ~- {: {4 I( N' q7 \& o2 f' l
bwlabel函数
, I5 [8 h3 U, L4 D  P: d2 I) T$ v$ ]% k
' F6 R4 |8 y: n9 P- j8 @+ t! B
L = bwlabel(BW,n); r- f, _# t9 N$ s
返回一个和BW大小相同的L矩阵,包含了标记了BW中每个连通区域的类别标签,这些标签的值为1、2、num(连通区域的个数)。n的值为4或8,表示是按4连通寻找区域,还是8连通寻找,默认为8。7 }  f! i  Y5 _; S0 S1 P
4连通或8连通是图像处理里的基本感念:而8连通,是说一个像素,如果和其他像素在上、下、左、右、左上角、左下角、右上角或右下角连接着,则认为他们是联通的;4连通是指,如果像素的位置在其他像素相邻的上、下、左或右,则认为他们是连接着的,连通的,在左上角、左下角、右上角或右下角连接,则不认为他们连通。请注意“或”字的含义,就是满足其中一个条件就认为是连通的。
# V5 q0 F2 `: A! R& D[L,num] = bwlabel(BW,n)这里num返回的就是BW中连通区域的个数。
& ^# B  X* J# _: \$ u/ \通俗的说,这个函数的作用是用来找这个二值图像中的连通区域的,对于不同的符合条件的连通区域(4连通,8连通)分别用不同的标号加以区别,结果保存在L这个矩阵里,而num里保存的是输入图像中连通区域的总数。  Z: s5 M- _; K9 {) `
2 m$ v# n7 V2 G/ D! E8 s! p* L: }% x  w3 K

2 I0 \2 j5 w2 R: W0 qRegionprops函数
( }9 f6 g! W6 d+ m, M4 H: M
: M  `) `% o( o  v! ~$ P4 n. ?2 N0 `% Z! H" C: [3 A' ^9 @# ^; Y! s. s
Regionprops:用途是get the properties of region,即用来度量图像区域属性的函数。, Y0 v( X. g/ X4 ]

2 Y( g7 }' D$ x" @+ g语法:STATS = regionprops(image,properties)( n2 d1 d8 x; Q7 G* d! E

# w- J& A4 p& d4 w- @  Simage是为传入的是bwlabel函数传出的,经过标记后的图像数据。
3 t( |8 q1 |) G+ ]) Q1 h% j. k
7 M( ~5 [  l7 ]/ {% w' Oproperties:这个则是你需要传入的参数。
- Y, h7 D- C) w6 V6 U  D: p9 K2 n( b
比如我们需要求面积,则传入Area参数。
! |8 o& l  k* x) N2 v$ {
* j; |/ P8 s1 g/ o- r9 `' X求周长,则传入Perimeter参数。
) B1 }$ C$ f( t- P4 h( ?
) u# g0 D7 l' S8 x6 Y( G求离心率,则传入Eccentricity参数。
0 l) R1 e2 I; I' y6 _/ E/ K3 e5 ?9 x1 x* r9 O. G) [
regionprops 函数具体有哪些参数可以参考Matlab官方文档。( ~& w! g3 K. l4 e3 G
- |& l; y, m7 A3 r  M
在Matlab右上角查询regionprops函数,点开,则会有最官方的使用方法和参数含义。2 x2 t- ~; h! ]5 a. S) S

, _2 P8 V; P9 T, p  e5 D" f : q! X* I, u! R6 F3 |* N5 M
$ F& c! B) u5 E6 l! P( G
这个函数非常强大,不止这个教程中的三个功能。6 ~  N+ M# X' p5 ?  w

8 t. _8 p. s( f
6 @  m0 G( R9 |' Y1 p; w3 U+ U/ {) N$ P" A

! ^  D, \( h6 h* h* V, d统计连通域代码:% X8 }- n- e1 q; [+ O8 p% Z3 Y
5 k9 t5 d8 _2 ?. q) V# w
  • %先闭运算 再开运算
  • 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');
    4 z% d1 B! ]6 ?, U6 n& D4 Y
  
3 g6 f$ }/ x" x- n5 C& S4 }' U' |7 D8 p$ J
标记图像各个图形,进行图形编号代码
" W( |& ]8 C9 {* R4 \1 T6 N( V+ i3 T
  • 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
      i# z" A; f/ E7 L
- R; m' c* w5 T7 ^' X( P& Z
运行结果图像:
( S9 y9 Y5 Q3 U2 I$ z/ M: j. {0 ?! k6 |) p
. a) ^6 L/ v- P4 h* Y+ ~

, v6 t! X% {  k! |8 Y
% \. t) G1 q( N3 R& w* x) N3.计算周长,面积与离心率
: d  ]5 W5 t( x; s1 B3 m# @2 {/ t/ Z1 O
6 j) o* v, n$ `" X) L7 q  \5 m
接上一次的题目:计算出图像左上角绿色方块的面积和周长,计算出右下角红色椭圆的离心率
8 W4 e$ o) L( q1 ]/ w+ Q- n/ r# s+ ?6 M* h
​ 要计算出左上角和右下角图像的值,首先,你要先识别出那个图形,你才能对其进行计算。这里就需要使用到前面bwlabel函数标记的矩阵。1 Z( J4 L/ S' k8 o
* H( u' y0 b8 k, I

/ V& P/ L1 c; O* |, J0 ~' J! k
& v' H$ p) s- a( P3 Z8 q; R代码即:
; t; p( u6 b0 m7 R5 p5 @* L! @
$ w8 n! E0 S( g3 d
  • image_part3 = (copy_mark_image == 3);% t2 ^/ E8 C% q

+ f) q; ]6 D9 z, q' I6 ^8 j6 C0 y2 m8 f- E6 G+ a. V
根据标记的数值,来判断是不是那个区域,然后将那个标记的区域取出,并显示出来。, Y) L- {8 w# ]% L) I
+ [) Z& M/ G: `/ S
效果图:注意,使用regionprops函数计算周长和面积,计算的是白色区域的周长和面积。黑白颜色颠倒,那个计算出来的数值则不正确。
; l. V7 ^! u& B7 A* ]. [9 K3 R
1 Z6 V0 i2 t4 U0 `- R
) ?) w$ M; M: A  v! J) h4 W. M" v: i) d- z
+ ~1 Y3 a9 B6 Z9 J+ h" \
计算代码:
8 h* g/ e8 a& O
+ r5 _3 @+ k0 n7 H' S  T% b" X+ ?+ W7 j
  • 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);# v0 n$ e* y+ Y9 @+ H- B* c" ~5 U! E
   
. _2 I, M' x% [( d) f% W' v
* c5 b$ L2 M, K计算结果将在matlab的命令行窗口打印出来:
. q! Y1 g( f$ u0 o) k) }$ d* r% M  c/ N
round_area = 7044.000000   —— 周长
; }, D) n& i6 r; D! g% k3 z4 bs.Perimeter = 320.200000     ——面积
- N# L' r7 ?2 J$ A2 a6 |oval.Eccentricity = 0.915874  ——离心率( E+ k8 Q, a* f- o( U

; b3 z7 o0 {4 x) Q7 u# l+ ~ 3 w8 ^( Z5 r& W

" T4 V5 W3 D9 Z+ m5 ]/ B, F" X1 L" G; c6 v7 L" c7 X

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-7-1 15:25 , Processed in 0.078125 second(s), 26 queries , Gzip On.

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

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

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