ASSIGNMENT - 2
19ECE455 – BIOMEDICAL SIGNAL PROCESSING
IMAGE PROCESSING USING PYTHON
Daejuswaram G
CB.EN.U4ECE22115
Daejuswaram G, CB.EN.U4ECE22115
19ECE455
BIOMEDICAL SIGNAL PROCESSING – ASSIGNMENT - 2
Question 1: Write a python program to apply suitable spatial
filtering to remove the noise for the below various noisy images
and write the inference.
a) Rician noise
CODE:
import cv2
import numpy as np
from skimage.restoration import denoise_nl_means, estimate_sigma
import matplotlib.pyplot as plt
def remove_rician_noise(input_path, output_path_prefix='denoised_rician_image',
show_results=True):
image = cv2.imread(input_path)
if image is None:
raise ValueError("Image not found at the specified path")
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
normalized_image = gray_image.astype(np.float32) / 255.0
sigma_est = np.mean(estimate_sigma(normalized_image, channel_axis=None))
h_values = [0.8 * sigma_est, 1.2 * sigma_est, 1.8 * sigma_est]
denoised_images = []
for i, h in enumerate(h_values):
denoised_image = denoise_nl_means(
1|Page
Daejuswaram G, CB.EN.U4ECE22115
normalized_image,
h=h,
fast_mode=True,
patch_size=5,
patch_distance=3,
channel_axis=None
)
denoised_image = (denoised_image * 255).astype(np.uint8)
denoised_images.append(denoised_image)
output_path = f"{output_path_prefix}_h{i+1}.jpg"
cv2.imwrite(output_path, denoised_image)
if show_results:
plt.figure(figsize=(15, 5))
plt.subplot(141), plt.imshow(gray_image, cmap='gray'), plt.title('Noisy Image')
for i, (denoised, h) in enumerate(zip(denoised_images, h_values)):
plt.subplot(1, 4, i+2), plt.imshow(denoised, cmap='gray'), plt.title(f'Denoised
(h={h:.2f})')
plt.show()
if __name__ == "__main__":
input_image_path = r"C:\Users\Daejuswaram Gopinath\Desktop\Q1 (BSP)\Picture1.png"
remove_rician_noise(input_image_path)
OUTPUT:
2|Page
Daejuswaram G, CB.EN.U4ECE22115
b) Salt and Pepper noise
CODE:
import cv2
import matplotlib.pyplot as plt
def remove_salt_pepper_noise(image_path, kernel_sizes=[3, 5, 7]):
noisy_image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
if noisy_image is None:
raise FileNotFoundError(f"Image not found at {image_path}")
denoised_images = [cv2.medianBlur(noisy_image, k) for k in kernel_sizes]
return noisy_image, denoised_images, kernel_sizes
if __name__ == "__main__":
input_path = r"C:\Users\Daejuswaram Gopinath\Desktop\Q1 (BSP)\Picture2.png"
noisy_img, clean_imgs, kernel_sizes = remove_salt_pepper_noise(input_path,
kernel_sizes=[3, 5, 7])
plt.figure(figsize=(15, 5))
plt.subplot(1, 4, 1), plt.imshow(noisy_img, cmap='gray'), plt.title("Noisy Image")
for i, (clean_img, k) in enumerate(zip(clean_imgs, kernel_sizes)):
plt.subplot(1, 4, i+2), plt.imshow(clean_img, cmap='gray'), plt.title(f"Denoised
(k={k})")
plt.show()
for i, (clean_img, k) in enumerate(zip(clean_imgs, kernel_sizes)):
cv2.imwrite(f"denoised_result_k{k}.png", clean_img)
3|Page
Daejuswaram G, CB.EN.U4ECE22115
OUTPUT:
c) Gaussian noise
CODE:
import cv2
import matplotlib.pyplot as plt
def remove_gaussian_noise(image_path, kernel_sizes=[3, 5, 7], sigmas=[1.0, 2.0, 3.0]):
noisy_image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
if noisy_image is None:
raise FileNotFoundError(f"Image not found at {image_path}")
denoised_images = [cv2.GaussianBlur(noisy_image, (k, k), s) for k, s in zip(kernel_sizes,
sigmas)]
return noisy_image, denoised_images, kernel_sizes, sigmas
if __name__ == "__main__":
input_path = r"C:\Users\Daejuswaram Gopinath\Desktop\Q1 (BSP)\Picture3.png"
noisy_img, clean_imgs, kernel_sizes, sigmas = remove_gaussian_noise(input_path,
kernel_sizes=[3, 5, 7], sigmas=[1.0, 2.0, 3.0])
plt.figure(figsize=(15, 5))
plt.subplot(1, 4, 1), plt.imshow(noisy_img, cmap='gray'), plt.title("Noisy Image")
4|Page
Daejuswaram G, CB.EN.U4ECE22115
for i, (clean_img, k, s) in enumerate(zip(clean_imgs, kernel_sizes, sigmas)):
plt.subplot(1, 4, i+2), plt.imshow(clean_img, cmap='gray'), plt.title(f"Denoised (k={k},
σ={s})")
plt.show()
for i, (clean_img, k, s) in enumerate(zip(clean_imgs, kernel_sizes, sigmas)):
cv2.imwrite(f"gaussian_denoised_k{k}_sigma{s}.png", clean_img)
OUTPUT:
d) Periodic noise
CODE:
import cv2
import numpy as np
import matplotlib.pyplot as plt
def remove_periodic_noise(image_path, visualize=True, threshold=220, radius_factor=1.2):
img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
if img is None:
raise FileNotFoundError(f"Image not found at {image_path}")
5|Page
Daejuswaram G, CB.EN.U4ECE22115
rows, cols = img.shape
nrows = cv2.getOptimalDFTSize(rows)
ncols = cv2.getOptimalDFTSize(cols)
padded = cv2.copyMakeBorder(img, 0, nrows-rows, 0, ncols-cols,
cv2.BORDER_CONSTANT, value=0)
dft = cv2.dft(np.float32(padded), flags=cv2.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)
magnitude = cv2.magnitude(dft_shift[:,:,0], dft_shift[:,:,1])
log_spectrum = np.log(1 + magnitude)
spectrum_normalized = cv2.normalize(log_spectrum, None, 0, 255,
cv2.NORM_MINMAX)
_, noise_mask = cv2.threshold(np.uint8(spectrum_normalized), threshold, 255,
cv2.THRESH_BINARY)
center = (ncols//2, nrows//2)
mask = np.ones((nrows, ncols, 2), np.float32)
contours, _ = cv2.findContours(noise_mask, cv2.RETR_LIST,
cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
if len(cnt) > 5:
(x,y), radius = cv2.minEnclosingCircle(cnt)
if radius > 5 and radius < 100: # Valid noise component range
cv2.circle(mask, (int(x),int(y)), int(radius * radius_factor), (0,0), -1)
filtered = dft_shift * mask
idft = np.fft.ifftshift(filtered)
reconstructed = cv2.idft(idft)
denoised = cv2.magnitude(reconstructed[:,:,0], reconstructed[:,:,1])
denoised = cv2.normalize(denoised, None, 0, 255, cv2.NORM_MINMAX)[:rows, :cols]
return np.uint8(denoised)
if __name__ == "__main__":
input_path = r"C:\Users\Daejuswaram Gopinath\Desktop\Q1 (BSP)\Picture4.png"
params = [(220, 1.2), (200, 1.5), (240, 1.0)]
6|Page
Daejuswaram G, CB.EN.U4ECE22115
results = [remove_periodic_noise(input_path, threshold=t, radius_factor=r) for t, r in
params]
plt.figure(figsize=(15, 5))
plt.subplot(141), plt.imshow(cv2.imread(input_path, cv2.IMREAD_GRAYSCALE),
cmap='gray'), plt.title("Original")
for i, (res, (t, r)) in enumerate(zip(results, params), start=2):
plt.subplot(1, 4, i), plt.imshow(res, cmap='gray'), plt.title(f"Threshold: {t}, Factor: {r}")
plt.show()
for i, (res, (t, r)) in enumerate(zip(results, params)):
cv2.imwrite(f"denoised_threshold{t}_factor{r}.png", res)
OUTPUT:
e) Speckle noise
CODE:
import cv2
import numpy as np
import matplotlib.pyplot as plt
7|Page
Daejuswaram G, CB.EN.U4ECE22115
def remove_speckle_noise(image_path, median_ksize=5, gaussian_ksize=5,
bilateral_diameter=9, sigma_color=75, sigma_space=75):
print(f"Loading image: {image_path}") # Debug: Checking file path
img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
if img is None:
print("Error: Could not load image. Check path and format.")
return None, None, None
print("Applying filters...")
median_filtered = cv2.medianBlur(img, median_ksize)
gaussian_filtered = cv2.GaussianBlur(img, (gaussian_ksize, gaussian_ksize), 0)
bilateral_filtered = cv2.bilateralFilter(img, bilateral_diameter, sigma_color, sigma_space)
print("Filters applied successfully.")
return median_filtered, gaussian_filtered, bilateral_filtered
if __name__ == "__main__":
image_path = r"C:\Users\Daejuswaram Gopinath\Desktop\Q1 (BSP)\Picture5.png"
param_sets = [
(3, 3, 7, 50, 50),
(5, 5, 9, 75, 75),
(7, 7, 11, 100, 100)
]
results = [remove_speckle_noise(image_path, *params) for params in param_sets]
plt.figure(figsize=(12, 8))
plt.subplot(3, 3, 1)
original_img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
if original_img is None:
print("Error: Could not load original image for display.")
else:
8|Page
Daejuswaram G, CB.EN.U4ECE22115
plt.imshow(original_img, cmap='gray')
plt.title('Original Image')
plt.axis('off')
for i, (median, gaussian, bilateral) in enumerate(results, start=1):
if median is None or gaussian is None or bilateral is None:
print(f"Skipping set {i} due to error in filtering.")
continue
try:
plt.subplot(3, 3, 3 * (i - 1) + 2)
plt.imshow(median, cmap='gray')
plt.title(f'Median {param_sets[i-1][0]}')
plt.axis('off')
plt.subplot(3, 3, 3 * (i - 1) + 3)
plt.imshow(gaussian, cmap='gray')
plt.title(f'Gaussian {param_sets[i-1][1]}')
plt.axis('off')
plt.subplot(3, 3, 3 * (i - 1) + 4)
plt.imshow(bilateral, cmap='gray')
plt.title(f'Bilateral {param_sets[i-1][2]}')
plt.axis('off')
except Exception as e:
print(f"Error while plotting set {i}: {e}")
plt.tight_layout()
plt.show()
for i, (median, gaussian, bilateral) in enumerate(results):
if median is not None and gaussian is not None and bilateral is not None:
success_m = cv2.imwrite(f'median_filtered_{i}.jpg', median)
9|Page
Daejuswaram G, CB.EN.U4ECE22115
success_g = cv2.imwrite(f'gaussian_filtered_{i}.jpg', gaussian)
success_b = cv2.imwrite(f'bilateral_filtered_{i}.jpg', bilateral)
if success_m and success_g and success_b:
print(f"Successfully saved results for set {i}.")
else:
print(f"Failed to save some images for set {i}.")
OUTPUT:
10 | P a g e
Daejuswaram G, CB.EN.U4ECE22115
Question 2: Write a program in Python to explore different
methods for improving the visual quality of the below medical
images.
I. Point Processing
a. Image Negative
CODE:
import numpy as np
import cv2
import matplotlib.pyplot as plt
def image_negative(image):
negative_image = 255 - image
return negative_image
image = cv2.imread(r"C:\Users\Daejuswaram Gopinath\Desktop\Q1 (BSP)\Picture6.png",
cv2.IMREAD_GRAYSCALE)
negative_image = image_negative(image)
fig, axes = plt.subplots(1, 2, figsize=(8, 4))
axes[0].imshow(image, cmap='gray')
axes[0].set_title("Original Image")
axes[1].imshow(negative_image, cmap='gray')
axes[1].set_title("Negative Image")
for ax in axes:
11 | P a g e
Daejuswaram G, CB.EN.U4ECE22115
ax.axis("off")
plt.show()
OUTPUT:
b. Image Thresholding
CODE:
import numpy as np
import cv2
import matplotlib.pyplot as plt
def image_thresholding(image, threshold=128):
binary_image = np.where(image >= threshold, 255, 0).astype(np.uint8)
return binary_image
12 | P a g e
Daejuswaram G, CB.EN.U4ECE22115
image = cv2.imread(r"C:\Users\Daejuswaram Gopinath\Desktop\Q1 (BSP)\Picture7.png",
cv2.IMREAD_GRAYSCALE)
threshold = 30
binary_image = image_thresholding(image, threshold)
fig, axes = plt.subplots(1, 2, figsize=(8, 4))
axes[0].imshow(image, cmap='gray')
axes[0].set_title("Original Image")
axes[1].imshow(binary_image, cmap='gray')
axes[1].set_title(f"Thresholded Image (T={threshold})")
for ax in axes:
ax.axis("off")
plt.show()
OUTPUT:
c. Image Grey Level Slicing with Background
CODE:
13 | P a g e
Daejuswaram G, CB.EN.U4ECE22115
import numpy as np
import cv2
import matplotlib.pyplot as plt
def grey_level_slicing(image, min_range, max_range, slice_value=255):
sliced_image = np.where((image >= min_range) & (image <= max_range), slice_value,
image)
return sliced_image.astype(np.uint8)
image = cv2.imread(r"C:\Users\Daejuswaram Gopinath\Desktop\Q1 (BSP)\Picture8.png",
cv2.IMREAD_GRAYSCALE)
min_range = 125
max_range = 190
slice_value = 200
sliced_image = grey_level_slicing(image, min_range, max_range, slice_value)
fig, axes = plt.subplots(1, 2, figsize=(8, 4))
axes[0].imshow(image, cmap='gray')
axes[0].set_title("Original Image")
axes[1].imshow(sliced_image, cmap='gray')
axes[1].set_title(f"Gray Level Sliced Image ({min_range}-{max_range})")
for ax in axes:
ax.axis("off")
plt.show()
OUTPUT:
14 | P a g e
Daejuswaram G, CB.EN.U4ECE22115
d. Contrast Stretching
CODE:
import cv2
import numpy as np
import matplotlib.pyplot as plt
def contrast_stretching(image_path):
img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
if img is None:
print("Error: Could not load image")
return
a = np.min(img)
b = np.max(img)
c = 50
d = 255
stretched = c + ((img - a) * (d - c) / (b - a))
stretched = np.clip(stretched, 0, 255).astype(np.uint8)
15 | P a g e
Daejuswaram G, CB.EN.U4ECE22115
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.imshow(img, cmap='gray')
plt.title('Original Image')
plt.axis('off')
plt.subplot(1, 2, 2)
plt.imshow(stretched, cmap='gray')
plt.title('Contrast Stretched Image')
plt.axis('off')
plt.tight_layout()
plt.show()
plt.figure(figsize=(10, 4))
plt.subplot(1, 2, 1)
plt.hist(img.ravel(), 256, [0,256])
plt.title('Original Histogram')
plt.subplot(1, 2, 2)
plt.hist(stretched.ravel(), 256, [0,256])
plt.title('Stretched Histogram')
plt.tight_layout()
plt.show()
return stretched
if __name__ == "__main__":
image_path = r"C:\Users\Daejuswaram Gopinath\Desktop\Q1 (BSP)\Picture9.png"
result = contrast_stretching(image_path)
OUTPUT:
16 | P a g e
Daejuswaram G, CB.EN.U4ECE22115
II. Histogram Processing
CODE:
import numpy as np
import cv2
import matplotlib.pyplot as plt
def histogram_equalization(image):
hist, bins = np.histogram(image.flatten(), 256, [0, 256])
cdf = hist.cumsum()
17 | P a g e
Daejuswaram G, CB.EN.U4ECE22115
cdf_normalized = cdf * 255 / cdf[-1]
equalized_image = np.interp(image.flatten(), bins[:-1],
cdf_normalized).reshape(image.shape)
return equalized_image.astype(np.uint8)
image = cv2.imread(r"C:\Users\Daejuswaram Gopinath\Desktop\Q1 (BSP)\Picture10.png",
cv2.IMREAD_GRAYSCALE)
equalized_image = histogram_equalization(image)
hist_original, _ = np.histogram(image.flatten(), 256, [0, 256])
hist_equalized, _ = np.histogram(equalized_image.flatten(), 256, [0, 256])
fig, axes = plt.subplots(2, 2, figsize=(10, 8))
axes[0, 0].imshow(image, cmap='gray')
axes[0, 0].set_title("Original Image")
axes[0, 1].imshow(equalized_image, cmap='gray')
axes[0, 1].set_title("Histogram Equalized Image")
axes[1, 0].plot(hist_original, color='black')
axes[1, 0].set_title("Original Histogram")
axes[1, 1].plot(hist_equalized, color='black')
axes[1, 1].set_title("Equalized Histogram")
for ax in axes.ravel():
ax.axis("off") if len(ax.images) > 0 else ax.set_xticks([]), ax.set_yticks([])
plt.show()
18 | P a g e
Daejuswaram G, CB.EN.U4ECE22115
OUTPUT:
III. Intensity Transformation Operations
a. Log transformation
CODE:
import numpy as np
import cv2
import matplotlib.pyplot as plt
19 | P a g e
Daejuswaram G, CB.EN.U4ECE22115
def log_transformation(image, c=1):
image = image.astype(np.float32) + 1
log_image = c * np.log(image)
log_image = (log_image / np.max(log_image)) * 255
return log_image.astype(np.uint8)
image = cv2.imread(r"C:\Users\Daejuswaram Gopinath\Desktop\Q1 (BSP)\Picture11.png",
cv2.IMREAD_GRAYSCALE)
c = 255 / np.log(1 + np.max(image)) # Compute scaling factor
enhanced_image = log_transformation(image, c)
fig, axes = plt.subplots(1, 2, figsize=(8, 4))
axes[0].imshow(image, cmap='gray')
axes[0].set_title("Original Image")
axes[1].imshow(enhanced_image, cmap='gray')
axes[1].set_title("Log Transformed Image")
for ax in axes:
ax.axis("off")
plt.show()
OUTPUT:
20 | P a g e
Daejuswaram G, CB.EN.U4ECE22115
b. Inverse log
CODE:
import numpy as np
import cv2
import matplotlib.pyplot as plt
def inverse_log_transformation(image, c=1):
image = image.astype(np.float32)
inv_log_image = np.exp(image / c) - 1
inv_log_image = (inv_log_image / np.max(inv_log_image)) * 255 # Normalize to 0-255
return inv_log_image.astype(np.uint8)
image = cv2.imread(r"C:\Users\Daejuswaram Gopinath\Desktop\Q1 (BSP)\Picture12.png",
cv2.IMREAD_GRAYSCALE)
c = 255 / np.log(1 + np.max(image)) # Compute scaling factor
enhanced_image = inverse_log_transformation(image, c)
fig, axes = plt.subplots(1, 2, figsize=(8, 4))
axes[0].imshow(image, cmap='gray')
axes[0].set_title("Original Image")
axes[1].imshow(enhanced_image, cmap='gray')
axes[1].set_title("Inverse Log Transformed Image")
for ax in axes:
ax.axis("off")
plt.show()
21 | P a g e
Daejuswaram G, CB.EN.U4ECE22115
OUTPUT:
c. Power-law (gamma) transformation
CODE:
import numpy as np
import cv2
import matplotlib.pyplot as plt
def gamma_transformation(image, gamma=1.0, c=1):
image = image.astype(np.float32) / 255.0 # Normalize to range [0,1]
gamma_image = c * (image ** gamma)
gamma_image = (gamma_image * 255).astype(np.uint8) # Scale back to [0,255]
return gamma_image
image = cv2.imread(r"C:\Users\Daejuswaram Gopinath\Desktop\Q1 (BSP)\Picture13.png",
cv2.IMREAD_GRAYSCALE)
gamma = 0.8
enhanced_image = gamma_transformation(image, gamma)
fig, axes = plt.subplots(1, 2, figsize=(8, 4))
axes[0].imshow(image, cmap='gray')
axes[0].set_title("Original Image")
axes[1].imshow(enhanced_image, cmap='gray')
22 | P a g e
Daejuswaram G, CB.EN.U4ECE22115
axes[1].set_title(f"Gamma Transformed Image (γ={gamma})")
for ax in axes:
ax.axis("off")
plt.show()
OUTPUT:
IV. Bit-Plane Slicing
CODE:
import cv2
import numpy as np
import matplotlib.pyplot as plt
def bit_plane_slicing(image_path):
img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
if img is None:
print("Error: Could not load image")
23 | P a g e
Daejuswaram G, CB.EN.U4ECE22115
return
height, width = img.shape
bit_planes = np.zeros((height, width, 8), dtype=np.uint8)
for i in range(8):
mask = 1 << i
bit_planes[:,:,i] = cv2.bitwise_and(img, mask)
bit_planes[:,:,i] = np.where(bit_planes[:,:,i] > 0, 255, 0)
plt.figure(figsize=(12, 6))
plt.subplot(3, 3, 1)
plt.imshow(img, cmap='gray')
plt.title('Original Image')
plt.axis('off')
for i in range(8):
plt.subplot(3, 3, i + 2)
plt.imshow(bit_planes[:,:,i], cmap='gray')
plt.title(f'Bit Plane {i}')
plt.axis('off')
plt.tight_layout()
plt.show()
return bit_planes
if __name__ == "__main__":
image_path = r"C:\Users\Daejuswaram Gopinath\Desktop\Q1 (BSP)\Picture13.png"
bit_planes = bit_plane_slicing(image_path)
24 | P a g e
Daejuswaram G, CB.EN.U4ECE22115
OUTPUT:
V. Image Masking
a. Laplacian of the image
b. Sharpen image adding original image and output of a
c. Sobel of original image
d. Smoothing of output of c
e. Mask image formed by product of c and d
f. Sharpen the image by sum of original and f
25 | P a g e
Daejuswaram G, CB.EN.U4ECE22115
CODE:
import cv2
import numpy as np
import matplotlib.pyplot as plt
def process_image(image_path):
image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
if image is None:
print("Error: Unable to read the image.")
return
laplacian = cv2.Laplacian(image, cv2.CV_64F)
laplacian = np.uint8(np.absolute(laplacian))
sharpened_laplacian = cv2.addWeighted(image, 1.5, laplacian, -0.5, 0)
sobel_x = cv2.Sobel(image, cv2.CV_64F, 1, 0, ksize=3)
sobel_y = cv2.Sobel(image, cv2.CV_64F, 0, 1, ksize=3)
sobel_magnitude = np.sqrt(sobel_x**2 + sobel_y**2)
sobel_magnitude = np.uint8(np.absolute(sobel_magnitude))
smoothed_sobel = cv2.GaussianBlur(sobel_magnitude, (5, 5), 0)
mask_image = cv2.multiply(sobel_magnitude, smoothed_sobel)
final_sharpened = cv2.addWeighted(image, 1.5, mask_image, -0.5, 0)
plt.figure(figsize=(15, 10))
plt.subplot(2, 3, 1)
plt.title("Original Image")
plt.imshow(image, cmap='gray')
plt.axis("off")
plt.subplot(2, 3, 2)
plt.title("Laplacian Image")
26 | P a g e
Daejuswaram G, CB.EN.U4ECE22115
plt.imshow(laplacian, cmap='gray')
plt.axis("off")
plt.subplot(2, 3, 3)
plt.title("Sharpened (Laplacian)")
plt.imshow(sharpened_laplacian, cmap='gray')
plt.axis("off")
plt.subplot(2, 3, 4)
plt.title("Sobel Magnitude")
plt.imshow(sobel_magnitude, cmap='gray')
plt.axis("off")
plt.subplot(2, 3, 5)
plt.title("Smoothed Sobel")
plt.imshow(smoothed_sobel, cmap='gray')
plt.axis("off")
plt.subplot(2, 3, 6)
plt.title("Final Sharpened Image")
plt.imshow(final_sharpened, cmap='gray')
plt.axis("off")
plt.show()
image_path = r"C:\Users\Daejuswaram Gopinath\Desktop\Q1 (BSP)\Picture15.png"
process_image(image_path)
27 | P a g e
Daejuswaram G, CB.EN.U4ECE22115
OUTPUT:
28 | P a g e