1.
Hadamard Transform and Inverse
import numpy as np
from [Link] import hadamard
import cv2
import [Link] as plt
image = [Link]("[Link]", cv2.IMREAD_GRAYSCALE)
image = [Link](image, (256, 256))
[Link](1, 3, 1)
[Link](image, cmap='gray')
[Link]("Original Image")
[Link]('off')
image = image / 255.0
H = hadamard(256)
transformed = H @ image @ H
[Link](1, 3, 2)
[Link](np.log1p([Link](transformed)), cmap='gray')
[Link]("Hadamard Transformed")
[Link]('off')
reconstructed = (H @ transformed @ H) / (256*256)
[Link](1, 3, 3)
[Link](reconstructed, cmap='gray')
[Link]("Reconstructed")
[Link]('off')
[Link]()
2. Histogram Equalization and Specification
#equalization
import cv2
import numpy as np
import [Link] as plt
# Load the grayscale image
image = [Link]('[Link]', 0) # Replace '[Link]' with your image file
# Perform Histogram Equalization using OpenCV function
equalized_image = [Link](image)
# Calculate histograms for both images
hist_original = [Link]([image], [0], None, [256], [0, 256])
hist_equalized = [Link]([equalized_image], [0], None, [256], [0, 256])
# Plot the original and equalized images and their histograms
[Link](figsize=(12, 12))
# Plot the original image and its histogram
[Link](2, 2, 1)
[Link]("Original Image")
[Link](image, cmap='gray')
[Link]('off')
[Link](2, 2, 2)
[Link]("Histogram of Original Image")
[Link](hist_original, color='black')
[Link]([0, 256])
# Plot the equalized image and its histogram
[Link](2, 2, 3)
[Link]("Equalized Image")
[Link](equalized_image, cmap='gray')
[Link]('off')
[Link](2, 2, 4)
[Link]("Histogram of Equalized Image")
[Link](hist_equalized, color='black')
[Link]([0, 256])
# Show the results
plt.tight_layout()
[Link]()
#matching
import cv2
import numpy as np
import [Link] as plt
def calculate_cdf(hist):
# Calculate the cumulative distribution function (CDF)
cdf = [Link]() # Cumulative sum of the histogram
cdf_normalized = cdf / cdf[-1] # Normalize the CDF to [0, 1]
return cdf_normalized
def histogram_matching(source, reference):
# Calculate histograms
hist_source = [Link]([source], [0], None, [256], [0, 256])
hist_reference = [Link]([reference], [0], None, [256], [0, 256])
# Calculate the CDF for source and reference histograms
cdf_source = calculate_cdf(hist_source)
cdf_reference = calculate_cdf(hist_reference)
# Create a lookup table to match the histograms
mapping = [Link](256, dtype=np.uint8)
# For each pixel in the source image, find the closest match in the reference CDF
g = 0 # Initialize reference pixel index
for s in range(256):
while g < 256 and cdf_reference[g] < cdf_source[s]: #g < 256: Ensures that g does not
exceed the
maximum intensity value of 255.
g += 1 # If g = 3, after g += 1, g will become 4.
mapping[s] = g
# Apply the transformation
matched_image = mapping[source]
return matched_image
# Load the source and reference images
source_image = [Link]('[Link]', 0) # Replace with the source image path
reference_image = [Link]('[Link]', 0) # Replace with the reference image path
# Perform histogram matching
matched_image = histogram_matching(source_image, reference_image)
# Plot the images and histograms
[Link](figsize=(12, 12))
# Source Image
[Link](2, 2, 1)
[Link]("Source Image")
[Link](source_image, cmap='gray')
[Link]('off')
# Reference Image
[Link](2, 2, 2)
[Link]("Reference Image")
[Link](reference_image, cmap='gray')
[Link]('off')
# Matched Image
[Link](2, 2, 3)
[Link]("Matched Image")
[Link](matched_image, cmap='gray')
[Link]('off')
# Plot histograms
[Link](2, 2, 4)
[Link]("Histograms")
[Link](source_image.ravel(), bins=256, color='blue', alpha=0.5, label="Source")
[Link](reference_image.ravel(), bins=256, color='red', alpha=0.5, label="Reference")
[Link](matched_image.ravel(), bins=256, color='green', alpha=0.5, label="Matched")
[Link](loc='upper right')
[Link]([0, 256])
plt.tight_layout()
[Link]()
3. Apply smoothing filter and sharpening filters in the spatial domain. Compare
the effects on the image quality.
#smoothing
import cv2
import numpy as np
import [Link] as plt
# --------------------- 1. Mean Filter (with multiple kernel sizes) ---------------------
# Load image for mean filtering
mean_image = [Link]('[Link]', cv2.IMREAD_GRAYSCALE)
# Define different kernel sizes
mean_kernel_sizes = [3, 10, 20, 50]
[Link](figsize=(15, 8))
for i, kernel_size in enumerate(mean_kernel_sizes, 1):
# Apply mean (average) filter using blur()
mean_filtered = [Link](mean_image, (kernel_size, kernel_size))
# Display results
[Link](2, 2, i)
[Link](mean_filtered, cmap='gray')
[Link](f'Mean Filter ({kernel_size}x{kernel_size})')
[Link]('off')
[Link]('Mean Filtering with Different Kernel Sizes')
plt.tight_layout()
[Link]()
# --------------------- 2. Weighted Average Filter ---------------------
# Load image for weighted average filtering
weighted_image = [Link]('[Link]', cv2.IMREAD_GRAYSCALE)
# Define a 3x3 weighted kernel with more emphasis on the center pixel
weighted_kernel = [Link]([[1, 2, 1],
[2, 4, 2],
[1, 2, 1]], dtype=np.float32)
# Normalize the kernel so the sum equals 1
weighted_kernel /= [Link](weighted_kernel)
# Apply filter2D for weighted average filtering
weighted_filtered = cv2.filter2D(weighted_image, -1, weighted_kernel)
# Display original and filtered images
[Link](figsize=(10, 5))
[Link](1, 2, 1)
[Link](weighted_image, cmap='gray')
[Link]('Original Image (Weighted Avg)')
[Link]('off')
[Link](1, 2, 2)
[Link](weighted_filtered, cmap='gray')
[Link]('Weighted Average Filtered')
[Link]('off')
plt.tight_layout()
[Link]()
# --------------------- 3. Median Filter ---------------------
# Load image for median filtering
median_image = [Link]('[Link]', cv2.IMREAD_GRAYSCALE)
# Define kernel size
median_kernel_size = 9
# Apply median filter
median_filtered = [Link](median_image, median_kernel_size)
# Display results
[Link](figsize=(10, 5))
[Link](1, 2, 1)
[Link](median_image, cmap='gray')
[Link]('Original Image (Median)')
[Link]('off')
[Link](1, 2, 2)
[Link](median_filtered, cmap='gray')
[Link](f'Median Filtered (Kernel: {median_kernel_size}x{median_kernel_size})')
[Link]('off')
plt.tight_layout()
[Link]()
# --------------------- 4. Min Filter ---------------------
# Load image for min filtering
min_image = [Link]('[Link]', cv2.IMREAD_GRAYSCALE)
# Define kernel size
min_kernel_size = 3
# Apply erosion which performs a min operation
min_filtered = [Link](min_image, [Link]((min_kernel_size, min_kernel_size), np.uint8))
# Display results
[Link](figsize=(10, 5))
[Link](1, 2, 1)
[Link](min_image, cmap='gray')
[Link]('Original Image (Min)')
[Link]('off')
[Link](1, 2, 2)
[Link](min_filtered, cmap='gray')
[Link](f'Min Filtered (Kernel: {min_kernel_size}x{min_kernel_size})')
[Link]('off')
plt.tight_layout()
[Link]()
# --------------------- 5. Max Filter ---------------------
# Load image for max filtering
max_image = [Link]('[Link]', cv2.IMREAD_GRAYSCALE)
# Define kernel size
max_kernel_size = 3
# Apply dilation which performs a max operation
max_filtered = [Link](max_image, [Link]((max_kernel_size, max_kernel_size), np.uint8))
# Display results
[Link](figsize=(10, 5))
[Link](1, 2, 1)
[Link](max_image, cmap='gray')
[Link]('Original Image (Max)')
[Link]('off')
[Link](1, 2, 2)
[Link](max_filtered, cmap='gray')
[Link](f'Max Filtered (Kernel: {max_kernel_size}x{max_kernel_size})')
[Link]('off')
plt.tight_layout()
[Link]()
#sharpening
import cv2
import numpy as np
import [Link] as plt
# ------------------------- Laplacian Image Enhancement -------------------------
def enhance_image_laplacian(image):
# Define Laplacian kernel (second-order derivative)
laplacian_kernel = [Link]([[1, 1, 1],
[1, -8, 1],
[1, 1, 1]])
# Apply Laplacian filter
laplacian = cv2.filter2D(image, -1, laplacian_kernel)
# Enhance image: Enhanced = Original - Laplacian
enhanced = [Link](image, laplacian)
# Display result
[Link](figsize=(10, 4))
[Link](1, 3, 1), [Link](image, cmap='gray'), [Link]('Original')
[Link](1, 3, 2), [Link](laplacian, cmap='gray'), [Link]('Laplacian Filter')
[Link](1, 3, 3), [Link](enhanced, cmap='gray'), [Link]('Enhanced Image')
[Link]("Laplacian Image Enhancement")
plt.tight_layout()
[Link]()
# ------------------------- Unsharp Masking -------------------------
def unsharp_masking(image, k=1.5):
# Apply Gaussian blur to get a smoothed version
blurred = [Link](image, (5, 5), 0)
# Unsharp mask = Original - Blurred
mask = [Link](image, blurred)
# Sharpened image = Original + k * Mask
sharpened = [Link](image, 1.0 + k, blurred, -k, 0)
# Display result
[Link](figsize=(10, 4))
[Link](1, 3, 1), [Link](image, cmap='gray'), [Link]('Original')
[Link](1, 3, 2), [Link](mask, cmap='gray'), [Link]('Unsharp Mask')
[Link](1, 3, 3), [Link](sharpened, cmap='gray'), [Link]('Sharpened Image')
[Link]("Unsharp Masking (k = {:.1f})".format(k))
plt.tight_layout()
[Link]()
# ------------------------- Highboost Filtering -------------------------
def highboost_filtering(image, A=2.0):
# Apply Gaussian blur
blurred = [Link](image, (5, 5), 0)
# Highboost: Highboost = A * Original - (A - 1) * Blurred
highboost = [Link](image, A, blurred, 1 - A, 0)
# Display result
[Link](figsize=(10, 4))
[Link](1, 2, 1), [Link](image, cmap='gray'), [Link]('Original')
[Link](1, 2, 2), [Link](highboost, cmap='gray'), [Link]('Highboost Filtered (A =
{:.1f})'.format(A))
[Link]("Highboost Filtering")
plt.tight_layout()
[Link]()
# ------------------------- Load Image and Run All Enhancements -------------------------
def run_all_filters(image_path):
# Read image in grayscale
image = [Link](image_path, cv2.IMREAD_GRAYSCALE)
if image is None:
print("Error: Could not read the image at", image_path)
return
# Apply each enhancement technique
enhance_image_laplacian(image)
unsharp_masking(image, k=1.5)
highboost_filtering(image, A=2.0)
# ------------------------- Main Code -------------------------
# Replace with your image file
image_path = '[Link]'
run_all_filters(image_path)
4. perform edge detection using Sobel, Prewitt, Roberts, and Canny operators.
Display and compare and detected edges.
import cv2
import numpy as np
import [Link] as plt
# ------------------------ Load Image ------------------------
# Load grayscale image
image = [Link]("[Link]", cv2.IMREAD_GRAYSCALE)
if image is None:
print("Error: Image not found.")
exit()
# Optional: Apply Gaussian blur to reduce noise
blurred = [Link](image, (3, 3), 0)
# ------------------------ 1. Sobel Operator ------------------------
sobel_x = [Link](blurred, cv2.CV_64F, 1, 0, ksize=3)
sobel_y = [Link](blurred, cv2.CV_64F, 0, 1, ksize=3)
sobel = [Link](sobel_x**2 + sobel_y**2)
sobel = np.uint8([Link](sobel, 0, 255))
# ------------------------ 2. Prewitt Operator ------------------------
prewitt_x = [Link]([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]])
prewitt_y = [Link]([[1, 1, 1], [0, 0, 0], [-1, -1, -1]])
prewitt_x_img = cv2.filter2D(blurred, -1, prewitt_x)
prewitt_y_img = cv2.filter2D(blurred, -1, prewitt_y)
prewitt = [Link](prewitt_x_img**2 + prewitt_y_img**2)
prewitt = np.uint8([Link](prewitt, 0, 255))
# ------------------------ 3. Roberts Operator ------------------------
roberts_cross_x = [Link]([[1, 0], [0, -1]])
roberts_cross_y = [Link]([[0, 1], [-1, 0]])
roberts_x = cv2.filter2D(blurred, -1, roberts_cross_x)
roberts_y = cv2.filter2D(blurred, -1, roberts_cross_y)
roberts = [Link](roberts_x**2 + roberts_y**2)
roberts = np.uint8([Link](roberts, 0, 255))
# ------------------------ 4. Canny Operator ------------------------
canny = [Link](blurred, 100, 200)
# ------------------------ Display All Results ------------------------
[Link](figsize=(12, 8))
[Link](2, 3, 1)
[Link](image, cmap='gray')
[Link]("Original Image")
[Link]('off')
[Link](2, 3, 2)
[Link](sobel, cmap='gray')
[Link]("Sobel Edge")
[Link]('off')
[Link](2, 3, 3)
[Link](prewitt, cmap='gray')
[Link]("Prewitt Edge")
[Link]('off')
[Link](2, 3, 4)
[Link](roberts, cmap='gray')
[Link]("Roberts Edge")
[Link]('off')
[Link](2, 3, 5)
[Link](canny, cmap='gray')
[Link]("Canny Edge")
[Link]('off')
plt.tight_layout()
[Link]("Edge Detection: Sobel, Prewitt, Roberts, Canny", fontsize=16)
plt.subplots_adjust(top=0.88)
[Link]()
5. Compress an image using JPEG or DCT-based coding and then decompress it.
Compare the original and reconstructed image using PSNR and compression
ratio
import cv2
import numpy as np
import [Link] as plt
from [Link] import peak_signal_noise_ratio as psnr, mean_squared_error as mse
# ---------------- Step 1: Load and Resize Image ----------------
image = [Link]('[Link]', cv2.IMREAD_GRAYSCALE)
image = [Link](image, (128, 128)) # Resize for faster DCT processing
# ---------------- Step 2: DCT Compression Function ----------------
def dct_compress(img, threshold=10):
h, w = [Link]
compressed = [Link]((h, w), dtype=np.float32)
nonzero_coeffs = 0
total_coeffs = 0
for i in range(0, h, 8):
for j in range(0, w, 8):
block = img[i:i+8, j:j+8].astype(np.float32)
dct_block = [Link](block)
total_coeffs += 64
dct_block[[Link](dct_block) < threshold] = 0 # Zero small values
nonzero_coeffs += np.count_nonzero(dct_block)
compressed[i:i+8, j:j+8] = dct_block
return compressed, nonzero_coeffs, total_coeffs
# ---------------- Step 3: DCT Decompression Function ----------------
def dct_decompress(dct_img):
h, w = dct_img.shape
decompressed = [Link]((h, w), dtype=np.float32)
for i in range(0, h, 8):
for j in range(0, w, 8):
block = dct_img[i:i+8, j:j+8]
idct_block = [Link](block)
decompressed[i:i+8, j:j+8] = idct_block
return [Link](decompressed, 0, 255).astype(np.uint8)
# ---------------- Step 4: Compress and Decompress ----------------
compressed_dct, kept, total = dct_compress(image, threshold=10)
reconstructed = dct_decompress(compressed_dct)
# ---------------- Step 5: Metrics ----------------
mse_val = mse(image, reconstructed)
psnr_val = psnr(image, reconstructed)
compression_ratio = total / kept if kept > 0 else float('inf')
print(f"📏 MSE: {mse_val:.2f}")
print(f"📶 PSNR: {psnr_val:.2f} dB")
print(f"📦 Compression Ratio: {compression_ratio:.2f}:1")
# ---------------- Step 6: Show Images ----------------
[Link](figsize=(10, 4))
[Link](1, 2, 1)
[Link](image, cmap='gray')
[Link]("Original Image")
[Link]('off')
[Link](1, 2, 2)
[Link](reconstructed, cmap='gray')
[Link]("Reconstructed Image")
[Link]('off')
[Link]("DCT-Based JPEG-like Compression", fontsize=14)
plt.tight_layout()
[Link]()
6. Apply morphological operations, opening and closing on a binary image.
Demonstrate how these operations help in noise removal or object separation.
import cv2
import numpy as np
from [Link] import cv2_imshow
# Load grayscale image
img = [Link]('[Link]', cv2.IMREAD_GRAYSCALE)
# Add synthetic salt noise
noise = [Link](0, 100, [Link], dtype=np.uint8)
noisy_img = [Link](img, noise)
# Define structuring element
kernel = [Link](cv2.MORPH_ELLIPSE, (5, 5))
# Apply opening (erosion → dilation)
opened = [Link](noisy_img, cv2.MORPH_OPEN, kernel)
# Display results
print("Noisy Image with Salt Noise:")
cv2_imshow(noisy_img)
print("\nAfter Opening Operation:")
cv2_imshow(opened)
import cv2
import numpy as np
from [Link] import cv2_imshow
# Load grayscale image
img = [Link]('[Link]', cv2.IMREAD_GRAYSCALE)
# Add synthetic pepper noise
noisy_img = [Link]()
pepper_noise = [Link]([Link]) < 0.02 # 2% black noise
noisy_img[pepper_noise] = 0
# Define structuring element
kernel = [Link](cv2.MORPH_ELLIPSE, (5, 5))
# Apply closing (dilation → erosion)
closed = [Link](noisy_img, cv2.MORPH_CLOSE, kernel)
# Display results
print("Noisy Image with Pepper Noise:")
cv2_imshow(noisy_img)
print("\nAfter Closing Operation:")
cv2_imshow(closed)
7. Sharpen a grayscale image using gradient-based masks (Sobel or Prewitt).
Visualize the enhanced image and discuss the results.
import cv2
import numpy as np
import [Link] as plt
def gradient_sharpening(image_path, method='sobel'):
# Load grayscale image
image = [Link](image_path, cv2.IMREAD_GRAYSCALE)
if image is None:
print("Error: Could not load image.")
return
if method == 'sobel':
# Sobel gradients
grad_x = [Link](image, cv2.CV_64F, 1, 0, ksize=3)
grad_y = [Link](image, cv2.CV_64F, 0, 1, ksize=3)
method_name = "Sobel"
elif method == 'prewitt':
# Prewitt gradients using custom kernels
kernel_x = [Link]([[-1, 0, 1],
[-1, 0, 1],
[-1, 0, 1]])
kernel_y = [Link]([[1, 1, 1],
[0, 0, 0],
[-1, -1, -1]])
grad_x = cv2.filter2D(image, -1, kernel_x).astype(np.float32)
grad_y = cv2.filter2D(image, -1, kernel_y).astype(np.float32)
method_name = "Prewitt"
else:
print("Invalid method. Choose 'sobel' or 'prewitt'.")
return
# Gradient magnitude
gradient = [Link](grad_x**2 + grad_y**2)
gradient = np.uint8([Link](gradient, 0, 255))
# Sharpen: add scaled gradient to original
sharpened = [Link](image, 1.0, gradient, 1.5, 0)
sharpened = [Link](sharpened, 0, 255).astype(np.uint8)
# Plot results
[Link](figsize=(12, 5))
[Link](1, 3, 1), [Link](image, cmap='gray'), [Link]('Original Image'), [Link]('off')
[Link](1, 3, 2), [Link](gradient, cmap='gray'), [Link](f'{method_name} Gradient'),
[Link]('off')
[Link](1, 3, 3), [Link](sharpened, cmap='gray'), [Link]('Sharpened Image'),
[Link]('off')
[Link](f"Image Sharpening using {method_name} Gradient", fontsize=14)
plt.tight_layout()
[Link]()
8. Convert a color image from RGB to HSV and CMYK. Visualize each channel
and explain its significance.
import cv2
import numpy as np
import [Link] as plt
# ---------------- Step 1: Load Color Image ----------------
img_bgr = [Link]('[Link]')
img_rgb = [Link](img_bgr, cv2.COLOR_BGR2RGB)
# ---------------- Step 2: Convert RGB to HSV ----------------
hsv_img = [Link](img_rgb, cv2.COLOR_RGB2HSV)
H, S, V = [Link](hsv_img)
# ---------------- Step 3: Convert RGB to CMYK Manually ----------------
img_float = img_rgb.astype('float32') / 255.0
K = 1 - [Link](img_float, axis=2)
C = (1 - img_float[..., 0] - K) / (1 - K + 1e-6)
M = (1 - img_float[..., 1] - K) / (1 - K + 1e-6)
Y = (1 - img_float[..., 2] - K) / (1 - K + 1e-6)
# Clip to [0,1]
C = [Link](C, 0, 1)
M = [Link](M, 0, 1)
Y = [Link](Y, 0, 1)
K = [Link](K, 0, 1)
# ---------------- Step 4: Plot RGB, HSV, CMYK Channels ----------------
[Link](figsize=(14, 10))
# RGB Image
[Link](3, 3, 1), [Link](img_rgb)
[Link]("Original RGB Image"), [Link]('off')
# HSV Channels
[Link](3, 3, 2), [Link](H, cmap='hsv')
[Link]("Hue (H) Channel"), [Link]('off')
[Link](3, 3, 3), [Link](S, cmap='gray')
[Link]("Saturation (S) Channel"), [Link]('off')
[Link](3, 3, 4), [Link](V, cmap='gray')
[Link]("Value (V) Channel"), [Link]('off')
# CMYK Channels
[Link](3, 3, 5), [Link](C, cmap='gray')
[Link]("Cyan (C) Channel"), [Link]('off')
[Link](3, 3, 6), [Link](M, cmap='gray')
[Link]("Magenta (M) Channel"), [Link]('off')
[Link](3, 3, 7), [Link](Y, cmap='gray')
[Link]("Yellow (Y) Channel"), [Link]('off')
[Link](3, 3, 8), [Link](K, cmap='gray')
[Link]("Black (K) Channel"), [Link]('off')
[Link]("RGB to HSV and CMYK Conversion", fontsize=16)
plt.tight_layout()
[Link]()