数学建模社区-数学中国

标题: 深度学习和目标检测系列教程 8-300:目标检测常见的标注工具LabelImg和将xml文件提... [打印本页]

作者: 杨利霞    时间: 2021-7-14 15:18
标题: 深度学习和目标检测系列教程 8-300:目标检测常见的标注工具LabelImg和将xml文件提...

' H$ f: r" w! Q深度学习和目标检测系列教程 8-300:目标检测常见的标注工具LabelImg和将xml文件提取图像信息
3 t( O1 X' L9 f4 w! ?0 Y* v: k! U; h图像标注主要用于创建数据集进行图片的标注。本篇博客将推荐一款非常实用的图片标注工具LabelImg,重点介绍其安装使用过程。如果想简单点,请直接下载打包版(下载地址见结尾),无需编译,直接打开即可!
; V( _3 ?/ J* Q7 j' g) r2 t: L, H- P* p
! J$ U# B2 I/ r/ u! {5 E& k
感谢原作者对Github的贡献,博主发现软件已经更新,可以关注最新版本。这个工具是一个用 Python 和 Qt 编写的完整的图形界面。最有意思的是,它的标注信息可以直接转换成XML文件,这和PASCAL VOC和ImageNet使用的XML是一样的。' D, c/ r3 V) g) k* v7 L$ Q6 _
: c1 s/ n3 i+ K2 l
: c) l" f3 q+ v$ B) A; F
附注。作者在5月份更新了代码,现在最新版本号是1.3.0,博主亲测,源码在Windows 10和Ubuntu 16.04上正常运行。: j) \0 u2 F+ O' D

7 e. v7 {6 M/ q3 v6 w0 D0 |& ^

! \" b* [7 B9 }具体的安装查看Github教程:https://github.com/wkentaro/labelme/#installation
+ e( `6 Y+ e: j8 J1 ~) u9 H) [* M- x' ?$ ^, j" w9 s8 P
5 g0 D# J. e! T1 ^5 A
在原作者的github下载源码:https://github.com/tzutalin/labelImg# W! @7 f: r' p+ l' Y
。解压名为labelImg-master的文件夹,进入当前目录的命令行窗口,输入如下语句依次打开软件。1 q( F1 K+ i! n: _* k& U# M/ C

5 D% E+ s. R* g

; o# h% G5 Y9 ^6 w8 Zpython labelImg.py0 g, s) ]6 \$ Z. B  V
1! s$ ^9 p% M4 ]' R

! F  G# i8 |3 v4 W  s# A' k
* S, l( C( \: o7 |+ }- o
. `4 H6 J- A6 \7 p$ R  Z

: j1 {) Y! |7 a4 f具体使用/ y0 q/ ?: z9 D, l$ s
修改默认的XML文件保存位置,使用快捷键“Ctrl+R”,更改为自定义位置,这里的路径一定不能包含中文,否则不会保存。3 ~/ O( u  B8 Y$ K
) c  q, |9 l% D" x. r- L
( G- }3 `1 ~$ t+ H! `) u
使用notepad++打开源文件夹中的data/predefined_classes.txt,修改默认分类,如person、car、motorcycle这三个分类。0 _; o! |1 }7 e
9 ^, Z" ~, P1 M9 o4 b* \
7 q* v4 R% W! v% y
“打开目录”打开图片文件夹,选择第一张图片开始标注,用“创建矩形框”或“Ctrl+N”启动框,点击结束框,双击选择类别。完成一张图片点击“保存”保存后,XML文件已经保存到本地了。单击“下一张图片”转到下一张图片。9 n' I3 F2 N% F' _

