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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x

3 j4 G1 k; T) A' D( P+ B1.二值化图像& x' j, d) v: s
​ 用于处理的图像,一般都是为二值图像。这里也不例外,因为要调用那些图像处理函数,传入的图像都是二值化后的图像。
) X8 c. b6 j7 n# H+ ]3 |! m5 G' d# i. F8 r  b$ C% `& \
二值化操作代码:
# S4 f5 f$ ?1 ]; h: k+ k2 t' b* r. }5 I1 j& o5 _
  • 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);1 e5 b7 T& B+ `

& w  A) }; n1 z$ e运行结果:
7 L9 F1 j# D: L, W* q, U/ t- M' x& m* c. j9 V; K6 j% e
/ u: W: c& z* i8 k! Y6 I
" t6 D8 u: `5 X# l4 K4 r9 T
/ ^6 I# s1 c* z
2.统计标注连通域
- n3 w5 |5 z: O# G5 L) @/ g/ s& _# K/ g7 L7 ]
参考网址:- H' E9 e# K* a( c1 f

, t0 d9 Z8 i: E+ J* {6 K5 XMatlab中bwlabel函数的使用+ \9 X# Z3 {0 y( n% V$ q! [

+ q: F: P& ], l  |7 ~  D# a0 ^matlab的Regionprops详解- n! N& F: C4 h& \* k
5 X, j8 P' U! R7 ~2 R0 t0 ~# y% G6 n) o
% o! `3 ~% R& O, f  u0 s9 w
bwlabel函数9 y2 N: A, c- h0 x/ v9 i

3 Y# f; y. {; w7 G+ w/ F* D
  O: g/ X0 `3 x' S4 a' ]4 k$ SL = bwlabel(BW,n)
) y5 f0 u/ C1 M返回一个和BW大小相同的L矩阵,包含了标记了BW中每个连通区域的类别标签,这些标签的值为1、2、num(连通区域的个数)。n的值为4或8,表示是按4连通寻找区域,还是8连通寻找,默认为8。
9 \% k4 d6 e1 s' L4连通或8连通是图像处理里的基本感念:而8连通,是说一个像素,如果和其他像素在上、下、左、右、左上角、左下角、右上角或右下角连接着,则认为他们是联通的;4连通是指,如果像素的位置在其他像素相邻的上、下、左或右,则认为他们是连接着的,连通的,在左上角、左下角、右上角或右下角连接,则不认为他们连通。请注意“或”字的含义,就是满足其中一个条件就认为是连通的。
" W/ T6 B( J- z1 U$ j8 \0 T0 r[L,num] = bwlabel(BW,n)这里num返回的就是BW中连通区域的个数。
# r. e. U( p9 r0 l5 M& N, H通俗的说,这个函数的作用是用来找这个二值图像中的连通区域的,对于不同的符合条件的连通区域(4连通,8连通)分别用不同的标号加以区别,结果保存在L这个矩阵里,而num里保存的是输入图像中连通区域的总数。8 ]5 z/ G' W7 @1 I7 ]8 j- [8 P

