数学建模社区-数学中国

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

作者: 杨利霞    时间: 2021-7-14 15:18
标题: 深度学习和目标检测系列教程 8-300:目标检测常见的标注工具LabelImg和将xml文件提...
1 h8 ]/ V- \% ]* p
深度学习和目标检测系列教程 8-300:目标检测常见的标注工具LabelImg和将xml文件提取图像信息0 N; E5 R$ w5 V& ?
图像标注主要用于创建数据集进行图片的标注。本篇博客将推荐一款非常实用的图片标注工具LabelImg,重点介绍其安装使用过程。如果想简单点,请直接下载打包版(下载地址见结尾),无需编译,直接打开即可!
8 Q8 a" @6 P( ]  `1 A8 |. r( C6 }' P+ B' ?! o5 c

. W* W% g5 B2 `- `感谢原作者对Github的贡献,博主发现软件已经更新,可以关注最新版本。这个工具是一个用 Python 和 Qt 编写的完整的图形界面。最有意思的是,它的标注信息可以直接转换成XML文件,这和PASCAL VOC和ImageNet使用的XML是一样的。
0 B/ K3 }, B( N! E; m6 k' N
0 \6 G0 s2 f# R
! r5 u* o1 N6 u: u. e6 ]
附注。作者在5月份更新了代码,现在最新版本号是1.3.0,博主亲测,源码在Windows 10和Ubuntu 16.04上正常运行。0 i8 h2 f/ }, t' U+ }

