, q% s8 r7 y! | 5 M; _: p6 I9 P& V- Z2 i def __init__(self, image_dir, xml_dir, width, height, transforms=None):* \: ?9 q7 z ^# X' q/ m
self.transforms = transforms 1 P, J; _5 E6 u( `" p1 {0 q- p self.image_dir = image_dir & m. Y) W; ~) @ self.xml_dir = xml_dir 9 ]4 f" u0 d: r/ C' B# w- w0 \ self.height = height* t' p8 S; f( ?8 t
self.width = width! y. ^' }% ^% H/ |0 i# Z% ^' w# ]7 k
1 x4 g8 d; E! d$ ]$ {" U+ r
* D/ ]% |$ S0 @! c7 a7 @$ Z
# sorting the images for consistency / j! Q# z2 ?3 t/ s8 ~9 p Z # To get images, the extension of the filename is checked to be jpg ^' w9 F& j5 f
self.imgs = [image for image in os.listdir(self.image_dir) $ K* e9 f! r: D if image[-4:] == '.jpg'] : n( }8 o1 D% l. ?) { R! L self.xmls = [xml for xml in os.listdir(self.xml_dir)# f8 a: f3 `1 D+ T# m9 ~( f! k
if xml[-4:] == '.xml'] 6 l! E5 E8 n2 w5 a( c7 @ 7 [! D; ^5 K( r/ P" |% Y$ e* p3 f
# classes: 0 index is reserved for background7 c0 q2 X1 E; t8 X* n1 k4 s9 P4 u
self.classes = ['apple', 'banana', 'orange']+ o) ` f1 I, \! z$ \5 b
6 k$ E& Y% h7 s + P/ w. c& R, J1 Y# R- {$ Y def __getitem__(self, idx): 7 Z: m; j9 G$ Q; n- W+ H* M) p+ G( g P( m
& p$ g' F* u: l4 s5 B0 f8 k! D
img_name = self.imgs[idx] 3 Q- t0 \) ^- F- w image_path = os.path.join(self.image_dir, img_name) 9 Q, ^: o5 q+ z$ O 5 J w& C0 X5 q+ n1 ?$ z ) K) h5 D! M% D0 K* P7 |2 T7 J7 @) R/ X # reading the images and converting them to correct size and color) ^% s3 ^ w% d
img = cv2.imread(image_path)7 P% Q* k; @! x9 c5 ~$ D* ^1 _
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).astype(np.float32) ! |; ~3 r; L3 _$ U" E6 s1 l img_res = cv2.resize(img_rgb, (self.width, self.height), cv2.INTER_AREA) " i( v6 F0 Z8 a& D # diving by 255 : t. ]# |3 i1 x% v2 W img_res /= 255.0 - N Y* U q6 N k( Q5 K$ ] 9 s5 W' W' i1 v6 S5 u) N0 k0 t6 _: k4 K( D0 x
# annotation file2 q$ M8 v& j& C+ R7 _5 ?3 T7 y
annot_filename = img_name[:-4] + '.xml' ! X. K& s# H3 o( h# ]2 W annot_file_path = os.path.join(self.xml_dir, annot_filename) . A& X0 F1 V7 L; R8 M7 Z: \5 W% V# f! d, u$ t+ ? D+ X
# j: W; S; w, A boxes = [] 5 A6 G$ }' D' V7 t3 ` labels = [] 1 i' Z, ?5 a! X7 J5 r* J tree = et.parse(annot_file_path) " r) P) d3 _9 i% @9 H! I% f, ]9 ` root = tree.getroot() 2 d4 `6 j) j4 S. f3 ]6 n" G% B7 |0 H4 H; \5 C. E
! d, p* ?) ]( N2 ^0 G! I- X7 T! M9 u # cv2 image gives size as height x width 7 n5 |( X9 I1 [, G4 T wt = img.shape[1] 6 g* c, |- ~8 o- l0 Y ht = img.shape[0] 8 o! ]1 u& u$ n7 q: V2 B$ x6 _% z- i- c. @' |" K
* o; x6 a8 j& e. W! p; q% x0 z
# box coordinates for xml files are extracted and corrected for image size given; H' J7 D9 y: T5 T, u2 q
for member in root.findall('object'):% f6 A: |- ?1 W4 c+ ~: g# {; M
labels.append(self.classes.index(member.find('name').text)) 4 i) v7 @ }6 ` - d* ]* }5 M" H; d; c N% A% m6 V6 W' S( s$ r# H* w" ^1 [6 O
# bounding box - M4 @" ~: x8 j% B$ K& o xmin = int(member.find('bndbox').find('xmin').text) 5 _& K1 o6 F+ d) a) e' F3 J9 ^ xmax = int(member.find('bndbox').find('xmax').text) 1 w# w" k% r9 |8 W+ \. d% R; F% d. R$ U ) V0 v) F* r j+ v3 M2 n+ ~8 b0 Z3 ]9 F; V. {. O; j
ymin = int(member.find('bndbox').find('ymin').text)1 T1 a/ |* ^- F7 W% l- V
ymax = int(member.find('bndbox').find('ymax').text)8 G( b& s& f0 y2 c) H
! C8 Y! s1 m3 d/ C
" M: l% X* @& H& Z6 K2 @; F' T
xmin_corr = (xmin / wt) * self.width. E7 ?# Q& i8 w) I
xmax_corr = (xmax / wt) * self.width q* C# C. }$ D( n% I9 n
ymin_corr = (ymin / ht) * self.height ' `8 L: Q- A" ?" M' N& T% W: [ ymax_corr = (ymax / ht) * self.height0 r h4 Y( B) z
boxes.append([xmin_corr, ymin_corr, xmax_corr, ymax_corr])3 a( Q5 Y/ |) V. W# U8 G
/ `* d4 P" l& Y- S& W( b/ ]" O9 X7 o# x% v
# convert boxes into a torch.Tensor( y; h' w: E& \0 p0 k+ f0 n
boxes = torch.as_tensor(boxes, dtype=torch.float32), R$ H) d7 p" ]; E3 d! e( t% Y" V8 A- \
# ~+ y* K* R4 E0 v
* z& i4 D' [+ V3 R$ Y! N( Q3 g% ?; ^% _
# getting the areas of the boxes1 x7 a, V% V, z W, g
area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0]) / s/ [$ D5 B! {) q& \- H4 u% P
9 `' i& e( a# t5 }: L2 L, y4 d4 j
# suppose all instances are not crowd# p9 y4 F: x8 h' n. V r" i F) T
iscrowd = torch.zeros((boxes.shape[0],), dtype=torch.int64) 2 `% E6 E$ D3 \4 ]3 t 2 O- R2 H4 |8 b8 e& i$ [5 D! r' n! t1 S
labels = torch.as_tensor(labels, dtype=torch.int64) 4 Y! N) Y G' o4 b0 m. k' B, B7 z' f
- t* r6 V" i e& r
target = {}/ v% b+ \! c+ B, t3 T
target["boxes"] = boxes/ F9 I, D2 M9 N- E
target["labels"] = labels 7 k3 r; a3 I- ^# k6 M: J target["area"] = area1 ^$ d/ k3 `. P) ^+ M
target["iscrowd"] = iscrowd 5 k9 r$ W& C0 d" ` # image_id + K# q5 B A8 {. ?+ n, { image_id = torch.tensor([idx]) 2 m$ ^- ~: S' d+ ? target["image_id"] = image_id ( D4 [1 H2 ] n' Y+ ]3 i! }* r) r' } E9 ?8 H: X: [
" @: V" }; f2 R5 d) |; u$ `4 g4 N. A2 W
if self.transforms: & y1 `. z/ U: C* n sample = self.transforms(image=img_res, 0 Y/ I7 @5 X. ^; ?! ]' M bboxes=target['boxes'],' \% s* \- A" R- y/ f3 o
labels=labels) }, W* Y! V5 H, J
% f) r* u# g7 q9 o7 n! c . m; }/ W4 P4 e: v9 _/ A$ _ img_res = sample['image']7 K, d. y. L* c
target['boxes'] = torch.Tensor(sample['bboxes'])" o; o/ V7 q5 R. T" r
A+ c# P: |! O # e4 i% J3 O, V9 d+ c return img_res, target5 C* O5 y& |& K8 y( T3 U
+ M' A0 _! r: w, `
z) x1 L) C2 d/ H( \
def __len__(self): " @% U/ U. y$ U% Z5 d3 u/ J6 | return len(self.imgs); Z4 r+ Y9 d u; R' f4 B1 I
) a6 [! ~( ^) R$ {5 a. c/ a$ ?9 D8 z# G+ \- G
# function to convert a torchtensor back to PIL image + X% k4 ?: P. Y m2 E; F3 c: bdef torch_to_pil(img):% P7 q! u' h. h; Y! R Y6 e5 |9 F
return torchtrans.ToPILImage()(img).convert('RGB') 2 p1 p' \; L: J5 p1 Y . U: _# L3 `( l- y& N/ N # ?( X+ b/ |! A) {2 L ! H* G5 D5 w9 ~2 n" v+ y$ y; N3 {7 |8 p% |+ V: r/ t: o' q" D
def plot_img_bbox(img, target):: \" }) Z' [* B8 G
# plot the image and bboxes ! W8 K, B9 g4 E% W fig, a = plt.subplots(1, 1) % Y3 y/ N' p) j: } fig.set_size_inches(5, 5) % \2 p& e! X( M1 I2 D; g1 d a.imshow(img), i5 s- y& @ f* {/ ~2 ?& {8 B
for box in (target['boxes']): * [* s) T- J4 w" | | x, y, width, height = box[0], box[1], box[2] - box[0], box[3] - box[1]$ l* R# S% }: f" C
rect = patches.Rectangle((x, y), $ z2 F; s/ B- V/ j& N: f3 \2 l width, height,7 p! [* k O6 G9 ^+ _
linewidth=2, ) T2 _* f4 B7 x: @9 q* ]$ m edgecolor='r',1 m5 Z) f6 p( u: ?/ h' f
facecolor='none')$ j$ q& k/ I9 a+ l+ R( [, O
- }/ p; t; v3 w) a1 ? 7 P- i& s! I4 F$ P # Draw the bounding box on top of the image : ?" M2 V, D' [: j$ f V1 ^6 F. w a.add_patch(rect) 8 Z2 H5 y+ J; X1 o plt.show()4 Y6 _9 l! n9 X/ j1 T. k9 M2 s
( m* ?) F" i9 ?) e1 q$ f
6 u1 _3 f# k$ @) w) R 3 m3 F; t( j- d7 n ]4 j8 P# `0 B- g G% N3 @1 G" U- f; O
def get_transform(train):3 |. ]9 K ^* V% S# Y
if train:& g! J' K) t3 j9 @0 w
return A.Compose([2 B/ _) f& F& v p1 K! u
A.HorizontalFlip(0.5), 6 V3 N, i( E) F# I4 m- G& ? # ToTensorV2 converts image to pytorch tensor without div by 255+ [& ]2 J* D7 m* ~5 i
ToTensorV2(p=1.0)" `% k7 e' X' k) A8 f
], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']}). c% w$ |1 K7 ^9 m9 A
else: 4 Z; k9 F+ V/ l* S return A.Compose([( j+ k0 F: k/ ~( S" W
ToTensorV2(p=1.0)5 C' h" w4 k$ u: Q3 k3 K
], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})& K& t2 g2 p# p) ^/ l
1 A, g* ]3 i0 l! D% K# v
" i& ^. @! z9 N z O 5 @, x( z8 F+ W: e ) n5 B% C2 q F" N ! @! v0 @4 d' i: F0 l9 [0 l0 C" w4 a4 ~4 K" k3 G! J! Q
dataset = FruitImagesDataset(train_image_dir,train_xml_dir, 480, 480, transforms= get_transform(train=True))9 @& S0 k. H. h3 W. t5 y( j7 J
5 d7 w: ~& f/ A( l1 M
5 U) v/ r# }- y( }4 G# Kprint(len(dataset)) ; k: ?: ^; k4 I. e! [1 i# getting the image and target for a test index. Feel free to change the index. 0 i0 ]7 F s% ?9 O9 Uimg, target = dataset[29]) M J" a" N9 L/ @5 q
print(img.shape, '\n', target)6 u m" y1 Z9 \& Q
plot_img_bbox(torch_to_pil(img), target) Q- {$ _. a0 V1 @$ x$ q. Z$ b3 l1 # k- s. J2 C0 }" g3 _2 g2 ! ^* X% |! C% G36 A6 J( w6 H6 b( q8 Y$ ]: r0 S
46 k* L: a7 y9 W/ E! N4 ^# O) A
5/ c/ @' s* g( {% Y( m2 Z `, O
61 \- M8 Z* d& k
7 . s! E0 P m3 k9 K1 y# G8 @: u" z6 q8' f7 |! |- D$ C. }6 s
9; n w' d) U2 W- y) w: U
10 / H; I) A8 x/ A' U% M) l117 L" u% }0 ]. k5 C
12 1 z1 z J |4 l3 o% }13 ' F$ [8 T# B+ f" {5 z3 X: o! U: O14 4 \! H; a# G. Q0 d' n z. a154 j/ J# I3 E9 m
16; Y; T, d1 d* G; y6 c
17, y, v- o1 ]/ ~; w4 h, A9 k7 f
186 x2 {# G9 W y; d
19+ C, j4 \: I3 {0 A% l
20 ; C0 ~5 r5 }/ j! e, W, r21) D1 K# `$ e \
221 I# V( r' D+ j2 n
233 G& B" Y; Y9 M& v; R( {, y
24 . q8 n+ q4 i' t* ]2 P/ |0 V0 a4 o. \253 l: J' c8 y0 I5 D; ?
26 ; x# [) A. s9 ?* c. b0 r: {9 @27 2 o2 x7 D" _1 M& n28' w0 {4 T+ z3 f4 \6 H/ Z( x5 i7 ?
29 s0 x0 k# U ?: ?' i30% [, e$ Y/ r! x( w+ O
31 + g b4 @0 u- \$ Q32* I/ w: O+ h* N
33' d8 @' n, I# b& a
34 & Y$ S+ r- u: F* T4 V35 ' D H3 {! [1 E3 b: _9 h, u36 1 u- ?: P% [) Z6 a, L: {% R37 9 D5 ~& z I# }7 E3 Q38& w! V( B- y# T+ \9 i) E
391 u+ z: _- W3 D+ c2 q
40 ; M/ j$ W0 i: W& M8 _) C( E41! V$ k& M: S) J
42 6 X# v3 y+ ^$ G& t43 * ]: w- z. O8 x# u% B44 8 G5 H- U& y& P1 L45 3 O7 ~& Y; ?2 Y3 k+ l46 $ q! f# s& F, E* R! f7 v47- g% K( L k# \ ^
48, Z \9 U% o4 R: B4 m5 ]
49. C2 g: N b" C
50# H5 M b7 d9 S# [0 g2 B$ d
512 x% J9 p+ K# _; L0 D. m
52 / G( W8 y. E; y8 i53 i6 G/ L2 s& w2 y; E$ ~+ M. i54 $ Y/ f8 Z) V% E) S$ A: e/ K) o9 p55 ! t/ X. ?; o$ ^7 X6 t56 7 M- X- H( f$ b" R( b) C7 w571 ?# k3 p3 {& L, }* S6 v( X! l' I/ D% D5 y
581 r3 r; N0 Q1 l. H
598 ^8 G4 }) t h6 X: R: i
60 0 k, |: f, T& j+ p61* L. [4 V* l$ ^
622 x C5 f, V+ I$ b: b# w
63 5 M; U8 {; Z- F; \6 y( d( E; _. b& T% D64 $ `% z, p7 b: T2 C% B# I: K6 F65 ' C' O' N* O0 x0 K# D- l% P1 z66! Y& e$ H4 N4 \ }
67 a% Z; h" H6 [- K T3 g1 s$ O683 x. q- S1 A( v$ m
69; T3 s' y0 a% X8 l3 {0 W
70 5 g; U2 ~: j, m4 ], E+ j71 2 I {; C( t6 u' `2 B3 j) i' g* a: R72: E4 D+ }( Y7 X+ }
73! \- L! H# {( [2 t' {
74 # y2 V* B* D. P: w$ J752 E) Y7 b6 c9 d8 L+ C
76 2 k) S( ^& Q4 A) N77 $ H _! i* ^/ ?7 C1 a+ {& F78 2 C2 o; n- a# o: H6 E79 & v: {# L. [: p% W2 h* T( E80! l( ^6 H: n: ^
81& a5 ?3 P3 n1 o- ^* C: ?
821 K9 r) k* K* t* g6 T; m1 l
83; v! y# W v( ^# u- a# ]1 W! N
84! n$ m" ?5 p$ R. }% c& z- l
85: }" @6 X q$ R4 w# X' h
86 - c) N+ I b- u# U: G- Z3 B% f87, s/ z8 s8 J* `2 h; o6 m8 N
88$ t, O( r; d, z/ j' G; M% f) f
89 8 z' U; s" M( {# S3 _- n90 ( o. q% u; W7 x, I91 - O& Z W( q: `' B92! w& ^7 J# @5 ]( W
930 y4 H$ b) @! h
94 0 q; T* k3 b- L" ?; w" w* f95 5 L. ~1 l& @4 c! t( b6 \; U% x96 0 z: p( ~' I8 Z( K* f* U& g* G8 v97 / q, S0 C5 y7 N+ P0 K3 W8 |+ L98 8 d8 G- T# l, K% R9 z! S& H! a99 . ^* R' R% _- |) Q+ N A" Z& i- |, L) L100; Y4 y" P. ]) O& }3 m7 e- I
1016 F1 o+ w* w& K, N# w" [/ F1 G
102 ( w6 Z5 |2 k/ \+ V# v103. c, k+ K/ R2 @; z% b
104" l! t4 h) L+ ^# z
105/ `+ @- ~( K$ s& h: P: a$ `$ g
106 & P8 J' b3 k6 R107 - @* |, X( [7 [* M) d/ f$ a) M# d108 7 ]$ j N8 D) I- z. u; a1091 u/ ]& |! P' d/ Q, V5 y- ^
110. H$ O8 c/ P1 {$ L8 E& H
111) c, E, X8 m& S* \& U- v
112% b$ u2 B$ B( t' Z N. J' t6 \/ s
113 ; F- S- w" C) ^# h: U1142 w6 b' ^3 l% t- m
115' _" k4 M% r) P1 }# Q/ U
116) m7 S( R( _7 s
117 ) C- A r) O# ~( z118 - P7 w5 B& f* J. P1 n' ]119! f/ Z) g2 i% K b4 m
120 s% r3 b8 v5 h) v, u( v# I
121 : \: [( u# t/ F: l, {7 ]6 V7 z8 E122 1 G$ O6 {6 X' G- ]1 J123 ' V) |3 ?: [1 \* U124 . e- O4 O% _* E0 `4 w125 - G2 [, X' r- _- e) h7 [; G: h1265 a; m- _" S3 P2 g7 v @( \
127 1 { p# R+ L: [0 M/ B4 ] q1288 m$ y' q A* m& Q" [: P
129 " h# e+ ?. ~% ^* k130 ' k6 f$ _6 A: K0 v# k2 K1311 C) `0 g$ I$ y6 n: X3 j# g
1328 v# h! m. j& N) D
133* h# @4 L/ I* V- c1 I5 s- U* ?
134 |0 h; y( U9 A# s }
1352 o8 v9 s |+ x- h
1369 p+ y5 A/ }& }. j/ n2 f
137 ' E l0 R e* J( k! P' B1389 Z4 ^; }' j9 s$ s
139 # d3 N7 j4 e% D+ r# o+ W# S1406 T. {* k9 s- K& H W5 \
141 : i% A1 R5 p& n* E( B- `) |0 B142 ! w/ g% z# J7 U8 a+ k3 D( D1432 v, A" o) T5 u
144: i) N( |1 c& c* z6 P
145 S$ j# S) o' K; R
1460 |& p7 p3 @9 m" h0 _, g M
147 ' G4 _2 I1 r; _. f" ~0 F5 p! C148 + s' g' f6 Y& Y! |0 h2 G149 9 l# ^1 f1 u! ~, s" ]' D& Q150- B, y+ A7 {7 h, t* m, C/ @8 P$ L
151$ B$ r$ v3 a% g- P
152 @. j% M& ]6 h O' Q. S
153: O! q# ]' }& u/ }, @, q$ _* v
1547 i p& N) f9 R% `
155- R# s8 @4 l! M' i+ J/ U8 s
156: e: Y) W ~. w) S$ a
输出如下: $ }7 O z" D, c# I; X6 h- V+ z, V0 a& o, \/ \& l1 d
( V/ O/ B% d: {torch.Size([3, 480, 480]) 3 Y* l2 x0 X& k# H
{'boxes': tensor([[130.8000, 97.8000, 327.6000, 292.2000],* N6 _' N% |* C% d4 i
[159.0000, 268.8000, 349.8000, 427.8000], $ G& D+ v8 @) k2 U# ^ [ 0.0000, 282.0000, 118.2000, 429.6000],( y n" g& V) ]' `: l9 C9 E
[ 43.8000, 107.4000, 199.2000, 280.2000],6 J" x. b4 N( `& 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])} v* j% Q$ |5 e6 Y; w1 3 E* ~ o) y2 a2 * ~6 [% \. L M; o. d2 P7 c3 1 O5 c' |) z( R0 o4" E9 X0 B3 g! e
5 ; R s8 [( f' V/ q' p1 L. q, D6- j% |: f7 L/ M1 b. v. Z
: ], h# z, i1 d1 d5 B
3 B' j6 x7 g6 V' E$ s- S2 T 6 ^! r' [ i: _ `- Y5 N: b: l% A! G( K* x. t
下载地址8 q6 u/ d6 \; i! y. O
链接:https://pan.baidu.com/s/1QZDgeYTHyAlD2xhtJqZ-Yw3 h6 C# m$ B f
提取码:srjn : A0 {8 B: R& z————————————————# V' {+ Y% h) O# S
版权声明:本文为CSDN博主「刘润森!」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 1 i% @6 _; b4 P! e0 k原文链接:https://blog.csdn.net/weixin_44510615/article/details/1184962730 a1 b6 v, X9 f8 r