@@ -45,11 +45,14 @@ def main(args):
4545
4646 # Image preprocessing
4747 img_path = args .image # TODO: make sure the image is in img_path
48- image = Image .open (img_path )
49- orig_w , orig_h = image .size # PIL is (width, height)
50- img = image .resize ((model_size , model_size ))
48+ # image = Image.open(img_path)
49+ img = cv2 .imread (img_path ) # read as numpy
50+ img = cv2 .cvtColor (img , cv2 .COLOR_BGR2RGB )
51+ orig_h , orig_w = img .shape [:2 ] # PIL is (width, height)
5152 x = np .array (img , dtype = 'float32' )
5253 x /= 255.
54+ x , pad = pad_image (x ) # use when the model has been trained on padded data
55+ x = cv2 .resize (x , dsize = ((model_size , model_size )), interpolation = cv2 .INTER_CUBIC )
5356 x = np .expand_dims (x , 0 )
5457
5558 # Check model
@@ -81,20 +84,25 @@ def main(args):
8184 end = timer ()
8285 print ('{} seconds for inference with ONNX runtime' .format ((end - start )))
8386
87+ ## Subtract padding offset
88+ if orig_h < orig_w :
89+ out_boxes [:,[0 ,2 ]] -= pad * (model_size / orig_w ) / 2.
90+ elif orig_h > orig_w :
91+ out_boxes [:,[1 ,3 ]] -= pad * (model_size / orig_h ) / 2.
92+ else :
93+ pass # square image
94+ out_boxes = np .clip (out_boxes , 0.0 , model_size )
8495 # Resize to original dimensions
8596 out_boxes [:,[0 ,2 ]] *= orig_h // model_size
8697 out_boxes [:,[1 ,3 ]] *= orig_w // model_size
87-
88- # Print
89- for i , c in enumerate (out_classes ):
90- score = out_scores [i ]
91- box = out_boxes [i ]
92- print (box , ' ' , class_names [c ])
98+
99+ # Read in as PIL format
100+ pil_image = Image .open (img_path )
93101
94102 # Formatting
95- thickness = (image .size [0 ] + image .size [1 ]) // 300
103+ thickness = (pil_image .size [0 ] + pil_image .size [1 ]) // 300
96104 font = ImageFont .truetype (font = 'font/FiraMono-Medium.otf' ,
97- size = np .floor (3e-2 * image .size [1 ] + 0.5 ).astype ('int32' ))
105+ size = np .floor (3e-2 * pil_image .size [1 ] + 0.5 ).astype ('int32' ))
98106 # Generate colors for drawing bounding boxes.
99107 hsv_tuples = [(x / len (class_names ), 1. , 1. )
100108 for x in range (len (class_names ))]
@@ -111,14 +119,14 @@ def main(args):
111119
112120 if score > args .score :
113121 label = '{} {:.2f}' .format (predicted_class , score )
114- draw = ImageDraw .Draw (image )
122+ draw = ImageDraw .Draw (pil_image )
115123 label_size = draw .textsize (label , font )
116124
117125 top , left , bottom , right = box
118126 top = max (0 , np .floor (top + 0.5 ).astype ('int32' ))
119127 left = max (0 , np .floor (left + 0.5 ).astype ('int32' ))
120- bottom = min (image .size [1 ], np .floor (bottom + 0.5 ).astype ('int32' ))
121- right = min (image .size [0 ], np .floor (right + 0.5 ).astype ('int32' ))
128+ bottom = min (pil_image .size [1 ], np .floor (bottom + 0.5 ).astype ('int32' ))
129+ right = min (pil_image .size [0 ], np .floor (right + 0.5 ).astype ('int32' ))
122130 print (label , (left , top ), (right , bottom ))
123131
124132 if top - label_size [1 ] >= 0 :
@@ -139,8 +147,8 @@ def main(args):
139147
140148 # Save image w/ bbox
141149 suffix = '.' + img_path .split ('.' )[- 1 ]
142- save_path = image .save (img_path .replace (suffix , '_onnx_out.' + suffix ))
143- image .show ()
150+ save_path = pil_image .save (img_path .replace (suffix , '_onnx_out.' + suffix ))
151+ pil_image .show ()
144152
145153def get_class (classes_path ):
146154 classes_path = os .path .expanduser (classes_path )
@@ -156,6 +164,32 @@ def get_anchors(anchors_path):
156164 anchors = [float (x ) for x in anchors .split (',' )]
157165 return np .array (anchors ).reshape (- 1 , 2 )
158166
167+ def pad_image (np_img ):
168+ """Use numpy operations to add padding around an image in
169+ numpy format (an array of rank 3 - so 3 channels) in order
170+ to create a square image.
171+ """
172+ h , w , c = np_img .shape [0 :3 ]
173+ side_len = max (h , w )
174+ # Create our square "palette" or area upon which the image data is placed
175+ # Make it kinda grey
176+ new_np_img = np .ones (side_len * side_len * c , dtype = 'float32' ).reshape (side_len ,
177+ side_len , c ) / 2.0
178+
179+ if h > w :
180+ for i in range (c ):
181+ old_patch = np_img [:, :, i ]
182+ pad = (side_len - w )// 2
183+ new_np_img [:, pad :(pad + w ), i ] = old_patch
184+ elif w > h :
185+ for i in range (c ):
186+ old_patch = np_img [:, :, i ]
187+ pad = (side_len - h )// 2
188+ new_np_img [pad :(pad + h ), :, i ] = old_patch
189+ else :
190+ return np_img , 0
191+ return new_np_img , pad
192+
159193def yolo_head (feats , anchors , num_classes , input_shape , calc_loss = False ):
160194 """Convert final layer features to bounding box parameters."""
161195 feats = K .constant (feats )
0 commit comments