" a$ l9 Y! d& ^6 s) a/ V
1 G6 ]! {. z5 o' ~- w
具体的安装查看Github教程:https://github.com/wkentaro/labelme/#installation
$ ^- X3 o) k5 I2 S' s- x  Q6 h+ _  W  ]( o0 f
3 z/ u9 X" I/ A  z
在原作者的github下载源码:https://github.com/tzutalin/labelImg
2 }& q: S6 \" A9 q0 d( k+ G) I  n" r& \。解压名为labelImg-master的文件夹,进入当前目录的命令行窗口,输入如下语句依次打开软件。  R. P& i! l2 f* L& e
, N3 W$ J# @: m
1 f, e: `7 [7 V3 K0 h5 x
python labelImg.py
$ @$ q* D- I5 E1/ m5 F0 |. a- u! S

$ Z' F7 U1 s( T% H9 L6 B
4 N2 z: \  U2 [! C$ b
% N5 }3 o% G. k3 G% E# g% B

7 N- n: n) N1 E* z: j/ k. M2 O8 j2 Z具体使用
) S! k1 X/ z8 c+ a0 L) v0 w* _) ?修改默认的XML文件保存位置,使用快捷键“Ctrl+R”,更改为自定义位置,这里的路径一定不能包含中文,否则不会保存。
2 B; X" `4 i+ p
9 I7 g* F- ], g2 ]. P& `" @

0 E2 H4 A$ w- i) w! y3 ~6 g+ u使用notepad++打开源文件夹中的data/predefined_classes.txt,修改默认分类,如person、car、motorcycle这三个分类。
" T+ V: I# f( t: b7 q9 v5 ^+ c- I& m+ v! ?, M! [) f* T& V
6 k* w9 v0 _0 n7 i! O
“打开目录”打开图片文件夹,选择第一张图片开始标注,用“创建矩形框”或“Ctrl+N”启动框,点击结束框,双击选择类别。完成一张图片点击“保存”保存后,XML文件已经保存到本地了。单击“下一张图片”转到下一张图片。
/ J7 n! i0 S% H  v  a$ O2 a& [8 m( R$ I; _, y! ]* B( c, l! R! r

4 ~6 r# _8 f% W  F贴标过程可以随时返回修改,保存的文件会覆盖上一个。  {0 |; J- H/ `8 ]* [& Y5 n
' e) q( H, m/ N1 c! K3 ]
" X$ T! A& d( g1 \* `6 H5 o1 \/ a
完成注解后,打开XML文件,发现和PASCAL VOC格式一样。. E/ ^; ?. R% N0 S# e
( e4 Y' t. v8 Z' {

3 X) U0 r$ j# r/ v2 j% @将xml文件提取图像信息
) {, b/ @/ n% t& V. `6 ^下面列举如何将xml文件提取图像信息,图片保存到image文件夹,xml保存标注内容。图片和标注的文件名字一样的。
7 U: c. S6 ~9 X1 l$ Y9 t7 r3 h2 t( @
0 w/ b/ Y' l! [/ A2 m5 d  G
9 A) P. }; I" F) A; A

8 o9 Z6 \0 ?; H下面是images图片中的一个。) ~6 X& Y% [) m! |% m# @5 H4 Y( m8 U
4 @) X* e5 i! z) ~  E, P
3 M# T4 h; e8 _' ]* D1 A! L
下面是对应的xml文件。
4 x) h2 i4 I; Y2 u; t4 p) S$ A9 u$ V1 }

& q4 P( g, l2 L( `<annotation>
, P4 _; f" T9 V9 A9 v/ f" P; s. c        <folder>train</folder>9 V/ Y. |" Y. B0 s# T( ~! H
        <filename>apple_30.jpg</filename>4 y7 N: w3 |3 u5 \' D
        <path>C:\tensorflow1\models\research\object_detection\images\train\apple_30.jpg</path>
  W1 i, w& I9 r, h, t2 Z        <source>
9 Z5 s/ Q& S# Z  A8 k0 c                <database>Unknown</database>3 Y" }$ r2 ]2 J1 g. ^
        </source>
; a1 C5 c( ^* i        <size>& L) M8 @3 t9 o8 x# F% k
                <width>800</width>
9 B! z2 P8 W0 @3 r! y  V                <height>800</height>
' l, F: X# E: ]3 x! }" L                <depth>3</depth>
4 V% O5 P& B$ {. o        </size>
, N2 u) _- y! l$ Q; Q# [1 d4 Z        <segmented>0</segmented>
3 h/ s5 t0 Y5 Z' Z8 a/ n7 \# z        <object>
: E# u; z" X! _) `5 I' c                <name>apple</name>
/ {" y3 ~( v* s8 }9 b/ T* D                <pose>Unspecified</pose>% ]4 O* p1 T  c6 y- M
                <truncated>0</truncated>
3 t4 ?# c: Y5 A2 e6 j7 E6 e0 z                <difficult>0</difficult>
  A0 t% `$ a2 S, p/ N                <bndbox>' j; n8 B% L5 t5 M
                        <xmin>254</xmin>
2 `9 S- W" I' o4 ]* M. d- K4 R+ Q) j                        <ymin>163</ymin>
/ ]! y  n! Z+ }9 {5 a' D$ O                        <xmax>582</xmax>( t% N; |; E1 Z9 L0 ]3 o3 {' L$ G
                        <ymax>487</ymax>
6 A, x. F: X% Q" q; t! C7 T                </bndbox>
$ l& N7 w4 ?+ z  V8 `% C% ]        </object>! Q7 l8 O; b5 R  G; l" V2 \
        <object>
; \3 [+ T2 h$ T0 G                <name>apple</name>
+ e1 d; ?: D6 c  _8 O9 u9 N                <pose>Unspecified</pose>
# S) s- C/ L, t                <truncated>0</truncated>, }% _0 M9 O/ B/ @
                <difficult>0</difficult>
% C9 J6 D" y- {2 j! _' M+ r                <bndbox>) [+ o5 |1 u7 a! ]
                        <xmin>217</xmin>
- Q9 W9 ^4 q8 \* A8 B3 D: p, w% |                        <ymin>448</ymin>4 G9 I4 d* `7 Y5 I
                        <xmax>535</xmax>* e7 h& y. ^. O4 Q3 u
                        <ymax>713</ymax>
" s( W3 l, U& q5 A1 R# r                </bndbox>
: X# Q! H6 V3 A$ s  R% h        </object>
& V4 \; E, ], g6 X2 w        <object>
; t. R- O) N$ V. |% k                <name>apple</name>2 V0 M' \$ o& e9 p% L, K  j
                <pose>Unspecified</pose>1 Z. L% L0 \0 h8 k: ?
                <truncated>1</truncated>5 ~3 C) A1 Y# S& @
                <difficult>0</difficult>; P* f5 B9 b' M5 o/ E
                <bndbox>; S0 U2 v* w: Y8 o& [
                        <xmin>603</xmin>
! Q, ?: \! ^9 l* H- Q, I8 l                        <ymin>470</ymin># S1 u+ w" B: K8 k, L( O- k
                        <xmax>800</xmax>6 H  U9 x6 k7 w+ J' q) e
                        <ymax>716</ymax>) g* }# c/ K' c  h1 ]8 N
                </bndbox>0 h! a5 V6 r2 {- T9 W; I
        </object>2 r# D! l4 g( M6 L% t; j: e
        <object>8 `0 `+ {$ w. Q& d: b6 r) T9 b
                <name>apple</name>
4 c6 c! r7 Y- J' X6 C* W' Z7 d                <pose>Unspecified</pose>! u  g0 L: Y- o& f' J* U) r+ m$ v
                <truncated>0</truncated>
6 `2 ^. ^5 S! ?                <difficult>0</difficult>- e+ i# Q/ r) {& O9 b$ D# N
                <bndbox>: \/ ?0 c! }  Q4 _# O* {8 C
                        <xmin>468</xmin>
% Z  T+ ~( i9 V9 o  `7 d6 L                        <ymin>179</ymin>
4 j. R* }- J; A' o( J, G4 P                        <xmax>727</xmax>) k0 K1 d# ^, z: _* D
                        <ymax>467</ymax>0 z1 {6 c! [1 o4 c3 G2 R
                </bndbox>
+ c. ~' H! e0 P* ], ?: t# r; R        </object>1 B  k/ ]4 F: D! U
        <object>
& W9 s8 Q) P8 Z2 Y' a0 U7 Z8 z/ \2 u                <name>apple</name>
7 y4 J3 t5 p* Y* A- c& b, Y  o  m- j! ]                <pose>Unspecified</pose>
' F, a: |2 b6 T+ _! r  y                <truncated>1</truncated>; O8 K! Y0 t# F+ Z" o* }
                <difficult>0</difficult>
