Mimage Manipulation Using Python
Mimage Manipulation Using Python
1
Note: you may need to restart the kernel to use updated packages.
1.2 1) Rotate an image by 45°, 90°, and 180° using OpenCV and Pillow.
1.2.1 OpenCV
[7]: import cv2
import matplotlib.pyplot as plt
# Hide axes
for ax in axes:
ax.axis('off')
2
# Save the output as a single image file
output_path = r"C:\Users\roari\Downloads\Bird_rotated_output.jpg"
plt.savefig(output_path)
plt.show()
1.2.2 Pillow
[27]: from PIL import Image
import matplotlib.pyplot as plt
3
axes[1].imshow(rotated_45_rgb)
axes[1].set_title("Rotated 45°")
axes[2].imshow(rotated_90_rgb)
axes[2].set_title("Rotated 90°")
axes[3].imshow(rotated_180_rgb)
axes[3].set_title("Rotated 180°")
# Hide axes
for ax in axes:
ax.axis('off')
4
# Crop the image to focus on the bird
cropped_image = image[y:y+h, x:x+w]
1.3.2 Pillow
[31]: from PIL import Image
import matplotlib.pyplot as plt
5
# Get image dimensions
width, height = image.size
# Define the cropping coordinates and size (left, upper, right, lower)
x, y, w, h = 120, 50, 450, 400
left = x
upper = y
right = min(x + w, width) # Ensure the cropping box does not exceed the image␣
↪dimensions
lower = min(y + h, height) # Ensure the cropping box does not exceed the image␣
↪dimensions
6
2 Advance analysis of resize image.
2.1 USING SSIM MAP
[5]: import warnings
from cryptography.utils import CryptographyDeprecationWarning
# Define the cropping coordinates and size (left, upper, right, lower)
x, y, w, h = 120, 50, 450, 400
left = x
upper = y
right = min(x + w, width) # Ensure the cropping box does not exceed the image␣
↪dimensions
lower = min(y + h, height) # Ensure the cropping box does not exceed the image␣
↪dimensions
# Resize the cropped image to match the original image's dimensions for␣
↪comparison
7
cropped_image_gray_resized = cv2.resize(cropped_image_gray, (image_gray.
↪shape[1], image_gray.shape[0]))
SSIM Map (Score: 0.30): A visual representation of the Structural Similarity Index (SSIM) between
the original and resized/cropped images. SSIM is a metric used to measure the perceptual similarity
between two images, considering factors like luminance, contrast, and structure.
Insights from the SSIM Map:
The SSIM Map provides valuable information about the differences between the original and re-
sized/cropped images:
Low SSIM Score (0.30): The relatively low SSIM score of 0.30 indicates that there are significant
structural differences between the two images. This suggests that the resizing or cropping process
has affected the image’s overall appearance and quality. Dark Regions: The darker regions in the
8
SSIM Map highlight areas where the differences between the images are more pronounced. These
areas likely correspond to regions where the image has been distorted or lost information due to
resizing or cropping. Structural Similarity: The SSIM metric considers structural similarity, which
means it is sensitive to changes in the spatial arrangement of image features. Therefore, the dark
regions in the SSIM Map likely indicate areas where the spatial relationships between elements
have been altered.
axes[2].imshow(resized_images_rgb[1])
axes[2].set_title("Resized 512x512")
axes[2].axis('off')
9
# Show the combined plot
plt.tight_layout()
plt.show()
2.2.2 Pillow
[33]: from PIL import Image
import matplotlib.pyplot as plt
10
axes[1].set_title("Resized 256x256")
axes[1].axis('off')
axes[2].imshow(resized_images_rgb[1])
axes[2].set_title("Resized 512x512")
axes[2].axis('off')
11
# Convert images to grayscale for pixel-by-pixel difference and Fourier␣
↪transform
image_gray = image.convert("L")
resized_images_gray = [resized.convert("L") for resized in resized_images]
plt.imshow(magnitude_spectrum, cmap='gray')
plt.title(title)
plt.axis('off')
# Plot results
fig, axes = plt.subplots(3, 3, figsize=(15, 15))
# Original images
axes[0, 0].imshow(image_gray, cmap='gray')
axes[0, 0].set_title("Original Image")
axes[0, 0].axis('off')
12
# Pixel-by-pixel difference
axes[1, 0].imshow(image_gray, cmap='gray')
axes[1, 0].axis('off')
# Fourier transforms
axes[2, 0].axis('off')
axes[2, 1].axis('off')
axes[2, 2].axis('off')
plt.subplot(3, 3, 7)
plot_fft(np.array(image_gray), "FFT of Original Image")
plt.subplot(3, 3, 8)
plot_fft(resized_array_256, "FFT of Resized 256x256")
plt.subplot(3, 3, 9)
plot_fft(resized_array_512, "FFT of Resized 512x512")
13
Analyzing the Image: Original and Pixel-by-Pixel Difference Maps Understanding the Components:
Original Image (Grayscale): The initial image in grayscale format, providing a baseline for com-
parison. Pixel-by-Pixel Difference (256x256): A difference map showing the pixel-wise differences
between the original image and a resized (256x256) version of the image. Pixel-by-Pixel Difference
(512x512): A difference map showing the pixel-wise differences between the original image and a
resized (512x512) version of the image. Insights from the Difference Maps:
The difference maps provide valuable information about the impact of resizing on the image:
Noise and Artifacts: The difference maps are filled with noise and artifacts, indicating that the
resizing process has introduced significant distortions into the image. This is especially evident in
the 256x256 difference map, where the noise is more pronounced. Loss of Detail: The noise and
artifacts in the difference maps suggest that the resizing process has led to a loss of detail in the
image. This is because resizing often involves downsampling, which can reduce the number of pixels
and blur fine features. Image Quality Degradation: The presence of noise and artifacts indicates a
14
significant degradation in image quality. This is particularly noticeable in the 256x256 difference
map, where the noise is more severe. Conclusion:
Based on the analysis of the difference maps, it can be concluded that resizing the image has
introduced significant noise and artifacts, leading to a degradation in image quality and a loss of
detail. The impact of resizing is more pronounced in the 256x256 difference map, suggesting that
smaller image sizes are more susceptible to distortion during resizing.Analyzing the FFTs of Resized
Images Understanding the FFT:
The Fast Fourier Transform (FFT) is a mathematical technique used to decompose a signal into
its frequency components. In the context of images, the FFT can be used to analyze the spatial
frequency content of an image. High-frequency components represent fine details and edges, while
low-frequency components represent overall brightness and smooth variations.
Insights from the FFTs:
Impact of Resizing on Frequency Content:
The FFTs of the resized images show a noticeable difference compared to the FFT of the original
image. This indicates that resizing has altered the frequency content of the image. The FFT of
the resized 256x256 image appears more spread out and contains more high-frequency components.
This suggests that resizing to a smaller dimension has introduced additional high-frequency noise
or artifacts. The FFT of the resized 512x512 image is closer to the original FFT but still shows
some differences. This indicates that resizing to a larger dimension has less impact on the frequency
content. Noise Introduction:
The increased high-frequency content in the FFTs of the resized images suggests that the resizing
process has introduced noise. This noise can be attributed to interpolation techniques used during
resizing, which can introduce artifacts. The amount of noise introduced may be more significant
for smaller resized images, as the interpolation process has to fill in more pixels. Loss of Detail:
The changes in the frequency content due to resizing can lead to a loss of detail in the image.
High-frequency components represent fine details, and if these components are affected by noise or
artifacts, it can result in a loss of sharpness and clarity.
Conclusion: The FFT analysis reveals that resizing an image can significantly impact its frequency
content. Smaller resized images are more likely to introduce noise and artifacts, leading to a loss
of detail and a degradation in image quality. The choice of resizing algorithm and the extent of
resizing can influence the severity of these effects.
15
# Convert the image from BGR to RGB for displaying with matplotlib
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
16
1. RGB (Red, Green, Blue) Description: Color Model: RGB is an additive color model where
colors are created by combining red, green, and blue light in various intensities. Representation:
Each pixel is represented by three values corresponding to the intensities of red, green, and blue.
Use: Colour Manipulation
2. HSV (Hue, Saturation, Value) Description: Color Model: HSV represents colors in terms of hue
(color type), saturation (color intensity), and value (brightness). Representation: Hue describes
the type of color, saturation represents the purity of the color, and value indicates the brightness.
Use: Colour Adjustment
3. Grayscale Description: Color Model: Grayscale images represent intensity only, with no color
information. Each pixel is a shade of gray from black to white. Representation: Each pixel
is represented by a single value that denotes its intensity. Use: Edge detectionScenarios for Each
Conversion: 1) RGB to HSV: Detect or track objects based on their color rather than their intensity
2) RGB to Grayscale: Edge detection 3) HSV to RGB: Colour-based processing
# Convert the image from BGR to RGB for displaying with matplotlib
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
17
# Convert the image back from HSV to RGB
image_hsv_rgb = cv2.cvtColor(image_hsv, cv2.COLOR_HSV2RGB)
# Create a subplot with 2 rows and 4 columns (2 for images and 2 for histograms)
fig, axes = plt.subplots(2, 4, figsize=(20, 10))
hist_rgb = compute_histogram(image_rgb, 3)
for i, color in enumerate(('r', 'g', 'b')):
axes[1, 0].plot(hist_rgb[i], color=color)
axes[1, 0].set_title("RGB Histogram")
axes[1, 0].set_xlim([0, 256])
hist_hsv = compute_histogram(image_hsv, 3)
for i, color in enumerate(('r', 'g', 'b')):
axes[1, 1].plot(hist_hsv[i], color=color)
axes[1, 1].set_title("HSV Histogram")
axes[1, 1].set_xlim([0, 256])
hist_gray = compute_histogram(image_gray, 1)
axes[1, 2].plot(hist_gray, color='black')
18
axes[1, 2].set_title("Grayscale Histogram")
axes[1, 2].set_xlim([0, 256])
hist_hsv_rgb = compute_histogram(image_hsv_rgb, 3)
for i, color in enumerate(('r', 'g', 'b')):
axes[1, 3].plot(hist_hsv_rgb[i], color=color)
axes[1, 3].set_title("HSV to RGB Histogram")
axes[1, 3].set_xlim([0, 256])
RGB TO HSV: The Red colour intensity increses and it is more concentrated in different peaks
while there is sharp decrease in blue and green colour intensity in initial but at the end green
intensity graph increases to peak. HSV TO RGB: If we observe closely there is some fluctuation in
original vs this graph means some deteoration in image quality because original colour pixels are
altered.
19
import matplotlib.pyplot as plt
import pandas as pd
# Flatten images
original_rgb_flat = flatten_image(image_rgb)
hsv_rgb_flat = flatten_image(image_hsv_rgb)
gray_rgb_flat = flatten_image(image_gray_rgb)
20
axes[0, i].set_ylabel('HSV')
# Adjust layout
plt.tight_layout()
plt.show()
21
RGB vs HSV:
The scatter plots show a strong positive correlation between the original RGB values and the cor-
responding HSV values. This indicates that the conversion from RGB to HSV preserves the overall
color information and intensity. The diagonal lines in the scatter plots suggest a linear relationship
between the pixel values. This is expected, as the HSV transformation is a mathematical conversion
that preserves the underlying color information.
RGB vs Grayscale:
The scatter plots show a less clear relationship between the original RGB values and the grayscale
values. This is because the grayscale conversion collapses the color information into a single intensity
channel. The scatter plots are more scattered, indicating a loss of color information during the
grayscale conversion.
Loss : Original/HSV to Greyscale :- Colour information loss more in Blue > than Red
> than Green Insights from the Scatter Plots:
RGB vs Grayscale:
The scatter plots show a general linear relationship between the original RGB values and the
grayscale values. This indicates that the grayscale conversion is primarily based on the overall
intensity of the pixels. The scatter plots for the red and green channels show a slightly stronger
correlation than the scatter plot for the blue channel, suggesting that the grayscale conversion may
be more heavily influenced by the red and green components.
HSV vs Grayscale:
The scatter plots show a less clear relationship between the HSV values and the grayscale values.
This is because the grayscale conversion collapses the color information into a single intensity
channel, while the HSV representation includes information about hue and saturation. The scatter
plots are more scattered, indicating a loss of color information during the grayscale conversion.
8 3. Histogram Analysis .
8.1 Generate and plot the histogram of the original image and the grayscale
version.
[41]: import cv2
import matplotlib.pyplot as plt
22
# Convert the image to grayscale
image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# RGB Histograms
axes[0, 0].plot(hist_r, color='red')
axes[0, 0].set_title("Red Channel Histogram")
axes[0, 0].set_xlim([0, 256])
# Grayscale Histogram
axes[1, 1].plot(hist_gray, color='gray')
axes[1, 1].set_title("Grayscale Histogram")
axes[1, 1].set_xlim([0, 256])
23
8.2 Performing histogram equalization on the grayscale image to enhance its
contrast, and plot the histogram of the enhanced image.
[49]: import cv2
import matplotlib.pyplot as plt
24
hist_equalized = cv2.calcHist([equalized_image], [0], None, [256], [0, 256])
# Adjust layout
plt.tight_layout()
plt.show()
25
Equalized image saved as: C:\Users\roari\Downloads\Bird_Equalized.jpg
Insights from the Histograms:
Original Grayscale Histogram: The histogram shows a concentration of pixel values on the darker
side, indicating a lack of contrast in the original image. Equalized Grayscale Histogram: The
equalized grayscale histogram shows a more uniform distribution of pixel values, indicating that
histogram equalization has successfully stretched the contrast.
[82]: import cv2
import matplotlib.pyplot as plt
26
# Perform histogram equalization
equalized_image = cv2.equalizeHist(image_gray)
# Adjust layout
plt.tight_layout()
plt.show()
27
9 4. Image Filtering.
9.0.1 Apply the following filters to the grayscale version of an image and observe the
changes:
� Gaussian Blur � Median Filter � Sharpening Filter
[59]: import cv2
import numpy as np
import matplotlib.pyplot as plt
28
axes[1, 0].axis('off')
# Adjust layout
plt.tight_layout()
plt.show()
29
Laplacian sharpening kernel. It is less aggressive compared to the kernel with a central value of
5, and might produce different results.1. Gaussian Blur Description:Gaussian Blur is a smoothing
filter that reduces image noise and detail by averaging the pixel values within a kernel. It uses a
Gaussian function to weight pixels around the center more heavily.
2. Median Filter Description:Median Filter is a non-linear filter that replaces each pixel’s value
with the median value of the pixels in its neighborhood. It is particularly effective at preserving
edges while removing noise.
3. Sharpening Filter Description:Sharpening Filter increases the contrast between adjacent pixels
to enhance the definition of edges and fine details in an image. It does so by amplifying the
high-frequency components.Insights from the Images:
Gaussian Blur: The Gaussian blur image appears smoother and less detailed than the original
image. This is because the Gaussian blur filter averages pixel values in a neighborhood, reducing
noise and blurring edges. Median Filter: The median filter image also appears slightly smoother
than the original image, but it preserves edges better than the Gaussian blur. This is because the
median filter replaces each pixel with the median value of its neighbors, which can help to remove
noise while preserving edges. Sharpening Filter: The sharpening filter image appears sharper and
has more defined edges than the original image. This is because the sharpening filter enhances the
contrast between edges, making them more prominent.
10 5. Combining Techniques.
10.1 Convert the image to Grayscale.
[76]: import cv2
import matplotlib.pyplot as plt
# Convert the grayscale image from BGR (OpenCV format) to RGB (matplotlib␣
↪format)
30
# Display the grayscale image
axes[0].imshow(gray_image_rgb, cmap='gray')
axes[0].set_title("Grayscale Image")
axes[0].axis('off') # Hide the axes
31
resized_gray_image = cv2.resize(gray_image, (300, 300))
# Compute histograms
def compute_histogram(image):
return cv2.calcHist([image], [0], None, [256], [0, 256])
hist_resized = compute_histogram(resized_gray_image)
hist_equalized = compute_histogram(equalized_gray_image)
32
[84]: import cv2
import matplotlib.pyplot as plt
33
# Apply histogram equalization to enhance the contrast of the grayscale image
equalized_gray_image = cv2.equalizeHist(resized_gray_image)
# Adjust layout
plt.tight_layout()
plt.show()
34
image = cv2.imread(image_path)
# Compute histograms
def compute_histogram(image):
return cv2.calcHist([image], [0], None, [256], [0, 256])
hist_resized = compute_histogram(resized_gray_image)
hist_equalized = compute_histogram(equalized_gray_image)
hist_blurred = compute_histogram(blurred_image)
35
axes[2, 1].plot(hist_blurred, color='black')
axes[2, 1].set_title("Histogram of Blurred Image")
axes[2, 1].set_xlim([0, 256])
36
Insights from the Histograms:
Original Grayscale Histogram: The histogram shows a concentration of pixel values on the darker
side, indicating a lack of contrast in the resized grayscale image. Histogram of Equalized Image: The
37
histogram shows a more uniform distribution of pixel values, indicating that histogram equalization
has effectively stretched the contrast. Histogram of Blurred Image: The histogram shows a wider
peak and a narrower range of pixel values, indicating that the Gaussian blur has reduced the
contrast and smoothed the image.
[98]: import cv2
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
# Flatten images
resized_flat = flatten_image(resized_gray_image)
equalized_flat = flatten_image(equalized_gray_image)
blurred_flat = flatten_image(blurred_image)
38
plt.title('Box Plot of Pixel Value Distribution Before and After Image␣
↪Processing')
plt.show()
11 END
[ ]:
39