' _. }7 L% V) j, T
: s# E( e! r9 `8 v
贴标过程可以随时返回修改,保存的文件会覆盖上一个。
  v, G2 n/ y( {" k5 F/ h5 y4 l1 Q# O. ^

0 d3 b8 J5 ~9 f4 z& \5 J0 G完成注解后,打开XML文件,发现和PASCAL VOC格式一样。
2 Z% q! u& U+ [% r% L
$ h4 `3 j: y% a: J6 M- [# d- G

- S% `! P; Q' L/ h3 L6 p将xml文件提取图像信息; @# q, O9 o) g: ~4 |
下面列举如何将xml文件提取图像信息,图片保存到image文件夹,xml保存标注内容。图片和标注的文件名字一样的。
6 U3 d8 U+ t3 A& x
6 {" S, N, p. s* u) \( u# d

# j* N9 H6 u4 e/ i- c. \
( f5 d/ t2 r+ c2 f7 G
6 J  C0 O2 J. E; D' K
下面是images图片中的一个。2 c" }$ b. Y7 i$ a/ U1 s0 V

( E0 A& ]% s+ r" i- x
  m! m! K$ v0 [: ?  |* }  H
下面是对应的xml文件。  }* p5 r0 v- J; U" g' [. m: @
  {* D1 i! ]6 Q
. `8 b4 c$ ?2 P% Z" V
<annotation>8 g# n' u, Z( d& B1 T* O
        <folder>train</folder>" b& {4 {9 j6 @$ Y0 W5 x" g& Q  v
        <filename>apple_30.jpg</filename>
3 D; u* R. a. X        <path>C:\tensorflow1\models\research\object_detection\images\train\apple_30.jpg</path>
7 r' X/ f) e! |5 F1 {, ?) \        <source>3 h5 U: z5 T' G( Z  g" L+ B
                <database>Unknown</database>
  a. @+ K1 F5 }& w        </source>
, W: F- E8 b  @6 ~9 _. d, N! z        <size>
6 Q* ]9 v1 R' `3 b                <width>800</width>
% o& `5 ]+ M' y                <height>800</height>' q6 b' G6 {4 c6 A2 ]
                <depth>3</depth>
9 _# q+ {* J* u8 d        </size>
) A) |7 h: w- ]0 y* k; R& L        <segmented>0</segmented>
- s+ c; a* p! L9 u* X7 L  Y        <object>
  v, J- Z2 i5 d" P4 i3 m" h. E                <name>apple</name>
& t+ P8 N! E. v+ Y* D5 {                <pose>Unspecified</pose>6 Y% P* n- e3 B
                <truncated>0</truncated>
2 H/ `) l* k! s0 |- N, g                <difficult>0</difficult>% k3 U4 c; o3 ~( w; ~) P
                <bndbox>! k4 ~$ z; W1 F7 w8 {1 _& D, z3 C
                        <xmin>254</xmin>
" [" T# @; O; e5 Z* d                        <ymin>163</ymin>
" y) Y3 T, j. x                        <xmax>582</xmax>
+ t, W$ d4 K: K6 H) @$ ^3 @" k                        <ymax>487</ymax>
7 @( I/ g3 t; ]3 C2 q                </bndbox>9 g6 |# c. ?$ }
        </object>6 U6 y' q1 ?! h4 k
        <object>1 ~! ]! N3 H- l! L* m0 V
                <name>apple</name>/ R! L, d4 N1 G: o" w
                <pose>Unspecified</pose>
! w/ Y7 q2 n0 I5 l                <truncated>0</truncated>
# a& g5 ?6 T/ p) `2 Z                <difficult>0</difficult>
, o+ v6 O5 S5 m                <bndbox>
/ y# D8 H, N$ l5 _                        <xmin>217</xmin>
  N4 y/ L/ t4 y  E8 Q                        <ymin>448</ymin>
/ O0 Y" G- j( t0 ?: [1 e$ ]                        <xmax>535</xmax>
- S; N7 j9 v$ s. w8 f" {+ ?  Z) M                        <ymax>713</ymax>
: y" P. A* b9 x. z1 e* f' P$ ]                </bndbox>
4 A% d* z7 S+ m        </object>
  g+ K9 r/ V4 J! q        <object>' Q7 m: X9 O4 ~; O+ r
                <name>apple</name>
6 l6 M, k# B+ W3 [; A7 r* k                <pose>Unspecified</pose>
+ ]6 l. J( _( M6 o" w+ ~5 p) A                <truncated>1</truncated>6 @# C1 [+ l. W0 a7 B! V- z
                <difficult>0</difficult>+ y3 o0 v7 h1 T) t' h6 q5 Z
                <bndbox>
, ]5 T% @( @# ]                        <xmin>603</xmin># I9 l9 q) O3 |
                        <ymin>470</ymin>  T. z4 P% l6 k' A$ Y: }4 b* G' m
                        <xmax>800</xmax>
, @% A3 ~- n4 C5 r, ~5 p                        <ymax>716</ymax>
' O" S2 c9 T: l- f                </bndbox>
# Q( ^$ z5 q0 ]" f0 e; h5 L        </object>& D% @4 j! @% _
        <object>( W9 ^3 ?2 i) K$ X2 o
                <name>apple</name>
5 L8 }6 k5 w+ ^; J                <pose>Unspecified</pose>
- N9 A7 q/ X. [                <truncated>0</truncated>: P8 Q# k' m- T. J# t
                <difficult>0</difficult>0 o! J3 \: X9 P+ D6 T% x/ G
                <bndbox>
  i$ [/ B$ T# v# X, [7 T0 b                        <xmin>468</xmin>9 l1 f. E  f  d% x  j  i0 P0 e
                        <ymin>179</ymin>
& m% U. a: Y! W; W, ~; Z: B6 z                        <xmax>727</xmax>9 k1 X) I. u$ _2 G2 Z$ Y
                        <ymax>467</ymax>. t" H' ?( u3 a$ Z# p9 ~" p
                </bndbox>% [' H1 Q0 s) ^. O# J
        </object>
: s- F. _/ A" H# n$ {        <object>. `' a, a& ]' y
                <name>apple</name>
  D3 R0 V# O/ l* a% p                <pose>Unspecified</pose># r( [  E1 d( W; i7 A( |/ P
                <truncated>1</truncated>8 e; n. m  ]% M, c
                <difficult>0</difficult>
( U5 F/ z1 a& X4 c                <bndbox>
# V* a( w+ u$ C+ `                        <xmin>1</xmin>
+ }1 |$ `, g+ O: M* `' n                        <ymin>63</ymin>1 z' n: U. p$ M, t* i) ^, S* j
                        <xmax>308</xmax>  @: v, m3 T( r0 ^' U9 X+ I4 h
                        <ymax>414</ymax>
+ |1 n0 ^: Y& `* ~0 }  ~) H                </bndbox>
, [# h5 s$ U" S/ j        </object>& [- H+ S+ U3 x
</annotation>
. ^$ c% s. u; ^  d2 M" _11 E5 p1 B5 F/ e; y- m4 |* e- L. C
23 J* A/ [' ?/ z) I5 A, q' S
3- r% L' M* K) b; {# B; t4 D
4& _4 W5 p2 y7 z/ h0 H% S
5% R0 [* x7 L+ |5 [& \- D4 P2 T
6
3 m5 I2 g: w6 h2 N. D8 [! f78 w+ {1 }7 ?- u8 A
8
: m& c& C& O' l3 G! G6 t- @+ l96 x1 h. j% u) c7 X$ Q2 T" }
10& _1 B' P, c. l" E1 |1 ^0 y
111 w8 `9 Y* }! W' h" s
123 m- B1 w% E' q; E; b
13
8 F+ \% z- d9 q* j! T# N. F; \0 ~14
' O- @6 @! l5 C8 D15
, v- p9 B$ X. j( R  o# L6 Q161 }! [- \& W9 Y  q, A
17
* V  D+ ~3 M% ~6 h18
3 B% Z  p. A- F" m19
& \5 Y2 a" x; `- {% P" U, P' @, y$ Z20
" X' K6 a# a! n1 W) O- n; ?21
; D' h# G3 ?) G& X, d* U22( L8 f0 k7 _5 H: x! k) k
23
7 j& N& f) k3 N- x2 C9 \243 J' U2 C; `; d4 p* n' H4 j5 k
25
5 A; Z6 k# o0 ?/ N2 d* {, \2 X26
) Z! P% R5 t, L) O- J. j27  j9 }+ T3 z4 T2 V# m5 g
28
. n9 {1 n! \+ J+ c29
6 j  c% z# a8 e+ R8 q30/ c/ q- G0 r  }/ |# F
31
+ a, F& M2 S  X6 `32# p3 B6 ]+ w# A4 o
33
: o9 G# z1 ]5 l6 b+ B7 y8 _34
2 P! L5 m  r8 w$ O. a35; y1 ?; M/ g( ]  C; o" N
36+ R0 l' B8 g: Z2 K. Y7 ]" u
37
4 F, A4 @: \# _38- F3 w2 a4 C1 E6 N$ p. k
390 o3 B; n% l0 U& Z- H" ~% u$ n
40
8 T7 m' v* f+ R/ z) H$ I417 z. k4 H+ W# a) c
42
5 c2 N3 Q4 D/ y3 _6 h5 }43  ~3 p' h; i; I" v  C" [
44
% q3 A0 Q' X# ]! z+ F: ?45
) B6 n# o5 B0 t! k( L, i46* {2 n& c$ r9 E
47  w2 B! @8 l  A5 e# N
481 p- d+ q& q. m4 O+ B; j1 Q
49
2 H$ x0 O1 F; C3 ?: @9 i5 h50
& e8 v$ t6 o, x' \1 ^/ M+ O8 s, c51
1 ]0 }0 M; B! u8 H1 F52
# A5 j6 B. `. o! i5 X3 H2 Y3 Y53
! @5 v/ c* v- J54+ y6 |4 l- P1 `8 N) W
55
1 ~* n# ?! s+ ^7 T1 O* O( y% m2 p569 f  e5 g# B) ?( Q9 i) F
57$ J" e5 c. p  c, C8 D% j
58
/ Y7 q; T+ j; u  H0 N3 J, ^; F' u59+ Q" E8 Z, M6 u
60
( u  ~# n5 O$ P3 o. K+ q) l' y7 i61
) V+ H  C! l7 G62+ I2 R4 @0 J$ ^0 n& j4 C
63
9 d, b$ T$ V  h6 |64
+ S% Y: N9 h' r# _! q651 r; C8 s( _, g, [+ K5 K
66
2 _% A* O) x& p. P; V& ^( M67
1 T7 n0 o7 u& t7 e68  E& s+ K3 e8 H7 z& _7 F+ o- u% S
695 ~+ F7 A, t5 d0 T: @7 n$ X( u! D
70% l0 a( X+ F+ j8 v) n# p- z) a
71& z9 N% T+ Q( q6 x! [6 k
72
; C" [" q2 k9 b% |73, |. L0 ~' [& @/ V7 T1 @5 d
74
% m5 L1 S4 C& I1 I) J将xml文件提取图像信息,主要使用xml和opencv,基于torch提取,代码比较凌乱。7 A8 N' Z" R" i7 A

+ g0 j: C5 v$ D# g" }, S/ s

! d7 U' d7 z9 O5 S* U" g$ N1 b9 oimport os
5 H3 `2 R( Q9 R: nimport numpy as np; t# ^+ s6 W3 d$ H. U
import cv2( w9 c$ i1 F* y$ S. O
import torch5 |( ^$ _9 P" j7 D
import matplotlib.patches as patches6 V4 \( Y' R6 [9 V8 W' t
import albumentations as A) c) P1 z: d; w: \
from albumentations.pytorch.transforms import ToTensorV2
: R9 G/ }) ^/ a& u, efrom matplotlib import pyplot as plt$ R! C- q8 x* M; V4 Y" |
from torch.utils.data import Dataset
8 d/ ^* j2 w, N% k/ c% H- q' l+ Kfrom xml.etree import ElementTree as et
% d2 n- t, T, Ofrom torchvision import transforms as torchtrans# ~- O2 x; k+ {4 N' H

8 R' p3 M2 A. R( b8 {( B2 _

1 e, j% [' z* Y8 ?8 L# defining the files directory and testing directory
4 ]# v0 z2 p/ i$ f3 R' Y- ktrain_image_dir = 'train/train/image'4 a: O$ F1 H# u
train_xml_dir = 'train/train/xml'6 N' U/ J' @1 @! p
# test_image_dir = 'test/test/image'( T* b8 h! T* q8 a" c
# test_xml_dir = 'test/test/xml'4 H( g, r$ r9 z# S% Z. e& E
7 k/ U# _% P& i* [
* c9 Z6 v& C2 r! K8 C( Q# @1 G8 C& P. n
class FruitImagesDataset(Dataset):' h" _0 K0 X  Z
0 }% {3 w2 d8 w9 Z

/ R4 N( m9 k3 n, |    def __init__(self, image_dir, xml_dir, width, height, transforms=None):1 O& q/ P, V" V; V. O) I
        self.transforms = transforms
8 Z. t' g. Q7 e2 M        self.image_dir = image_dir: t7 ]# x5 |% V8 G( k, G0 u
        self.xml_dir = xml_dir" H. [  q0 T; l2 h
        self.height = height' [5 j: ^9 q+ B6 A4 o
        self.width = width
  f) _$ F. A) V. o6 P5 d7 m
6 g; U6 c1 ~4 h% q% I: \

8 \3 f6 B: y; c# d) w        # sorting the images for consistency
7 A8 b! X9 _3 S2 [) d        # To get images, the extension of the filename is checked to be jpg
7 K2 L4 n+ J  ^: P* {, p        self.imgs = [image for image in os.listdir(self.image_dir); c& Q5 y  L# B
                     if image[-4:] == '.jpg']
# p. o0 o& U3 G( F  f% N1 v        self.xmls = [xml for xml in os.listdir(self.xml_dir)+ O( T) |" M% i8 k3 Y, J+ Y  s
                     if xml[-4:] == '.xml']. L$ u8 s$ h' j( c

6 t: x$ i9 Q+ f% }