3 D- n  B7 n4 ^- b                <bndbox>) F7 t" ]  l0 }0 w' n' t
                        <xmin>1</xmin>
- f1 p" o" I: L  [: m3 l6 T0 M                        <ymin>63</ymin>. b5 W9 e8 W$ C( D
                        <xmax>308</xmax>3 ~2 E$ ?; B& \; w& F
                        <ymax>414</ymax>
+ P) S  ~7 F9 s9 W- W/ O5 ^8 a                </bndbox>
$ h$ G: I2 G- ^: L        </object>( _/ _. S3 W* h: c, x5 G  B
</annotation>6 `# o, W% {7 r1 c1 ]
1
) G# G2 @! W- E: Z' g4 p' B( w2
& [3 K6 a* |8 ?: F5 k  f3* y; q% S7 w7 V# r7 G+ @) f
40 q0 ^) E  H0 B0 t
5
: O. r- d2 C0 q* j" d6 g" w! s6
* i, @$ s) C! ]/ Y1 @7/ I/ {/ c6 f" [/ L
8$ i/ D: M0 f/ G' r' P
9; H& l4 q) z( O0 b' `, q/ P" e
106 _$ o+ M5 u9 A
110 d; |: w2 }) G7 X3 a* y
12
1 E# k0 t" d- W/ s13
; H% O" A: }3 Q# r" x+ R146 [$ F1 O2 b1 W( U6 [- Y7 F
15  \- T' r! d+ K+ Z! a0 n
16
$ p( `2 g) F) a4 y( }  M' P" E8 x17
% s7 F( c, s1 K  K+ I5 }18
7 r) _- t) {1 T. [! \19& L1 c7 t" t' y9 j" @6 \9 ^2 ~
208 o; p+ d3 t0 |# _3 B, y1 t  D$ K
21: _' `/ |6 Q2 Y' J3 t) S  t
22: R9 B' L- ?6 V2 ]5 Q
23& G- j/ W2 F$ H$ P/ |; s
242 f/ X: C2 r! I( K) S% d3 U
25' }8 H& y5 k' s# p* n
26- f4 m0 W0 I& Y% R2 M
27
/ n; z, T3 Z! @( C# Z2 y. z28
. Y4 X$ |3 ~; i+ o- \/ P" Q0 F29
9 U; d, U& X" b) ~, w5 l7 Q- J$ E30
5 E5 M0 V: e& H" W" p31  v, ?$ x" \: Z% M6 l/ w" U
32) X+ {4 p6 E1 R. R" A+ |4 e! G  @
33; W- _. K" b+ G) ^
34! r$ u/ p3 Q$ P: L  O
35
. l& X5 G  l# O6 R7 q5 A1 e5 d36- Z- I. x* |6 U7 f2 P! X9 @
37) W2 K+ u  }. `2 e9 J  |
38
  L" J4 V2 e! P. H39; ?. u: o  Q% o* v) j9 p3 [3 |! i; k
40
5 a' L9 m( V" T- S41
  t# ?) f, {" q+ K  l42/ P( X& K+ t: ]) I& W! F
43
/ n4 K- |1 n( o0 s7 G8 l44
, {" @, B1 c/ v+ U" _45( }* L% J; D; K7 i
466 D1 u6 H9 }  e! P' w* T8 A  \
470 y1 x. S/ b8 K
48
8 B3 q2 d/ w8 `' Z& ?3 X) l49
3 A' i; a$ x; m8 b$ x: \50# @/ N; {" [& H1 F# E0 B; K
51
9 {" {) v' ~4 Y52" I/ z6 q) W" \! W5 o% E" g$ j
53
7 E5 z! ]& N0 W54
1 v6 D- i+ I( Y55
$ L, A" W2 J( o. @% m3 K565 e: O$ v: x, W; o+ ~) Z
57, C) w6 l& W. Q0 G4 R
58
3 T' T: j1 D% X0 H: G5 d591 o0 J' D; J+ l9 j, }1 g/ d
60, {  N4 e* L" t& B# q' J3 b
61" B( H# u* u; `
62
: I' D9 H' @0 C" j8 w% P63  f" d) y$ e' O
64
( z& [# i+ n' m# ]4 p65
+ _, i. ]! [) c7 a. Q* R( g66: b8 J9 K6 N' o* j$ D% [; H
673 n- V5 ~* g5 t8 H* Q4 {
68! _' ]9 A" O! o4 @: t' ?* ^( ^  [
696 c& U% J6 Q8 M
707 o& U/ M' {7 a- h
71
2 c9 @5 {( D, q72- m& f3 p/ a5 I( X" N% v/ d
73
5 x0 L" L/ l1 M74" H6 l/ f1 f" q+ }& g6 Y$ B' p) ^
将xml文件提取图像信息,主要使用xml和opencv,基于torch提取,代码比较凌乱。' F! K; a/ O; e7 J/ w
$ z. d5 ?8 Y" A. O6 L# Z

8 p$ \# {; J; A8 {& Q0 n, [2 bimport os
2 z; U0 ]5 U) z" n& I( fimport numpy as np" ]& H% G) k. E5 h  ~. q8 U
import cv2% C) y! H3 s; P+ u$ Y
import torch% w/ b4 ]' I& l) Y  i9 a8 J
import matplotlib.patches as patches5 J, ?& ]5 U% M* _, n
import albumentations as A' i/ [  I8 l) e( j" m
from albumentations.pytorch.transforms import ToTensorV2
* T% V8 q. j" O4 x' Rfrom matplotlib import pyplot as plt: i% H- X! W$ V6 T7 q
from torch.utils.data import Dataset
+ O5 H+ t" X7 @) _  a) L% Lfrom xml.etree import ElementTree as et: H0 y: `$ l& f- y4 D0 ?
from torchvision import transforms as torchtrans. T) K& [: N; M; m0 D. N  ]

& }. I/ r& }- N3 R& G  p9 _

