! p6 e! s! t/ z将xml文件提取图像信息/ t5 B% N8 }3 }/ X
下面列举如何将xml文件提取图像信息,图片保存到image文件夹,xml保存标注内容。图片和标注的文件名字一样的。, S. |5 f, o. C3 o0 r2 O8 x
- C6 x' r( X0 c5 {8 g! y1 i O3 r2 g: \& J0 s
- ]$ q! D1 Y/ [% i% C% o6 m / l$ w7 i" `. U, |3 X下面是images图片中的一个。. b: P- z5 O; b( c$ u5 t5 F
( @! c+ A' n5 R0 d b" {
7 K" K- K. r1 k- u! i
下面是对应的xml文件。" ^' R' h) G) X- P
1 b A( D, r' V$ _, ` l+ z, G; |+ @7 m6 j9 _) B& a0 o
<annotation> 9 N A5 U, ]+ j% ~; V <folder>train</folder>+ H& `; I) O; {2 B
<filename>apple_30.jpg</filename>5 N4 f3 m: a* y7 o8 D! U, @
<path>C:\tensorflow1\models\research\object_detection\images\train\apple_30.jpg</path> * s" X6 C. Q& R" \2 A7 j7 N <source># h( O/ h0 }! g3 Q
<database>Unknown</database>" p, f* G" A. R) @* K; K
</source>+ c* [2 M% V3 ?4 t$ P6 T' e
<size>/ R' U' \6 b( `- ~
<width>800</width>) H! A; H5 l) ?; S5 z/ |! A
<height>800</height>6 t4 a$ ? c( [$ t9 R: `; \- a
<depth>3</depth>+ P" q* E5 c+ a0 y; ^" z- y
</size> : c3 A( A& i: Z! A <segmented>0</segmented> + Z1 Y; a# H3 s5 y5 l <object> , Y1 n; o! {! J1 B3 G" l6 G <name>apple</name>* S5 C: u) `; P6 f
<pose>Unspecified</pose>) f# P1 J8 |& T3 [
<truncated>0</truncated>. k3 d& a* [2 y8 }+ C1 e$ O9 w
<difficult>0</difficult>3 a. v, f5 N+ n$ l
<bndbox>9 O" ^( D' \/ t) C8 n3 r' G
<xmin>254</xmin> 4 k. a3 [9 o5 Q+ t2 x7 M4 b <ymin>163</ymin> 7 C& d8 Q( v& i( g1 T( N+ j! U <xmax>582</xmax> ' R8 \3 v1 q/ A5 a <ymax>487</ymax>6 u& D% q4 C3 }/ T% L
</bndbox>' U" ^' D* S0 g( A/ v+ @
</object>. p: _0 z! H, C
<object>! C+ E1 f; ^/ d* d4 M' C3 ~
<name>apple</name> - D; J- f' Q3 p3 X1 C" b <pose>Unspecified</pose> * c- Q, N& J9 H1 w% } <truncated>0</truncated>0 i9 s6 N* ?2 h/ j. q
<difficult>0</difficult> 9 m; J; P; o, E/ {. t8 ^ <bndbox>; j4 {' l2 x4 @8 d! @+ U
<xmin>217</xmin> * Q; O! N9 R! F# ^, ?( r9 _+ D- {5 Y <ymin>448</ymin> + Z, Z$ d2 u3 ~6 `, R: m) M8 i <xmax>535</xmax> }- q+ P( f* C# o' Q
<ymax>713</ymax> 2 Z1 I2 q+ k- N2 v+ ]6 {) r( f7 G </bndbox> ; A w `* e7 D( `3 |% T" [ </object>2 s6 c6 U$ S1 |1 T2 {' v6 ]
<object> & j5 _& T/ L0 O9 L <name>apple</name>, g! F# \' Q6 e/ ^$ z$ B2 F
<pose>Unspecified</pose> ! }9 Y! Q. J4 d <truncated>1</truncated>3 Y( f, e( r3 ~9 R8 _4 K/ l
<difficult>0</difficult>$ b8 }, A6 x; P; @9 ]
<bndbox> 8 g$ |# {! k# i5 ` <xmin>603</xmin>$ R" W9 K& e' j
<ymin>470</ymin>% t% D5 T. T4 m6 m
<xmax>800</xmax> % a7 t( l' F2 ` S7 J <ymax>716</ymax>( F9 W, L+ U( T2 A& V
</bndbox>; G: ~: Y! z" V
</object>. g: h( m2 X' L3 Q4 q
<object> $ k& K) U+ E6 J2 B( D3 R1 R( ~4 | <name>apple</name>" n8 ^# _ n+ f
<pose>Unspecified</pose> 9 D/ X3 |; d. K <truncated>0</truncated> / K2 ]) r: ^& X4 [6 O. k <difficult>0</difficult> 4 J: T5 K" _' ? <bndbox> 9 [0 [& T; R6 w$ U' c/ l <xmin>468</xmin>3 S7 x4 Y- o( l8 Y5 I, v
<ymin>179</ymin>$ {# [- S: p1 B7 Z# o9 X# [: @
<xmax>727</xmax> 3 W: t. P0 h G( Y( m* l <ymax>467</ymax> 0 V" ~4 z- [2 S2 t </bndbox> & q5 _" x/ v- L7 W0 X" A2 V </object>5 `' V8 y+ Y4 c I. X
<object>* D9 L) g/ a0 c# {/ y) S
<name>apple</name> 6 G K9 |; G6 A _0 g2 f0 w7 u7 R <pose>Unspecified</pose> " O, P$ b9 A5 Y4 m6 O <truncated>1</truncated> ( Y4 R( S/ h& S9 J$ z <difficult>0</difficult> 0 R6 P8 g+ p6 }3 H# E: u0 Z! [+ I <bndbox> : i e3 [) K9 \/ @" ` <xmin>1</xmin>: O0 `9 K0 g& [$ @' O; l
<ymin>63</ymin>7 w& S8 \! z$ r4 e/ M
<xmax>308</xmax>2 v7 ]3 R$ R7 o2 N7 ~* F
<ymax>414</ymax>: F u" y d! j E
</bndbox>$ B3 g4 s) `3 k. ^! P' v
</object>% ?% }4 d8 }0 v. @' a
</annotation> 8 v* ?& b* y U+ b3 L+ x4 q1 ; a/ C# \& ^/ U$ j3 E2 3 O) Q0 x6 X" e# j. g3+ H8 x/ U, ^# s( }" B8 q
4 2 p' U5 f1 p# o5 ; s5 J/ N) t2 f; z7 N6 / k7 [/ f H/ {9 M# M2 U# |$ Q73 z( t# B9 V4 Z7 p& T; b
81 M& S: O* F% O0 ]3 e
9 $ z- i) t! Z5 t0 h) C10, f2 j& I) k, k5 ]! _8 q
11- d% t' k$ p) Y
12 % [, Z; y6 x- ]. h5 P0 Q: Q Z137 d+ `: V! Z( y
14+ a, r% r# g3 L
155 L3 u+ V# n2 v! G2 m
16% C+ R$ T% h4 C* I$ [4 @
17- X2 ~5 u( x! @3 l- |' X6 v
18 8 e( x! T& [' B6 w: @( _' t/ O19. r# i: o4 [, T4 D1 v. g
20" D9 p. I& H) Z/ }0 G1 L+ [
21 8 U7 \2 i3 Y0 ~3 \22. G& j! f; t8 @% R) M
23 $ h$ p# X2 F m% h" @: N4 Q8 L24- R' A3 c" @: ~
25 : B% A' Z" f6 h( E8 Q26 ; k9 I' m2 I7 } D27) e2 `& y5 }$ Q8 Y" T( a
28. a9 _7 n& F+ Z! F1 z2 }# J
293 I6 y* ?8 y/ j, ~1 E* V& ~% O9 m
30! {% a5 C1 U0 D) n' ? {( e
31 ! m: \! H( M) i3 _) H7 u32, {5 ?- s+ Z- ?
33 5 {, j+ a' N2 {2 a" Y4 }0 E34 " W0 a/ u: o! b# ^ v% I0 [35 ! l6 h) ~6 b/ Y3 O+ Y36 ( Q! G. g8 F( Q9 \# r) t371 A( Z* @9 N& C# q/ b
38 9 o6 d+ J& J/ {/ j39! }/ _* E. K3 j+ Q G" y
40 + ~; q- }1 r" s+ V% }41$ l/ W5 G* g8 Y, R& @& |: P$ A
42 ' C D. Y* [9 n2 a* t6 M43* t+ M4 @: Y0 V! N
44% ]: k! C9 @* q& Q- p
45" B% s& c- p8 K) H) A
46* H0 Z! Y _! S- T( E C/ ?# `
47! a9 Z1 g8 R4 `' f8 Q4 W
48 1 N o* F& O0 k+ Z49 : T4 p4 f* v% ~" x50+ _) i, ?1 Q4 u) G
51! b8 h2 D, Z# V$ K6 C3 u
522 i3 e5 V4 u2 `- ~ w
53% ]4 L, }0 ^- `- X7 X& F
54 3 q' g) S& r6 `. i( i55$ l. w4 O4 F6 m3 g
56* v+ o- w* L/ u! \+ K. E
57 - I/ e9 D3 t* t1 D# R58 ) ~+ a: b. Z% n, M o59( v4 e% x9 J- G3 `1 x
60 - ~5 w' e( a; U, k61* I2 V n! F8 ]0 P$ O: j
62 - w+ ]7 j0 k! t0 R0 R8 v6 ]/ d' T63 ; I) C6 P+ P5 |! r# t64 9 D! c$ g$ v2 P. w65 ( u3 P. u4 N0 J66 6 j1 @: i5 [, |; Z1 G' u5 G% S1 ~- W67& _- w7 s+ d' M
68- Z- w0 _: b+ N8 y& P
69" x& S: x! M! `/ D i& i0 u
70; d: U0 \; P# p
718 `4 `# E% J5 c- f
72 " T8 t! d; C. b K" K6 ]735 _# }$ g: c4 w# Q% T+ D
74- f1 \0 o6 C! u8 h1 V9 y/ ^
将xml文件提取图像信息,主要使用xml和opencv,基于torch提取,代码比较凌乱。$ ]% `) R# G+ T
$ d) R( O- w$ }. F, _
0 U2 o* @2 b! @7 \4 I0 ^
import os7 z: y' S. l! c; }; d: M2 t
import numpy as np / u4 ~1 j9 b: W& Fimport cv2* U" n5 {) P2 }+ \, H6 W
import torch8 d3 I7 n! b( \/ _5 M
import matplotlib.patches as patches 3 S4 x$ H4 C2 q. ~7 L% Cimport albumentations as A1 E) Y' Z4 g$ k. P
from albumentations.pytorch.transforms import ToTensorV26 v" d3 Z5 L- P! v) u& h- J
from matplotlib import pyplot as plt' P7 H; |' B1 \9 d% |- i# B1 }' M
from torch.utils.data import Dataset1 Z& g/ ^9 u4 H: M2 q
from xml.etree import ElementTree as et 7 \: x! B8 O& R& Nfrom torchvision import transforms as torchtrans ' m0 P: {- I+ y2 E 6 G4 a9 d; F. i8 e. k3 {4 b2 _ / { K: V$ l# ~2 h5 e) L# defining the files directory and testing directory - {- r: H8 ]6 i, F( |8 m; @* Mtrain_image_dir = 'train/train/image'% I' R3 ]3 b8 D: \
train_xml_dir = 'train/train/xml' 0 L, A @) |) A7 e" x% d0 z# test_image_dir = 'test/test/image'" W8 L: K* O7 {3 A
# test_xml_dir = 'test/test/xml'. G5 p$ L6 Z0 x U" H' U
; n2 F, h( M6 b+ I
0 T4 V% R a% w1 [! A/ ?6 w
class FruitImagesDataset(Dataset):6 t L' i1 y5 ^/ l; Y4 y/ V
7 g$ J1 ]1 C4 p+ {; z4 w5 J. p " S* E6 |& j4 ^! }3 O1 w def __init__(self, image_dir, xml_dir, width, height, transforms=None):/ O1 ~( U' ^$ Q* q, h; H7 Z: r
self.transforms = transforms : ]1 a/ j& Q4 _" n# x self.image_dir = image_dir/ |5 e9 S1 L+ S& c0 c9 Z
self.xml_dir = xml_dir $ P% M1 G8 x2 M& O self.height = height 3 b& }$ G: `8 C self.width = width " F! b/ A: p! e9 R2 A( a . [% ?9 i `3 b3 D" i. U# {/ h* k7 Q F
# sorting the images for consistency , n1 R5 f& [$ B$ F1 \- c# x3 {( v7 B # To get images, the extension of the filename is checked to be jpg- V# B& y! P8 L a4 f7 F
self.imgs = [image for image in os.listdir(self.image_dir) 3 w8 O2 f4 K! T$ Q5 f: v1 q if image[-4:] == '.jpg'] ( |" a& \! G. R' e6 @& j. ~ self.xmls = [xml for xml in os.listdir(self.xml_dir) 7 Q. K; @# P9 c% B. Y! \ if xml[-4:] == '.xml'] ! K; L3 {9 h& j4 j, M1 Q0 o- }" r4 J/ w3 G" O7 [& o& H0 b6 d+ R$ [
# [# r4 t5 d! w: V7 m& P, ?1 G5 h7 h # classes: 0 index is reserved for background ) N+ q& c Q) m5 u7 |' ^ self.classes = ['apple', 'banana', 'orange'] ( _3 |* B+ {/ N0 w% ^+ e: E% W: F W9 F3 v0 l
0 n4 x A$ J9 X def __getitem__(self, idx):, g( r# F3 c+ w) `
6 E5 g6 u ~: N% w2 X% z
) W$ `4 ~4 H$ {
img_name = self.imgs[idx]1 S+ |! {9 n3 T4 B2 w' \
image_path = os.path.join(self.image_dir, img_name) . w; p. O( @: A& T 1 Q- [9 ]& J; s9 g0 O' I1 p8 `1 _# {. {' N7 Y4 Q/ e% l
# reading the images and converting them to correct size and color . Q: m' s- R ] img = cv2.imread(image_path)5 I# l8 u+ i8 z) `& T, q9 {7 J
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).astype(np.float32) * z6 J$ Q0 G; F9 M3 m. D* N4 m img_res = cv2.resize(img_rgb, (self.width, self.height), cv2.INTER_AREA) 8 d6 J9 i* o2 t5 k: Z # diving by 255, ]$ F+ w/ a5 X8 U; E
img_res /= 255.0 U8 G- v0 p+ U! m" e9 v$ C 8 `! K# s- L* E( f + L1 b0 X; i( D% D! N # annotation file: T a4 N0 C. x3 ]7 f
annot_filename = img_name[:-4] + '.xml' 8 J" u- e }+ R S0 @9 Q annot_file_path = os.path.join(self.xml_dir, annot_filename) l5 v0 h7 c+ C; `; B" @! f( o, z4 `- X8 o: j/ N: }
3 ^- N) C# R* o3 ^3 @ boxes = [] L9 k8 t4 z3 E" b/ m8 ^: p$ Q: d) P
labels = [] ~ Q, t, s5 U tree = et.parse(annot_file_path)) k- @( Q* D; j
root = tree.getroot() : E8 b4 [, Z. ]/ ^( p' g+ C3 G) I' T* P: O; D' X- [. {7 A
# T6 E% |# z/ W8 O; J- O+ g
# cv2 image gives size as height x width0 m' E) b1 J# |4 L; c# [! Z/ b& ]9 ?
wt = img.shape[1] 5 c- U1 G" v' T. {! a ht = img.shape[0]. n, w( r1 T0 ?! K1 S. Q. K
# y' R% D9 s6 D8 i5 R6 b4 ` " N, @) Q: o3 D$ T" G$ L # box coordinates for xml files are extracted and corrected for image size given+ v4 a+ Y# s: ]: G, X
for member in root.findall('object'):. E% I2 T# x# N, ~ q: F
labels.append(self.classes.index(member.find('name').text)), N, @( ~6 A9 D0 R. W: [
0 E8 U% N) ? Y/ U
9 b$ u7 ^8 F$ J! e # convert boxes into a torch.Tensor1 p O6 X1 v( t4 ]; S( r9 T' d* L
boxes = torch.as_tensor(boxes, dtype=torch.float32)6 c( M( G- P. m8 d
b) q i) f- d; t" q) J 7 S' o$ N: V/ n0 K$ D. E # getting the areas of the boxes p6 k- ~( b8 r3 K* Q# a" f2 z
area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0]) 5 Q" O1 w7 O, h2 F0 }4 e8 P 3 C' h" I& a: h" f/ G4 ?1 k* \1 S$ B; k* b8 k* U: ]
# suppose all instances are not crowd 8 h# [8 z5 m! _7 s, \ iscrowd = torch.zeros((boxes.shape[0],), dtype=torch.int64)9 J. t7 ?1 v+ y; w9 L( ?
2 I' c# ~1 g# _$ T8 }
' I0 X7 U& l+ L; _( W3 y& V
labels = torch.as_tensor(labels, dtype=torch.int64) . X7 p4 f- M4 w' o( g* k6 ^5 v ~0 z) K