7 M7 ~  c8 @+ _3 C        # classes: 0 index is reserved for background- a. o& Z! I& k) x2 ^  R6 O$ \: R& A, j
        self.classes = ['apple', 'banana', 'orange']
% R- W( E  i  d' m) {9 C5 o+ Y3 R% {& t  |

7 I" H9 f0 s- h# y3 v, S. t    def __getitem__(self, idx):
( U6 g$ J3 Y* U% d* a+ v. v: X1 O" I' [+ Q+ F0 u

2 y" P( F* }1 p+ c7 p( m        img_name = self.imgs[idx]
% v) u  c8 q0 J+ E2 L8 p, w5 H3 e, t0 R        image_path = os.path.join(self.image_dir, img_name)/ O$ j) G% Z; Q% U2 X

9 v! k' x' z# K6 |, e1 u: D/ M- K+ G% I
, ~, c) U" S: ~5 w' m2 v) y' X
        # reading the images and converting them to correct size and color& t: m8 m: ~! i9 b: L. K
        img = cv2.imread(image_path)
# K5 S9 D+ S/ f" Q        img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).astype(np.float32)) Q% k7 `  b! m: q% t
        img_res = cv2.resize(img_rgb, (self.width, self.height), cv2.INTER_AREA)
% e1 ~# w0 z! ~7 k+ H        # diving by 255& g2 w* ~- T# t% B
        img_res /= 255.0# o# Y: g" l$ J, F3 d
