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$ Y5 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' a3 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 ~