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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
% K0 V7 h5 ~( Z* d1 Z& G" ]) G2 @$ Q
1.二值化图像) |0 L3 E; s1 e# Q
​ 用于处理的图像,一般都是为二值图像。这里也不例外,因为要调用那些图像处理函数,传入的图像都是二值化后的图像。
8 B: _4 C0 H# R
0 \- j0 }( w0 H; j- Y1 J  E二值化操作代码:
  H2 L! f, Z, y. L0 I) G
6 k- [6 M' X8 k
  • 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);4 _, ?3 t% U0 [' _& Y

. w4 S. E5 W: [2 P/ c2 U# ], X- |$ e运行结果:
$ `' R+ o# Y, C4 p
& ]4 b. q- k+ W+ I & K' a* e6 o3 R* M+ }

! b3 `' O3 g. u; r7 h/ s8 Q! ]* l5 B* D. u7 X% z+ {  I3 d" F- m
2.统计标注连通域
; F% {' Y3 n: d- F
. F: m6 W$ ~7 N% e- u参考网址:4 p  f6 z7 K6 G' U: W. S& ^

- |$ y) Y! ?& WMatlab中bwlabel函数的使用; k) D1 d5 g1 I% S+ O4 q

* L8 d% V4 y" i! {, h6 fmatlab的Regionprops详解
) @! {0 W8 f3 v0 M- e7 V
2 ?/ A6 _& O- B$ U
( p" @( B* e, x0 H# Q( R- I- e0 Xbwlabel函数  g" v0 {& {/ _! z. X6 l9 M4 u
+ y. O. s  ?+ Z% {* g
2 J7 g& D- x+ A/ ~
L = bwlabel(BW,n)
3 M0 Y" P  o* \9 S* \+ e& m返回一个和BW大小相同的L矩阵,包含了标记了BW中每个连通区域的类别标签,这些标签的值为1、2、num(连通区域的个数)。n的值为4或8,表示是按4连通寻找区域,还是8连通寻找,默认为8。& S7 O  ^7 B, N# E
4连通或8连通是图像处理里的基本感念:而8连通,是说一个像素,如果和其他像素在上、下、左、右、左上角、左下角、右上角或右下角连接着,则认为他们是联通的;4连通是指,如果像素的位置在其他像素相邻的上、下、左或右,则认为他们是连接着的,连通的,在左上角、左下角、右上角或右下角连接,则不认为他们连通。请注意“或”字的含义,就是满足其中一个条件就认为是连通的。% R6 J5 E( o( Y/ N
[L,num] = bwlabel(BW,n)这里num返回的就是BW中连通区域的个数。% K" h( z- k: j
通俗的说,这个函数的作用是用来找这个二值图像中的连通区域的,对于不同的符合条件的连通区域(4连通,8连通)分别用不同的标号加以区别,结果保存在L这个矩阵里,而num里保存的是输入图像中连通区域的总数。7 m9 L0 z2 i! {- l! u$ f2 e0 H

4 L0 ~1 ^3 z. @; `- {; |4 x4 F+ ]" U8 _3 W; n* h# g
Regionprops函数
6 t3 T  _! k( w) o# r& }
7 o" g. X9 i1 N5 z) E% Q8 N
' Y8 v* [- [+ Y7 o- V3 l$ BRegionprops:用途是get the properties of region,即用来度量图像区域属性的函数。
- ~2 s* [9 p8 o- u. Y& a4 B* P: \: @9 M8 C0 u
语法:STATS = regionprops(image,properties); y6 P) A  w8 I+ X9 J
: G- j( {) K, }4 x
image是为传入的是bwlabel函数传出的,经过标记后的图像数据。, [  w. G2 d$ D

! l1 I8 L' H6 }properties:这个则是你需要传入的参数。
) D- D: O$ W/ x3 x, t! H9 Y. Y9 L# g- U6 q! Z1 N
比如我们需要求面积,则传入Area参数。
. [3 d2 x& h" [- ^) `1 ~6 d
) p7 q8 ~$ o9 b% ?1 v5 H: t求周长,则传入Perimeter参数。: R. B) X6 W4 Q. K( s. j8 O
: F( Z1 I& U0 Q
求离心率,则传入Eccentricity参数。
$ Z- d" V+ I3 K+ m. |& C2 \0 ?+ Y  e: j# D4 x
regionprops 函数具体有哪些参数可以参考Matlab官方文档。7 U$ ~9 ~' N) K

" s8 x# s: x: B6 r在Matlab右上角查询regionprops函数,点开,则会有最官方的使用方法和参数含义。! V. U, P6 U# @3 X+ i1 f# _

: W/ d0 |- O' Y6 {& W 0 q' U1 ?7 ~# b4 O. T( |
3 ]0 S% f( p0 l" }1 _# v0 |
这个函数非常强大,不止这个教程中的三个功能。7 Q" ]/ i' ^6 D3 Q. O( v

3 c# A9 T" y2 g+ I
! L1 B& |1 S! N3 v" y
) f/ s6 E- n1 N  n+ c" Z  s& Z+ `5 c) P
统计连通域代码:  k0 [& N5 X, j" }, _) U' q/ \

" E! m3 z4 B( r9 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');2 B/ h0 A4 f/ O5 D; k" Q
  
: N; h0 R; C# l  V; F0 D6 P5 ]
6 Q" L! X4 ^2 Z7 v+ n7 `标记图像各个图形,进行图形编号代码
- p6 _2 @* `1 S- B! f0 N+ S
( k- j4 g' t8 U
  • 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: X) Z" |9 \. p

; l7 a* V1 `  x+ w: F运行结果图像:
2 i( _' O  p) L5 k% ]2 S# \2 e# H, n

/ x- {$ O1 t. f. a7 M1 P1 }( q( R8 A7 U
+ O- A, J7 \) ]' A
3.计算周长,面积与离心率
' ?+ K8 g, [6 J/ t
% H9 {/ h5 K/ U5 ]: I1 H1 @( U% Z% W' u; N
接上一次的题目:计算出图像左上角绿色方块的面积和周长,计算出右下角红色椭圆的离心率! f- Q* q/ a( t

& @3 e, X' o7 h. B( X: P3 g; C+ Z/ d​ 要计算出左上角和右下角图像的值,首先,你要先识别出那个图形,你才能对其进行计算。这里就需要使用到前面bwlabel函数标记的矩阵。
* _9 S7 K, Q# |4 ?% ]9 b* T- L- c' M- V

( p" ]3 i% x9 ]
2 |1 K3 i% b8 D% \代码即:2 u4 ~2 M9 E, x

2 n7 D2 `" A# S% {5 N  [
  • image_part3 = (copy_mark_image == 3);( b( \: O8 r( u  S+ l  u8 V
9 V: r9 i7 p& r# Q) u( O; ~

+ [% D6 }+ p  k  X. c9 \: }9 H根据标记的数值,来判断是不是那个区域,然后将那个标记的区域取出,并显示出来。
: t/ \! b& _+ ~. L! {! g) C& E7 p& W
效果图:注意,使用regionprops函数计算周长和面积,计算的是白色区域的周长和面积。黑白颜色颠倒,那个计算出来的数值则不正确。2 ~9 E6 s8 N0 {- w5 S' p2 U0 f

7 b, O+ z, S/ F) b+ n2 u
6 w* `3 C* o$ k% q+ p8 [, o: j: N) F5 G$ W( h
; D5 [. j' {0 Y8 M
计算代码:( A3 P7 ?9 Z( A2 I2 T# K$ l1 E
9 `; p. O- ?3 x. H
  • 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% q; {& n' y% L0 k& _
   
  e" w& Y3 U; T6 D" _( ^
' Z: {) q: H* X, y; E$ `计算结果将在matlab的命令行窗口打印出来:
. i. `9 F5 p2 a0 j$ ^% ~3 I2 s6 W& y7 t9 I* j& v. [5 R
round_area = 7044.000000   —— 周长0 x$ x* Z& F. ?3 N  X
s.Perimeter = 320.200000     ——面积
, B/ z; r- c  toval.Eccentricity = 0.915874  ——离心率
& ?  K/ _! [# `; c, z! R* d# W# }7 l, m2 e( Z

; f7 u5 u% e) w. r8 `8 H" ]8 n* M1 U- n; b( J6 _% {8 l. b
$ E2 y# {2 C$ _9 e

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

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

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

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

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