# N& a) L2 A+ {+ e- j
& p& Y. `4 ]  M5 U
        # annotation file
* [2 Q5 b5 P  c4 ]8 J" G& u        annot_filename = img_name[:-4] + '.xml'
1 M4 \* ?/ ~& c) j* h+ m+ ^- u        annot_file_path = os.path.join(self.xml_dir, annot_filename)/ i; V) f+ y* e2 @1 y

' J6 ^1 G, l, h0 v, N# s4 b9 q, k" L

, S% h6 Y$ K% U  Y$ R        boxes = []
, P+ r/ J. l. K' H% a: a9 R5 R        labels = []' k) m7 U9 a( `9 F: l; f) p
        tree = et.parse(annot_file_path)
- }  N6 W5 c) v) ~4 Q  A8 r        root = tree.getroot()4 g* b, h2 q: t% Q
1 D# L, m( ^) C, ?% s3 K

6 b: }7 `- f3 Y  v$ s* U        # cv2 image gives size as height x width
% I1 n4 `  l3 E* T/ u& L        wt = img.shape[1]
+ j  a+ v8 s, C: B        ht = img.shape[0]
  P7 o1 F6 Z4 f0 r# i
' y' r6 n  D9 m4 a! ]! L  G* I! I, e
* a6 _/ j+ p0 r
        # box coordinates for xml files are extracted and corrected for image size given" }5 R; U' P1 O
        for member in root.findall('object'):
