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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x

0 r9 h' i. g/ F( Z5 F5 S1.二值化图像$ Y  c5 f4 g$ \% j  q  x; W
​ 用于处理的图像,一般都是为二值图像。这里也不例外,因为要调用那些图像处理函数,传入的图像都是二值化后的图像。
7 ^! C& C0 @# _7 s6 x, r  J6 j, h5 \. Z4 I
二值化操作代码:: S5 C( R  k* Y# ^3 Q

1 W4 a6 N& A6 j( G8 j! u
  • 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 \8 B, n! ]8 J6 a) u7 J9 H

2 P* O8 K# D; C/ Z& a$ k# x% E; ?4 j/ w运行结果:% M0 r& K+ M& p  L

; W1 Z* Q4 V' O5 D. }: i, y+ l6 F ' n% P/ A" s6 _+ O
) j- p' `: I3 m6 G
) s; O) J, ~% |( X' n
2.统计标注连通域  `* t7 X% g$ f5 p! I  c, X

- W. ?/ D7 J6 `; V参考网址:
7 ~+ |( x- D( U% c- R5 |: I" o; u. J8 m0 r) o$ `! {7 x
Matlab中bwlabel函数的使用
# K& ~( o- Y, _. y" S# f, M& ~
+ d# r* v- @$ o! }8 {9 B; f4 ^matlab的Regionprops详解
9 d# F$ L% H3 l
: o% K9 B9 c: a. R8 Y$ ~) q
4 A' g! T2 G+ P1 X: e+ Tbwlabel函数
, p! L9 o6 a  i% x$ g2 M+ B5 M# _5 k+ {8 z" e# f
4 d0 c1 ]' o# l
L = bwlabel(BW,n)/ o+ [+ V2 |% J6 n+ u, y, r* ?
返回一个和BW大小相同的L矩阵,包含了标记了BW中每个连通区域的类别标签,这些标签的值为1、2、num(连通区域的个数)。n的值为4或8,表示是按4连通寻找区域,还是8连通寻找,默认为8。
, {5 B# h  G! X3 `9 K/ W  x) i: _6 k4连通或8连通是图像处理里的基本感念:而8连通,是说一个像素,如果和其他像素在上、下、左、右、左上角、左下角、右上角或右下角连接着,则认为他们是联通的;4连通是指,如果像素的位置在其他像素相邻的上、下、左或右,则认为他们是连接着的,连通的,在左上角、左下角、右上角或右下角连接,则不认为他们连通。请注意“或”字的含义,就是满足其中一个条件就认为是连通的。
; P, s% F$ U' H+ O[L,num] = bwlabel(BW,n)这里num返回的就是BW中连通区域的个数。
4 c: [+ F- B# O6 W) X$ K通俗的说,这个函数的作用是用来找这个二值图像中的连通区域的,对于不同的符合条件的连通区域(4连通,8连通)分别用不同的标号加以区别,结果保存在L这个矩阵里,而num里保存的是输入图像中连通区域的总数。
" @% S4 ~: I# P- V# i! f. |  Q" W; d' v

: u+ _( f; M: @( x. tRegionprops函数+ c  z0 B. q' X

( l/ @$ o2 n( g
. D, h& s3 ^: pRegionprops:用途是get the properties of region,即用来度量图像区域属性的函数。
: G- G: X* r- W7 H5 d4 ?& p4 r' o/ T7 q0 v: b& h; }
语法:STATS = regionprops(image,properties)* w0 T3 l3 B( N9 E- p( ^8 I
: g3 `/ f0 q( }! m6 W5 o
image是为传入的是bwlabel函数传出的,经过标记后的图像数据。
/ ^+ v5 _+ U: l4 T# |% C; q# V
7 j$ C% E' p& X3 Tproperties:这个则是你需要传入的参数。
, H( n9 l2 f$ q
$ g+ L  b" {" E3 f比如我们需要求面积,则传入Area参数。+ u" x4 u( M5 v/ ~8 B
" }# b. }! ~2 r+ P: \; H, G5 z' I
求周长,则传入Perimeter参数。" y; \' i: G7 m* F* m  P  s5 A" z; N

% f6 ^: e! N" X5 Q0 ~' y求离心率,则传入Eccentricity参数。
. o# R+ f4 p4 M
5 [1 @, x3 t' O& M- _8 zregionprops 函数具体有哪些参数可以参考Matlab官方文档。8 \, j% J# g! s4 p

% t! u7 _1 h% N- Q( f3 T! o. M: \$ Y- U在Matlab右上角查询regionprops函数,点开,则会有最官方的使用方法和参数含义。$ W" E0 l* y9 r) u
# ~. r% \- M" h
7 I. j) M! L3 e! i
. V& H  |8 j" q# o/ s6 N
这个函数非常强大,不止这个教程中的三个功能。
& \: s/ r2 a* F
0 f" f2 I/ q0 k  A# M+ n+ g" l" z2 D
2 F( d1 r* V6 a# P
; \% d9 x( \9 e* W6 h# J1 m5 `
! c1 d$ `& q3 `& @6 d统计连通域代码:
( @, T1 C: F/ |) |3 `! W. R) K) T& i& ?3 n5 \$ G9 V! c0 T. D/ f4 V6 H
  • %先闭运算 再开运算
  • 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');
    . A4 j4 h1 z& R9 T
  
6 }5 ?: q0 l2 b# G3 u. m0 D- z
7 X8 B8 L  f' v标记图像各个图形,进行图形编号代码
0 b! O& T8 j0 s. P
6 e' s1 R0 U6 K0 d3 T% g
  • 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
    ' E/ o- d  a  m2 C* O
& F# R6 e- @/ Z
运行结果图像:0 Y* ~3 L8 o: x
" F( D7 s, @; Q2 u  P2 \/ ?
- h! E& K0 V- O) j6 ?( q& k
' t; q/ t5 ]# I6 H% m
* _2 g8 r: I7 _" q! q
3.计算周长,面积与离心率& O2 [) p, V0 w1 ]( I& u0 f
7 m  k5 ^. G+ F

- s2 i8 H' t4 R6 W( n3 E接上一次的题目:计算出图像左上角绿色方块的面积和周长,计算出右下角红色椭圆的离心率) [5 o* ]6 @5 j0 F0 W
! s1 ?; E7 s) B4 R
​ 要计算出左上角和右下角图像的值,首先,你要先识别出那个图形,你才能对其进行计算。这里就需要使用到前面bwlabel函数标记的矩阵。
8 C3 o: F8 @/ `5 F9 w2 z! V/ T7 w# p8 k: m

7 x. K6 G; P; l9 V" `9 ~/ D
' A2 H% L. }7 s( Y6 F4 t代码即:
7 S' P; N! ~8 ]+ Q6 @  j+ c$ w: K  z: N- [! u  ?" e4 X
  • image_part3 = (copy_mark_image == 3);
    ' y* m7 w2 Z3 |; n0 o& d6 r

3 |8 x7 `* J1 x' F/ B) x8 K% O
) j6 _1 m4 R; G0 T7 V0 T9 Q! O! y根据标记的数值,来判断是不是那个区域,然后将那个标记的区域取出,并显示出来。* s$ s. w8 H& M- |! B. p

& h( f" K7 f( F7 D效果图:注意,使用regionprops函数计算周长和面积,计算的是白色区域的周长和面积。黑白颜色颠倒,那个计算出来的数值则不正确。8 H( K9 ~9 ~/ T- U
2 v1 z- h- O0 g- f1 [
! ^* y) w1 w! B( u1 f- |* h) M
9 E+ F& X5 d2 s
2 |  w3 B! |3 B" o
计算代码:4 \7 M5 l- D0 `: {3 a5 K# f
1 i1 i1 M1 X! c% S) 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);
    ! G" l+ G( y9 Z/ \5 R
   
/ c! `0 m; |- v2 y& O
" G2 y4 m; s, q9 W4 ^, U计算结果将在matlab的命令行窗口打印出来:
2 e6 R) P, V' r, ~( g+ u5 [' t$ i8 _8 v: X1 p
round_area = 7044.000000   —— 周长$ J3 N* w, I0 O7 ]+ w, Z
s.Perimeter = 320.200000     ——面积
9 d+ o! O) P1 h2 Y$ [oval.Eccentricity = 0.915874  ——离心率( q1 z6 J' q$ A, z& F

0 M, ^& C. D; W. U
/ U" u* G+ g0 w* g; p3 N, l5 Q& K4 `* u3 G

! l/ e3 V* ^. G

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-6-17 00:20 , Processed in 0.078125 second(s), 26 queries , Gzip On.

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

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

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