Skip to content

Commit 22e785d

Browse files
Add files via upload
1 parent 6ee6545 commit 22e785d

File tree

1 file changed

+180
-0
lines changed

1 file changed

+180
-0
lines changed

Codes/Simple_Filtering.py

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
# Input RGB image and implementing simple filtering
2+
3+
# Importing needed libraries
4+
import numpy as np
5+
from PIL import Image
6+
import matplotlib.pyplot as plt
7+
8+
# Creating an array from image data
9+
input_image = Image.open("images/eagle.jpeg")
10+
image_np = np.array(input_image)
11+
12+
# Checking the type of the array
13+
print(type(image_np)) # <class 'numpy.ndarray'>
14+
# Checking the shape of the array
15+
print(image_np.shape) # (270, 480, 3)
16+
17+
# Showing image with every channel separately
18+
channel_0 = image_np[:, :, 0]
19+
channel_1 = image_np[:, :, 1]
20+
channel_2 = image_np[:, :, 2]
21+
22+
# Checking if all channels are different
23+
print(np.array_equal(channel_0, channel_1)) # False
24+
print(np.array_equal(channel_1, channel_2)) # False
25+
26+
# Creating a figure with subplots
27+
f, ax = plt.subplots(nrows=2, ncols=2)
28+
# ax is (2, 2) np array and to make it easier to read we use 'flatten' function
29+
# Or we can call each time ax[0, 0]
30+
ax0, ax1, ax2, ax3 = ax.flatten()
31+
32+
# Adjusting first subplot
33+
ax0.imshow(channel_0, cmap=plt.get_cmap('Reds'))
34+
ax0.set_xlabel('')
35+
ax0.set_ylabel('')
36+
ax0.set_title('First channel')
37+
38+
# Adjusting second subplot
39+
ax1.imshow(channel_1, cmap=plt.get_cmap('Greens'))
40+
ax1.set_xlabel('')
41+
ax1.set_ylabel('')
42+
ax1.set_title('Second channel')
43+
44+
# Adjusting third subplot
45+
ax2.imshow(channel_2, cmap=plt.get_cmap('Blues'))
46+
ax2.set_xlabel('')
47+
ax2.set_ylabel('')
48+
ax2.set_title('Third channel')
49+
50+
# Adjusting fourth subplot
51+
ax3.imshow(image_np)
52+
ax3.set_xlabel('')
53+
ax3.set_ylabel('')
54+
ax3.set_title('Original image')
55+
56+
# Function to make distance between figures
57+
plt.tight_layout()
58+
# Giving the name to the window with figure
59+
f.canvas.set_window_title('GreyScaled image with three identical channels')
60+
# Showing the plots
61+
plt.show()
62+
63+
# Preparing image for Edge detection
64+
# Converting RGB image into GrayScale image
65+
# Using formula:
66+
# Y' = 0.299 R + 0.587 G + 0.114 B
67+
image_GrayScale = image_np[:, :, 0] * 0.299 + image_np[:, :, 1] * 0.587 + image_np[:, :, 2] * 0.114
68+
# Checking the type of the array
69+
print(type(image_GrayScale)) # <class 'numpy.ndarray'>
70+
# Checking the shape of the array
71+
print(image_GrayScale.shape) # (270, 480)
72+
# Giving the name to the window with figure
73+
plt.figure('GrayScale image from RGB')
74+
# Showing the image by using obtained array
75+
plt.imshow(image_GrayScale, cmap=plt.get_cmap('gray'))
76+
plt.show()
77+
78+
# Applying to the GrayScale image Pad frame with zero values
79+
# Using NumPy method 'pad'
80+
GrayScale_image_with_pad = np.pad(image_GrayScale, (1, 1), mode='constant', constant_values=0)
81+
# Checking the shape
82+
print(GrayScale_image_with_pad.shape) # (272, 482)
83+
84+
# Preparing image for convolution
85+
# In order to get filtered image (convolved input image) in the same size, it is needed to set Hyperparameters
86+
# Filter (kernel) size, K_size = 3
87+
# Step for sliding (stride), Step = 1
88+
# Processing edges (zero valued frame around image), Pad = 1
89+
# Consequently, output image size is (width and height are the same):
90+
# Width_Out = (Width_In - K_size + 2*Pad)/Step + 1
91+
# Imagine, that input image is 5x5 spatial size (width and height), then output image:
92+
# Width_Out = (5 - 3 + 2*1)/1 + 1 = 5, and this is equal to input image
93+
94+
# Preparing zero valued output arrays for filtered images (convolved images)
95+
# The shape is the same with input image according to the chosen Hyperparameters
96+
# For three filters for Edge detection and implementing it only for one GrayScale channel
97+
output_image_1 = np.zeros(image_GrayScale.shape)
98+
output_image_2 = np.zeros(image_GrayScale.shape)
99+
output_image_3 = np.zeros(image_GrayScale.shape)
100+
101+
# Declaring standard filters (kernel) with size 3x3 for edge detection
102+
filter_1 = np.array([[1, 0, -1], [0, 0, 0], [-1, 0, 1]])
103+
filter_2 = np.array([[0, 1, 0], [1, -4, 1], [0, 1, 0]])
104+
filter_3 = np.array([[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]])
105+
# Checking the shape
106+
print(filter_1.shape, filter_2.shape, filter_3.shape)
107+
# ((3, 3) (3, 3) (3, 3)
108+
109+
110+
# In order to prevent appearing values that are less than -1
111+
# Following function is declared
112+
def relu(array):
113+
# Preparing array for output result
114+
r = np.zeros_like(array)
115+
# Using 'np.where' setting condition that every element in 'array' has to be more than appropriate element in 'r'
116+
result = np.where(array > r, array, r)
117+
# Returning resulted array
118+
return result
119+
120+
121+
# In order to prevent appearing values that are more than 255
122+
# The following function is declared
123+
def image_pixels(array):
124+
# Preparing array for output result
125+
# Creating an empty array
126+
r = np.empty(array.shape)
127+
# Filling array with 255 value for all elements
128+
r.fill(255)
129+
# Using 'np.where' setting condition that every element in 'array' has to be less than appropriate element in 'r'
130+
result = np.where(array < r, array, r)
131+
# Returning resulted array
132+
return result
133+
134+
135+
# Implementing convolution operation for Edge detection for GrayScale image
136+
# Going through all input image with pad frame
137+
for i in range(GrayScale_image_with_pad.shape[0] - 2):
138+
for j in range(GrayScale_image_with_pad.shape[1] - 2):
139+
# Extracting 3x3 patch (the same size with filter) from input image with pad frame
140+
patch_from_input_image = GrayScale_image_with_pad[i:i+3, j:j+3]
141+
# Applying elementwise multiplication and summation - this is convolution operation
142+
# With filter_1
143+
output_image_1[i, j] = np.sum(patch_from_input_image * filter_1)
144+
# With filter_2
145+
output_image_2[i, j] = np.sum(patch_from_input_image * filter_2)
146+
# With filter_3
147+
output_image_3[i, j] = np.sum(patch_from_input_image * filter_3)
148+
149+
# Applying 'relu' and 'image_pixels' function to get rid of negative values and that ones that more than 255
150+
output_image_1 = image_pixels(relu(output_image_1))
151+
output_image_2 = image_pixels(relu(output_image_2))
152+
output_image_3 = image_pixels(relu(output_image_3))
153+
154+
# Showing results on the appropriate figures
155+
figure_1, ax = plt.subplots(nrows=3, ncols=1)
156+
157+
# Adjusting first subplot
158+
ax[0].imshow(output_image_1, cmap=plt.get_cmap('gray'))
159+
ax[0].set_xlabel('')
160+
ax[0].set_ylabel('')
161+
ax[0].set_title('Edge #1')
162+
163+
# Adjusting second subplot
164+
ax[1].imshow(output_image_2, cmap=plt.get_cmap('gray'))
165+
ax[1].set_xlabel('')
166+
ax[1].set_ylabel('')
167+
ax[1].set_title('Edge #2')
168+
169+
# Adjusting third subplot
170+
ax[2].imshow(output_image_3, cmap=plt.get_cmap('gray'))
171+
ax[2].set_xlabel('')
172+
ax[2].set_ylabel('')
173+
ax[2].set_title('Edge #3')
174+
175+
# Function to make distance between figures
176+
plt.tight_layout()
177+
# Giving the name to the window with figure
178+
figure_1.canvas.set_window_title('Convolution with filters (simple filtering)')
179+
# Showing the plots
180+
plt.show()

0 commit comments

Comments
 (0)