& H/ {0 B- L! s: e6 A. o6 q; X            labels.append(self.classes.index(member.find('name').text))
; Z/ f3 |& X7 O2 P# o3 A: Z: A
5 H0 H5 W, t6 X3 O+ d
  T/ p" Z; T) \$ f& Z
            # bounding box
2 c4 ^- T- S0 M; C0 E            xmin = int(member.find('bndbox').find('xmin').text)
5 `2 l) y- L) L! y! w5 L; V( f            xmax = int(member.find('bndbox').find('xmax').text)
' o! \: E8 E% f, l- u  e
8 o, A" B' W4 e6 f2 |
, }# [' s: |# m; N9 h, C
            ymin = int(member.find('bndbox').find('ymin').text)
5 J8 f% n3 |$ {2 x            ymax = int(member.find('bndbox').find('ymax').text)
1 u# E! j. D3 y
7 y; N6 @9 A2 }0 B6 [6 h/ w9 k0 R
) l1 Y. \3 H4 b) x% _
            xmin_corr = (xmin / wt) * self.width
- l2 T5 M; p) L* J/ j* k* t' l3 K: f            xmax_corr = (xmax / wt) * self.width8 X1 `- x5 s* m; A
            ymin_corr = (ymin / ht) * self.height5 X0 d6 U% L: O
            ymax_corr = (ymax / ht) * self.height
1 W" U8 e# A2 V$ t! I. T            boxes.append([xmin_corr, ymin_corr, xmax_corr, ymax_corr])
) }; Z9 E8 e+ \2 h( V  u. w: a) A- N$ P9 @# h, M; ^
& O5 G: g7 K% {. m% ]2 \( S
        # convert boxes into a torch.Tensor
6 f4 [( A9 h  H9 f        boxes = torch.as_tensor(boxes, dtype=torch.float32)- n' X+ I# E6 w6 D) J3 A
2 ~, u! B* F% \( n- b+ P

5 B1 W% g# D9 H5 ?+ v, B        # getting the areas of the boxes4 n! R6 o+ X: s2 r" d
        area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0])% k* @" m1 E9 g1 }! x

7 S, M, {5 s' |$ p, N8 u

1 f2 H  S! [) M' C( s/ L4 y8 _        # suppose all instances are not crowd- ~% H; q4 t& s( H, f
        iscrowd = torch.zeros((boxes.shape[0],), dtype=torch.int64)6 j8 U" d  \/ X" l; e/ l

4 B! F, g8 O( j2 Q6 ?3 a

: w% M7 p$ W, A6 V        labels = torch.as_tensor(labels, dtype=torch.int64)
0 }( t  u' t' N6 J7 p
! q4 A1 I: L& F1 ]" V* D( t6 N) B

1 u/ `- y2 e, v        target = {}
  `5 t5 _3 T3 A% O) G: k$ Q: z        target["boxes"] = boxes
* D9 q# @0 j* t+ ]0 {        target["labels"] = labels* ~6 t" `  @) w( ]
        target["area"] = area
6 n9 f* s, M" v3 m6 f/ y        target["iscrowd"] = iscrowd; g$ P+ Y! I0 y7 f  p
        # image_id
, J. u' O. \2 @0 p# E        image_id = torch.tensor([idx])
& x4 d4 H  ^$ k; [3 c' ]1 S        target["image_id"] = image_id
7 r. A5 k9 ^: I, `, g. k9 A! s
; h, s( i( j, Z- v  z2 A2 ]

$ P  Z# ?. W1 R  Q        if self.transforms:
3 v% A: B& F9 N. A' |            sample = self.transforms(image=img_res,
# n7 h- I$ X4 b4 I3 b6 p. g% y                                     bboxes=target['boxes'],
6 S4 k* a# N, X9 [7 @0 A3 I                                     labels=labels)- e2 X  m: H3 s$ O" d8 x8 _

: I% y5 D7 u* ^! L' I0 \( f$ ]
2 n# h# Q2 l  P5 q. G
            img_res = sample['image']: X# `" ^: q' r0 K" u7 t
            target['boxes'] = torch.Tensor(sample['bboxes'])
/ B. \/ @2 ?1 n) T6 e% l& J7 S  n! k% ?" c; M' Z8 O  j

' {. o( Z0 O; q" B4 T- T        return img_res, target
% O# q( l( Y% F/ o( V* P3 C9 B! ^% E2 J: ~5 T
5 |/ c0 L- `: Q5 r) H9 V
    def __len__(self):
* _" {/ U; ?' z8 c6 }" b        return len(self.imgs)7 f( c, k8 d3 F/ |
$ E7 f! J* v# Q. }& [  v1 w
! n: e& h( q; D. k/ p
# function to convert a torchtensor back to PIL image
, B( l- B7 c2 Idef torch_to_pil(img):
9 X3 v0 @  {/ Y3 J  D5 t3 R& P6 {    return torchtrans.ToPILImage()(img).convert('RGB')- X1 O# E( [3 f) ^/ r+ C
5 _  p+ m; |, S$ x' N

- Z" h) W' Y% x
& H$ j3 z% c; j6 E! A/ ^

+ i& L" H3 V  s7 y+ X- Tdef plot_img_bbox(img, target):
7 J: N: k9 A' l/ |    # plot the image and bboxes4 N& c/ K8 t  z+ b- @% o2 |
    fig, a = plt.subplots(1, 1)1 b) m8 j; u$ M, L5 d: h/ s8 B( \
    fig.set_size_inches(5, 5)# P+ u5 T  m9 ]% C& L
    a.imshow(img)+ I  v: ^7 Q3 [9 n
    for box in (target['boxes']):
2 _. G6 c& l- m) U) C+ d7 V' h        x, y, width, height = box[0], box[1], box[2] - box[0], box[3] - box[1]; Y. L# X. q9 R9 d# O
        rect = patches.Rectangle((x, y),
7 J4 ^- v- T, l/ L% {                                 width, height,+ I& J# Y. T8 J
                                 linewidth=2,8 l3 Q# b- \+ |. j6 I- ?1 Z3 _
                                 edgecolor='r',. C2 B4 p) k' d( u3 i
                                 facecolor='none')( j. w; J- ]: |. R( i

- `, u3 z. `, |; |2 V: S8 v
8 P: @. A0 @0 ?8 F! X9 E  c" D9 @
        # Draw the bounding box on top of the image
( }. j7 Z; I: K        a.add_patch(rect)
; V$ C  ]1 i1 K9 a% }. N    plt.show(). d  [6 P+ c9 M" @7 [. `/ X1 K
! Q3 s/ c8 u# b; O

5 L  u' y; F( j" ]& }
' J! v+ m% G9 l5 n: z/ F
' @1 N8 y2 Y% G% w: s3 C+ Y$ _  N  y2 W
def get_transform(train):
- g4 i3 x; {7 c, t    if train:9 o9 l3 y. X# c- _3 Q4 M
        return A.Compose([
+ U. G' k; T  u/ k            A.HorizontalFlip(0.5),
( j+ S9 S: R, b4 O* Y/ r1 N4 Z- y            # ToTensorV2 converts image to pytorch tensor without div by 255$ F! o1 a( E- w  m8 Q6 D
            ToTensorV2(p=1.0)
/ A2 w3 ^+ U9 j& }+ s# J2 g- g' |        ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})
7 p3 a$ P! y4 ?6 o. f    else:
- K- K/ i7 U$ ^  K& S2 a        return A.Compose([
- f6 g! B3 a3 ]2 i0 T            ToTensorV2(p=1.0)+ ]: m5 x: m/ c! E- |
        ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})
6 L/ g* ]/ T! ^/ Z) E2 c/ h0 Y# E) [' {
4 X7 o4 X$ O: L9 N& ~7 Q

5 V; t4 F# K3 `! K: {. T

2 @$ @6 m% h" l/ s9 k1 [2 B
& }9 ?8 j6 m$ L' O
( `& l7 d% u) o* C3 c0 i
dataset = FruitImagesDataset(train_image_dir,train_xml_dir, 480, 480, transforms= get_transform(train=True))  L/ Z4 e2 m( Z; T+ C0 w1 D

% j9 I+ A& N9 Q8 x8 |
$ e# i! ^: s, |. k& B6 \
print(len(dataset)): v) ~2 B: D+ t
# getting the image and target for a test index.  Feel free to change the index.2 j* ?+ P% Y9 O
img, target = dataset[29]
: a1 N+ A$ A% a% R( N. eprint(img.shape, '\n', target)
  ?* G2 _' q1 O- J' cplot_img_bbox(torch_to_pil(img), target)  J2 [  D; N2 Z! z; s! H+ b
1
, y9 H! z. K( }) D" ]% D/ }* J2- A; y" K0 [: e$ B7 s% `- R
3- E, ]1 p0 c& G0 \9 d
4+ N" g! f, v- [1 I1 A7 J
5$ R2 M; }: d1 C( c+ K  q. |
61 c7 v% b( v9 I5 `7 C
7
0 ?2 [3 J* K8 [/ h, l! B+ G80 i7 o0 u9 t& v, E8 b/ Y
9& J6 a8 w: ^. I3 E% P
101 d& c( o6 x& y- l. H7 Y/ J
11) T( m8 w* @1 Z( E  w
12% E; P7 J) L/ f, ^- z
13
7 J2 W3 A/ N4 V  n/ ~! [$ f14$ _& X0 R1 M- S( V) w
15
. q, y+ m% j& C1 I16
0 f$ l9 M0 Z& @! T17
$ q0 X8 r! O2 v( k+ o0 U! p7 R3 x6 @18# ]" y. b) @- C; t: X/ I
19
! `2 s' e3 D4 F1 z. p. K5 X20
+ v6 y: [4 v; j. B/ z, s21
+ o' b5 f: Q! Y" {  p* j229 B6 p, a3 P& S  ~. R/ u  o& A
23
/ C2 Y6 f$ d8 B" B' d. [24+ V8 [2 t% _0 F+ c  I( m
25
) C$ H9 P+ L) b( y- i4 {& m3 ]26/ G9 \. E- P0 Y: w  Q6 o! ~
27& t$ W1 m( o( D  S" M# Q0 s/ X+ r; V! h
28. l& V8 `# D" F8 W
291 o( S" a; ~* c  z8 d8 n
30, I- T# k1 z& \0 J% N6 V
31
: g+ U% v* M) y2 B, J+ x32
- ^' G" l: q% J9 E337 Q: R6 S' c( A* v1 N0 l
34  v* Y' l3 B% X9 A5 ]9 W( \- o6 e
35) v6 H/ B6 v9 |1 i3 X
36
% U# \! d2 L5 J" u  L37
* k* n6 l1 w$ Z$ o2 J8 O38
, a4 o- F2 {( r! W% y39, d' Y3 q3 I' P* _) y& i8 {1 B
40
$ s- R7 P4 H$ {: G. w41. q6 D7 h: Q+ c
42
$ H! d, W, L0 f; ?43, V- F% p6 U& m- k8 Y
44% G9 _. K/ ^2 @
45
& j- u& W9 a6 @4 v46, L% V* C2 ^" V- Q
472 M6 F8 K! c( a9 M* L
48
( Z7 e3 P( D* d5 F  r49. n. q0 r# n$ ]) i1 ]2 p: T
50% h# p1 S$ A* \) j, F  O, W$ p
51
. V6 B/ s# n1 _# H! B, [524 C& u2 w8 h, p$ u* O- i
53
& l: t- S  d# @54! c5 A0 O4 x" p% R3 v" K! K! k) m6 W# ^
55
3 _9 h& l, m; O- T' G+ o3 a6 f56
% p# ?( m% \0 I9 O57
* E; p1 G8 ?" a3 [# d58; @  G/ n. m  L7 l* c* a8 e
59
! b" i6 Q; h; P* d/ E; T5 M' L. [60
' Z+ k5 e$ `0 I. Z  R& |2 d5 O0 L! ]61
% W5 Y' g7 Y, t62" M& i4 v4 i$ t8 A
633 w& }" f& G1 a9 M& s
64# P$ v0 [8 r. [9 U# C
65  A7 q' n3 o' x+ g% s" x
66  [2 A; |- k; G  {# z+ D& u1 I, t
67* I  o* d  F6 ]' S( H7 K2 H6 n
68: ^; v, Z8 ^9 }* s. o& L& @. d
693 o+ ^: _& W' f5 E
70+ v) a6 G7 u, I: X6 a3 W1 S
71
4 T) J- b1 X* }+ @+ \5 A72
2 P# ]9 I% w( }, O73* N( _$ ~+ N6 i, j  b: Z% Y/ X% c
74
# |3 _0 j; Y* p, y1 v% d; f75
  H, ^- A& J8 d. @76
