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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
- w. R: d6 E; Y3 V2 _) q
1.二值化图像5 j9 J) ]- U! z  t& U
​ 用于处理的图像,一般都是为二值图像。这里也不例外,因为要调用那些图像处理函数,传入的图像都是二值化后的图像。) _# P  a- X7 O- m- X

& [/ {+ c7 r8 B二值化操作代码:2 z, G0 y  ?2 ~$ R8 i2 [3 D- I

* i# z* \0 W9 V  q# X5 [/ ~6 R
  • 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 N, _3 v5 O- v
- l1 A1 n. e) D7 q
运行结果:' x2 I, t! p0 n; S4 {" Q. [' ?

4 f+ w& v+ h8 Q1 ^9 a! x
9 Q- r+ ?1 a/ Z7 n6 J' a- v
( \$ z& I, e, D& i# J9 K( R  ]) j# i4 e' u- S' o4 Y
2.统计标注连通域
4 U+ [- ~* |, _0 t3 x
1 P/ Q4 H' `( q9 W参考网址:
1 k* ^' I0 K) H7 ?/ l7 Y" s/ G7 [* y8 x0 _- k; j
Matlab中bwlabel函数的使用
4 D3 v- a: f( ~' f( p/ f' z& J3 Q! Y. J% h% J
matlab的Regionprops详解
, F3 k4 _# a3 Z; Q5 `0 M* O5 y" ]$ O1 w/ T5 i0 r8 e' d8 g
  O; H& {8 w! e5 y$ Z$ T" b7 I+ h
bwlabel函数1 g  y( q8 q0 ]0 ]5 ]5 j6 H" p

( O4 @/ o8 p, ~  m* k; z2 u1 `% F% y3 {5 _* U/ v7 b# s
L = bwlabel(BW,n)" U2 _' I/ s/ D1 _
返回一个和BW大小相同的L矩阵,包含了标记了BW中每个连通区域的类别标签,这些标签的值为1、2、num(连通区域的个数)。n的值为4或8,表示是按4连通寻找区域,还是8连通寻找,默认为8。
( ?6 d4 d; D( e; s+ d7 c) b" N4连通或8连通是图像处理里的基本感念:而8连通,是说一个像素,如果和其他像素在上、下、左、右、左上角、左下角、右上角或右下角连接着,则认为他们是联通的;4连通是指,如果像素的位置在其他像素相邻的上、下、左或右,则认为他们是连接着的,连通的,在左上角、左下角、右上角或右下角连接,则不认为他们连通。请注意“或”字的含义,就是满足其中一个条件就认为是连通的。
8 J- j; s6 J! T2 E4 B2 V[L,num] = bwlabel(BW,n)这里num返回的就是BW中连通区域的个数。
6 A9 b% I2 |: U) g, O通俗的说,这个函数的作用是用来找这个二值图像中的连通区域的,对于不同的符合条件的连通区域(4连通,8连通)分别用不同的标号加以区别,结果保存在L这个矩阵里,而num里保存的是输入图像中连通区域的总数。
5 n9 w% J7 {- R8 z" c: k  R
5 A5 s, g, J( i- p" r8 N. H( [
0 F/ n4 k# G$ B: i, ^Regionprops函数  z: q3 x- K) B- j

0 C3 T+ B) I: ~% U; p9 s2 H  c1 z% k( t5 o) Y
Regionprops:用途是get the properties of region,即用来度量图像区域属性的函数。7 n8 M0 y( o+ Z: @, f5 n' y3 `% Y

# s4 }3 d! H/ B! `0 N, A& `语法:STATS = regionprops(image,properties)& s: W& }' D! Z! z6 z. Y; D
1 d  a8 l6 @  G+ s3 r$ H3 O0 f/ e
image是为传入的是bwlabel函数传出的,经过标记后的图像数据。+ _4 H; ^! e& b( A

/ p, X; Q1 m( k' ?/ i! |properties:这个则是你需要传入的参数。) r7 y8 j6 P+ b& g6 R4 U3 n

6 t! M/ [, I. r) g5 B' o比如我们需要求面积,则传入Area参数。
# M4 J' N5 b# Q0 b2 q
4 J5 |* i& L$ W3 @* Z' x4 t* S求周长,则传入Perimeter参数。
7 ]& Y& F4 C8 M3 q2 P1 l( ~1 Y* K' ^" G1 J5 |% i( b8 T
求离心率,则传入Eccentricity参数。
& ^9 |6 t6 k/ {6 d" I- F5 \; a5 D
* Z# y/ O) U9 w2 b) T1 |# D7 \regionprops 函数具体有哪些参数可以参考Matlab官方文档。0 N% b, K! K$ P# y4 g

! ?# F# x/ w% C; \- b0 T在Matlab右上角查询regionprops函数,点开,则会有最官方的使用方法和参数含义。
+ P! `% l7 g0 \0 }7 u' g7 m2 }# P* v- Z% }
0 M5 h; \- C9 X- x% d) N% l
0 r) l* v& H; x) H0 \/ u  d4 a
这个函数非常强大,不止这个教程中的三个功能。
$ J! n8 Q6 ]/ p: K1 E
8 s9 U; q- G4 x. b# ? 2 t: R0 u1 u6 T' x) Q- l

  o% |! c7 |+ `0 M8 z2 h7 n' j3 Q) q5 p' I3 N+ @9 ~+ P
统计连通域代码:8 d( ?- O- ?" H0 W, y+ o/ t# b
3 K% z. o2 i$ d# U" C' ~
  • %先闭运算 再开运算
  • 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');
    9 }+ d* m0 l3 X. X2 X+ v, }
  : D. i& Y+ |5 S8 {

- I" z4 y" V1 w* F, \: b* o! [: F标记图像各个图形,进行图形编号代码
6 c  V# Y7 J8 h. P
8 s! v2 B  P% r& D# C5 o
  • 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
    7 }, |  [) x8 ]

. k8 Z  d/ M6 R' T4 C0 v/ {/ r运行结果图像:
8 J- a8 K+ Z; y; Q
+ |- ]. c# }8 [' j! R8 ^
& ]/ ?) C- m9 w8 E) |- I6 m" J/ k* ^& G8 D; j

. K: ?4 ?- r2 ~3.计算周长,面积与离心率
5 _% t% x5 m6 Y7 [' d) v' m! _5 f% n1 k) ?( T

1 G- A: p* X5 M. b$ C接上一次的题目:计算出图像左上角绿色方块的面积和周长,计算出右下角红色椭圆的离心率% C, B9 K1 l2 p7 ~# c6 v

- U3 n3 L+ p1 p​ 要计算出左上角和右下角图像的值,首先,你要先识别出那个图形,你才能对其进行计算。这里就需要使用到前面bwlabel函数标记的矩阵。9 }1 T5 p. y/ {1 O" _' f

! e; y& F7 t! O% Z* c6 ~8 L& @
# r# x. x! _! D% B# A0 \3 ]: z! W4 y! L- |: K
代码即:
) C% N* N' H6 x6 }6 I( X' [( H) ?% i+ I
  • image_part3 = (copy_mark_image == 3);
    7 J/ e' g. ^  {4 n( v) Q7 h

2 j& }3 I5 ^  B. q. _' o2 n: j7 U' J$ l: E$ i/ M( s* y& J
根据标记的数值,来判断是不是那个区域,然后将那个标记的区域取出,并显示出来。; a- F2 M- O: ?5 ^/ P9 J" E; _9 [
3 p+ o; @, E" H* r) x" p: K( t
效果图:注意,使用regionprops函数计算周长和面积,计算的是白色区域的周长和面积。黑白颜色颠倒,那个计算出来的数值则不正确。
7 `: x2 ]  |7 ?7 O# v8 l: K  Y- s9 s8 x

$ e  S, s6 O/ F( f: O  R& [$ u
% c" {0 f& t: ]1 K; @& ?+ A) ]! j8 d1 `, f
计算代码:
/ N0 x0 K( s1 B1 v. ?3 L8 P9 h( t  U
  • 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);' _" E6 f" T. Y% ^) g2 ]2 i
   
% D$ G+ O# q, c, ^- i  @) C( Z" h6 Y: i- M( T) x' P! _% ~
计算结果将在matlab的命令行窗口打印出来:0 {4 q* }# @- N) T
+ S' `1 t# ~; u3 L# j) |
round_area = 7044.000000   —— 周长
# _+ V: o. D+ W, I0 x' ?9 @  Qs.Perimeter = 320.200000     ——面积2 ^2 o+ Y# Z+ M8 N& n
oval.Eccentricity = 0.915874  ——离心率( |. a1 O6 T& M$ g- N2 S

. [5 r1 N6 k* E
" ?  |1 }: o* k% R5 m) |
7 o' A$ R! N) u9 k; W5 \! V
0 ~; R5 O+ Q1 `, s4 n8 A

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-11-23 21:45 , Processed in 0.171875 second(s), 27 queries , Gzip On.

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

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

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