7 S- V5 o* b. Y; r6 E6 v  o# defining the files directory and testing directory
8 e8 A1 v! @: w) F  M' t$ u) ptrain_image_dir = 'train/train/image') V2 c$ @% d4 O: _% S: u5 w0 W4 }8 p
train_xml_dir = 'train/train/xml'8 r3 T0 y. B8 ?; T: C, X
# test_image_dir = 'test/test/image'
  t) J* `! ?+ ~+ S4 O$ R, ^6 }6 Y; k% K% o. y# test_xml_dir = 'test/test/xml'3 ~+ Y  ]2 ]7 k0 L3 h3 t

! [- I& b  [6 i1 s! S+ Q

; N4 C. o3 q* |+ @3 x, y0 W7 x. c0 X3 pclass FruitImagesDataset(Dataset):
  ?9 a% j0 \- _0 r# J& A; S& A( a  u3 R1 C

" U9 s* u' r; `% m6 J5 r( V8 |    def __init__(self, image_dir, xml_dir, width, height, transforms=None):8 X# x8 d! G7 f* `3 t% J; o' m
        self.transforms = transforms
; S% n* V) Y. c4 u$ A        self.image_dir = image_dir1 M8 F% S; V+ C5 d- R" ~1 W
        self.xml_dir = xml_dir