! b. }9 `9 f4 I77
9 o- [, H, I% S5 x78/ g, A# w8 V& Y4 M3 T% W8 {. U
79
7 Y! g9 M  B# n3 [; Y2 E7 Q80
* t( g% i5 G+ c! C4 e81
% S+ s$ `) J6 J: O; Z+ D82+ ^" T8 h% s- @. U5 g! |
832 |7 Y; p& g: q* h: P/ Z
84
9 K1 r# T/ D6 D8 R- _85! i* d- T' K. v
86- ]2 G* s, c  z* V2 O% W
875 [# e0 R/ a3 h/ v1 t
88( O, m( v& y+ n$ u6 K4 V9 w# c0 y% s  Z
89& M1 B  d5 H3 r' a0 c
90& I. Z, i* X1 O
914 j- f; A3 J( W6 ?
92+ ^$ w! J$ \# f2 _3 J( s' `% g
933 n% ]7 y/ `9 W5 i- A- I
94
! D2 `& o% g$ g. h9 {6 T95. o  w* f2 ?, k
96
$ b+ Y* e5 _' g8 e! g) i6 \972 p7 r5 E! i8 O: n( p$ I+ u. E
98: \1 P* M1 U. @) g+ v
99
* w* N+ Y0 y  r% m4 r( P- h) R1000 F1 ]3 j) F$ I5 ~
101! h; c2 {0 a1 R9 h
102
; n# m8 \5 Q, ?9 D1 m3 O3 Y103
( {" D* D7 T) D3 x" B+ ^104! V( C7 N  q, \/ R6 _8 c
105& O: }5 ~% n; h
1066 i. J3 V, ^3 n- [1 ]+ }
107
. {" j, y& z7 v108
& c0 L) R( s2 F# q9 F109  P  h7 |/ e* V
110
: x3 V5 U+ w. k0 X111& ]6 F+ e( B- u2 s
112
9 n8 Y5 R. r8 h8 s! [) h! p113% r* I% s: X3 W% P2 j% r* B) Y
114" z9 I2 {. G) J+ g5 c
115
/ S$ I3 E! }" v7 T0 w8 A) k4 X: s0 C- u116
: Z  _+ r3 W8 W3 \9 K117
; [3 y, j+ ~  |: S118
- |$ N" G' V' b$ O! U: ~119
4 w, ~7 R/ l) D; K120
+ G6 [; f  I! m1 C! K; a2 D121! b: }0 ]# q: h$ H* J; w( H
122, i% p6 t2 h6 R; E7 B
123
" |( Z8 X: k2 `! N1 X6 Z124/ C, {3 Q1 Q% ?3 U
1258 q6 q* h; ^% w' ]* ~1 F" e( C
126* w9 C/ |# A" Y* ]" c' i6 J, x8 H' V
127
! V" C. p9 X: J4 M- s7 l) G' y$ I128
* t/ N4 i5 J# B$ r6 n' t: f129/ ^5 q4 }9 I7 C, R" @8 t) T" e
130: m/ \4 I4 }' q0 A9 X
131+ x( r; W' `4 [
1326 U) L, D2 w8 a' M
133
& r+ ]& m' R7 a8 A+ V134
9 x& y# ?  \( P( p4 m0 d135
1 j% h# u' B- u: ~136
/ j4 ^, U8 L9 K/ [" |9 l! P137
% b, {* g2 N+ }4 r, H138! s+ T- A, h: E0 x) t8 L1 w
139% }( |9 K* i! k1 y9 p
140
- q4 D! [8 O( ^' z: \141
+ M, s' l- o: \  l  X! ~142
0 I/ Z0 q& Y6 a9 Y/ D6 d+ T  ~$ w143$ c$ K3 P" n8 Q- d
144
5 Z: T( J, ^/ Y$ v1458 }% F+ R2 ~$ T$ \% e# Q% E5 J1 i$ r! Q
146
" P7 n4 M8 C: [4 l3 i5 c1 e* p7 F1478 J* s5 C/ y( J5 m
148
. J# a. [8 O& B149
& t- ~+ D/ ~, |4 V150/ T, O. k) ?6 W# w8 z  a6 Z
151' g0 Y1 \/ |* n. r* v# g* t
152
5 I4 c" ^" i% |5 @2 Y153& P. o( D6 V2 b' d8 R  g9 D
154
0 p1 u7 \' \0 G: G; d, _+ J+ y* ?" V155
; z% r! f  L0 s& S% a" A156
0 J& D  q2 S% ]9 L; D0 ^( v输出如下:6 D2 ?7 [* b. `/ p; h/ _+ i

# e5 {7 s/ e' g# G5 q) A0 x

! y9 D: m% H4 n% Gtorch.Size([3, 480, 480])
7 @. m% v* |9 d7 _0 f# |$ f/ k {'boxes': tensor([[130.8000,  97.8000, 327.6000, 292.2000],
7 C' x, M& [; e0 u' c        [159.0000, 268.8000, 349.8000, 427.8000]," y7 d+ F5 Z( x1 r! z
        [  0.0000, 282.0000, 118.2000, 429.6000],4 j( o: `' ~( j1 d4 x! O- Z2 A4 c
        [ 43.8000, 107.4000, 199.2000, 280.2000],
9 T6 S2 r  Q  S+ w5 ^8 C        [295.2000,  37.8000, 479.4000, 248.4000]]), 'labels': tensor([0, 0, 0, 0, 0]), 'area': tensor([38257.9258, 30337.2012, 17446.3223, 26853.1270, 38792.5195]), 'iscrowd': tensor([0, 0, 0, 0, 0]), 'image_id': tensor([29])}
6 P/ t, N8 v; r, S) U2 d1) G4 N& [: w9 Y$ u, ~. @
2
! c7 g$ u1 P# \* U* u6 o( C" B3, d, m4 t4 O3 @- I7 c
4$ c  m, R3 ?5 A$ w2 t0 c& `
5- M( V, Q0 R1 _/ C& S% C# @1 _/ C
6
! Y) v; W/ f8 O) {( t
+ t# k1 b' K$ q8 s

& C6 k% t0 R- b5 a9 t2 }; D! K6 x& Q3 G% A4 c
' p) y8 C8 \' l, O) E9 C% {; I
下载地址
- X, e9 M" }$ R  r8 y链接:https://pan.baidu.com/s/1QZDgeYTHyAlD2xhtJqZ-Yw6 Z  a& t: f% |& G5 g/ I- `
提取码:srjn9 _6 V6 k! Y" x2 A/ k
————————————————7 X6 \0 U, o( h- L
版权声明:本文为CSDN博主「刘润森!」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
) f4 k2 F: J1 ]5 k2 ]9 L2 h2 {原文链接:https://blog.csdn.net/weixin_44510615/article/details/118496273
, b, i$ |: S; A* O9 M5 b" K$ t7 c8 Q- n+ \

$ Q9 k% [7 m' a' M




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5