def test_numpy(self): x = np.array([24, 48, 64, 96]) bbox = BBox2D(x) bb_np = bbox.numpy(mode=XYWH) assert np.array_equal(bb_np, x) bbox = BBox2D(x, mode=XYXY) bb_np_2 = bbox.numpy(mode=XYXY) assert np.array_equal(bb_np_2, x)
def test_numpy(self): x = np.array([24, 48, 64, 96]) bbox = BBox2D(x) bb_np = bbox.numpy(two_point=False) assert np.array_equal(bb_np, x) bbox = BBox2D(x, two_point=True) bb_np_2 = bbox.numpy(two_point=True) assert np.array_equal(bb_np_2, x)
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 load_annotations(self, index): # data_list has key from 0001 to 0090, num videos file_indices = self.data_list[index] dir_path = osp.join(self.data_dir, file_indices) bbox_path = osp.join(dir_path + "-box.txt") bboxes = [] cls_indices = [] with open(bbox_path, 'r') as file: lines = file.readlines() random = np.random.choice(len(lines), len(lines), replace=False) for i in random: lis = str(lines[i]).split("\n")[0].split(" ") box = BBox2D(list(map(float, lis[1:])), mode=1) if box.x1 <= 640.0 and box.x2 <= 640 and box.y1 <= 480 and box.y2 <= 480 \ and (box.x2 > box.x1) and (box.y2 > box.y1) \ and box.w > 20 and box.h > 20: bboxes.append(box.tolist(1)) cls_indices.append(self.classes[lis[0]]) annot = np.zeros((len(bboxes), 5)) annot[:, :4] = np.array(bboxes) annot[:, 4] = cls_indices return annot
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 test_aspect_ratio(): box = BBox2D([0, 0, 15, 15], mode=XYXY) box_ar = aspect_ratio(box, [0.5, 1, 2]) gt_box_ar = BBox2DList(np.array([[-3.5, 2., 18.5, 13.], [0., 0., 15., 15.], [2.5, -3, 12.5, 18.]]), mode=XYXY) assert box_ar == gt_box_ar
def test_tolist(self): bbox = BBox2D([24, 48, 64, 96]) bbox_list = bbox.tolist(mode=XYWH) for x, y in zip(bbox_list, [24, 48, 64, 96]): assert x == y bbox_list_2 = bbox.tolist(mode=XYXY) for x, y in zip(bbox_list_2, [24, 48, 87, 143]): assert x == y
def test_mul(self): bbox = BBox2D([24, 48, 64, 96], mode=XYXY) scaled_bbox = bbox * 2 assert np.array_equal(scaled_bbox.numpy(mode=XYXY), np.array([48, 96, 128, 192], dtype=np.float)) scaled_bbox_left = 2 * bbox assert np.array_equal(scaled_bbox_left.numpy(mode=XYXY), np.array([48, 96, 128, 192], dtype=np.float))
def test_tolist(self): bbox = BBox2D([24, 48, 64, 96]) bbox_list = bbox.tolist(two_point=False) for x, y in zip(bbox_list, [24, 48, 64, 96]): assert x == y bbox_list_2 = bbox.tolist(two_point=True) for x, y in zip(bbox_list_2, [24, 48, 87, 143]): assert x == y
def test_aspect_ratio(self): bbox = BBox2D([0, 0, 16, 16]) new_bbox = bbox.aspect_ratio(1) assert new_bbox.w == 16 and new_bbox.h == 16 new_bbox = bbox.aspect_ratio(0.5) assert new_bbox.w == 11 and new_bbox.h == 22 new_bbox = bbox.aspect_ratio(2) assert new_bbox.w == 23 and new_bbox.h == 12
def test_h(self): bbox = BBox2D([24, 48, 64, 96]) bbox.height = 93 assert bbox.height == 93 and bbox.y1 == 48 and bbox.y2 == 140 bbox.h = 93 assert bbox.height == 93 and bbox.h == 93 with pytest.raises(ValueError): bbox.h = -1 with pytest.raises(ValueError): bbox.height = -1
def test_w(self): bbox = BBox2D([24, 48, 64, 96]) bbox.width = 70 assert bbox.width == 70 and bbox.x1 == 24 and bbox.x2 == 93 bbox.w = 70 assert bbox.width == 70 and bbox.w == 70 with pytest.raises(ValueError): bbox.w = -1 with pytest.raises(ValueError): bbox.width = -1
def __getitem__(self, index): row = self.img_class_info.iloc[index] img = cv2.imread(row["image_path"], cv2.IMREAD_COLOR) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img_resize = cv2.resize(img, (740, 224)) # Cropping to 224x224 considering bounding box labels if row["class"] == 1: # Parse bboxes in image bbox_ls = [int(float(v)*(740/1240)) for v in row["bbox_l"].split(",")] bbox_ts = [int(float(v)*(224/375)) for v in row["bbox_t"].split(",")] bbox_rs = [int(float(v)*(740/1240)) for v in row["bbox_r"].split(",")] bbox_bs = [int(float(v)*(224/375)) for v in row["bbox_b"].split(",")] #print("Crop bound: [%.2f ~ %.2f]" % (min(bbox_ls), max(bbox_ls))) rand_box_idx = np.random.randint(0, len(bbox_ls)) l_bnd, r_bnd = max(0, int(bbox_rs[rand_box_idx]-224)), min(img_resize.shape[1]-224, int(bbox_ls[rand_box_idx])) if l_bnd > r_bnd: l_bnd, r_bnd = r_bnd, l_bnd elif l_bnd == r_bnd: r_bnd += 1 #print("Random cropping", (l_bnd, r_bnd)) crop_idx = np.random.randint(l_bnd, r_bnd) #crop_idx = np.random.randint(min(img_resize.shape[1]-224, max(0, int(min(bbox_ls)))), min(int(max(bbox_ls)), img_resize.shape[1]-224)+1) else: crop_idx = np.random.randint(0, img_resize.shape[1]-224) img_crop = img_resize[:, crop_idx:crop_idx+224] assert(crop_idx >= 0) target = {} label = 1.0 if row["class"] == 1 else 0.0 bboxs = [] # Using bounding box info if row["class"] == 1: for (bbox_l, bbox_t, bbox_r, bbox_b) in zip(bbox_ls, bbox_ts, bbox_rs, bbox_bs): # Calculate coverage? crop_box = {"x1": crop_idx, "x2": crop_idx+224, "y1": 0, "y2": 224} obj_box = {"x1": bbox_l, "x2": bbox_r, "y1": bbox_t, "y2": bbox_b} # Positive tile if any of the pedestrian bounding box has a coverage of over 80% coverage = get_iou(crop_box, obj_box) bboxs.append(BBox2D((bbox_l-crop_idx, bbox_t, bbox_r-crop_idx, bbox_b), mode=XYXY)) target["label"] = label target["bboxs"] = bboxs imgT = self.transform(img_crop) #print(imgT.shape, img_crop.shape) return (imgT, target)
def generate_bbox(b_mask): contours, hierarchy = cv2.findContours(b_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) boxes = [] for c in contours: (x, y, w, h) = cv2.boundingRect(c) boxes.append([x, y, x + w, y + h]) boxes = np.asarray(boxes) left, top = np.min(boxes, axis=0)[:2] right, bottom = np.max(boxes, axis=0)[2:] box = BBox2D((left, top, right, bottom), mode=1) return [left, top, right, bottom], box.height * box.width
def aspect_ratio(bbox: BBox2D, ratios): """ Enumerate box for each aspect ratio. """ cx, cy = bbox.center() w, h = bbox.w, bbox.h size = w * h size_ratios = size / ratios ws = np.round(np.sqrt(size_ratios)) hs = np.round(ws * ratios) stack = np.vstack((cx - 0.5 * (ws - 1), cy - 0.5 * (hs - 1), cx + 0.5 * (ws - 1), cy + 0.5 * (hs - 1))) boxes = BBox2DList(stack.T, two_point=True) return boxes
def test_contains_point(self): bbox = BBox2D([24, 48, 64, 96]) with pytest.raises(ValueError): bbox.contains(1) with pytest.raises(ValueError): bbox.contains([1, 2, 3]) # test tuple assert bbox.contains((35, 57)) # test list assert bbox.contains([35, 57]) # test numpy array assert bbox.contains(np.array([35, 57])) assert not bbox.contains([22, 57]) assert not bbox.contains([25, 47]) assert not bbox.contains([90, 57]) assert not bbox.contains([25, 144])
def aspect_ratio(bbox: BBox2D, ratios): """ Enumerate box for each aspect ratio. """ cx, cy = bbox.center() w, h = bbox.w, bbox.h size = w * h ratios = np.asarray(ratios, dtype=np.float) size_ratios = size / ratios ws = np.round(np.sqrt(size_ratios)) hs = np.round(ws * ratios) stack = np.vstack((cx - 0.5 * (ws - 1), cy - 0.5 * (hs - 1), cx + 0.5 * (ws - 1), cy + 0.5 * (hs - 1))) boxes = BBox2DList(stack.T, mode=XYXY) return boxes
def test_box_shapes(self): n = 10 l = [BBox2D(np.random.randint(0, 1024, size=4)) for _ in range(n)] bbl = BBox2DList(l) assert bbl.shape == (n, 4) lx1 = np.array([b.x1 for b in l]) lx2 = np.array([b.x2 for b in l]) ly1 = np.array([b.y1 for b in l]) ly2 = np.array([b.y2 for b in l]) assert lx1.shape == bbl.x1.shape assert ly1.shape == bbl.y1.shape assert lx2.shape == bbl.x2.shape assert ly2.shape == bbl.y2.shape assert np.array_equal(lx1, bbl.x1) assert np.array_equal(lx2, bbl.x2) assert np.array_equal(ly1, bbl.y1) assert np.array_equal(ly2, bbl.y2) assert bbl.x1.shape == (n, )
def test_x1(self): bbox = BBox2D([24, 48, 64, 96]) bbox.x1 = 25 assert bbox.x1 == 25 and bbox.w == 63
def test_non_equality(self): b = BBox2D([1, 2, 3, 4]) assert (b == [1, 2, 3, 4]) == False
def test_equality(self): b1 = BBox2D([1, 2, 3, 4]) b2 = BBox2D([1, 2, 3, 4]) assert b1 == b2 b3 = BBox2D([1, 2, 3, 5]) assert b1 != b3
def test_nonbasic_box(self): bbox2 = BBox2D([24, 48, 64, 96]) self.attributes_test(bbox2, 24, 48, 87, 143, 64, 96)
def test_basic_box(self): bbox1 = BBox2D([0, 0, 500, 500]) self.attributes_test(bbox1, 0, 0, 499, 499, 500, 500)
def test_y1(self): bbox = BBox2D([24, 48, 64, 96]) bbox.y1 = 51 assert bbox.y1 == 51 and bbox.h == 93
def test_constructor_5_items(self): with pytest.raises(ValueError): BBox2D([1, 2, 3, 4, 5]) with pytest.raises(ValueError): BBox2D(np.array([1, 2, 3, 4, 5]))
def test_x2(self): bbox = BBox2D([24, 48, 64, 96]) bbox.x2 = 89 assert bbox.x2 == 89 and bbox.w == 66
def test_invalid_x2(self): bbox = BBox2D([24, 48, 64, 96]) with pytest.raises(ValueError): bbox.x2 = bbox.x1 - 1
def test_constructor_invalid_type(self): with pytest.raises(TypeError): BBox2D("1, 2, 3, 4")
def test_invalid_y1(self): bbox = BBox2D([24, 48, 64, 96]) with pytest.raises(ValueError): bbox.y1 = bbox.y2 + 1
def test_copy_constructor(self): bbox1 = BBox2D([10, 11, 510, 511]) bbox2 = BBox2D(bbox1) self.attributes_test(bbox2, 10, 11, 519, 521, 510, 511)