% @# Q5 o# ~( E1 g* k9 B        self.height = height6 i+ I. G+ s8 h: ^/ c# q7 r* h
        self.width = width: Z( b4 X, w- Y
. o2 D% y" L2 N/ w! W' J

  B" S* {4 f) s/ Y4 H/ ?        # sorting the images for consistency/ `+ |  j5 Z# U' D
        # To get images, the extension of the filename is checked to be jpg! P5 b* T; P/ y( [+ d
        self.imgs = [image for image in os.listdir(self.image_dir)
( M/ J3 k) ~# u  s( i8 _. ?  u                     if image[-4:] == '.jpg']
! x) |) L! l0 B: V3 ]1 V$ U        self.xmls = [xml for xml in os.listdir(self.xml_dir): A! Z( t+ j: ?6 m0 D& S9 t
                     if xml[-4:] == '.xml']
# H# h- R9 e( z' S" C2 B! b! F' j4 u: F, |' v' V

$ L  B7 {9 R1 F% k( }0 T        # classes: 0 index is reserved for background
$ u' E5 t! K% e0 B0 D7 b5 \( Z        self.classes = ['apple', 'banana', 'orange']7 d: [9 C+ c5 H( E& p

& [+ @1 D7 @" w( \! H' ^5 p

0 @+ \+ o* }$ Z# u    def __getitem__(self, idx):
& d9 ~  r6 L/ @/ Z! d, I: n& y% K+ t7 [
6 D+ p: R/ i8 d. {6 a% c
        img_name = self.imgs[idx]* l0 _. A$ ~- U  l9 [' i
        image_path = os.path.join(self.image_dir, img_name)
7 Q$ G+ f: ^/ @& m
* ]" Z( |5 O1 a; Q$ Y
5 G, k. L  o5 q4 ^
        # reading the images and converting them to correct size and color. A# l/ [* g5 F; Z
        img = cv2.imread(image_path)* t4 y* V% A! ^0 l7 p& T
        img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).astype(np.float32): K3 L6 R- r" F! h1 W" h; |4 |
        img_res = cv2.resize(img_rgb, (self.width, self.height), cv2.INTER_AREA)
: t% U" G6 M9 }$ t% {+ N        # diving by 2554 J  b: K* P) `& P4 g8 F
        img_res /= 255.0% j" u' w/ h) B/ N* D. g3 k( ~( H
9 L3 i7 ~4 n' \0 M1 W1 I

5 y5 l9 C9 q1 S- {( s2 n        # annotation file
( I$ z' R7 b& G. T2 }6 w        annot_filename = img_name[:-4] + '.xml'+ Z; q% R2 r  Y* t7 }
        annot_file_path = os.path.join(self.xml_dir, annot_filename)
: T+ @. m- k# s* [
" t* L3 R) ]" w, [4 v. i
/ |. N5 ~+ Q) F+ ~0 w  D
        boxes = []
1 b+ p! R2 j( t* r* k        labels = []
' X' ^0 |* [5 v! Q) M  g) b        tree = et.parse(annot_file_path)6 J( p5 N, [- Q8 U2 P# Z
        root = tree.getroot()0 L' Y- z1 c8 }! i
! k7 w- j2 }0 n8 ]" c/ r- Q) O
" W: J/ c3 e1 l; ?; q! l
        # cv2 image gives size as height x width
! g4 N' R; Y/ |3 l; ?        wt = img.shape[1]
7 O% j# D) S/ b5 p        ht = img.shape[0]* [$ A- s$ q- K1 P# b
# K( R' B% X; [6 d

& v* ^, X$ E) r( a0 ~1 N- r( z        # box coordinates for xml files are extracted and corrected for image size given
2 A8 s" [6 N' i0 P        for member in root.findall('object'):
, q7 z% \7 z4 q. H. {( A) C5 x. E            labels.append(self.classes.index(member.find('name').text))
/ a$ y* k& b: V
. v: h( n) t  x. G, z' a
3 v. E7 v) o2 N$ L- o% j8 t& ?' s
            # bounding box; ?" a# _# l; l% ~1 S- d
            xmin = int(member.find('bndbox').find('xmin').text)
* l/ D' t; U7 ]( o            xmax = int(member.find('bndbox').find('xmax').text)0 ?' X% S$ X9 _# w( G# `

9 z4 ^$ r; k6 S7 w# A
/ G  s% ^* c, _$ D+ P
            ymin = int(member.find('bndbox').find('ymin').text)
$ R+ a" ?2 a! l1 I6 u8 U            ymax = int(member.find('bndbox').find('ymax').text)! S- [$ f" a- v& N) q9 B

; J: V9 S0 G- q% s: j) }
1 j( @+ x! }+ d/ }2 I2 l
            xmin_corr = (xmin / wt) * self.width3 O6 t8 ~, h& l" r
            xmax_corr = (xmax / wt) * self.width
) P  F- C! l+ o  F0 m) x* K# m            ymin_corr = (ymin / ht) * self.height
0 X+ D# J' p) A$ F1 Z( N5 P, A            ymax_corr = (ymax / ht) * self.height6 J0 A  [1 U  u9 j5 N- t
            boxes.append([xmin_corr, ymin_corr, xmax_corr, ymax_corr])/ N- i* X& o$ r! M3 G; W

1 i$ X6 n% ^! @* ?5 i( C

9 A, y: S$ g0 a% J9 J) z        # convert boxes into a torch.Tensor
3 ]  I# Z: _4 S' A+ {& L* k# }        boxes = torch.as_tensor(boxes, dtype=torch.float32)
1 m1 t& ], G6 ]" {6 c9 G9 t8 W/ i0 b- H% @0 k
5 e8 p, ?; I' _' x
        # getting the areas of the boxes; @  n; U8 }# @$ a% n; f
        area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0])! {. i; g3 p3 L& x( ?6 n" i9 \8 ?2 [
# K& q4 q+ v+ J5 H
7 o. s# Q0 o, G( t! X0 T% @( s
        # suppose all instances are not crowd3 u+ x  [5 l7 v7 a0 _# s6 A
        iscrowd = torch.zeros((boxes.shape[0],), dtype=torch.int64)
, R6 J+ P% F$ x3 v' N) O6 y
. c' g9 R" z+ Z, Y: Y: j$ n
& v$ x) w* J' [1 r' r1 e- d& [
        labels = torch.as_tensor(labels, dtype=torch.int64)
. y' F- }" W$ T- P; C" r3 l0 b# J+ e$ i
4 T7 I/ [5 M' M/ i
        target = {}5 Y5 X8 W, c: L0 i
        target["boxes"] = boxes
' z1 g  g! A( {; F        target["labels"] = labels
# z" I% ~. d7 j. y  S        target["area"] = area
# N. Q4 i( S) x- r, r9 M! n% \        target["iscrowd"] = iscrowd# s6 ]# u9 i& H1 {2 }1 \8 |
        # image_id
8 B1 a3 u! x' b5 w% ]/ m        image_id = torch.tensor([idx])2 g' G/ }9 P: X" e% h6 l
        target["image_id"] = image_id
* @/ j+ G- r$ T: s1 m  F- o
# V" @) M/ K5 k) s) D, x

- W+ O& S: K  a8 Y0 Q4 f6 j; W        if self.transforms:0 S# d  Z" z* H( B5 \' ~8 k
            sample = self.transforms(image=img_res,
! Q/ y7 b& l0 n' x# X0 n& y1 z                                     bboxes=target['boxes'],/ m; Y" o8 D! c5 O/ ?' H" `
                                     labels=labels); i1 d5 V: e  r/ ^1 m5 h' O
4 V. b! o. C" F, @9 |0 ~

/ i6 d4 T4 i& ?' D            img_res = sample['image']
5 n* e" l# _0 `6 v7 w0 Y' B. X+ K            target['boxes'] = torch.Tensor(sample['bboxes'])7 }: C; f+ ?& g( V2 R  `
1 \' d% x. ~7 |( J/ B& j- q

* w( {- p7 h: E( E) m1 s6 C7 [+ K        return img_res, target
8 _3 g/ D2 p7 }0 W2 v* |: [1 G. \

1 Z; C2 B- ?. I, d4 c7 g    def __len__(self):
% I* @: M% S1 q, m: N        return len(self.imgs)
0 `. B( m0 g; h3 M5 C8 N* a( z
, k( U1 e% ?) o/ u( ]+ }2 J

. G. U9 [; H( z+ q9 F# function to convert a torchtensor back to PIL image/ N+ T5 a4 A8 G4 B
def torch_to_pil(img):; A$ q8 {/ G8 {
    return torchtrans.ToPILImage()(img).convert('RGB')
& k6 Y. D; F7 y4 X- U; ]
7 Y+ I2 [; F- x* C! n- \
0 O$ _# J1 D! G* _, F$ V; i3 \
: @* z" H! }* Q  O8 h
3 O7 V1 I% ?* _1 u" ~, j& o, o
def plot_img_bbox(img, target):
- ^$ ]" z% ?4 R" S    # plot the image and bboxes% X, e, E/ e9 r$ o
    fig, a = plt.subplots(1, 1)2 `3 f" |' `! d$ a/ k
    fig.set_size_inches(5, 5)' q/ T/ n. Y0 I' R. M! y
    a.imshow(img)4 |2 e% |! ]1 }) \/ R
    for box in (target['boxes']):5 w3 m0 S0 h# y: M  _7 v6 H8 z
        x, y, width, height = box[0], box[1], box[2] - box[0], box[3] - box[1]2 a- ?2 N7 Z) E& w2 O7 I6 p5 @* s* D
        rect = patches.Rectangle((x, y),0 i$ N/ Y1 f6 F; x' G" X
                                 width, height,7 j: U4 A+ i6 C
                                 linewidth=2,9 T5 s3 y2 D* }
                                 edgecolor='r',
4 a0 H) q: R# a4 f' A% S2 _3 f) @1 c                                 facecolor='none')
" z& P' Y; O9 ~9 U/ @! |5 s
' x- n8 p" ~; r- d6 y) s: h
7 v3 D7 I9 Z1 b5 o  |. s; y
        # Draw the bounding box on top of the image: v6 t7 i8 R: e) v( w9 T
        a.add_patch(rect); K. S" N# ]5 d, g; S# A( Y
    plt.show()3 {1 T- n) q9 ]! j. ?' `
