From 45ce034ca9311a594cf0a30d1f84937bedcd6d64 Mon Sep 17 00:00:00 2001 From: Gasper Spagnolo Date: Tue, 15 Nov 2022 10:46:07 +0100 Subject: [PATCH] Se 3b done --- assignment3/solution.py | 53 +++++++++++++++++++++++++++++-- assignment3/uz_framework/image.py | 38 ++++++++++++++++++++++ 2 files changed, 88 insertions(+), 3 deletions(-) diff --git a/assignment3/solution.py b/assignment3/solution.py index 433b0d3..13cc92c 100644 --- a/assignment3/solution.py +++ b/assignment3/solution.py @@ -226,8 +226,8 @@ def two_c(): # EXCERCISE 2: Exercise 1: Edges in images # ############################################ def ex3(): - three_a() - #three_b() + #three_a() + three_b() #three_c() def three_a(): @@ -251,6 +251,53 @@ def three_a(): plt.show() +def three_b(): + """ + Implement the function hough_find_lines that accepts a binary image, the number + of bins for ϑ and ρ (allow the possibility of them being different) and a threshold. + Create an accumulator matrix A for the parameter space (ρ, ϑ). Parameter ϑ is + defined in the interval from −π/2 to π/2, ρ is defined on the interval from −D to + D, where D is the length of the image diagonal. For each nonzero pixel in the image, + generate a curve in the (ρ, ϑ) space by using the equation (7) for all possible values + of ϑ and increase the corresponding cells in A. Display the accumulator matrix. Test + the method on your own synthetic images ((e.g. 100 × 100 black image, with two + white pixels at (10, 10) and (10, 20)). + Finally, test your function on two synthetic images oneline.png and rectangle.png. First, you should obtain an edge map for each image using either your + function findedges or some inbuilt function. Run your implementation of the Hough + algorithm on the resulting edge maps. + """ + SIGMA = 1 + THETA = 0.02 + T_LOW = 0.04 + T_HIGH = 0.16 + + synthetic_image = np.zeros((100, 100)) + synthetic_image[10, 10] = 1 + synthetic_image[10, 20] = 1 + + oneline_image = uz_image.imread_gray('./images/oneline.png', uz_image.ImageType.float64) + rectangle_image = uz_image.imread_gray('./images/rectangle.png', uz_image.ImageType.float64) + + oneline_image_edges = uz_image.find_edges_canny(oneline_image, SIGMA, THETA, T_LOW, T_HIGH) + rectangle_image_edges = uz_image.find_edges_canny(rectangle_image, SIGMA, THETA, T_LOW, T_HIGH) + + fig, axs = plt.subplots(3, 3) + + axs[0, 0].imshow(synthetic_image, cmap='gray') + axs[0, 0].set_title('Synthetic image') + axs[2, 0].imshow(uz_image.hough_find_lines(synthetic_image, 200, 200, 0.2)) + axs[0, 1].imshow(oneline_image, cmap='gray') + axs[0, 1].set_title('Oneline image') + axs[1, 1].imshow(oneline_image_edges, cmap='gray') + axs[0, 2].imshow(rectangle_image, cmap='gray') + axs[0, 2].set_title('Rectangle image') + axs[1, 2].imshow(rectangle_image_edges, cmap='gray') + axs[1, 0].set_visible(False) + axs[2, 1].imshow(uz_image.hough_find_lines(oneline_image_edges, 200, 200, 0.2)) + axs[2, 2].imshow(uz_image.hough_find_lines(rectangle_image_edges, 200, 200, 0.2)) + + + plt.show() # ######## # @@ -260,7 +307,7 @@ def three_a(): def main(): #ex1() #ex2() - #ex3() + ex3() if __name__ == '__main__': main() diff --git a/assignment3/uz_framework/image.py b/assignment3/uz_framework/image.py index a25f401..10f2179 100644 --- a/assignment3/uz_framework/image.py +++ b/assignment3/uz_framework/image.py @@ -653,4 +653,42 @@ def hough_transform_a_point(x: int, y: int, n_bins: int) -> npt.NDArray[np.float accumlator[int(r), i] += 1 return accumlator + + +def hough_find_lines(image: Union[npt.NDArray[np.float64], npt.NDArray[np.uint8]], n_bins_theta: int, n_bins_rho: int, treshold: float) -> npt.NDArray[np.uint64]: + """" + Accepts: bw image with lines, n_bins_theta, n_bins_rho, treshold + Returns: image points above treshold transformed into hough space + """ + + image = image.copy() + image[image < treshold] = 0 + theta_values = np.linspace(-np.pi/2, np.pi/2, n_bins_theta) + rho_values = np.linspace(-np.sqrt(image.shape[0]**2 + image.shape[1]**2), np.sqrt(image.shape[0]**2 + image.shape[1]**2), n_bins_rho) + accumulator = np.zeros((n_bins_rho, n_bins_theta), dtype=np.uint64) + + cos_precalculated = np.cos(theta_values) + sin_precalculated = np.sin(theta_values) + y_s, x_s = np.nonzero(image) + + # Loop through all nonzero pixels above treshold + for i in range(len(y_s)): + x = x_s[i] + y = y_s[i] + + # Precalculate rhos + rhos = [] + for theta in range(n_bins_theta): + rho = int(np.round(x * cos_precalculated[theta] + y * sin_precalculated[theta])) + rhos.append(rho) + + # Bin the rhos + binned = np.digitize(rhos, rho_values) + + # Add to accumulator + for theta in range(n_bins_theta): + accumulator[binned[theta], theta] += 1 + + return accumulator +