def test_point_dist(self): """Test point distance calculation.""" data = (((0, 0), (8, 9), 12.0416), ((1, 3), (8, 9), 9.2195), ((-3, 34), (8, -99), 133.4541), ((3.5, 34.1), (8.0, 99.6), 65.6544)) for p1, p2, out in data: self.assertEqual(round(ft.point_dist(p1, p2), 4), out)
def test_point_dist(self): """Test point distance calculation.""" data = ( ((0,0), (8,9), 12.0416), ((1,3), (8,9), 9.2195), ((-3,34), (8,-99), 133.4541), ((3.5,34.1), (8.0,99.6), 65.6544) ) for p1, p2, out in data: self.assertEqual( round(ft.point_dist(p1, p2), 4), out )
def test_shape_360(self): """Test the shape:360 feature. Extracts the shape from two slightly rotated versions of the same image. Then the medium square error between the two extracted shapes is calculated and checked. """ max_error = 0.05 shape = [] for i, path in enumerate(IMAGES_ERYCINA): im_path = os.path.join(self.base_dir, path) img = cv2.imread(im_path) if img == None or img.size == 0: raise SystemError("Failed to read %s" % im_path) # Resize the image if it is larger then the threshold. img = scale_max_perimeter(img, MAX_SIZE) # Perform segmentation. mask = grabcut(img, 5, None, 1) # Create a binary mask. Foreground is made white, background black. bin_mask = np.where((mask == cv2.GC_FGD) + (mask == cv2.GC_PR_FGD), 255, 0).astype('uint8') # Obtain contours (all points) from the mask. contour = ft.get_largest_contour(bin_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) # Fit an ellipse on the contour to get the rotation angle. box = cv2.fitEllipse(contour) rotation = int(box[2]) # Extract the shape. intersects, center = ft.shape_360(contour, rotation) # For each angle save the mean distance from center to contour and # the standard deviation for the distances. means = [] sds = [] for angle in range(0, 360): distances = [] for p in intersects[angle]: d = ft.point_dist(center, p) distances.append(d) if len(distances) == 0: mean = 0 sd = 0 else: mean = np.mean(distances, dtype=np.float32) if len(distances) > 1: sd = np.std(distances, ddof=1, dtype=np.float32) else: sd = 0 means.append(mean) sds.append(sd) # Normalize and save result. means = cv2.normalize(np.array(means), None, -1, 1, cv2.NORM_MINMAX) sds = cv2.normalize(np.array(sds), None, -1, 1, cv2.NORM_MINMAX) shape.append([means, sds]) # Check the medium square error for the means. self.assertLess(error(shape[0][0].ravel(), shape[1][0].ravel(), mse), max_error) # Check the medium square error for the standard deviations. self.assertLess(error(shape[0][1].ravel(), shape[1][1].ravel(), mse), max_error)
def test_shape_360(self): """Test the shape:360 feature. Extracts the shape from two slightly rotated versions of the same image. Then the medium square error between the two extracted shapes is calculated and checked. """ max_error = 0.05 shape = [] for i, path in enumerate(IMAGES_ERYCINA): im_path = os.path.join(self.base_dir, path) img = cv2.imread(im_path) if img == None or img.size == 0: raise SystemError("Failed to read %s" % im_path) # Resize the image if it is larger then the threshold. img = scale_max_perimeter(img, MAX_SIZE) # Perform segmentation. mask = grabcut(img, 5, None, 1) # Create a binary mask. Foreground is made white, background black. bin_mask = np.where((mask==cv2.GC_FGD) + (mask==cv2.GC_PR_FGD), 255, 0).astype('uint8') # Obtain contours (all points) from the mask. contour = ft.get_largest_contour(bin_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) # Fit an ellipse on the contour to get the rotation angle. box = cv2.fitEllipse(contour) rotation = int(box[2]) # Extract the shape. intersects, center = ft.shape_360(contour, rotation) # For each angle save the mean distance from center to contour and # the standard deviation for the distances. means = [] sds = [] for angle in range(0, 360): distances = [] for p in intersects[angle]: d = ft.point_dist(center, p) distances.append(d) if len(distances) == 0: mean = 0 sd = 0 else: mean = np.mean(distances, dtype=np.float32) if len(distances) > 1: sd = np.std(distances, ddof=1, dtype=np.float32) else: sd = 0 means.append(mean) sds.append(sd) # Normalize and save result. means = cv2.normalize(np.array(means), None, -1, 1, cv2.NORM_MINMAX) sds = cv2.normalize(np.array(sds), None, -1, 1, cv2.NORM_MINMAX) shape.append([means, sds]) # Check the medium square error for the means. self.assertLess(error(shape[0][0].ravel(), shape[1][0].ravel(), mse), max_error) # Check the medium square error for the standard deviations. self.assertLess(error(shape[0][1].ravel(), shape[1][1].ravel(), mse), max_error)