! z# q, p: h8 v, c8 M

- Q4 i4 g& P) s3 g' }+ D' R9 U* t
5 k- L( O9 u+ A1 G( |

, T* c! N2 i* c/ G% @5 Pdef get_transform(train):
! p9 j6 Q6 q, M) T( z    if train:
# x" X; T; O* o1 `% N# a5 n; T        return A.Compose([, s: T5 s0 @* Y7 ]! c8 Y
            A.HorizontalFlip(0.5),% j9 P- I, }8 i5 g# s9 S9 _
            # ToTensorV2 converts image to pytorch tensor without div by 2552 N: a/ R9 i& N+ u% K
            ToTensorV2(p=1.0)
% X" c, Q& U  S! k6 R- F' D        ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})
6 h/ k8 B" {0 q' e) e5 t6 `1 q, ]    else:7 ^* i/ |  E% {3 F
        return A.Compose([
' F4 ^8 M" p$ g% j$ z            ToTensorV2(p=1.0)
+ {$ z) [2 f4 k        ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})- r9 M! b/ ~$ r0 |3 R

. }# G  G$ e, N

0 H' u1 K9 y, j8 M* _: e/ L! V0 O4 q
- q1 V# J7 a4 U1 _5 O

9 K4 k% u9 W4 K4 I' P9 G! J1 e
+ q  Q* q2 e  c4 e+ M9 r
dataset = FruitImagesDataset(train_image_dir,train_xml_dir, 480, 480, transforms= get_transform(train=True))
" f8 d9 v9 [  N0 B; C) X+ k4 x2 i, r2 M' W

, F2 j& p8 R5 N* aprint(len(dataset))
- ?1 T9 b/ X. U. z. C# getting the image and target for a test index.  Feel free to change the index.# l2 t9 J8 U  A# g0 ~0 O* N6 o) u/ P
img, target = dataset[29]* m  k- [' I" {% i) I9 ?/ t
print(img.shape, '\n', target)( S: ?# s' }+ R0 i
plot_img_bbox(torch_to_pil(img), target)
/ R. t$ b. {& q1
% O# @1 a' _9 @0 q! ?# n2# u- E" e4 c) s5 f" x1 a
3& p1 T+ k7 Q  p: h+ P
4
* n2 \; K0 O  }1 _5
& t8 V; Q7 b8 B  @4 Y62 S: ^) g" f( O% o2 l
7% D# n. ]- \5 Z  F- v+ L4 C
88 F2 h  B7 s0 P8 P+ M6 ]+ \
9! s/ T6 r( A2 x
10
* E5 W3 G/ Q/ |) u; v3 Q11
) k2 ~; _/ s+ X; E12
2 c2 U. d$ z7 ]13- ]2 P  B) j5 \4 J! P4 G
143 _) {* I! j: u4 S/ \: x5 O6 F: B8 ^5 i
15
& O: o' s+ k3 e) o- x8 C16- T' D2 Q0 A9 D
17
3 C7 }) X  i- X2 q! _( p2 V" x" }, \18
+ y+ @  Q( f+ Z4 S' o- M19
$ y: ]/ B4 h; M# |# p; t( p/ q" P207 @5 w! @; W# v* ?
21
; F' |. `; p' p( T8 q22
" O3 w4 y% W" l+ N8 e: q. K6 C23# ?( P" h. A4 K6 A( {
24
! s. ^4 p; C) H: e6 g' d258 P' Z6 r) M6 S) a8 F% V  ~1 m
264 N9 o! G( {4 Y1 I. \9 h0 h% l
27; s! u5 q7 x* s" T+ E
28! v& L' z- G+ F7 ~6 h. Q
29
& d* l( |& ~& N  A. E9 E30
& X; x0 b  Z& p/ ]5 k5 ?! t31' k# e: }# p/ y$ \8 B
32
) {7 f# q* ]4 r$ r% K# M33
/ I2 j, d2 x/ |34
$ r- ?0 |  Z: \35
& M4 Y2 B; v  P" |8 r" Z# G5 ^362 O8 d& N: P0 `1 c5 B
37
% F8 T; [8 ?$ a9 Q/ C8 P8 M6 v38  D5 P5 d2 w  L5 ?
39! v7 Q' |- A/ B
40: e" x4 {& ?1 Q+ W* w
41) {6 n6 G* g3 x" j* [  b; c
42" W* W/ }+ w9 ]
43
7 O! F( w! p4 \6 w! c44
  Y! ]& f0 F; f# f% i* ]45
9 U. R! }% I& h, ?: O, w- q4 D) D46
; |+ b+ D$ C% h" m47) p" l, x& h; I2 J! z
48
# j' U( `5 e+ k+ F1 y! B# @' m+ r4 W49
" a+ l1 W& `* F50! B' ^, b! b- s, F6 s
51
3 T$ T; p# \) i# ^2 M52
. C4 m! d& e6 a4 X% i53& R; H4 G* s" P0 S7 T7 K
54, ~, J/ R( d1 E) k/ A
55- {3 |: Z6 C* Z/ I
56
+ @, `  a! {! N: X579 N' u) P8 s1 `. G) a- Q1 U. v8 f
58
$ }: K+ R. P- `) v, t% @: ]+ m/ G* z59
) d# |' b' R; d" Z+ D* v60
2 P# ]% C' y$ x# U* ^61' e/ B- t$ k: {! O8 z
62
  v/ b2 z" h& O: g  f* v3 j63
5 @' K3 B6 x9 X$ v64/ I( h, C; q- q6 R8 [! P" y
65
" u7 d" P$ K$ p3 ?5 G* y6 m66
1 d* I* A, M8 S6 _: R6 I67
; l3 T( V, Q- b$ c$ N9 R0 W68
2 F8 `9 ]. W6 g. s69
1 k" e5 ^$ p  r9 [; T- U% ~" `70! B( Z$ W) W3 M
71$ Z$ p. P1 M2 d1 w$ B
72
8 Q5 w: e0 z2 U; P+ ~732 w8 y7 `1 \- I; K
74
- y0 Y* e1 W# L8 F" }- m753 f, h# |# I9 E
76
( ~4 T; O/ }* L77
, @$ N* r+ W5 d6 @7 j+ a3 f8 B78
6 j; w6 j2 c! {6 R- _7 |79
( ~& h4 f% w$ G80
0 }7 D$ M0 i" Z2 u6 Q& x81% V( ]) M/ x& m/ b+ `
82
1 T2 E# |9 C$ [, l# u83
, {6 V& l# W5 q5 B$ H- J" r84, z" Y' Q& a: ]* B$ B* M, @
85
: R9 |/ U' ?; V1 \, S" i! w86
% d0 r9 W( s7 ?( |+ M" u87
( s% d! p& @7 o# Z, B" ^3 n885 K$ q2 U, @$ U- c5 s
89
- J! ~  x7 C- u: [# x90) W& t. Z' e. O& V
91
" R8 k: Y2 p5 E" M' N9 G' Q0 e8 F929 p% `( K9 j$ V5 w( d8 V
93! A" G: s4 W" C$ }
94
! [+ f1 g, a5 H! `! n8 k95  Y# ^8 ^5 Z% s( p, b
96
- y# S. l: G1 `8 {4 h0 u97+ \, b; W3 y, ]2 c# Q/ X) ?
98& C( b% g' `: s9 C- G! Y; n% H
99
. ]$ i$ ?0 g2 u( v100
& p2 l6 K9 v8 S+ r2 k101
" j9 R' N) ]% y$ C& N: b1021 s+ L+ W. F- |# y6 A# M
103
% R. R4 Y* C; K; }. Z" E1048 M& m3 W2 i3 ]
105
8 m4 r% }: f5 V1 `106) R+ Z7 w( L3 m* j
107
; t' Z* i, N( }# Q' l4 f108
9 [4 {! v- H& r# T* u1 u) \9 Z4 B109* T+ s- O* e# D% l
110
* L; d# z" `4 }$ n( l( b5 t. `2 w111$ B6 v9 Y7 Q0 `- U
1121 b  q5 O4 v# e
113! G8 T: w. K2 |% ?
1148 A% U; x8 f# x" Y; ?; L3 ?2 W2 L
115
+ a9 i# @3 ^! x4 F7 h; b116: H9 h5 a+ m6 K5 Q% r! \/ A
117
. w6 Q. s/ [' s3 _/ \! w* U118
" {1 d8 T8 ~5 s& p9 z119
: `4 ^9 ~" R. d9 ]2 S120
' }7 r% S  P+ K( P  S3 m121' A0 c, W* y# O  T9 e# R9 b. g8 O
122
# X8 }6 [# i5 T( Y123, u8 d5 X7 q1 n1 S2 c0 k& }. o
124
& f0 x: X. _( W4 o125+ E! X9 |' ]" F9 Y+ T; v4 b
126
; `* o" @3 R9 ?( I- H: _1275 o" U3 ^% |/ I# ~9 H
128/ X( T4 @1 t& Q9 A5 }" ~" q
1294 P$ b; L5 q6 j- ?# a
130. T+ d( A0 J7 ]' N* K+ u
1318 K3 n7 a. z$ ?0 K
1327 K6 `! ]# q1 w& m" D
1332 c8 y% y5 `# V- j& X4 e
1347 q, ]! d9 S5 k% B" O3 u: u
135; D% t/ n" W) G: ^
136
2 q2 Q$ T/ F8 l8 M$ O137, B- l  Y9 a$ Q6 M& n# _
138
( K9 s8 I7 k* r+ F7 g139
+ k% F8 T7 o9 I. Y6 w: m1409 Z- Y7 G) @' e- L
141
# R( e- @" e; z2 i142
. Q. _6 x$ N8 a/ A" R6 @143: w( Y/ c7 Z# _+ F/ ~5 H$ }
1447 q+ H: ]" x6 Q$ p3 n
145
3 n5 z3 y% n, |1 E8 P146$ I  w  @$ R' W* g
1470 N2 G7 i. u3 |5 ?
148
: l: j2 }$ N) t& j5 K3 p149
* B2 _! q8 l) F$ U4 a150
2 G( O1 I9 v4 h3 {151: {4 b. W9 N( s* _
152
8 y" Q! z8 X5 O* ?$ e8 `! q! {153
1 A/ C/ X( ?6 Y2 N7 B$ r154
  G, J6 P' t$ a& m: t3 M155
7 r3 T" Q  j: y; F5 }1565 m  ^! B( D, L
输出如下:
8 @% i- D& V$ H' |& F, N$ X' _/ A7 F; ]: G% X

" w; d- }3 E4 Dtorch.Size([3, 480, 480]) . x* L4 P2 T+ _( i/ u% w
{'boxes': tensor([[130.8000,  97.8000, 327.6000, 292.2000],  w3 o$ U) k- N2 o
        [159.0000, 268.8000, 349.8000, 427.8000],
% h$ o) m% W& Y. a8 P2 ~4 v        [  0.0000, 282.0000, 118.2000, 429.6000],
/ K" t2 L: l: m0 A9 J: g3 M9 g        [ 43.8000, 107.4000, 199.2000, 280.2000],! p: k* I3 r( J
        [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])}1 V* O, }, e6 b9 E
1
" D& q7 s, j; z( m9 X5 \( ~2, k+ Z2 t, z6 Q
35 @" F! c3 j9 |( [7 O# [
4
) s2 ?* o$ e& S8 U, T" s- P53 ?8 F) C3 T+ x0 {
6- A' c  g& P! g

, t, ~2 c4 R, i0 g2 b
9 h' U! V& c) D+ }0 c

( J2 A* ]+ ]" j! P/ k7 ?" _

9 O* z+ B! P( }" |! k2 ^2 _下载地址
2 t3 \5 S# H* b' |( r: K1 }& F" o链接:https://pan.baidu.com/s/1QZDgeYTHyAlD2xhtJqZ-Yw
) [, v1 _/ S4 F提取码:srjn
% K& e8 C# ?. O, J————————————————
) X8 G8 _( l; f  S! X版权声明:本文为CSDN博主「刘润森!」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。) y' H( y4 p6 _0 ^; f/ E4 F
原文链接:https://blog.csdn.net/weixin_44510615/article/details/118496273( _& o8 l2 Q& l/ C8 L9 R/ @- S

; J" D& Z; ?2 J+ U! W7 A( u; D0 A/ q- `3 z! `% |+ u





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