diff --git a/Question 1.ipynb b/Question 1.ipynb index dc4574a..90b07a5 100644 --- a/Question 1.ipynb +++ b/Question 1.ipynb @@ -113,7 +113,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 6, @@ -334,7 +334,8 @@ "metadata": {}, "outputs": [], "source": [ - "from scipy import ndimage" + "from scipy import ndimage\n", + "from scipy.ndimage import convolve" ] }, { @@ -539,30 +540,68 @@ "outputs": [], "source": [ "def compute_gradient_magnitude(gr_im, kx, ky):\n", - " # Ensure the image is a float64 for computation\n", - " gr_im_float64 = gr_im.astype(np.float64)\n", + " \"\"\"\n", + " Compute gradient magnitude of a grey image with given kernels.\n", "\n", - " # Compute gradients in x and y direction\n", - " grad_x = cv2.filter2D(gr_im_float64, -1, kx.astype(np.float64))\n", - " grad_y = cv2.filter2D(gr_im_float64, -1, ky.astype(np.float64))\n", + " Parameters:\n", + " - gr_im: 2D numpy array, input grey image.\n", + " - kx: 2D numpy array, horizontal kernel.\n", + " - ky: 2D numpy array, vertical kernel.\n", "\n", - " # Compute gradient magnitude\n", - " magnitude = np.sqrt(grad_x**2 + grad_y**2)\n", + " Returns:\n", + " - grad_mag: 2D numpy array, gradient magnitude.\n", + " \"\"\"\n", + " # Validate input gr_im\n", + " if not isinstance(gr_im, np.ndarray) or gr_im.dtype != np.uint8 or gr_im.ndim != 2:\n", + " raise ValueError(\"gr_im must be a 2-dimensional numpy array of data type uint8\")\n", + " # Convert inputs to float64 for computation\n", + " gr_im = gr_im.astype(np.float64)\n", + " kx = kx.astype(np.float64)\n", + " ky = ky.astype(np.float64)\n", " \n", - " return magnitude\n", + " # Compute horizontal and vertical gradients using convolution\n", + " grad_x = convolve2d(gr_im, kx, mode='same', boundary='symm')\n", + " grad_y = convolve2d(gr_im, ky, mode='same', boundary='symm')\n", + " \n", + " # Compute gradient magnitude\n", + " grad_mag = np.sqrt(grad_x**2 + grad_y**2)\n", + " \n", + " print(\"Gradient Magnitude Array:\")\n", + " print(grad_mag)\n", + " \n", + " return grad_mag.astype(np.float64)\n", "\n", "def compute_gradient_direction(gr_im, kx, ky):\n", - " # Ensure the image is a float64 for computation\n", - " gr_im_float64 = gr_im.astype(np.float64)\n", - " \n", - " # Compute gradients in x and y direction\n", - " grad_x = cv2.filter2D(gr_im_float64, -1, kx.astype(np.float64))\n", - " grad_y = cv2.filter2D(gr_im_float64, -1, ky.astype(np.float64))\n", + " \"\"\"\n", + " Compute gradient direction of a grey image with given kernels.\n", "\n", - " # Compute gradient direction\n", - " direction = np.arctan2(grad_y, grad_x)\n", + " Parameters:\n", + " - gr_im: 2D numpy array, input grey image.\n", + " - kx: 2D numpy array, horizontal kernel.\n", + " - ky: 2D numpy array, vertical kernel.\n", + "\n", + " Returns:\n", + " - grad_dir: 2D numpy array, gradient direction.\n", + " \"\"\"\n", + " # Validate input gr_im\n", + " if not isinstance(gr_im, np.ndarray) or gr_im.dtype != np.uint8 or gr_im.ndim != 2:\n", + " raise ValueError(\"gr_im must be a 2-dimensional numpy array of data type uint8\")\n", + " # Convert inputs to float64 for computation\n", + " gr_im = gr_im.astype(np.float64)\n", + " kx = kx.astype(np.float64)\n", + " ky = ky.astype(np.float64)\n", " \n", - " return direction" + " # Compute horizontal and vertical gradients using convolution\n", + " grad_x = convolve2d(gr_im, kx, mode='same', boundary='symm')\n", + " grad_y = convolve2d(gr_im, ky, mode='same', boundary='symm')\n", + " \n", + " # Compute gradient direction\n", + " grad_dir = np.arctan2(grad_y, grad_x)\n", + " \n", + " print(\"Gradient Direction Array:\")\n", + " print(grad_dir)\n", + " \n", + " return grad_dir.astype(np.float64)\n" ] }, { @@ -582,15 +621,38 @@ "execution_count": 23, "id": "63663950", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Gradient Magnitude Array:\n", + "[[0. 0. 0. ... 0. 0. 0.]\n", + " [0. 0. 0. ... 0. 0. 0.]\n", + " [0. 0. 0. ... 0. 0. 0.]\n", + " ...\n", + " [0. 0. 0. ... 0. 0. 0.]\n", + " [0. 0. 0. ... 0. 0. 0.]\n", + " [0. 0. 0. ... 0. 0. 0.]]\n", + "Gradient Direction Array:\n", + "[[0. 0. 0. ... 0. 0. 0.]\n", + " [0. 0. 0. ... 0. 0. 0.]\n", + " [0. 0. 0. ... 0. 0. 0.]\n", + " ...\n", + " [0. 0. 0. ... 0. 0. 0.]\n", + " [0. 0. 0. ... 0. 0. 0.]\n", + " [0. 0. 0. ... 0. 0. 0.]]\n" + ] + } + ], "source": [ "# For convolution\n", - "# magnitude = compute_gradient_magnitude(gr_im, kx_conv, ky_conv)\n", - "# direction = compute_gradient_direction(gr_im, kx_conv, ky_conv)\n", + "magnitude = compute_gradient_magnitude(gr_im, kx_conv, ky_conv)\n", + "direction = compute_gradient_direction(gr_im, kx_conv, ky_conv)\n", "\n", "# For Cross-Correlation\n", - "magnitude = compute_gradient_magnitude(gr_im, kx_cross, ky_cross)\n", - "direction = compute_gradient_direction(gr_im, kx_cross, ky_cross)" + "# magnitude = compute_gradient_magnitude(gr_im, kx_cross, ky_cross)\n", + "# direction = compute_gradient_direction(gr_im, kx_cross, ky_cross)" ] }, { @@ -628,25 +690,46 @@ } ], "source": [ - "assert np.allclose(m1_magnitude, magnitude), np.allclose(m1_direction, direction)\n", - "print (\"PASS: Method 1\")\n", + "all_pass = 0\n", "\n", - "assert np.allclose(m2_magnitude, magnitude), np.allclose(m2_direction, direction)\n", - "print (\"PASS: Method 2\")\n", + "try:\n", + " assert np.allclose(m1_magnitude, magnitude), np.allclose(m1_direction, direction)\n", + " print (\"PASS: Method 1\")\n", + " all_pass = all_pass + 1\n", + "except AssertionError as e:\n", + " print(\"Fail: Method 1\", e)\n", "\n", - "assert np.allclose(m3_magnitude, magnitude), np.allclose(m3_direction, direction)\n", - "print (\"PASS: Method 3\")\n", + "try:\n", + " assert np.allclose(m2_magnitude, magnitude), np.allclose(m2_direction, direction)\n", + " print (\"PASS: Method 2\")\n", + " all_pass = all_pass + 1\n", + "except AssertionError as e:\n", + " print(\"Fail: Method 2\", e)\n", "\n", - "assert np.allclose(m4_magnitude, magnitude), np.allclose(m4_direction, direction)\n", - "print (\"PASS: Method 4\")\n", + "try:\n", + " assert np.allclose(m3_magnitude, magnitude), np.allclose(m3_direction, direction)\n", + " print (\"PASS: Method 3\")\n", + " all_pass = all_pass + 1\n", + "except AssertionError as e:\n", + " print(\"Fail: Method 1\", e)\n", "\n", - "print (\"ALL PASS\")" + "try:\n", + " assert np.allclose(m4_magnitude, magnitude), np.allclose(m4_direction, direction)\n", + " print (\"PASS: Method 4\")\n", + " all_pass = all_pass + 1\n", + "except AssertionError as e:\n", + " print(\"Fail: Method 1\", e)\n", + "\n", + "if all_pass == 4:\n", + " print (\"ALL PASS\")\n", + "else:\n", + " print(f\"{all_pass} Passed, {4 - all_pass} Failed\")" ] }, { "cell_type": "code", "execution_count": null, - "id": "fb616c86", + "id": "cc4a6cdb", "metadata": {}, "outputs": [], "source": []