[CT404]: Finish Assignment 2

This commit is contained in:
2024-11-14 10:45:13 +00:00
parent 20c26c0cc3
commit cad9b09899
12 changed files with 237 additions and 28 deletions

View File

@ -0,0 +1,40 @@
import cv2
import numpy as np
# Load and pre-process binary image
binary_image = cv2.imread("./output/kernel_size_17.jpg", cv2.IMREAD_GRAYSCALE)
binary_image = cv2.medianBlur(binary_image, 3)
# Step 1.5: Extraction of Binary Regions of Interest / connected components
num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(binary_image, connectivity=8)
# Initialize an empty mask for filtered regions
filtered_mask = np.zeros(binary_image.shape, dtype=np.uint8)
total_globules = 0
# Task 1.6: Filtering of Fat Globules
for i in range(1, num_labels):
area = stats[i, cv2.CC_STAT_AREA]
# Calculate compactness
perimeter = cv2.arcLength(cv2.findContours((labels == i).astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0][0], True)
compactness = (perimeter ** 2) / area if area > 0 else 0
if (300 < area) and (compactness < 27):
total_globules += 1
filtered_mask[labels == i] = 255
cv2.imwrite("./output/filtered_fat_globules.jpg", filtered_mask)
print("Total globules: " + str(total_globules))
# Task 1.7: Calculation of the Fat Area
# Total area of the image in pixels (excluding the background)
total_image_area = binary_image.shape[0] * binary_image.shape[1]
# Total fat area (in pixels)
fat_area = np.sum(filtered_mask == 255)
# Calculate fat percentage
fat_percentage = (fat_area / total_image_area) * 100
print(f"Fat Area Percentage: {fat_percentage:.2f}%")

View File

@ -1,23 +0,0 @@
# Task 1.5: Extraction of Binary Regions of Interest / Connected Components
import cv2
import numpy as np
# read in noise-reduced image
image = cv2.imread("./output/kernel_size_25.jpg", cv2.IMREAD_GRAYSCALE)
# Find connected components
num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(image, connectivity=4)
# Create an output image (color) to label components
output_img = np.zeros((image.shape[0], image.shape[1], 3), dtype=np.uint8)
# Apply a single color (e.g., gray) to each component in the output image
for label in range(1, num_labels): # Skip background (label 0)
output_img[labels == label] = (200, 200, 200) # Light gray color for each component
# Overlay red text labels at component centroids
for i in range(1, num_labels): # Skip background (label 0)
x, y = int(centroids[i][0]), int(centroids[i][1])
cv2.putText(output_img, str(i), (x, y), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1) # Red color (BGR: (0, 0, 255))
cv2.imwrite("./output/region_of_interest.jpg", output_img)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 803 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 799 KiB

View File

@ -28,4 +28,42 @@ plt.imshow(magnitude_spectrum, cmap='gray')
plt.axis('off')
plt.savefig("./output/2_frequency_domain_low-pass_filter.jpg", bbox_inches='tight', pad_inches=0)
# Task 2.3: Frequency Domain Filtering
# Task 2.3: Frequency Domain Filtering for
channels = cv2.split(image)
filtered_channels = []
for channel in channels:
fft_channel = np.fft.fft2(channel)
# shift the zero frequency component to the center
fft_channel_shifted = np.fft.fftshift(fft_channel)
# create a Gaussian filter the same size as the channel
gaussian_kernel = cv2.getGaussianKernel(kernel_size[0], variance)
gaussian_kernel_2d = gaussian_kernel @ gaussian_kernel.T
# pad the Gaussian filter to match the size of the image channel
gaussian_kernel_padded = np.pad(gaussian_kernel_2d,
((0, fft_channel_shifted.shape[0] - gaussian_kernel_2d.shape[0]),
(0, fft_channel_shifted.shape[1] - gaussian_kernel_2d.shape[1])),
mode='constant', constant_values=0)
# shift the padded filter in the frequency domain
fft_gaussian_padded_shifted = np.fft.fftshift(np.fft.fft2(gaussian_kernel_padded))
# apply the low-pass filter to the channel
low_pass_filtered = fft_channel_shifted * fft_gaussian_padded_shifted
# perform the inverse FFT to get the filtered channel in the spatial domain
ifft_filtered = np.fft.ifft2(np.fft.ifftshift(low_pass_filtered))
# take the real part and normalize it
filtered_channel = np.real(ifft_filtered)
filtered_channel = np.clip(filtered_channel, 0, 255).astype(np.uint8)
# append the filtered channel to the list
filtered_channels.append(filtered_channel)
filtered_image_color = cv2.merge(filtered_channels)
cv2.imwrite("./output/3_filtered_color_image.jpg", filtered_image_color)

View File

@ -0,0 +1,53 @@
import cv2
import numpy as np
import matplotlib.pyplot as plt
# Task 2.1: Spatial Domain
image = cv2.imread("jennifer.jpg")
kernel_size = (15, 15)
variance = 20
smoothed_image = cv2.GaussianBlur(image, kernel_size, variance)
cv2.imwrite("./output/jennifer_spatial.jpg", smoothed_image)
# Task 2.3: Frequency Domain Filtering for
channels = cv2.split(image)
filtered_channels = []
for channel in channels:
fft_channel = np.fft.fft2(channel)
# shift the zero frequency component to the center
fft_channel_shifted = np.fft.fftshift(fft_channel)
# create a Gaussian filter the same size as the channel
gaussian_kernel = cv2.getGaussianKernel(kernel_size[0], variance)
gaussian_kernel_2d = gaussian_kernel @ gaussian_kernel.T
# pad the Gaussian filter to match the size of the image channel
gaussian_kernel_padded = np.pad(gaussian_kernel_2d,
((0, fft_channel_shifted.shape[0] - gaussian_kernel_2d.shape[0]),
(0, fft_channel_shifted.shape[1] - gaussian_kernel_2d.shape[1])),
mode='constant', constant_values=0)
# shift the padded filter in the frequency domain
fft_gaussian_padded_shifted = np.fft.fftshift(np.fft.fft2(gaussian_kernel_padded))
# apply the low-pass filter to the channel
low_pass_filtered = fft_channel_shifted * fft_gaussian_padded_shifted
# perform the inverse FFT to get the filtered channel in the spatial domain
ifft_filtered = np.fft.ifft2(np.fft.ifftshift(low_pass_filtered))
# take the real part and normalize it
filtered_channel = np.real(ifft_filtered)
filtered_channel = np.clip(filtered_channel, 0, 255).astype(np.uint8)
# append the filtered channel to the list
filtered_channels.append(filtered_channel)
filtered_image_color = cv2.merge(filtered_channels)
cv2.imwrite("./output/jennifer_freq.jpg", filtered_image_color)