def show_hough_transform(image): h, theta, d = hough_line(canny(image)) fig, ax = plt.subplots(1, 3, figsize=(15, 6)) ax[0].imshow(image, cmap=cm.gray) ax[0].set_title('Input image') ax[0].set_axis_off() ax[1].imshow( np.log(1 + h), extent=[np.rad2deg(theta[-1]), np.rad2deg(theta[0]), d[-1], d[0]], cmap='gray', aspect=1 / 20) ax[1].set_title('Hough transform') ax[1].set_xlabel('Angles (degrees)') ax[1].set_ylabel('Distance (pixels)') ax[2].imshow(image, cmap=cm.gray) for _, angle, dist in zip(*hough_line_peaks(h, theta, d)): y0 = (dist - 0 * np.cos(angle)) / np.sin(angle) y1 = (dist - image.shape[1] * np.cos(angle)) / np.sin(angle) ax[2].plot((0, image.shape[1]), (y0, y1), '-r') ax[2].set_xlim((0, image.shape[1])) ax[2].set_ylim((image.shape[0], 0)) ax[2].set_axis_off() ax[2].set_title('Detected lines') plt.tight_layout() return hough_line_peaks(h, theta, d)
def search_lines(blob, angle_range, npoints=1000, min_distance=100, min_angle=300, threshold=None): thetas = np.linspace(np.deg2rad(angle_range[0]), np.deg2rad(angle_range[1]), npoints) hspace, angles, distances = hough_line(blob, thetas) if threshold is not None: accum, angles, dists = hough_line_peaks(hspace, angles, distances, min_distance=min_distance, min_angle=min_angle, threshold=threshold * np.max(hspace)) else: accum, angles, dists = hough_line_peaks(hspace, angles, distances, min_distance=min_distance, min_angle=min_angle) return accum, angles, dists
def test_hough_line_peaks_dist(): img = np.zeros((100, 100), dtype=np.bool_) img[:, 30] = True img[:, 40] = True hspace, angles, dists = tf.hough_line(img) assert len(tf.hough_line_peaks(hspace, angles, dists, min_distance=5)[0]) == 2 assert len(tf.hough_line_peaks(hspace, angles, dists, min_distance=15)[0]) == 1
def test_hough_line_peaks_dist(): img = np.zeros((100, 100), dtype=np.bool_) img[:, 30] = True img[:, 40] = True hspace, angles, dists = tf.hough_line(img) with expected_warnings(['`background`']): assert len(tf.hough_line_peaks(hspace, angles, dists, min_distance=5)[0]) == 2 assert len(tf.hough_line_peaks(hspace, angles, dists, min_distance=15)[0]) == 1
def test_hough_line_peaks_dist(): img = np.zeros((100, 100), dtype=np.bool_) img[:, 30] = True img[:, 40] = True hspace, angles, dists = tf.hough_line(img) with expected_warnings(['`background`']): assert len( tf.hough_line_peaks(hspace, angles, dists, min_distance=5)[0]) == 2 assert len( tf.hough_line_peaks(hspace, angles, dists, min_distance=15)[0]) == 1
def skew_correction(img, edges, threshold=None, _save=False, _save_path="./"): # get HoughLinesMap h, theta, d = hough_line(edges) h_p, theta_p, d_p = None, None, None # get peaks of the HoughLinesMap if threshold is None: h_p, theta_p, d_p = hough_line_peaks(h, theta, d) else: h_p, theta_p, d_p = hough_line_peaks(h, theta, d, threshold=threshold) # get the histogram of the values of the angles hist, bins = np.histogram(theta_p, 360) # the most probable angle is complementary to the skew c_skew = np.rad2deg( (bins[np.argmax(hist)] + bins[np.argmax(hist) + 1]) / 2) skew = 90 - c_skew if c_skew > 0 else -c_skew - 90 # create a rotation matrix and rotate the image around its center matrix = cv2.getRotationMatrix2D((img.shape[1] / 2, img.shape[0] / 2), -skew, 1) dst = cv2.warpAffine(img, matrix, (img.shape[1], img.shape[0]), cv2.INTER_NEAREST) if _save: _path_name = os.path.join(_save_path, "_skew_hough") if not os.path.isdir(_path_name): os.mkdir(_path_name) hough_lines_all = img.copy() hough_lines_true = img.copy() diag = np.sqrt(np.power(img.shape[0], 2) + np.power(img.shape[1], 2)) for _, angle, dist in zip(*(h_p, theta_p, d_p)): a, b = np.cos(angle), np.sin(angle) x0, y0 = a * dist, b * dist x1 = int(x0 + diag * (-b)) y1 = int(y0 + diag * (a)) x2 = int(x0 - diag * (-b)) y2 = int(y0 - diag * (a)) cv2.line(hough_lines_all, (x1, y1), (x2, y2), (0, 255, 0), 4) if bins[np.argmax(hist)] <= angle <= bins[np.argmax(hist) + 1]: cv2.line(hough_lines_true, (x1, y1), (x2, y2), (0, 255, 0), 4) cv2.imwrite(os.path.join(_path_name, "pre_skew.jpg"), img) cv2.imwrite(os.path.join(_path_name, "post_skew.jpg"), dst) cv2.imwrite(os.path.join(_path_name, "hough_lines_all.jpg"), hough_lines_all) cv2.imwrite(os.path.join(_path_name, "hough_lines_true.jpg"), hough_lines_true) return dst, -np.deg2rad(skew)
def calculate_rotation(image): # sometimes we snag corners, by cropping the left and right 10% of the image we focus only on the # vertical bars formed by the structure height, width = image.shape crop = int(width * 0.1) cropped_image = image[:, crop: width - crop] # Find edges that have a strong vertical direction vertical_edges = sobel_v(cropped_image) # Separate out the areas where there is a large amount of vertically-oriented stuff segmentation = segment_edge_areas(vertical_edges) # Draw a line that follows the center of the segments at each point, which should be roughly vertical # We should expect this to give us four approximately-vertical lines, possibly with many gaps in # each line skeletons = skeletonize(segmentation) # Use the Hough transform to get the closest lines that approximate those four lines hough = transform.hough_line(skeletons, np.arange(-constants.FIFTEEN_DEGREES_IN_RADIANS, constants.FIFTEEN_DEGREES_IN_RADIANS, 0.0001)) # Create a list of the angles (in radians) of all of the lines the Hough transform produced, with 0.0 # being completely vertical # These angles correspond to the angles of the four sides of the channels, which we need to # correct for angles = [angle for _, angle, dist in zip(*transform.hough_line_peaks(*hough))] if not angles: raise ValueError("Image rotation could not be calculated. Check the images to see if they're weird.") else: # Get the average angle and convert it to degrees offset = sum(angles) / len(angles) * 180.0 / math.pi if offset > constants.ACCEPTABLE_SKEW_THRESHOLD: log.warn("Image is heavily skewed. Check that the images are valid.") return offset
def rotate_pic(pic): """ rotate_pic finds the offset angle by measuring the grid with a Hough line transform. It then de-rotates by this amount """ # for speed, only look at a 500x500 slice in the center of the image centercut = np.copy( pic[int(pic.shape[0] / 2.) - 500:int(pic.shape[0] / 2.) + 500, int(pic.shape[1] / 2.) - 500:int(pic.shape[1] / 2.) + 500, 0]) # find the grid in the image by looking for brighter regions centermask = (centercut < 1) * (centercut > 0.8) h, theta, d = tf.hough_line(centermask, theta=np.linspace(np.pi / 2 - 0.2, np.pi / 2 + 0.2, 1000)) _, angles, dist = tf.hough_line_peaks(h, theta, d) # plt.figure() # plt.imshow(centermask) # for ii in range(len(angles)): # rho = dist[ii] # theta = angles[ii] # # y0 = (rho - 0 * np.cos(theta)) / np.sin(theta) # y1 = (rho - centermask.shape[1] * np.cos(theta)) / np.sin(theta) # # plt.plot([0,centermask.shape[0]],[y0,y1],'r-') angle = np.mean(angles * 180 / np.pi - 90) corrected_pic = tf.rotate(pic, angle, cval=1) return corrected_pic, angle
def test_hough_line_peaks_zero_input(): # Test to make sure empty input doesn't cause a failure img = np.zeros((100, 100), dtype='uint8') theta = np.linspace(0, np.pi, 100) hspace, angles, dists = transform.hough_line(img, theta) h, a, d = transform.hough_line_peaks(hspace, angles, dists) assert_equal(a, np.array([]))
def compute_hough_transform(line_det_map1, line_det_map2, re_focus_angle=True): # focus theta for cuneiform horizontal lines theta_range = np.linspace(np.deg2rad(83), np.deg2rad(97), 50) # theta_range = np.linspace(np.deg2rad(-90) ,np.deg2rad(90), 180) # normal range # Classic straight-line Hough transform (usually angles from -90 to +90) h, theta, d = hough_line(line_det_map1, theta=theta_range) # debug # plt.imshow(np.log(1 + h), extent=[np.rad2deg(theta[-1]), np.rad2deg(theta[0]), d[-1], d[0]], cmap='gray', aspect=1/1.5) # plt.show() # focus angle and re-run if re_focus_angle: # get peaks accum, angles, dists = hough_line_peaks(h, theta, d, min_distance=1, min_angle=16, num_peaks=50) # get median angle m_angle = np.median(np.rad2deg(angles)) # modify theta theta_range = np.linspace(np.deg2rad(m_angle - 2), np.deg2rad(m_angle + 2), 50) theta_range2 = np.linspace(np.deg2rad(m_angle - 3), np.deg2rad(m_angle + 3), 50) # Classic straight-line Hough transform (usually angles from -90 to +90) h, theta, d = hough_line(line_det_map2, theta=theta_range) return h, theta, d, theta_range, theta_range2
def jet_detect(img, calibratemean, calibratestd, x): mean, std = image_stats(img) # compare mean & calibratemean if (mean < calibratemean * 0.8) or (mean > calibratemean * 1.2): print('no jet') for c in range(x): try: # binary = (img / (mean + 2 * std * 0.90 ** c)).astype(np.uint8) # binary = cv2.adaptiveThreshold(img, 1, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 50, 2) # binary = cv2.bitwise_not(imagem) # lines = cv2.HoughLines(binary, 1, np.radians(0.25), 30) # rho, theta = lines[0][0] binary = canny(img, sigma=2, use_quantiles=True, low_threshold=0.9, high_threshold=0.99) fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, figsize=(8, 3), sharex=True, sharey=True) ax1.imshow(img, cmap=plt.cm.gray) ax2.imshow(binary, cmap=plt.cm.gray) plt.show() h, theta, d = hough_line(binary) accum, angles, ds = hough_line_peaks(h, theta, d, min_distance=2) print(accum) print(angles) print(ds) # if (theta > math.radians(45)) and (theta < math.radians(135)): # print('invalid jet') # if (get_jet_width(img, rho, theta) * pxsize > 0.1): # print('invalid jet') # for rho, theta in lines[0]: # jetValid = true # if (theta > math.radians(70)): # jetValid = False # width = get_jet_width(binary, rho, theta) # if (width > [x]): # jetValid = False # if (jetValid == False): # reject jet except Exception: print(c) continue else: # show binary image # cv2.imshow('binary', binary) # cv2.waitKey(0) # cv2.destroyAllWindows() # return rho, theta # return 0, 0 return angles[0], ds[0] raise ValueError('unable to detect jet')
def get_orientation(image, debug=False): bin_image = (image > threshold_li(image)) * 1 dilated = scipy.ndimage.morphology.binary_dilation(bin_image, iterations=30) labeled, num_regions = mh.label(dilated) sizes = mh.labeled.labeled_size(labeled) mh.labeled.labeled_size(labeled) if len(sizes) > 2: too_small = np.where(sizes < np.flip(np.sort(sizes))[1]) labeled = mh.labeled.remove_regions(labeled, too_small) labeled = (labeled / np.max(np.unique(labeled))).astype(np.int) skeleton = skeletonize(labeled) h, theta, d = hough_line(skeleton) origin = np.array((0, skeleton.shape[1])) for _, angle, dist in zip(*hough_line_peaks(h, theta, d)): y0, y1 = (dist - origin * np.cos(angle)) / np.sin(angle) gradient = (y0 - y1) / origin[1] if debug == False: return math.degrees(np.arctan(gradient)) elif debug == True: f, ax = plt.subplots(figsize=(40, 20)) plt.imshow(bin_image) plt.show() f, ax = plt.subplots(figsize=(40, 20)) plt.imshow(dilated) plt.show() f, ax = plt.subplots(figsize=(40, 20)) plt.imshow(skeleton) plt.show() return math.degrees(np.arctan(gradient))
def calculate(self, image: np.ndarray, disk_size: int=9, mean_threshold: int=100, min_object_size: int=750) -> float: # Find edges that have a strong vertical direction vertical_edges = sobel_v(image) # Separate out the areas where there is a large amount of vertically-oriented stuff segmentation = self._segment_edge_areas(vertical_edges, disk_size, mean_threshold, min_object_size) # Draw a line that follows the center of the segments at each point, which should be roughly vertical # We should expect this to give us four approximately-vertical lines, possibly with many gaps in # each line skeletons = skeletonize(segmentation) # Use the Hough transform to get the closest lines that approximate those four lines hough = transform.hough_line(skeletons, np.arange(-constants.FIFTEEN_DEGREES_IN_RADIANS, constants.FIFTEEN_DEGREES_IN_RADIANS, 0.0001)) # Create a list of the angles (in radians) of all of the lines the Hough transform produced, with 0.0 # being completely vertical # These angles correspond to the angles of the four sides of the channels, which we need to # correct for angles = [angle for _, angle, dist in zip(*transform.hough_line_peaks(*hough))] if not angles: raise ValueError("Image rotation could not be calculated. Check the images to see if they're weird.") else: # Get the average angle and convert it to degrees offset = sum(angles) / len(angles) * 180.0 / math.pi if offset > constants.ACCEPTABLE_SKEW_THRESHOLD: log.warn("Image is heavily skewed. Check that the images are valid.") return offset
def detect_vertical_lines(data, max_deviation_from_vertical=1, row_begin=100, row_end=-100, min_distance=50): if "cropped_original" in data: image = data["cropped_original"] else: image = data["original"] image = np.gradient(image)[1] #Vertical component of gradient image = image[row_begin:row_end, :] h, theta, d = hough_line(image) #hough transform h[:, :90 - max_deviation_from_vertical] = 0 #Mask out areas that relate to non vertical lines h[:, 90 + max_deviation_from_vertical:] = 0 h = np.log(1 + h) #log scale for better visibility fx = [] for _, angle, dist in zip( *hough_line_peaks(h, theta, d, min_distance=min_distance)): y0 = (dist) / np.sin(angle) #y for x = 0 y1 = (dist - image.shape[1] * np.cos(angle)) / np.sin( angle) #y for x = image.shape[1] intercept = y0 slope = (y1 - y0) / float(image.shape[1]) fx.append([slope, intercept]) data["houghlines"] = fx #ax.plot(x, intercept+x*slope, '-r') return data
def hough_transform(self, err=np.pi * 1 / 12, threshold=0.49, ks=3): # -------------------- scikit-image hough line transform -------------------- theta = np.linspace(-np.pi * 1 / 4, np.pi * 3 / 4, 180) h, theta, distance = hough_line(self.edges_img, theta) hits, phi, rho = hough_line_peaks(h, theta, distance, min_distance=10, min_angle=50, threshold=threshold * h.max(), num_peaks=np.inf) lines = list(zip(phi, rho)) # -------------------- OpenCV hough line transform -------------------- # lines = cv2.HoughLines(self.edges_img.astype(np.uint8), 1, np.pi / 180, threshold).reshape(-1, 2) # lines = list(map(lambda x: tuple(x), lines[:, ::-1].tolist())) # -------------------- discriminate between vertical and horizontal lines -------------------- self.lines = dict(v=[], h=[], o=[]) for ix, (phi, _) in enumerate(lines): if abs(phi) < err or abs(phi - np.pi) < err: # vertical self.lines['v'].append(lines[ix]) elif abs(phi - np.pi / 2) < err: # horizontal self.lines['h'].append(lines[ix]) else: # irrelevant lines self.lines['o'].append(lines[ix]) return self.lines
def hough_transform(binary): try: h, angles, d = hough_line(binary) res = hough_line_peaks(h, angles, d, min_distance=1, threshold=int(binary.shape[0] / 3)) except Exception: raise ValueError('ERROR hough: not a jet') fig, axes = plt.subplots(1, 2) axes[0].imshow(binary) axes[1].imshow(binary) valid = [] for _, theta, dist in zip(*res): jetValid = True if (theta < np.radians(-45)) or (theta > np.radians(45)): print('ERROR angle: not a jet') jetValid = False yint = dist / np.sin(theta) xint = np.tan(theta) * yint if (dist < 0) or (xint > binary.shape[1]): print('ERROR xint: not a jet') jetValid = False if (jetValid): y0 = (dist - 0 * np.cos(theta)) / np.sin(theta) y1 = (dist - binary.shape[1] * np.cos(theta)) / np.sin(theta) axes[1].plot((0, binary.shape[1]), (y0, y1), 'r') valid.append([theta, dist]) axes[1].set_xlim((0, binary.shape[1])) axes[1].set_ylim((binary.shape[0], 0)) return valid
def y_coordinate_extractor(img_arr): middle_y_coor = 0.5 * img_arr.shape[0] image = rgb2gray(img_arr) image = np.asarray(image > 0.5, dtype=np.float32) edges = filters.sobel_h(image) h, theta, d = hough_line(edges) upper_y = img_arr.shape[0] lower_y = 0 thres_upp = img_arr.shape[0] thres_low = img_arr.shape[0] for _, angle, dist in zip(*hough_line_peaks(h, theta, d)): y0 = (dist - 0 * np.cos(angle)) / np.sin(angle) y1 = (dist - image.shape[1] * np.cos(angle)) / np.sin(angle) avg = (y0 + y1) / 2 if avg - middle_y_coor < thres_low and avg - middle_y_coor > 0: lower_y = avg thres_low = avg - middle_y_coor if middle_y_coor - avg < thres_upp and middle_y_coor - avg > 0: upper_y = avg thres_upp = middle_y_coor - avg return upper_y, lower_y
def filter_errors(image_folder, image_list, threshold=0.5, plot=False): """ This function filters errenous images out of an the image_list. It is based on the notion that erroneous images show slightly of horizontal bands over the image. Hough line detection is used to detect these lines. The erroneous images are separated from the correct images by thresholding the standard deviation over the line anlges. Parameters ---------- image_folder : string path to folder where images are located image_list : list list of image filenames (strings) threshold : float threshold on standard deviation of angles, under this threshold the images are considered erroneous. The default is 0.5. plot : boolean, optional if true the detected lines are plotted. Only for 1 image. Returns ------- errors : list list with the erroneous image filenames (strings) fig : matplotlib Figure, only if plot = True figure with the lines detected in the image Tested ------ bad_images = ['40_a.npy', '163_a.npy', '163_b.npy', '269_a.npy', '313_b.npy', '122_b.npy', '277_a.npy', '328_b.npy', '311_a.npy', '184_b.npy', '398_b.npy', '158_a.npy', '356_b.npy'] good_images = ['240_a.npy', '451_b.npy', '558_b.npy','617_a.npy', '61_b.npy','267_b.npy','490_b.npy','243_b.npy', '685_b.npy','696_a.npy'] good_images = ['318_a.npy', '527_b.npy', '100_a.npy', '100_b.npy', '101_a.npy', '101_b.npy', '102_a.npy', '102_b.npy', '103_a.npy', '103_b.npy', '104_a.npy', '104_b.npy', '105_a.npy','105_b.npy', '107_a.npy'] """ errors = [] for image in image_list: im = np.load((os.path.join(image_folder, image)))[:, :, 0] # edge filter using canny algorithm edges = canny(im, sigma=6) # detect lines using hough transform test_angles = np.linspace(np.pi / 4, 7 * np.pi / 4 / 2, 360 / 4) h, theta, d = hough_line(edges, theta=test_angles) accum, angle, dist = hough_line_peaks(h, theta, d) if plot: assert len(image_list) == 1, "plot can only be used for 1 image" fig = plot_detectedlines(im, h, theta, d) # filter based on standard deviation of angles std = np.std(angle) print(std) if std < threshold: errors.extend([image]) if plot: return errors, fig else: return errors
def manipExtract(image, thetaInit, method='standard'): if np.issubdtype(image.dtype, 'bool'): edge = image else: edge = canny_cv(image) rows, cols = image.shape h, theta, d = hough_line(edge, theta=np.arange(thetaInit - .3, thetaInit + .3, .01)) try: _, angle, dist = hough_line_peaks(h, theta, d, min_distance=1, num_peaks=1) y0 = (dist - 0 * np.cos(angle)) / np.sin(angle) y1 = (dist - cols * np.cos(angle)) / np.sin(angle) except IndexError: # i think this error is being thrown if the manipulator is not found? y0 = np.NaN y1 = np.NaN angle = np.NaN dist = np.NaN return y0, y1, angle, dist
def show_hough_transform(image, filename): low_dark = (0, 0, 0) high_dark = (50, 50, 50) only_dark = cv2.inRange(img, low_dark, high_dark) h, theta, d = hough_line(canny(only_dark)) # вычисляем преобразование Хаффа от границ изображения fig, ax = plt.subplots(1, 3, figsize=(15, 6)) ax[0].imshow(only_dark, cmap=cm.gray) ax[0].set_title('Input image') ax[0].set_axis_off() ax[1].imshow(np.log(1 + h), extent=[np.rad2deg(theta[-1]), np.rad2deg(theta[0]), d[-1], d[0]], cmap='gray', aspect=1/20) ax[1].set_title('Hough transform') ax[1].set_xlabel('Angles (degrees)') ax[1].set_ylabel('Distance (pixels)') ax[2].imshow(image, cmap=cm.gray) for _, angle, dist in zip(*hough_line_peaks(h, theta, d)): y0 = (dist - 0 * np.cos(angle)) / np.sin(angle) y1 = (dist - image.shape[1] * np.cos(angle)) / np.sin(angle) ax[2].plot((0, image.shape[1]), (y0, y1), '-r') ax[2].set_xlim((0, image.shape[1])) ax[2].set_ylim((image.shape[0], 0)) ax[2].set_axis_off() ax[2].set_title('Detected lines') plt.tight_layout() plt.savefig(filename, bbox_inches='tight') plt.close(fig)
def deskew(image, edge=True): """Rotate image so that lines will be horizontally aligned. :param image: ndarray, 2D binarized image :return: ndarray, 2D deskewed image """ rows, cols = image.shape image2 = canny(image, 5) if edge else image plt.imshow(image2, cmap='gray') plt.show() plt.imshow(image, cmap='gray') skew = 0 _, angles, dists = hough_line_peaks(*hough_line(image2)) for angle, dist in zip(angles, dists): y0 = (dist - 0 * np.cos(angle)) / np.sin(angle) y1 = (dist - cols * np.cos(angle)) / np.sin(angle) plt.plot((0, cols), (y0, y1), '-r') skew += 90 + np.rad2deg(angle) if angle < 0 else np.rad2deg(angle) - 90 skew /= angles.shape[0] if angles.shape[0] != 0 else 1 print(skew) plt.xlim([0, cols]) plt.ylim([rows, 0]) plt.show() return rotate(image, skew, resize=True, mode='constant', cval=255, preserve_range=True).astype(np.uint8)
def estimate_corner_lines(corner_region, corner_type, image_size): ''' Estimate the line parameters for the edges of the given marker corner Inputs: - corner_region: regionprops for the given corner of the marker - corner_type: either 'BL' for bottom-left or 'TR' for top-right - image_size: tuple of original camera image's size Return: A list of length 2 holding the line parameters of horizontal and vertical edges of the marker ''' corner_miny, corner_minx, corner_maxy, corner_maxx = corner_region.bbox # Pad the corner image to match the size of the entire image corner_image = util.pad(corner_region.intensity_image, ((corner_miny, image_size[0] - corner_maxy), (corner_minx, image_size[1] - corner_maxx)), mode='constant', constant_values=0) # Perform edge detection and Hough line transform corner_edges = feature.canny(corner_image, sigma=0) corner_hough = transform.hough_line(corner_edges, theta=np.linspace( -np.pi / 2, np.pi / 2, 360)) corner_hough_peaks = list( zip(*transform.hough_line_peaks( *corner_hough, min_angle=45, num_peaks=2))) corner_lines = [] def is_horizontal(peak): return abs(np.rad2deg(peak[1])) > 75 def is_vertical(peak): return abs(np.rad2deg(peak[1])) <= 15 # Categorized the detected lines as vertical or horizontal horizontal_peaks = list(filter(is_horizontal, corner_hough_peaks)) vertical_peaks = list(filter(is_vertical, corner_hough_peaks)) # Add the first estimated horizontal line if horizontal_peaks: corner_lines.append(horizontal_peaks[0]) else: # Create a horizontal line from the bottom edge (if BL type) or top edge (if TR type) angle = np.pi / 2 dist = corner_maxy if corner_type == 'BL' else corner_miny corner_lines.append((0, angle, dist)) # Add the first estimated vertical line if vertical_peaks: corner_lines.append(vertical_peaks[0]) else: # Create a vertical line from the left edge (if BL type) or right edge (if TR type) angle = 0.001 dist = corner_minx if corner_type == 'BL' else corner_maxx corner_lines.append((0, angle, dist)) return corner_lines
def is_arrow_check(img_edges): # Find lines using hough transform hspace, theta, dists = transform.hough_line(img_edges) # Extract lines lines = transform.hough_line_peaks(hspace, theta, dists, num_peaks=4) # Convert lines to list of lines lines = np.array(list(zip(*lines)), dtype=[('hspace', np.uint64), ('angle', np.float), ('dist', np.float)]) if len(lines) != 4: return False lines = list(lines) dists = [] while lines: found = False for i in range(1, len(lines)): if angle_difference(lines[0], lines[i]) < 0.1: # Found a line parallel to lines[0] dists.append(abs(lines[0][2] - lines[i][2])) del lines[i] del lines[0] found = True break if not found: break if len(dists) == 2 and abs(12.0 - dists[0]) < 5.0 and abs(12.0 - dists[1]) < 5.0: return True return False
def get_limits(self, max_width_proportion=0.45): """Busca dos lineas paralelas que correspondan al bajalenguas Args: max_width_proportion (float): Maxima proporcion del alto de la imagen (considerada apaisada) que puede abarcar el ancho del bajalenguas. Returns: status (str): Una descripcion del resultado de la busqueda. limits ([angles, dists]): Contiene dos numpy arrays. El primero contiene dos angulos y el segundo dos distancias. Cada par de angulo-distancia define la recta de arriba y de abajo del bajalenguas. """ max_angle_diff = 5. / 180 * np.pi im_width = np.amin(self.curr_im_lowres_g.shape) min_dist = int(1. / 6 * im_width) sigma = 3 edges = canny(self.curr_im_lowres_g, sigma) while np.mean(edges) < 0.01: sigma = (sigma - 0.1) if sigma < 0: break edges = canny(self.curr_im_lowres_g, sigma) self.edges = edges h, theta, d = hough_line(edges) params = hough_line_peaks(h, theta, d, num_peaks=6, min_distance=min_dist) self.params = params # Normalizo al ancho de la imagen dists = params[2] / im_width angles = params[1] dangles = pairwise_distances(angles[:, None]) dangles = np.dstack((dangles, np.abs(dangles - np.pi))) dangles = np.amin(dangles, 2) np.fill_diagonal(dangles, np.inf) i, j = np.unravel_index(np.argmin(dangles), dangles.shape) angles = np.array([angles[i], angles[j]]) dists = np.array([dists[i], dists[j]]) # Ordeno los bordes para que el de arriba quede primero norm_dist = np.sign(angles) * dists sort_idx = np.argsort(norm_dist) if i == j: status = 'Sin bajalenguas' limits = None elif dangles[i, j] > max_angle_diff: status = 'Sin bajalenguas - mal paralelismo' limits = None elif abs(np.diff(norm_dist)) > max_width_proportion: status = 'Sin bajalenguas - mal ratio' limits = None elif abs(angles[0]) < 20. / 180 * np.pi: status = 'Sin bajalenguas - mala inclinacion' limits = None else: status = 'Con bajalenguas' limits = [angles[sort_idx], dists[sort_idx]] return status, limits
def _determine_rotation_offset(image): """ Finds rotational skew so that the sides of the central trench are (nearly) perfectly vertical. :param image: raw image data in a 2D (i.e. grayscale) numpy array :type image: np.array() """ segmentation = create_vertical_segments(image) # Draw a line that follows the center of the segments at each point, which should be roughly vertical # We should expect this to give us four approximately-vertical lines, possibly with many gaps in each line skeletons = skeletonize(segmentation) # Use the Hough transform to get the closest lines that approximate those four lines hough = transform.hough_line( skeletons, np.arange(-Constants.FIFTEEN_DEGREES_IN_RADIANS, Constants.FIFTEEN_DEGREES_IN_RADIANS, 0.0001)) # Create a list of the angles (in radians) of all of the lines the Hough transform produced, with 0.0 being # completely vertical # These angles correspond to the angles of the four sides of the channels, which we need to correct for angles = [ angle for _, angle, dist in zip(*transform.hough_line_peaks(*hough)) ] if not angles: log.warn( "Image skew could not be calculated. The image is probably invalid." ) return 0.0 else: # Get the average angle and convert it to degrees offset = sum(angles) / len(angles) * 180.0 / math.pi if offset > Constants.ACCEPTABLE_SKEW_THRESHOLD: log.warn( "Image is heavily skewed. Check that the images are valid.") return offset
def removeChessboard(img): # Get the major lines in the image edges, dilatedEdges, (h, theta, d) = findLines(img) # Create image with ones to fill inn lines lines = np.ones(img.shape[:2]) # Add lines to image as zeroes for _, angle, dist in zip(*hough_line_peaks(h, theta, d)): y0 = (dist - 0 * np.cos(angle)) / np.sin(angle) y1 = (dist - img.shape[1] * np.cos(angle)) / np.sin(angle) x, y = line(int(y1), 0, int(y0), img.shape[1] - 1) x = np.clip(x, 0, img.shape[0] - 1) y = np.clip(y, 0, img.shape[1] - 1) lines[x, y] = 0 # Remove border edges from image with all edges w = 4 edges = np.pad(edges[w:img.shape[0] - w, w:img.shape[1] - w], w, mode='constant') # Erode the lines bigger, such that they cover the original lines lines = erosion(lines, square(13)) # Remove major lines and close shape paths removedChessboard = closing(edges * lines, square(8)) return removedChessboard
def align_hough(input_Image): #Converte a imagem do padrão RGB para uma imagem binária monImage = color.rgb2gray(input_Image) monImage = feature.canny(monImage) houghTransform, angles, d = transform.hough_line(monImage, theta=np.linspace( -np.pi / 2, np.pi / 2, 180)) hTP, angles, d = transform.hough_line_peaks(houghTransform, angles, d) angles = np.rad2deg(angles) + 90 angles = np.round(angles, 0) angles = angles.astype(int) angle = np.bincount(angles).argmax() if (angle > 90 and angle < 180): angle = angle + 180 transformedImage = transform.rotate(input_Image, angle, resize=True) #Pós processamento para remoção das bordas resultantes da rotação transformedImage = border_remove(transformedImage) return transformedImage, angles[0]
def classic_hough_line(img): edges = canny(img, sigma=10, low_threshold=0.05, high_threshold=0.10) # Classic straight-line Hough transform h, theta, d = hough_line(edges, ) # Generating figure 1 fig, axes = plt.subplots(1, 3, figsize=(15, 6)) ax = axes.ravel() ax[0].imshow(img, cmap=cm.gray) ax[0].set_title('Input image') ax[0].set_axis_off() ax[1].imshow( np.log(1 + h), extent=[np.rad2deg(theta[-1]), np.rad2deg(theta[0]), d[-1], d[0]], cmap=cm.gray, aspect=1 / 1.5) ax[1].set_title('Hough transform') ax[1].set_xlabel('Angles (degrees)') ax[1].set_ylabel('Distance (pixels)') ax[1].axis('image') ax[2].imshow(img, cmap=cm.gray) for _, angle, dist in zip(*hough_line_peaks(h, theta, d)): y0 = (dist - 0 * np.cos(angle)) / np.sin(angle) y1 = (dist - img.shape[1] * np.cos(angle)) / np.sin(angle) ax[2].plot((0, img.shape[1]), (y0, y1), '-r') ax[2].set_xlim((0, img.shape[1])) ax[2].set_ylim((img.shape[0], 0)) ax[2].set_axis_off() ax[2].set_title('Detected lines') plt.tight_layout() plt.show()
def houghTransform(s, sThreshold): """ DESCRIPTION: This function computes the hough transform, for determining the shock front. see: https://scikit-image.org/docs/dev/auto_examples/edges/plot_line_hough_transform.html INPUT: s - the 2D density field ln(\rho/\rho_0) sThreshold - the threshold for the field. Densities above this threshold will be used to identify the shock front OUTPUT: x - x coordinate of the Hough transform y - y coordinate of the Hough transform xMin - x coordinate of the window around the shock front yMin - y coordinate of the window around the shock front sMask - the mask, s.max() * sThreshold (for checking) """ print("Calculating the Hough Transform.") # Create a mask on s for detecting the ionisation front sMask = s > s.max() * sThreshold # run a hough transform on the masked density data dtheta = 0.05 # the d\theta around a vertical line approximation for the ion. front. # create a sample of test angles close to a vertical line tested_angles = np.linspace(np.pi + dtheta, np.pi - dtheta, 90) # run the Hough transform origin = np.array((0, sMask.shape[1])) # define the origin coordinate h, theta, d = hough_line(sMask, theta=tested_angles) # define the H. transform # pick the most dominant line from the H. transform hspace, angle, dist = hough_line_peaks(h, theta, d) # extract param. values y0, y1 = (dist[0] - origin * np.cos(angle[0])) / np.sin(angle[0]) # pick out the cooridinates in the density field from the line and create a window x, y = sampleHough(origin, [y0, y1]) xMin = x - windowSize xMax = x + windowSize # Just taking a single value at the for the window xMin = xMin[0] xMax = xMax[0] # Make sure the window size isn't larger than the actual data domain if xMin < 0: xMin = 0 elif xMin > sMask.shape[0] - 1: xMin = sMask.shape[0] - 1 # and for xMax too if xMax < 0: xMax = 0 elif xMax > sMask.shape[0] - 1: xMax = sMask.shape[0] - 1 return x, y, xMin, xMax, sMask
def alignRodCellvertically( Image, ifbinary=False, thres=0.4, #thres value for binary image plotting=False, # plotting the detected rod-direction inverse=False): """ automatically align rod-shaped cells vertically """ #image = util.ReadImg(Imagename).astype(np.uint8) #grey = cv2.cvtColor(rod,cv2.COLOR_RGB2GRAY) if ifbinary: binaryimage = Image else: if inverse: dummy, binaryimage = cv2.threshold( cv2.cvtColor(Image, cv2.COLOR_BGR2GRAY), 255 * thres, 255, cv2.THRESH_BINARY_INV) else: dummy, binaryimage = cv2.threshold( cv2.cvtColor(Image, cv2.COLOR_BGR2GRAY), 255 * thres, 255, cv2.THRESH_BINARY) # detect the direction of rod using the hough line detection # note, the angle unit is radian (1 radian = 57.2958 degree) Hspace, Angle, Dist = transform.hough_line(binaryimage) # find the peaks in the hough space peaks = transform.hough_line_peaks(Hspace, Angle, Dist) if len(peaks[0]) > 1: raise RuntimeError( 'More than 1 directions exist, plz use a image that contains only 1 direction' ) angle = peaks[1][0] dist = peaks[2][0] # now rotate the image based one the angle radianTodegree = 57.29 rotatedImage = imutils.rotate(Image, angle * radianTodegree) if plotting: origin = np.array((0, binaryimage.shape[1])) line = (dist - origin * np.cos(angle)) / np.sin(angle) plt.subplot(1, 2, 1) plt.imshow(Image) plt.plot(origin, line, 'r-') plt.ylim([0, binaryimage.shape[1]]) plt.xticks([]) plt.yticks([]) plt.title('detected directions') plt.subplot(1, 2, 2) plt.imshow(rotatedImage) plt.xticks([]) plt.yticks([]) plt.title('align vertically') return rotatedImage
def identify_based_on_lines(img_edges): # Find lines using hough transform hspace, theta, dists = transform.hough_line(img_edges) # Extract lines lines = transform.hough_line_peaks(hspace, theta, dists, num_peaks=10) # Convert lines to list of lines lines = np.array(list(zip(*lines)), dtype=[('hspace', np.uint64), ('angle', np.float), ('dist', np.float)]) shape_likeness = np.zeros(Shape.count) for i in range(1, Shape.count): shape = Shape.iterator[i] if shape == Shape.CAKE: hval = 0.0 if len(lines) >= 3: hval = abs(((lines[0][0] + lines[1][0]) * 0.5) - lines[2][0]) if hval >= 5.0: shape_likeness[i] = 0.0 else: shape_likeness[i] = 10.0 else: shape_likeness[i] = abs(shape.line_count - len(lines)) return shape_likeness
def test_hough_line_peaks_single_angle(): # Regression test for gh-4814 # This code snippet used to raise an IndexError img = np.random.random((100, 100)) tested_angles = np.array([np.pi / 2]) h, theta, d = transform.hough_line(img, theta=tested_angles) accum, angles, dists = transform.hough_line_peaks(h, theta, d, threshold=2)
def Hough(image, filter='Canny', sigma=3, show=False): ''' Read in an image and get the peak Hough line Parameters: image: The image to be read filter: Set whether to use Canny (default) or Sobel edge detection sigma: Sensitivity for Canny show: boolean to show the plot Hough plot Return: max_peak: The horizon line corresponding to the max peak edges: the edges ''' img_gray = color.rgb2gray(image) # Grayscale if (filter == 'Canny'): # Edge detection edges = feature.canny(img_gray, sigma=3) # Canny if (filter == 'Sobel'): edges = filters.sobel(img_gray) # Use Sobel # Hough transformation h, theta, d = hough_line(edges) # Get the max_peak max_peak = hough_line_peaks(h, theta, d, num_peaks=1) if(show): fig = plt.figure() plt.imshow(np.log(1 + h), extent=[np.rad2deg(theta[-1]), np.rad2deg(theta[0]), d[-1], d[0]], cmap=plt.cm.gray, aspect=1 / 1.5) return max_peak, edges
def test_hough_line_peaks_num(): img = np.zeros((100, 100), dtype=np.bool_) img[:, 30] = True img[:, 40] = True hspace, angles, dists = transform.hough_line(img) assert len(transform.hough_line_peaks(hspace, angles, dists, min_distance=0, min_angle=0, num_peaks=1)[0]) == 1
def align_with_boarder(image, sigma=1): edges = ft.canny(image, sigma=sigma) # edges = abs(fil.sobel_v(image)) h, theta, d = tf.hough_line(edges) a, rot_angle, c = tf.hough_line_peaks(h, theta, d, min_distance=0) image = rotate(image, np.rad2deg(rot_angle[0])) return image
def test_hough_line_peaks(): img = np.zeros((100, 150), dtype=int) rr, cc = line(60, 130, 80, 10) img[rr, cc] = 1 out, angles, d = tf.hough_line(img) out, theta, dist = tf.hough_line_peaks(out, angles, d) assert_equal(len(dist), 1) assert_almost_equal(dist[0], 80.723, 1) assert_almost_equal(theta[0], 1.41, 1)
def test_ideal_tfr(self): """Test if the ideal TFR can be found using the instantaneous frequency laws.""" _, iflaw1 = fmlin(128, 0.0, 0.2) _, iflaw2 = fmlin(128, 0.3, 0.5) iflaws = np.c_[iflaw1, iflaw2].T tfr, _, _ = pproc.ideal_tfr(iflaws) tfr[tfr == 1] = 255 tfr = tfr.astype(np.uint8) hspace, angles, dists = hough_line(tfr) for x in hough_line_peaks(hspace, angles, dists): self.assertEqual(len(x), 2)
def houghSides(bottle, edges, threshold, left): h, theta, d = hough_line(edges) accum = zip(*hough_line_peaks(h, theta, d)) sortedAccum = sorted(accum, key=getKey, reverse=True) sortedAccumR = [sa for sa in sortedAccum if sa[2] > 200] sortedAccumL = [sa for sa in sortedAccum if sa[2] <= 200] if left: hpeak, angle, dist = sortedAccumL[0] else: hpeak, angle, dist in sortedAccumR[0] return (1, dist, angle)
def test_hough_line_peaks_ordered(): # Regression test per PR #1421 testim = np.zeros((256, 64), dtype=np.bool) testim[50:100, 20] = True testim[85:200, 25] = True testim[15:35, 50] = True testim[1:-1, 58] = True hough_space, angles, dists = tf.hough_line(testim) hspace, _, _ = tf.hough_line_peaks(hough_space, angles, dists) assert hspace[0] > hspace[1]
def check_door(image, Pw_corners, Pi_corners, door_edges, required_matching_ratio=0.7, verbose=0): """Check if door is closed.""" results = {} image_sobel, image_edges = detect_edges(image) # Detect lines with Hough transform hough_accumulator, angles, dists = hough_line(image_edges) hspace, angles, dists = hough_line_peaks( hough_accumulator, angles, dists, threshold=150.0) # Estimate camera transformation by minimizing the distance between # calibration points params = optimize_transform(camera_params, Pw_corners, Pi_corners) if verbose >= 1: print("Parameters: %s" % np.round(params, 3)) cam2world = transform_from(matrix_from_euler_xyz(params[:3]), params[3:6]) kappa = params[-1] W2I = partial(world2image, cam2world=cam2world, kappa=kappa, **camera_params) # Get edge pixels in vicinity of lines Pi_line_points = check_edge_is_on_line(image_edges, angles, dists) if len(Pi_line_points) == 0: if verbose >= 1: print("No lines detected, assume that door is closed") door_closed = True else: # Check how good the edges of the door projected to the image match # detected edge pixels that correspond to lines matchings = [check_line_is_edge(edge, Pi_line_points, cam2world, kappa, camera_params) for edge in door_edges] results["door_edges_in_image"] = [m[0] for m in matchings] ratios = np.array([m[1] for m in matchings]) if verbose >= 1: print(("Matching ratios: " + ", ".join(["%.2f"] * len(ratios))) % tuple(100 * ratios)) door_closed = np.any(ratios > required_matching_ratio) results["cam2world"] = cam2world results["Pi_line_points"] = Pi_line_points results["image_sobel"] = image_sobel results["image_edges"] = image_edges results["lines"] = (angles, dists) return door_closed, W2I, results
def test_hough_line_peaks_angle(): img = np.zeros((100, 100), dtype=np.bool_) img[:, 0] = True img[0, :] = True hspace, angles, dists = tf.hough_line(img) assert len(tf.hough_line_peaks(hspace, angles, dists, min_angle=45)[0]) == 2 assert len(tf.hough_line_peaks(hspace, angles, dists, min_angle=90)[0]) == 1 theta = np.linspace(0, np.pi, 100) hspace, angles, dists = tf.hough_line(img, theta) assert len(tf.hough_line_peaks(hspace, angles, dists, min_angle=45)[0]) == 2 assert len(tf.hough_line_peaks(hspace, angles, dists, min_angle=90)[0]) == 1 theta = np.linspace(np.pi / 3, 4. / 3 * np.pi, 100) hspace, angles, dists = tf.hough_line(img, theta) assert len(tf.hough_line_peaks(hspace, angles, dists, min_angle=45)[0]) == 2 assert len(tf.hough_line_peaks(hspace, angles, dists, min_angle=90)[0]) == 1
def test_example(): # Construct toydata image = np.zeros((100, 100)) idx = np.arange(25, 75) image[idx[::-1], idx] = 255 image[idx, idx] = 255 # Classic straight-line Hough transform h, theta, d = hough_line(image) # plot plt.figure(figsize=(8, 4)) plt.subplot(131) plt.imshow(image, cmap=plt.cm.gray) plt.title('Input image') plt.subplot(132) plt.imshow(np.log(1 + h), extent=[np.rad2deg(theta[-1]), np.rad2deg(theta[0]), d[-1], d[0]], cmap=plt.cm.gray, aspect=1/1.5) plt.title('Hough transform') plt.xlabel('Angles (degrees)') plt.ylabel('Distance (pixels)') plt.subplot(133) plt.imshow(image, cmap=plt.cm.gray) rows, cols = image.shape for _, angle, dist in zip(*hough_line_peaks(h, theta, d)): y0 = (dist - 0 * np.cos(angle)) / np.sin(angle) y1 = (dist - cols * np.cos(angle)) / np.sin(angle) plt.plot((0, cols), (y0, y1), '-r') plt.axis((0, cols, rows, 0)) plt.title('Detected lines')
def satellites(self,maskflag=8,det_nthresh=3.0,ngrowth=1,min_length=200,conv_sigma=2.0,angle_accuracy=1.0,min_distance=40,min_angle=5,threshold=None,num_peaks=np.inf,touch_edge=False,thresh_absolute=True,nmax=100): """ maskflag: flag for satellite trails det_nthresh: relative threshold for detecting satellites ngrowth: dilation iterations for detections min_length: minimun lenght for satellites conv_sigma: convolution kernel to convolve the raw image angle_accuracy: the accurancy of caculating the theta angle of straight lines min_distance,min_angle,threshold,num_peaks: keywords in hough_line_peaks (skimage) touch_edge: need satellites touch the image edge thresh_abolute: threshold is absolute not relative nmax: maximum lines to be detected """ start=time.time() maskflag=maskflag | self.bad_flag if self.sky is None or self.sky_rms is None: raise AttributeError("get sky and skyrms first!") # convolve data with gaussian profile data_conv=self.data.copy() if self.mask is not None: data_conv[self.mask]=self.sky if conv_sigma is not None: data_conv=snd.filters.gaussian_filter(data_conv,sigma=conv_sigma) # detect signals gmask=data_conv - self.sky > self.sky_rms*det_nthresh # growth satellite trails by dilation operation if ngrowth >0: struct=np.ones((3,3)).astype('int') gmask=snd.morphology.binary_dilation(gmask,struct,iterations=ngrowth) if self.mask is not None: mask=gmask | (self.mask) else: mask=gmask.copy() #fits.writeto('gmask.fits',gmask.astype('uint8'),clobber=True) #fits.writeto('mask.fits',mask.astype('uint8'),clobber=True) # remove objects that are obviously not satellites labels,_=snd.label(mask) slices=snd.find_objects(labels) flags=np.zeros_like(self.data).astype('int') nr,nc=self.data.shape slcs=[] labs=[] for i,slc in enumerate(slices): ilabel=labels[slc] imask=mask[slc] igmask=gmask[slc] tmpmask=ilabel == i+1 slc0,slc1=slc # remove objects not touch edge using raw data if touch_edge and (not (slc0.start==0 or slc0.stop==nr or slc1.start==0 or slc1.stop==nc)): imask[tmpmask]=0 igmask[tmpmask]=0 ilabel[tmpmask]=0 continue # remove objects that are small size=ilabel.shape if np.max(size) < min_length: imask[tmpmask]=0 igmask[tmpmask]=0 ilabel[tmpmask]=0 continue # remove objects not touch edge using masked data if touch_edge: tmpdata=igmask.copy() tmpdata[~tmpmask]=0 if not tmpdata.any(): continue tmpslc0,tmpslc1=snd.find_objects(tmpdata)[0] r0=slc0.start+tmpslc0.start; c0=slc1.start+tmpslc1.start r1=r0+tmpslc0.stop-tmpslc0.start; c1=c0+tmpslc1.stop-tmpslc1.start; if not (r0==0 or r1==nr or c0==0 or c1==nc): imask[tmpmask]=0 igmask[tmpmask]=0 ilabel[tmpmask]=0 continue slcs.append(slc) labs.append(i+1) # no labels if len(slcs) == 0: print('No Satellite Found!') return [],[],[] # find satellites by using hough transform t=np.linspace(-np.pi/2.0,np.pi/2.0,np.fix(180/angle_accuracy)) h,theta,d=hough_line(mask,theta=t) print('hough max:',h.max()) thres=None if threshold is not None: if thresh_absolute: thres=threshold else: thres=threshold*h.max() else: if thresh_absolute: thres=3*min_length _,angles,dists = hough_line_peaks(h,theta,d, min_distance=min_distance, min_angle=min_angle, threshold=thres, num_peaks=num_peaks) print(angles,dists) # no labels if len(angles) > nmax: print('Too much lines, not to detect satellite!') return [],[],[] # refine the lines smask=np.zeros_like(self.data).astype('bool') newdists=[] #np.zeros_like(dists) newangles=[] #np.zeros_like(dists) widths=[] #np.ones_like(angles) # angle is y+ -> left is plus while y+ -> right is minus for i,(angle,dist) in enumerate(zip(angles,dists)): if np.abs(angle) >= np.pi/4.0: imask=mask.copy() data=data_conv.copy() angle1=angle else: imask=mask.transpose() data=data_conv.transpose() if angle >=0: angle1=np.pi/2.0-angle else: angle1=-np.pi/2.0-angle dist=-dist shape=data.shape lmask=np.zeros(shape).astype('bool') xx=np.arange(shape[1]) yy=(dist-xx*np.cos(angle1))/np.sin(angle1) intyy=np.round(yy).astype('int') for j in np.arange(2*min_distance+1): jsub=j-min_distance tmpyy=intyy+jsub index=np.where((tmpyy >=0) & (tmpyy < shape[0]))[0] if len(index) == 0: continue tmpxx=xx[index]; tmpyy=tmpyy[index] lmask[tmpyy,tmpxx]=imask[tmpyy,tmpxx] if touch_edge: tmpmask1=lmask[0,:] | lmask[-1,:] tmpmask2=lmask[:,0] | lmask[:,-1] if (not tmpmask1.any()) and (not tmpmask2.any()): continue #fits.writeto('lmask.fits',lmask.astype('int16'),clobber=True) width=lmask.sum(axis=0) tmpmask=width>0 if not tmpmask.any(): continue mwidth=np.ceil(np.median(width[tmpmask])).astype('int') if mwidth % 2 ==0: mwidth+=1 if mwidth >= min_distance: continue #print('satellite widths:',mwidth) mdata=data.copy() mdata[~lmask]=-np.inf indmax=np.argmax(mdata,axis=0) tmpmask=(width > 0) if tmpmask.sum() == 0: continue yy1=indmax[tmpmask];xx1=xx[tmpmask] model_line=linear_model.RANSACRegressor(linear_model.LinearRegression()) model_line.residual_threshold=min_distance model_line.fit(xx1.reshape((len(xx1),1)),yy1) """ y=kx+b d=x*cos(t)+y*sin(t) y=-1/tan(t)*x+d/sin(t) k=-1/tan(t) b=d/sin(t) """ k=model_line.estimator_.coef_[0] b=model_line.estimator_.intercept_ if k==0: angle1=np.pi/2.0 else: angle1=np.arctan(-1/k) mdist1=b*np.sin(angle1) tmpangle=angle1 tmpdist=mdist1 if np.abs(angle) < np.pi/4.0: if angle1 >=0: tmpangle=np.pi/2.0-angle1 else: tmpangle=-np.pi/2.0-angle1 tmpdist=-mdist1 newdists.append(tmpdist) newangles.append(tmpangle) widths.append(mwidth) lmask=np.zeros(shape).astype('bool') xx=np.arange(shape[1]) yy=(mdist1-xx*np.cos(angle1))/np.sin(angle1) intyy=np.round(yy).astype('int') tflag=0 for j in np.arange(mwidth): jsub=j-mwidth//2 tmpyy=intyy+jsub index=np.where((tmpyy >0) & (tmpyy < shape[0]))[0] if len(index) == 0: continue tmpxx=xx[index]; tmpyy=tmpyy[index] lmask[tmpyy,tmpxx]=imask[tmpyy,tmpxx] if touch_edge: tmpmask1=lmask[0,:] | lmask[-1,:] tmpmask2=lmask[:,0] | lmask[:,-1] if (not tmpmask1.any()) and (not tmpmask2.any()): continue if np.abs(angle) >= np.pi/4.0: smask=smask | lmask #mask=mask & (~lmask) else: smask=smask | lmask.transpose() #mask=mask & (~lmask.transpose()) flags=smask*maskflag if self.flags is not None: self.flags = np.bitwise_or(self.flags,flags) else: self.flags=flags if self.mask is not None: self.mask = self.mask | (flags > 0) else: self.mask = flags > 0 if self.weight is not None: tmpmask=flags>0 self.weight[tmpmask]=0 if len(newdists)==0: print('no satellite found!') print(newdists,newangles,widths) print('satellite time: ',time.time()-start) return newdists,newangles,widths
def interest_region(image, plot_image = 0): # constant th_x = 0.5 th_y = 0.5 lid_thickness = 680 bot_thickness = 230 side_thickness = 80 rotation_limit = 2 angle_u_lim = (90.0 + rotation_limit) / 180.0 * np.pi angle_d_lim = (90.0 - rotation_limit) / 180.0 * np.pi #Grayscale Conversion and Edge Detection if(len(image.shape)>2): image = rgb2gray(image) img_edge = canny(image, sigma = 3) #Image Rotation h, theta, d = hough_line(img_edge) h_peak, theta_peak, d_peak = hough_line_peaks(h, theta, d) theta_rotation = theta[np.where(np.absolute(theta_peak)<=angle_u_lim)] theta_rotation = theta_rotation[np.where(np.absolute(theta_rotation)>=angle_d_lim)] if(theta_rotation.size): rotate_angle = np.pi/2-np.absolute(np.mean(theta_rotation)) img_rotate = rotate(img_edge,rotate_angle*180) #rectangular region selection index = np.where(img_rotate>0) [hy,b] = np.histogram(index[0],100) by = (b[0:(len(b)-1)]+b[1:len(b)])/2 [hx,b] = np.histogram(index[1],100) bx = (b[0:(len(b)-1)]+b[1:len(b)])/2 temp = by[np.where(hy>=th_y*np.mean(hy))] if(len(temp)>0): bottom = np.amin(temp) top = np.amax(temp) else: bottom = 450 top = 1500 temp = bx[np.where(hx>=th_x*np.mean(hx))] if(len(temp)>0): left = np.amin(temp)+lid_thickness right = np.amax(temp)-bot_thickness if (right <= left): left = np.amin(temp)+int(lid_thickness/2) right = np.amax(temp)+int(lid_thickness/2) else: left = 1700 right = 3600-bot_thickness bottom = bottom + side_thickness top = top - side_thickness #print [bottom,top,left,right]; image_rotation = rotate(image,rotate_angle*180) interest_image = image_rotation[bottom:top,left:right]; if(plot_image == 1): fig, ax = plt.subplots(2,3) ax[0,0].imshow(image,cmap=plt.cm.gray) ax[0,0].set_title('Original Image') ax[0,1].imshow(img_edge,cmap=plt.cm.gray) ax[0,1].set_title('Canny Endge Detection') ax[0,2].imshow(image, cmap=plt.cm.gray) rows, cols = image.shape for _, angle, dist in zip(*hough_line_peaks(h, theta, d)): y0 = (dist - 0 * np.cos(angle)) / np.sin(angle) y1 = (dist - cols * np.cos(angle)) / np.sin(angle) ax[0,2].plot((0, cols), (y0, y1),'-r') ax[0,2].axis((0, cols, rows, 0)) ax[0,2].set_title('Detected lines') ax[0,2].set_axis_off() ax[1,0].imshow(img_rotate,cmap=plt.cm.gray) ax[1,0].set_title('Image Edge after Rotation') ax[1,1].scatter(index[1],index[0]) ax[1,1].set_aspect('equal') ax[1,1].set_title('Pixel Axises Histogram') divider = make_axes_locatable(ax[1,1]) axHistx = divider.append_axes("top", 1.2, pad=0.1, sharex=ax[1,1]) axHisty = divider.append_axes("right", 1.2, pad=0.1, sharey=ax[1,1]) # make some labels invisible plt.setp(axHistx.get_xticklabels() + axHisty.get_yticklabels(),visible=False) # now determine nice limits by hand: axHistx.hist(index[1], bins=bx) axHistx.axhline(y=th_y*np.mean(hy),c="red",linewidth=2,zorder=0) axHisty.hist(index[0], bins=by, orientation='horizontal') axHisty.axvline(x=th_x*np.mean(hx),c="red",linewidth=2,zorder=0) #axHistx.axis["bottom"].major_ticklabels.set_visible(False) for tl in axHistx.get_xticklabels(): tl.set_visible(False) axHistx.set_yticks([0, 400, 800, 1200]) #axHisty.axis["left"].major_ticklabels.set_visible(False) for tl in axHisty.get_yticklabels(): tl.set_visible(False) axHisty.set_xticks([0, 400, 800, 1200]) ax[1,2].imshow(interest_image,cmap=plt.cm.gray) ax[1,2].set_title('Edge Detection') plt.show() #""" return [interest_image,[bottom,top,left,right],rotate_angle*180]
h, theta, d = hough_line(image) fig, ax = plt.subplots(1, 3, figsize=(6, 3.5)) # Original image ax[0].imshow(image, cmap=plt.cm.gray) ax[0].axis('off') # Display Hough transform ax[1].imshow(np.log(1 + h), extent=[np.rad2deg(theta[-1]), np.rad2deg(theta[0]), d[-1], d[0]], cmap=plt.cm.gray, aspect=1 / 1.5) ax[1].axis('off') # Original image with lines detected ax[2].imshow(image, cmap=plt.cm.gray) rows, cols = image.shape for _, angle, dist in zip(*hough_line_peaks(h, theta, d, min_angle=5, min_distance=5)): y0 = (dist - 0 * np.cos(angle)) / np.sin(angle) y1 = (dist - cols * np.cos(angle)) / np.sin(angle) ax[2].plot((0, cols), (y0, y1), '-r') ax[2].axis((0, cols, rows, 0)) ax[2].axis('off') # Save a nice figure fig.tight_layout() fig.subplots_adjust(wspace=0, left=0, right=1, top=1, bottom=0) fig.savefig('./hough_lines.png', dpi=300)
def main(): if len(sys.argv) != 2: print "ERROR! Correct usage is:" print "\tpython test_hough_transform.py [gps_point_collection.dat]" return GRID_SIZE = 500 results = np.zeros((GRID_SIZE, GRID_SIZE), np.float) # Load GPS points with open(sys.argv[1], "rb") as fin: point_collection = cPickle.load(fin) for pt in point_collection: y_ind = math.floor((pt[0] - const.RANGE_SW[0]) / (const.RANGE_NE[0] -const.RANGE_SW[0]) * GRID_SIZE) x_ind = math.floor((pt[1] - const.RANGE_NE[1]) / (const.RANGE_SW[1] -const.RANGE_NE[1]) * GRID_SIZE) results[x_ind, y_ind] += 1.0 if results[x_ind, y_ind] >= 64: results[x_ind, y_ind] = 63 results /= np.amax(results) thresholded_results = np.zeros((GRID_SIZE, GRID_SIZE), np.bool) THRESHOLD = 0.02 for i in range(0, GRID_SIZE): for j in range(0, GRID_SIZE): if results[i,j] >= THRESHOLD: thresholded_results[i,j] = 1 else: thresholded_results[i,j] = 0 box_size = 50 x_ind = random.randint(box_size, GRID_SIZE-box_size) y_ind = random.randint(box_size, GRID_SIZE-box_size) # x_ind = 217 # y_ind = 175 test_img = thresholded_results[(x_ind-box_size):(x_ind+box_size),\ (y_ind-box_size):(y_ind+box_size)] h, theta, d = hough_line(test_img) # fig = plt.figure(figsize=(30,16)) # ax = fig.add_subplot(121, aspect='equal') # ax.imshow(test_img, cmap=plt.cm.gray) # # ax = fig.add_subplot(122) # img = skeletonize(test_img) # ax.imshow(img, cmap=plt.cm.gray) # plt.show() # fig = plt.figure(figsize=(30,16)) # ax = fig.add_subplot(131, aspect='equal') # ax.imshow(test_img, cmap=plt.cm.gray) # # ax = fig.add_subplot(132) # ax.imshow(np.log(1+h), # extent=[np.rad2deg(theta[-1]), np.rad2deg(theta[0]), d[-1], d[0]], # cmap=plt.cm.gray, aspect=1/1.5) # ax = fig.add_subplot(133) # ax.imshow(test_img, cmap=plt.cm.gray) # rows, cols = test_img.shape # for _, angle, dist in zip(*hough_line_peaks(h, theta, d)): # y0 = (dist - 0 * np.cos(angle)) / np.sin(angle) # y1 = (dist - cols * np.cos(angle)) / np.sin(angle) # ax.plot((0, cols), (y0, y1), '-r') # ax.set_xlim([0, cols]) # ax.set_ylim([rows, 0]) # plt.show() print "point at: ", x_ind, y_ind coords = [(y_ind-box_size, x_ind-box_size), (y_ind+box_size, x_ind-box_size),\ (y_ind+box_size, x_ind+box_size), (y_ind-box_size, x_ind+box_size), \ (y_ind-box_size, x_ind-box_size)] bound_box = Polygon(coords) patch = PolygonPatch(bound_box, fc='none', ec='red') fig = plt.figure(figsize=(30,16)) rows, cols = thresholded_results.shape ax = fig.add_subplot(121, aspect='equal') ax.imshow(thresholded_results, cmap=plt.cm.gray) ax.add_patch(patch) ax.set_xlim([0, cols]) ax.set_ylim([rows, 0]) ax = fig.add_subplot(122) ax.imshow(test_img, cmap=plt.cm.gray) for _, angle, dist in zip(*hough_line_peaks(h, theta, d, min_distance=8)): y0 = (dist - 0 * np.cos(angle)) / np.sin(angle) y1 = (dist - cols * np.cos(angle)) / np.sin(angle) ax.plot((0, cols), (y0, y1), '-r') rows, cols = test_img.shape ax.set_xlim([0, cols]) ax.set_ylim([rows, 0]) plt.show()
def _find_edges(self, image): """ Takes as input an RGB chessboard image and computes the Hough lines and intersections between them corresponding to the edges of the 64 squares. The function returns a tuple whose first element is a numpy array with shape (N,2) where N is the number of intersections between the Hough lines. The second element is a list of tuples (intensity, abs(theta), abs(r)) describing the significant Hough lines (in polar coordinates). """ image_canny = self.compute_canny_image(image) h, theta, d = hough_line(image_canny) ''' Small trick: we expect to get something like 11 horizontal lines and another 11 vertical lines: indeed the chessboard is made of 8 rows and 8 columns, i.e. 9 lines, plus 2 lines for the edges of the chessboard. So, to help hough_line_peaks() let's set the min. distance expected between two lines to the size of the image divided by 11. TODO: better way? Might cause problems if the board does not fit the whole frame... ''' min_distance = int(floor(image.shape[1] / 11)) hough_peaks = hough_line_peaks(h, theta, d, min_distance=min_distance, threshold=40) # TODO adjust threshold # separate horizontal from vertical lines vertical_lines = [] horizontal_lines = [] ''' In Hough space, straight lines are parametrized by coefficients (r,θ): r = x.cos(θ) + y.sin(θ) ; (r,θ) are the polar coordinates of the point on the line which lies closest to the origin, with r being either positive or negative, and -π/2 ≤ θ ≤ π/2 (with π/2 ≈ 1.57) A horizontal line is therefore one with θ=±π/2, and a vertical line is one with θ=0. Also, two lines are parallel iif they have the same θ (mod π/2). Finally, in scikit-image, keep in mind that the orientation is : O-----> | (x axis) | V (y axis) (where the origin is the top-left corner of our image) And as a consequence, positive angles are counted from the X axis toward the Y axis (i.e. "clockwise"). ''' for intensity, theta, r in zip(*hough_peaks): if np.fabs(theta) < self.LINE_ANGLE_TOLERANCE: vertical_lines.append((intensity, theta, r)) elif np.fabs(np.fabs(theta) - math.pi / 2) < self.LINE_ANGLE_TOLERANCE: horizontal_lines.append((intensity, theta, r)) ''' Only keep the 9 most significant lines of each direction and sort them by absolute radius, to return edges from top to bottom, and left to right. We sort by *absolute* radius because horizontal lines can be parametrized either as 'θ=π/2, r>0' or 'θ=-π/2, r<0' ''' for i,lines in enumerate((horizontal_lines, vertical_lines)): lines.sort(reverse=True) # reverse-sort by intensity del lines[9:] # only keep the 9 first lines.sort(key=lambda entry: np.fabs(entry[2])) # sort by absolute radius ''' Now let's find the intersections of these 18 lines. We are solving the following system: r1 = x.cos(θ1) + y.sin(θ1) and r2 = x.cos(θ2) + y.sin(θ2) for (x,y) The non-degenerate solution is: x = (r1.sin(θ2) - r2.sin(θ1))/D and y = (r2.cos(θ1) - r1.cos(θ2))/D with D = cos(θ1).sin(θ2) - sin(θ1).cos(θ2) = sin(θ2-θ1) We can see that this holds only if θ1 ≠ θ2, i.e. only if the lines are not parallel (which makes sense!). ''' intersections = [] for _, theta1, r1 in horizontal_lines: for _, theta2, r2 in vertical_lines: # don't attempt to compute the intersection if the lines are parallel denum = np.sin(theta2 - theta1) if denum < self.ANGLE_EPSILON: continue x_inter = (r1 * np.sin(theta2) - r2 * np.sin(theta1)) / denum y_inter = (r2 * np.cos(theta1) - r1 * np.cos(theta2)) / denum # register this intersection iff. it is *inside* the image if 0 < x_inter < image.shape[1] and 0 < y_inter < image.shape[0]: intersections.append((x_inter, y_inter)) hough_lines = horizontal_lines + vertical_lines # TODO we don't check that we get 9x9 intersections... ''' Since the horizontal and vertical lines have been sorted by increasing value of |r|, the intersections are now sorted from top-left to bottom-right corner of the image. ''' return np.array(intersections), hough_lines
def extract_corner_hough(patch): """ Extract four corner points using Hough transform """ # Find the lines that makes the boundary box using Hough Transform h, theta, d = hough_line(patch) # Divide the hough space for searching different horizontal and vertical lines hcroph = h[:, 0:30] rows, cols = patch.shape # Search all vertical lines in the hough parameter space # It is located in the middle, when theta is near zero vlf = [] for _, angle, dist in zip(*hough_line_peaks(h, theta, d, min_angle=9)): x0 = (dist - 0 * np.sin(angle)) / np.cos(angle) x1 = (dist - rows * np.sin(angle)) / np.cos(angle) vlf += [((x0, 0), (x1, rows))] # Likewise previous operation, but with horizontal lines # Located at the left, when theta is near minus 90 degree hlf = [] for _, angle, dist in zip(*hough_line_peaks(hcroph, theta, d, min_angle=9)): y0 = (dist - 0 * np.cos(angle)) / np.sin(angle) y1 = (dist - cols * np.cos(angle)) / np.sin(angle) hlf += [((0, y0), (cols, y1))] if DEBUG: plt.subplot(142) plt.title('hough line') plt.imshow(patch, cmap='gray') for i in xrange(len(vlf)): plt.plot((vlf[i][0][0], vlf[i][1][0]), (vlf[i][0][1], vlf[i][1][1]), 'r-') for i in xrange(len(hlf)): plt.plot((hlf[i][0][0], hlf[i][1][0]), (hlf[i][0][1], hlf[i][1][1]), 'r-') plt.axis([0, cols, rows, 0]) # Search the rightmost and leftmost vertical lines vl = [] vl += [search_closest_line(vlf, [(0, 0), (0, rows)])] vl += [search_closest_line(vlf, [(cols, 0), (cols, rows)])] # Search the topmost and bottommost horizontal lines hl = [] hl += [search_closest_line(hlf, [(0, 0), (cols, 0)])] hl += [search_closest_line(hlf, [(0, rows), (cols, rows)])] if len(hl) < 2 or len(vl) < 2: print 'Not enough lines found' return [] points = [vl[0], vl[-1], hl[0], hl[-1]] # Check for error for i in xrange(4): for j in xrange(i + 1, 4): if points[i] == points[j]: print 'Error Line' return [] # Calculate the intersection between pair of vertical and horizontal lines # The line is defined by using two points. p1 = calc_intersection(vl[0][0][0], vl[0][0][1], vl[0][1][0], vl[0][1][1], hl[0][0][0], hl[0][0][1], hl[0][1][0], hl[0][1][1]) p2 = calc_intersection(vl[0][0][0], vl[0][0][1], vl[0][1][0], vl[0][1][1], hl[1][0][0], hl[1][0][1], hl[1][1][0], hl[1][1][1]) p3 = calc_intersection(vl[1][0][0], vl[1][0][1], vl[1][1][0], vl[1][1][1], hl[0][0][0], hl[0][0][1], hl[0][1][0], hl[0][1][1]) p4 = calc_intersection(vl[1][0][0], vl[1][0][1], vl[1][1][0], vl[1][1][1], hl[1][0][0], hl[1][0][1], hl[1][1][0], hl[1][1][1]) # Find the nearest point for each corner dim = patch.shape corners = [(0, 0), (0, dim[0]), (dim[1], dim[0]), (dim[1], 0)] points = [p1, p2, p3, p4] dest_points = [[] for x in range(4)] for i in xrange(4): dest_points[i] = search_closest_points(corners[i], points) epsilon = 1e-10 for i in xrange(4): for j in xrange(i + 1, 4): if calc_distance(dest_points[i], dest_points[j]) < epsilon: print 'Error point' return [] return dest_points
def lines(base, test): image1 = imread(base, flatten=True) image2 = imread(test, flatten=True) # Angles a1 = [] a2 = [] group1_a1 = [] group2_a1 = [] group3_a1 = [] # # Plot 1 -> Base Case (original) # print "Plot 1" h, theta, d = hough_line(image1) rows, cols = image1.shape for _, angle, dist in zip(*hough_line_peaks(h, theta, d)): y0 = (dist - 0 * np.cos(angle)) / np.sin(angle) y1 = (dist - cols * np.cos(angle)) / np.sin(angle) degree = degrees(angle) a1.append(degree) if degree < -45 or degree > 45: if degree < -85 or degree > 85: pos_horizontal = [] neg_horizontal = [] if degree > 0: pos_horizontal.append(90 - degree) elif degree <= 0: neg_horizontal.append(-(degree + 90)) elif degree > -45 and degree < 0: if degree > -40 and degree < -25: group2_a1.append(degree) elif degree > 0 and degree < 45: if degree > 15 and degree < 40: group3_a1.append(degree) if len(pos_horizontal) == 0: avg_horizontal = reduce(lambda x, y: x + y, neg_horizontal) / float(len(neg_horizontal)) elif len(neg_horizontal) == 0: avg_horizontal = reduce(lambda x, y: x + y, pos_horizontal) / float(len(pos_horizontal)) else: avg_neg = reduce(lambda x, y: x + y, neg_horizontal) / float(len(neg_horizontal)) avg_pos = reduce(lambda x, y: x + y, pos_horizontal) / float(len(pos_horizontal)) avg_horizontal = (avg_pos + avg_neg)/2 print "BASE HORIZONTAL: " + str(avg_horizontal) h1, theta1, d1 = hough_line(image2) rows, cols = image2.shape group1_a2 = [] group2_a2 = [] group3_a2 = [] for _, angle, dist in zip(*hough_line_peaks(h1, theta1, d1)): y0 = (dist - 0 * np.cos(angle)) / np.sin(angle) y1 = (dist - cols * np.cos(angle)) / np.sin(angle) degree = degrees(angle) a2.append(degree) if degree < -45 or degree > 45: if degree < -85 or degree > 85: pos_horizontal_user = [] neg_horizontal_user = [] if degree > 0: pos_horizontal_user.append(90 - degree) elif degree <= 0: neg_horizontal_user.append(-(degree + 90)) elif degree > -45 and degree < 0: if degree > -40 and degree < -25: group2_a2.append(degree) elif degree > 0 and degree < 45: if degree > 15 and degree < 40: group3_a2.append(degree) a2.append(degrees(angle)) if len(pos_horizontal_user) == 0: avg_horizontal_user = reduce(lambda x, y: x + y, neg_horizontal_user) / float(len(neg_horizontal_user)) elif len(neg_horizontal_user) == 0: avg_horizontal_user = reduce(lambda x, y: x + y, pos_horizontal_user) / float(len(pos_horizontal_user)) else: avg_neg = reduce(lambda x, y: x + y, neg_horizontal_user) / float(len(neg_horizontal_user)) avg_pos = reduce(lambda x, y: x + y, pos_horizontal_user) / float(len(pos_horizontal_user)) avg_horizontal_user = (avg_pos + avg_neg)/2 avg_down = -1 avg_up =-1 base_down = reduce(lambda x, y: x + y, group2_a1) / float(len(group2_a1)) if len(group2_a2) > 0: avg_down = reduce(lambda x, y: x + y, group2_a2) / float(len(group2_a2)) base_up = reduce(lambda x, y: x + y, group3_a1) / float(len(group3_a1)) if len(group3_a2) > 0: avg_up = reduce(lambda x, y: x + y, group3_a2) / float(len(group3_a2)) print "USER HORIZONTAL: " + str(avg_horizontal_user) print "BASE DOWN: " + str(base_down) print "USER DOWN: " + str(avg_down) print "BASE UP: " + str(base_up) print "USER UP: " + str(avg_up) base_down = float(base_down) base_up = float(base_up) user_down = float(avg_down) user_up = float(avg_up) # Calculate score score = 10 lost_down = abs(base_down - avg_down) lost_up = abs(base_up - avg_up) lost_horizontal = abs(avg_horizontal - avg_horizontal_user) SCORE_FACTOR = 3 # equals max angle of error / 10 score1 = lost_down / SCORE_FACTOR score2 = lost_up / SCORE_FACTOR score3 = lost_horizontal / SCORE_FACTOR neg_points = (score1 + score2 + score3) / 3.0 score -= neg_points print "SCORE: " + str(score) return score
def skimage_transform(): #Source: http://scikit-image.org/docs/dev/auto_examples/plot_line_hough_transform.html image = data.imread('../images/window.jpg', True) # Classic straight-line Hough transform h, theta, d = hough_line(image) fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(8, 4)) ax1.imshow(image, cmap=plt.cm.gray) ax1.set_title('Input image') ax1.set_axis_off() ax2.imshow(np.log(1 + h), extent=[np.rad2deg(theta[-1]), np.rad2deg(theta[0]), d[-1], d[0]], cmap=plt.cm.gray, aspect=1/1.5) ax2.set_title('Hough transform') ax2.set_xlabel('Angles (degrees)') ax2.set_ylabel('Distance (pixels)') ax2.axis('image') ax3.imshow(image, cmap=plt.cm.gray) rows, cols = image.shape for _, angle, dist in zip(*hough_line_peaks(h, theta, d)): y0 = (dist - 0 * np.cos(angle)) / np.sin(angle) y1 = (dist - cols * np.cos(angle)) / np.sin(angle) ax3.plot((0, cols), (y0, y1), '-r') ax3.axis((0, cols, rows, 0)) ax3.set_title('Detected lines') ax3.set_axis_off() # Line finding, using the Probabilistic Hough Transform image = data.camera() edges = canny(image,2, 1, 25) lines = probabilistic_hough_line(edges, threshold=10, line_length=100, line_gap=3) fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(8,4), sharex=True, sharey=True) ax1.imshow(image, cmap=plt.cm.gray) ax1.set_title('Input image') ax1.set_axis_off() ax1.set_adjustable('box-forced') ax2.imshow(edges, cmap=plt.cm.gray) ax2.set_title('Canny edges') ax2.set_axis_off() ax2.set_adjustable('box-forced') ax3.imshow(edges * 0) for line in lines: p0, p1 = line ax3.plot((p0[0], p1[0]), (p0[1], p1[1])) ax3.set_title('Probabilistic Hough') ax3.set_axis_off() ax3.set_adjustable('box-forced') image = data.imread('../images/AMFGP02lg.jpg', True) edges = canny(image, 2, 1, 25) lines = probabilistic_hough_line(edges, threshold=10, line_length=100, line_gap=3) fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(8,4), sharex=True, sharey=True) ax1.imshow(image, cmap=plt.cm.gray) ax1.set_title('Input image') ax1.set_axis_off() ax1.set_adjustable('box-forced') ax2.imshow(edges, cmap=plt.cm.gray) ax2.set_title('Canny edges') ax2.set_axis_off() ax2.set_adjustable('box-forced') ax3.imshow(edges * 0) for line in lines: p0, p1 = line ax3.plot((p0[0], p1[0]), (p0[1], p1[1])) ax3.set_title('Probabilistic Hough') ax3.set_axis_off() ax3.set_adjustable('box-forced') image = data.imread('../images/window.jpg', True) edges = canny(image, 2, 1, 25) lines = probabilistic_hough_line(edges, threshold=10, line_length=100, line_gap=1) fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(8,4), sharex=True, sharey=True) ax1.imshow(image, cmap=plt.cm.gray) ax1.set_title('Input image') ax1.set_axis_off() ax1.set_adjustable('box-forced') ax2.imshow(edges, cmap=plt.cm.gray) ax2.set_title('Canny edges') ax2.set_axis_off() ax2.set_adjustable('box-forced') ax3.imshow(edges * 0) for line in lines: p0, p1 = line ax3.plot((p0[0], p1[0]), (p0[1], p1[1])) ax3.set_title('Probabilistic Hough') ax3.set_axis_off() ax3.set_adjustable('box-forced') plt.show()
between_fields = logical_and(field_area, logical_not(field_mask)) # Find the roads and separate the fields # Separate out into smaller blocks print('Separating Fields in image') for stride in [100, 200, 400]: # pixels num_row_strides = int_(between_fields.shape[0]/stride) num_col_strides = int_(between_fields.shape[1]/stride) r_stride = int_(between_fields.shape[0]/num_row_strides) c_stride = int_(between_fields.shape[1]/num_col_strides) for r in range(num_row_strides+1): for c in range(num_col_strides+1): h, theta, d = hough_line(between_fields[r*r_stride:(r+1)*r_stride, c*c_stride:(c+1)*c_stride]) threshold = 0 #0.0005*max(h) h, theta, d = hough_line_peaks(h, theta, d, min_distance=20, threshold=threshold) for n in range(len(theta)): if abs(theta[n]) < 0.1 or abs(theta[n]) > ((pi/2) - 0.1): draw_hough_line(field_mask[r*r_stride:(r+1)*r_stride, c*c_stride:(c+1)*c_stride], d[n], theta[n]) # do a few small openings field_mask = binary_opening(field_mask, rectangle(1, 5)) field_mask = binary_opening(field_mask, rectangle(5, 1)) imsave(fname_template.format('segmented_fields', 'png'), field_mask) # Label fields field_mask = label(field_mask, 4, 0) + 1 remove_small_objects(field_mask, 100, 1, True) field_props = regionprops(field_mask)
def lines(base, test): """ Reads two images of yoga poses and compares them. """ image1 = imread(base, flatten=True) image2 = imread(test, flatten=True) # Angles a1 = [] a2 = [] group1_a1 = [] group2_a1 = [] group3_a1 = [] # Generate figure and 2 axes from matplotlib fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4)) # # Plot 1 -> Base Case (original) # print "Plot 1" h, theta, d = hough_line(image1) ax1.imshow(image1, cmap=plt.cm.get_cmap('gray')) rows, cols = image1.shape for _, angle, dist in zip(*hough_line_peaks(h, theta, d)): y0 = (dist - 0 * np.cos(angle)) / np.sin(angle) y1 = (dist - cols * np.cos(angle)) / np.sin(angle) degree = degrees(angle) a1.append(degree) if degree < -45 or degree > 45: if degree < -85 or degree > 85: pos_horizontal = [] neg_horizontal = [] if degree > 0: pos_horizontal.append(90 - degree) elif degree <= 0: neg_horizontal.append(-(degree + 90)) ax1.plot((0, cols), (y0, y1), '-r') elif degree > -45 and degree < 0: if degree > -40 and degree < -25: group2_a1.append(degree) ax1.plot((0, cols), (y0, y1), '-r') elif degree > 0 and degree < 45: if degree > 15 and degree < 40: group3_a1.append(degree) ax1.plot((0, cols), (y0, y1), '-r') ax1.axis((0, cols, rows, 0)) ax1.set_title('Detected lines') ax1.set_axis_off() if len(pos_horizontal) == 0: avg_horizontal = reduce(lambda x, y: x + y, neg_horizontal) / float(len(neg_horizontal)) elif len(neg_horizontal) == 0: avg_horizontal = reduce(lambda x, y: x + y, pos_horizontal) / float(len(pos_horizontal)) else: avg_neg = reduce(lambda x, y: x + y, neg_horizontal) / float(len(neg_horizontal)) avg_pos = reduce(lambda x, y: x + y, pos_horizontal) / float(len(pos_horizontal)) avg_horizontal = (avg_pos + avg_neg)/2 print "BASE HORIZONTAL: " + str(avg_horizontal) # print group2_a1 # print group3_a1 # Plot 2 -> Test Case (submission) # print "\nPlot 2" h1, theta1, d1 = hough_line(image2) ax2.imshow(image2, cmap=plt.cm.gray) rows, cols = image2.shape group1_a2 = [] group2_a2 = [] group3_a2 = [] for _, angle, dist in zip(*hough_line_peaks(h1, theta1, d1)): y0 = (dist - 0 * np.cos(angle)) / np.sin(angle) y1 = (dist - cols * np.cos(angle)) / np.sin(angle) degree = degrees(angle) a2.append(degree) if degree < -45 or degree > 45: if degree < -85 or degree > 85: pos_horizontal_user = [] neg_horizontal_user = [] if degree > 0: pos_horizontal_user.append(90 - degree) elif degree <= 0: neg_horizontal_user.append(-(degree + 90)) ax2.plot((0, cols), (y0, y1), '-r') elif degree > -45 and degree < 0: if degree > -40 and degree < -25: group2_a2.append(degree) ax2.plot((0, cols), (y0, y1), '-r') elif degree > 0 and degree < 45: if degree > 15 and degree < 40: group3_a2.append(degree) ax2.plot((0, cols), (y0, y1), '-r') a2.append(degrees(angle)) # ax2.plot((0, cols), (y0, y1), '-r') if len(pos_horizontal_user) == 0: avg_horizontal_user = reduce(lambda x, y: x + y, neg_horizontal_user) / float(len(neg_horizontal_user)) elif len(neg_horizontal_user) == 0: avg_horizontal_user = reduce(lambda x, y: x + y, pos_horizontal_user) / float(len(pos_horizontal_user)) else: avg_neg = reduce(lambda x, y: x + y, neg_horizontal_user) / float(len(neg_horizontal_user)) avg_pos = reduce(lambda x, y: x + y, pos_horizontal_user) / float(len(pos_horizontal_user)) avg_horizontal_user = (avg_pos + avg_neg)/2 print "USER HORIZONTAL: " + str(avg_horizontal_user) # print sorted(a2, key=float) # print group2_a2 # print group3_a2 avg_down = -1 avg_up =-1 base_down = reduce(lambda x, y: x + y, group2_a1) / float(len(group2_a1)) if len(group2_a2) > 0: avg_down = reduce(lambda x, y: x + y, group2_a2) / float(len(group2_a2)) base_up = reduce(lambda x, y: x + y, group3_a1) / float(len(group3_a1)) if len(group3_a2) > 0: avg_up = reduce(lambda x, y: x + y, group3_a2) / float(len(group3_a2)) print "BASE DOWN: " + str(base_down) print "USER DOWN: " + str(avg_down) print "BASE UP: " + str(base_up) print "USER UP: " + str(avg_up) ax2.axis((0, cols, rows, 0)) ax2.set_title('Detected lines') ax2.set_axis_off() plt.show() return a1, a2
ax = axes.ravel() ax[0].imshow(image, cmap=cm.gray) ax[0].set_title('Input image') ax[0].set_axis_off() ax[1].imshow(np.log(1 + h), extent=[np.rad2deg(theta[-1]), np.rad2deg(theta[0]), d[-1], d[0]], cmap=cm.gray, aspect=1/1.5) ax[1].set_title('Hough transform') ax[1].set_xlabel('Angles (degrees)') ax[1].set_ylabel('Distance (pixels)') ax[1].axis('image') ax[2].imshow(image, cmap=cm.gray) for _, angle, dist in zip(*hough_line_peaks(h, theta, d)): y0 = (dist - 0 * np.cos(angle)) / np.sin(angle) y1 = (dist - image.shape[1] * np.cos(angle)) / np.sin(angle) ax[2].plot((0, image.shape[1]), (y0, y1), '-r') ax[2].set_xlim((0, image.shape[1])) ax[2].set_ylim((image.shape[0], 0)) ax[2].set_axis_off() ax[2].set_title('Detected lines') plt.tight_layout() plt.show() # Line finding using the Probabilistic Hough Transform image = data.camera() edges = canny(image, 2, 1, 25) lines = probabilistic_hough_line(edges, threshold=10, line_length=5,
import sys from scipy.ndimage import io, uniform_filter from skimage import transform from skimage import color from src.image_preprocess.PeakDetector import generate_green_map __author__ = "Kern" if len(sys.argv) < 2: raise ValueError("Usage:", sys.argv[0], " Missing some argument to indicate input files") path = sys.argv[1] image_input = io.imread(path) image = uniform_filter(image_input) image = generate_green_map(image) image_grey = color.rgb2gray(image) hspace, angles, dists = transform.hough_line(image_grey) hspace, angles, dists = transform.hough_line_peaks(hspace, angles, dists) print(hspace, angles, dists)
def determine_skew(self, img_file): img = io.imread(img_file, as_grey=True) edges = canny(img, sigma=self.sigma) h, a, d = hough_line(edges) _, ap, _ = hough_line_peaks(h, a, d, num_peaks=self.num_peaks) if len(ap) == 0: return {"Image File": img_file, "Message": "Bad Quality"} absolute_deviations = [self.calculate_deviation(k) for k in ap] average_deviation = np.mean(np.rad2deg(absolute_deviations)) ap_deg = [np.rad2deg(x) for x in ap] bin_0_45 = [] bin_45_90 = [] bin_0_45n = [] bin_45_90n = [] for ang in ap_deg: deviation_sum = int(90 - ang + average_deviation) if self.compare_sum(deviation_sum): bin_45_90.append(ang) continue deviation_sum = int(ang + average_deviation) if self.compare_sum(deviation_sum): bin_0_45.append(ang) continue deviation_sum = int(-ang + average_deviation) if self.compare_sum(deviation_sum): bin_0_45n.append(ang) continue deviation_sum = int(90 + ang + average_deviation) if self.compare_sum(deviation_sum): bin_45_90n.append(ang) angles = [bin_0_45, bin_45_90, bin_0_45n, bin_45_90n] lmax = 0 for j in range(len(angles)): l = len(angles[j]) if l > lmax: lmax = l maxi = j if lmax: ans_arr = self.get_max_freq_elem(angles[maxi]) ans_res = np.mean(ans_arr) else: ans_arr = self.get_max_freq_elem(ap_deg) ans_res = np.mean(ans_arr) data = { "Image File": img_file, "Average Deviation from pi/4": average_deviation, "Estimated Angle": ans_res, "Angle bins": angles} if self.display_output: self.display(data) if self.plot_hough: self.display_hough(h, a, d) return data