* C  O+ F$ {( B! _6 i( t
1 R8 K% Z, e; i' @Regionprops函数0 w- a* x% z( \. @

, _; |/ `* n# Y# E- V3 v# s' r4 n$ d( j. L) u$ w* {7 k5 t! n* |
Regionprops:用途是get the properties of region,即用来度量图像区域属性的函数。7 X, ~1 e+ r7 d) C
% D/ m% F( ]9 z" s# v/ v
语法:STATS = regionprops(image,properties)3 @2 U0 {# H$ m

8 A/ k" B7 n" Q2 a; f: p5 u; f/ ~image是为传入的是bwlabel函数传出的,经过标记后的图像数据。2 L% X8 \2 I; i% f) \6 a0 r
0 ~. W; e+ Z2 R. a1 |
properties:这个则是你需要传入的参数。
; M" N( l$ v* R% K, M$ t4 K( G% K; w
比如我们需要求面积,则传入Area参数。
7 _0 B& X- m, K+ q# x7 Y+ t
8 C% V$ s& y; R( ]1 Q$ m5 m: {* ?求周长,则传入Perimeter参数。
8 ?) T+ I" W9 ^% _. P# o
; R' I- ]: D9 F求离心率,则传入Eccentricity参数。  P4 A$ l6 C, ~: K

" a0 |2 ^/ `+ oregionprops 函数具体有哪些参数可以参考Matlab官方文档。
- a. E! V; S: w5 @- I1 I) F
# R  g# ~3 S$ B( U: A9 b* P3 t( K& T在Matlab右上角查询regionprops函数,点开,则会有最官方的使用方法和参数含义。0 H8 b6 ?7 U/ D% s5 J

- r( f' \7 o+ I5 \ # f1 S3 X9 Y: r3 P  t- n
9 o" L& |2 D8 N' f
这个函数非常强大,不止这个教程中的三个功能。
2 {3 |- E/ u  o+ C' e, y
6 V5 s+ {& J8 e6 |2 A9 W 7 g* e' y( c& t2 N$ r: g  E
5 G; E& v$ v, c. f. U3 {/ B! y7 s
5 Y6 u/ W4 i' S% M; y( \
统计连通域代码:" a1 E$ X# y: x& n5 Y& Y
; Z' R2 W! K0 e/ O, k/ \6 q8 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');/ B  G& ?0 D7 M
  
( R" t" M. a5 z+ ~/ S: J6 J' c& L; f! V% X/ n- |* B2 K6 r
标记图像各个图形,进行图形编号代码
# V' ^, n1 S: m; `0 T! b9 E# Z5 r" c( o4 k( E, g  X. M) C) x' g' Z
  • 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
    : E6 v7 B! l. o. b/ q
/ {% n- N8 g( a$ m. J9 q
运行结果图像:
! u' j( d- O! `. k8 r% W5 h6 R+ W! N
8 S% J  b2 V4 b  d- G3 t. n' k
" Z6 ~# q5 S% W* D& z

: b  u1 D- K& g/ H: T/ |3.计算周长,面积与离心率0 n# m: r# F! {$ V# R7 @# S& O
) |1 r6 h4 Y) |! ^1 g: G
6 T2 E! i2 W, f
接上一次的题目:计算出图像左上角绿色方块的面积和周长,计算出右下角红色椭圆的离心率  Y2 }! k2 p9 h9 }! ^/ C

1 f% B5 J2 D" H! E7 K( \6 m​ 要计算出左上角和右下角图像的值,首先,你要先识别出那个图形,你才能对其进行计算。这里就需要使用到前面bwlabel函数标记的矩阵。
" P& s# D, c0 M( g/ f( K$ Y
: l, y6 G3 T; K) p; t
. r  ^$ E) \8 O3 j+ K) r+ I& b$ C# ^
代码即:$ M! S5 X+ O+ y% x# s# q( t) k

/ x3 s/ W  T4 O! m1 `* m
  • image_part3 = (copy_mark_image == 3);2 f: d* G1 S0 X! T! [" R. @, {
/ e1 x& D/ r! A& e# \* y9 M8 y& c9 `
! f, p* }4 P. Y9 r" S
根据标记的数值,来判断是不是那个区域,然后将那个标记的区域取出,并显示出来。9 P9 p6 P' H# C& O/ O2 K, I: U

+ p0 j+ l( w5 p效果图:注意,使用regionprops函数计算周长和面积,计算的是白色区域的周长和面积。黑白颜色颠倒,那个计算出来的数值则不正确。8 c+ R/ ^# ?( \( C& y- }& m* e

( d+ H  H7 S; S  n7 s; F) ] 8 |- U2 k; e: \9 t: c

- l* L5 f, t, a* W: r* H& Y: _6 S( t6 |2 a
计算代码:
, T3 x3 }5 v: Y- [. b' m( R
9 f2 k/ p4 R( w0 s
  • 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  }7 `2 e: r: n# x
   
4 j* B, Z) A0 h+ b4 R' ^) B6 ]  M. A* q
计算结果将在matlab的命令行窗口打印出来:; \$ R& {% a: ~, B' [8 `4 z
) ]" ]& `1 w9 i# ?1 `
round_area = 7044.000000   —— 周长+ T# M" F' c5 Q; u/ D9 N9 [( t
s.Perimeter = 320.200000     ——面积; x8 I0 Q) C2 j5 L- V
oval.Eccentricity = 0.915874  ——离心率8 `' W* @2 U  M& P& H5 I
2 l2 ~" ~7 F$ o* ~# x$ ^" d: Q  O' w

; F0 W( ?$ [2 j- p6 z  Q' c. e" ^% m4 k6 u) H: r
. u" ~; E5 I- E

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-11-1 20:25 , Processed in 0.140625 second(s), 26 queries , Gzip On.

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

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

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