def is_overlap(test_index, boxes): if (len(boxes) <= 1): return False # there is nothing to compare to test_box = boxes[test_index] # XMin XMax YMin YMax b1 = BBox2D([ test_box['XMin'], test_box['YMin'], test_box['XMax'], test_box['YMax'] ]) flag_inside = False for i in range(0, len(boxes)): if (i == test_index): continue box = boxes[i] b2 = BBox2D([box['XMin'], box['YMin'], box['XMax'], box['YMax']]) iou = jaccard_index_2d(b1, b2) if (iou > 0.1): flag_inside = True break return flag_inside
def test_invalid_jaccard_index_2d(): # sample bounxing boxes (x, y, w, h) # should result in `nan` and be corrected to 0 bbox1 = [39, 63, 0, 0] bbox2 = [54, 66, 0, 0] a = BBox2D(bbox1) b = BBox2D(bbox2) iou = jaccard_index_2d(a, b) logger.debug("IoU={0}".format(iou)) assert iou == 0
def test_single_jaccard_index_2d(): # sample bounxing boxes (x, y, w, h) bbox1 = [39, 63, 203, 112] bbox2 = [54, 66, 198, 114] a = BBox2D(bbox1) b = BBox2D(bbox2) iou = jaccard_index_2d(a, b) bbox1[2], bbox1[3] = bbox1[2] + bbox1[0] - 1, bbox1[3] + bbox1[1] - 1 bbox2[2], bbox2[3] = bbox2[2] + bbox2[0] - 1, bbox2[3] + bbox2[1] - 1 gt_iou = naive_intersection_over_union(bbox1, bbox2) logger.debug("IoU={0}, Naive IoU={1}".format(iou, gt_iou)) assert iou == gt_iou
def get_iou_score(b1, b2): b1 = BBox2D(b1.numpy(), mode=XYXY) b2 = BBox2D(b2.numpy(), mode=XYXY) return jaccard_index_2d(b1, b2)
def create_list_of_false_clips(max_try, number_of_clips, my_img, target_rows, window_x, window_y): index, height, width, color = my_img.shape # create false targets success = 0 list_of_boxes = [] for i in range( 0, max_try ): # randomly select 100 clips to try and get MAX_TRY images if (success >= number_of_clips): break #make sure the it is valid range if ((height - window_y) <= 2): return list_of_boxes if ((width - window_x) <= 2): return list_of_boxes #select a clip that is not in target y_min = int(random.randint(0, height - window_y)) x_min = int(random.randint(0, width - window_x)) # not needed anymore: y_max = random.gauss(window_y, window_y / 10.0) + y_min x_max = random.gauss(window_x, window_x / 10.0) + x_min #y_max = window_y + y_min #x_max = window_x + x_min #exception handling, should not happen if (y_max > height): print("lb error - ymax exceed height") continue if (x_max > width): print('lb error - xmax exceed width') continue #does this clip fall inside target clips? flag_inside = False for index, row in target_rows.iterrows(): box1 = BBox2D([x_min, y_min, x_max, y_max]) box2 = BBox2D([ int(width * row['XMin']), int(height * row['YMin']), int(width * row['XMax']), int(height * row['YMax']) ]) iou = jaccard_index_2d(box1, box2) if (iou > 0): flag_inside = True break # this clip is inside the target area so you cannot use it! if (flag_inside): continue #clip this image because it is not in the target box success = success + 1 list_of_boxes.append((int(x_min), int(y_min), int(x_max), int(y_max))) return list_of_boxes
def process_image(my_image, img_index, my_logger, true_bounding_boxes): #reate grid z-level 0 #img_arr1, list_of_boxes1 = img_handler.get_grid(my_image, 0.4, WINDOW_X, WINDOW_Y, 3) # 51 pixel #img_arr2, list_of_boxes2 = img_handler.get_grid(my_image, 1.0, WINDOW_X, WINDOW_Y, 3) # 128 px #img_arr3, list_of_boxes3 = img_handler.get_grid(my_image, 0.75, WINDOW_X, WINDOW_Y, 3) # 96 pixel img_arr1, list_of_boxes1 = img_handler.get_grid(my_image, 0.6375 , WINDOW_X, WINDOW_Y, 3) # 51 pixel img_arr2, list_of_boxes2 = img_handler.get_grid(my_image, 1.6, WINDOW_X, WINDOW_Y, 3) # 128 px img_arr3, list_of_boxes3 = img_handler.get_grid(my_image, 0.9, WINDOW_X, WINDOW_Y, 3) # 96 pixel number_of_clips = img_arr1.shape[0] + img_arr2.shape[0] + img_arr3.shape[0] num_channels = 3 img_arr = np.empty((number_of_clips, WINDOW_Y, WINDOW_X, num_channels), dtype=int) img_arr, index = add_arr(img_arr, img_arr1, 0) img_arr, index = add_arr(img_arr, img_arr2, index) img_arr, index = add_arr(img_arr, img_arr3, index) img_arr = img_arr / 255 list_of_boxes = [] # using naive method to concat list_of_boxes = add_list(list_of_boxes, list_of_boxes1) list_of_boxes = add_list(list_of_boxes, list_of_boxes2) list_of_boxes = add_list(list_of_boxes, list_of_boxes3) results = my_model.predict(img_arr) print("Prediction completed for image using grid clips") #filter for results that meet threshold for the object detector results_true = [] for index in range(0, len(results)): result = results[index] if (result[1] > detector_threshold): results_true.append([index, result[1], True]) # (!) you need to check to see if this result overlaps with previous one, if so does it have higher prediction on the class, if so then you should remove the other prediction and replace with this one for index_1 in range(0, len(results_true)): box_1 = list_of_boxes[results_true[index_1][0]] predict_box_1 = bbox.BBox2D([box_1[0], box_1[1], box_1[2], box_1[3]], mode=1) for index_2 in range(0, len(results_true)): if (index_1 == index_2): # dont compare itself continue # get the bounding box corresponding to this one box_2 = list_of_boxes[results_true[index_2][0]] predict_box_2 = bbox.BBox2D([box_2[0], box_2[1], box_2[2], box_2[3]], mode=1) # do these boxes overlap? iou = jaccard_index_2d(predict_box_1, predict_box_2) if (iou > 0.1): # is Box 1 beat? box_1_value = results_true[index_1][1] box_2_value = results_true[index_2][1] if (box_2_value >= box_1_value): #flag box one as no good results_true[index_1][2] = False #bump up box_2 value a little bit results_true[index_2][1] = results_true[index_2][1] * 1.00001 #now remove all entries where = False results_final = [] for index in range(0, len(results_true)): if results_true[index][2] == True: results_final.append(results_true[index]) # draw the boxes on the image ious = [] true_box_iou = [-1.0 for i in range(len(true_bounding_boxes))] for index in range(0, len(results_final)): #person found, draw the box box = list_of_boxes[results_final[index][0]] # 0 = index of the box #draw rectangle cv2.rectangle(my_image, (box[0], box[1]), (box[2], box[3]), (255, 255, 255), 3) # calculate area of overlap ious = [] max_iou = 0.0 for q in range(0, len(true_bounding_boxes)): true_bounding_box = true_bounding_boxes[q] predict_box = bbox.BBox2D([box[0], box[1], box[2], box[3]], mode=1) true_box = bbox.BBox2D(true_bounding_box,mode=1) iou = jaccard_index_2d(predict_box, true_box) ious.append(iou) max_iou = max(iou, max_iou) true_box_iou[q] = max(true_box_iou[q], iou) # record the iou my_logger.write_line(str(img_index) + "," + str(results_final[index][0])+ "," + str(max_iou) + "," + file_to_scan + "\n") # record any 0 iou left over on true_boxes, i.e. false negative for q in range(0, len(true_bounding_boxes)): if true_box_iou[q] <= 0: my_logger.write_line(str(img_index) + "," + str(-1)+ "," + str(true_box_iou[q]) + "," + file_to_scan + "\n") # calculate false negatives # that each bounding box to see if it has been identified as a head # calculate the average iou sum_iou = 0 for iou in ious: sum_iou = sum_iou + iou if len(ious) > 0: iou = sum_iou / len(ious) else: iou = 0.0 # draw the true boxes for box in true_bounding_boxes: cv2.rectangle(my_image, (box[0], box[1]), (box[2], box[3]), (255, 0, 0), 2) ## Write some Text font = cv2.FONT_HERSHEY_SIMPLEX bottomLeftCornerOfText = (10, 50) fontScale = 0.5 fontColor = (255,255,255) lineType = 2 ''' cv2.putText(my_image, 'Average IoU: ' + str(iou), bottomLeftCornerOfText, font, fontScale, fontColor, lineType) ''' #save image with bounding boxes to output folder file_handler.save_image('obj_detected' + str(img_index) +'.png', path = my_paths.OBJ_TEST_RESULTS, image_data = my_image, flag_png = True, remove_color = False) return