Skip to content

Commit 3b515bb

Browse files
Update README.md
1 parent be1ba29 commit 3b515bb

File tree

1 file changed

+224
-3
lines changed

1 file changed

+224
-3
lines changed

README.md

Lines changed: 224 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,17 @@ Image processing. Getting data from images in form of matrix with numbers, slici
1717

1818
## Content
1919
Codes (it'll send you to appropriate file):
20-
* [Opening_png_jpg](https://github.com/sichkar-valentyn/Image_processing_in_Python/tree/master/Codes/Opening_png_jpg.py)
21-
* [Converting_RGB_to_GreyScale](https://github.com/sichkar-valentyn/Image_processing_in_Python/tree/master/Codes/Converting_RGB_to_GreyScale.py)
22-
* [Simple_Filtering](https://github.com/sichkar-valentyn/Image_processing_in_Python/tree/master/Codes/Simple_Filtering.py)
20+
* [Opening_png_jpg.py](https://github.com/sichkar-valentyn/Image_processing_in_Python/tree/master/Codes/Opening_png_jpg.py)
21+
* [Converting_RGB_to_GreyScale.py](https://github.com/sichkar-valentyn/Image_processing_in_Python/tree/master/Codes/Converting_RGB_to_GreyScale.py)
22+
* [Simple_Filtering.py](https://github.com/sichkar-valentyn/Image_processing_in_Python/tree/master/Codes/Simple_Filtering.py)
23+
* [Convolution_of_Images.py](https://github.com/sichkar-valentyn/Image_processing_in_Python/tree/master/Codes/Convolution_of_Images.py)
2324

2425
<br/>
2526
Experimental results (figures and tables on this page):
2627

2728
* <a href="#RGB channels of the image separately">RGB channels of the image separately</a>
2829
* <a href="#Examples of Simple Filtering for Edge Detection">Examples of Simple Filtering for Edge Detection</a>
30+
* <a href="#Convolution of Images">Convolution of Images</a>
2931

3032
<br/>
3133

@@ -142,6 +144,225 @@ Full code is available here: [Simple_Filtering.py](https://github.com/sichkar-va
142144

143145
<br/>
144146

147+
### <a name="Convolution of Images">Convolution of Images</a>
148+
Implementing image processing via convolution operation.
149+
<br/>Creating dunction for convolution, defining filters and showing resulted images.
150+
151+
Reading images, cropping and resizing them.
152+
<br/>Consider following part of the code:
153+
154+
```py
155+
# Importing needed libraries
156+
import numpy as np
157+
import matplotlib.pyplot as plt
158+
from scipy.misc import imread, imresize
159+
160+
# Reading images
161+
cat, dog = imread('images/cat.jpg'), imread('images/dog.jpg')
162+
163+
# Defining difference between width and height
164+
print(cat.shape) # (1080, 1920, 3)
165+
print(dog.shape) # (1050, 1680, 3)
166+
difference_cat = cat.shape[1] - cat.shape[0]
167+
difference_dog = dog.shape[1] - dog.shape[0]
168+
# Cropping images to make it square size
169+
# Cropping by width and taking middle part
170+
cat_cropped = cat[:, int(difference_cat / 2):int(-difference_cat / 2), :]
171+
dog_cropped = dog[:, int(difference_dog / 2):int(-difference_dog / 2), :]
172+
print(cat_cropped.shape) # (1080, 1080, 3)
173+
print(dog_cropped.shape) # (1050, 1050, 3)
174+
175+
# Defining needed image size for resizing
176+
image_size = 200
177+
# Defining output array for new images
178+
# For 2 images with height = width = image_size and 3 channels
179+
# (channels come at the end in order to show resized image)
180+
image_resized = np.zeros((2, image_size, image_size, 3))
181+
print(image_resized.shape) # (2, 200, 200, 3)
182+
# Resizing two images
183+
image_resized[0, :, :, :] = imresize(cat_cropped, (image_size, image_size)) # (200, 200, 3)
184+
image_resized[1, :, :, :] = imresize(dog_cropped, (image_size, image_size)) # (200, 200, 3)
185+
```
186+
187+
Preparing data for convolution operation.
188+
<br/>Consider following part of the code:
189+
190+
```py
191+
# Defining output array for new image
192+
# For 2 images with 3 channels and height = width = image_size
193+
x = np.zeros((2, 3, image_size, image_size))
194+
# Resizing two images
195+
# And transposing in order to put channels first
196+
x[0, :, :, :] = imresize(cat_cropped, (image_size, image_size)).transpose((2, 0, 1))
197+
x[1, :, :, :] = imresize(dog_cropped, (image_size, image_size)).transpose((2, 0, 1))
198+
print(x[0].shape) # (3, 200, 200)
199+
print(x[1].shape) # (3, 200, 200)
200+
```
201+
202+
Preparing weights for convolution for 2 filters with 3 channels and size 3x3.
203+
<br/>Consider following part of the code:
204+
205+
```py
206+
# Defining array for weights
207+
w = np.zeros((2, 3, 3, 3))
208+
209+
# First filter converts images into grayscale
210+
# Defining three channels for this filter - red, green and blue
211+
w[0, 0, :, :] = [[0, 0, 0], [0, 0.3, 0], [0, 0, 0]]
212+
w[0, 1, :, :] = [[0, 0, 0], [0, 0.6, 0], [0, 0, 0]]
213+
w[0, 2, :, :] = [[0, 0, 0], [0, 0.1, 0], [0, 0, 0]]
214+
215+
# Second filter will detect horizontal edges in the blue channel
216+
w[1, 2, :, :] = [[1, 2, 1], [0, 0, 0], [-1, -2, -1]]
217+
218+
# Defining 128 biases for the edge detection filter
219+
# in order to make output non-negative
220+
b = np.array([0, 128])
221+
```
222+
223+
Defining function for naive forward pass with convolution.
224+
<br/>Consider following part of the code:
225+
226+
```py
227+
"""
228+
Input consists of following:
229+
x of shape (N, C, H, W) - N data, each with C channels, height H and width W.
230+
w of shape (F, C, HH, WW) - We convolve each input with F different filters,
231+
where each filter spans all C channels; each filter has height HH and width WW.
232+
233+
'cnn_params' is a dictionary with following keys:
234+
'stride' - step for sliding
235+
'pad' - zero-pad frame around input
236+
237+
Function returns volume of feature maps of shape (N, F, H', W') where:
238+
H' = 1 + (H + 2 * pad - HH) / stride
239+
W' = 1 + (W + 2 * pad - WW) / stride
240+
241+
N here is the same as we have it as number of input images.
242+
F here is as number of channels of each N (that are now as feature maps)
243+
244+
"""
245+
246+
247+
def cnn_forward_naive(x, w, b, cnn_params):
248+
# Preparing parameters for convolution operation
249+
stride = cnn_params['stride']
250+
pad = cnn_params['pad']
251+
N, C, H, W = x.shape
252+
F, _, HH, WW = w.shape
253+
254+
# Applying to the input image volume Pad frame with zero values for all channels
255+
# As we have in input x N as number of inputs, C as number of channels,
256+
# then we don't have to pad them
257+
# That's why we leave first two tuples with 0 - (0, 0), (0, 0)
258+
# And two last tuples with pad parameter - (pad, pad), (pad, pad)
259+
# In this way we pad only H and W of N inputs with C channels
260+
x_padded = np.pad(x, ((0, 0), (0, 0), (pad, pad), (pad, pad)), mode='constant', constant_values=0)
261+
262+
# Defining spatial size of output image volume (feature maps) by following formulas:
263+
height_out = int(1 + (H + 2 * pad - HH) / stride)
264+
width_out = int(1 + (W + 2 * pad - WW) / stride)
265+
# Depth of output volume is number of filters which is F
266+
# And number of input images N remains the same - it is number of output image volumes now
267+
268+
# Creating zero valued volume for output feature maps
269+
feature_maps = np.zeros((N, F, height_out, width_out))
270+
271+
# Implementing convolution through N input images, each with F filters
272+
# Also, with respect to C channels
273+
# For every image
274+
for n in range(N):
275+
# For every filter
276+
for f in range(F):
277+
# Defining variable for indexing height in output feature map
278+
# (because our step might not be equal to 1)
279+
height_index = 0
280+
# Convolving every channel of the image with every channel of the current filter
281+
# Result is summed up
282+
# Going through all input image (2D convolution) through all channels
283+
for i in range(0, H, stride):
284+
# Defining variable for indexing width in output feature map
285+
# (because our step might not be equal to 1)
286+
width_index = 0
287+
for j in range(0, W, stride):
288+
feature_maps[n, f, height_index, width_index] = \
289+
np.sum(x_padded[n, :, i:i+HH, j:j+WW] * w[f, :, :, :]) + b[f]
290+
# Increasing index for width
291+
width_index += 1
292+
# Increasing index for height
293+
height_index += 1
294+
295+
# Returning resulted volumes of feature maps and cash
296+
return feature_maps
297+
```
298+
299+
Implementing convolution of each image with each filter and offsetting by bias.
300+
<br/>Consider following part of the code:
301+
302+
```py
303+
results = cnn_forward_naive(x, w, b, {'stride': 1, 'pad': 1})
304+
print(results.shape) # (2, 2, 200, 200) - two images with two channels
305+
```
306+
307+
Creating function for normalizing resulted images.
308+
<br/>Consider following part of the code:
309+
310+
```py
311+
def normalize_image(img):
312+
image_max, image_min = np.max(img), np.min(img)
313+
return 255 * (img - image_min) / (image_max - image_min)
314+
```
315+
316+
Preparing figures for plotting.
317+
<br/>Consider following part of the code:
318+
319+
```py
320+
figure_1, ax = plt.subplots(nrows=2, ncols=5)
321+
# 'ax 'is as (2, 5) np array and we can call each time ax[0, 0]
322+
323+
# Plotting original, cropped and resized images
324+
# By adding 'astype' we convert float numbers to integer
325+
ax[0, 0].imshow(cat)
326+
ax[0, 0].set_title('Original (900, 1600, 3))')
327+
ax[0, 1].imshow(cat_cropped)
328+
ax[0, 1].set_title('Cropped (900, 900, 3)')
329+
ax[0, 2].imshow(image_resized[0, :, :, :].astype('int'))
330+
ax[0, 2].set_title('Resized (200, 200, 3)')
331+
ax[0, 3].imshow(normalize_image(results[0, 0]), cmap=plt.get_cmap('gray'))
332+
ax[0, 3].set_title('Grayscale')
333+
ax[0, 4].imshow(normalize_image(results[0, 1]), cmap=plt.get_cmap('gray'))
334+
ax[0, 4].set_title('Edges')
335+
336+
ax[1, 0].imshow(dog)
337+
ax[1, 0].set_title('Original (1050, 1680, 3)')
338+
ax[1, 1].imshow(dog_cropped)
339+
ax[1, 1].set_title('Cropped (1050, 1050, 3)')
340+
ax[1, 2].imshow(image_resized[1, :, :, :].astype('int'))
341+
ax[1, 2].set_title('Resized (200, 200, 3)')
342+
ax[1, 3].imshow(normalize_image(results[1, 0]), cmap=plt.get_cmap('gray'))
343+
ax[1, 3].set_title('Grayscale')
344+
ax[1, 4].imshow(normalize_image(results[1, 1]), cmap=plt.get_cmap('gray'))
345+
ax[1, 4].set_title('Edges')
346+
347+
# Setting axes 'off'
348+
for i in range(2):
349+
for j in range(5):
350+
ax[i, j].set_axis_off()
351+
352+
# Giving the name to the window with figure
353+
figure_1.canvas.set_window_title('Image convolution')
354+
# Showing the plots
355+
plt.show()
356+
```
357+
358+
Showing resulted images on the figure.
359+
360+
![Convolution_of_Images](images/Image_convolution.png)
361+
362+
Full code is available here: [Convolution_of_Images.py](https://github.com/sichkar-valentyn/Image_processing_in_Python/tree/master/Codes/Convolution_of_Images.py)
363+
364+
<br/>
365+
145366
### MIT License
146367
### Copyright (c) 2018 Valentyn N Sichkar
147368
### github.com/sichkar-valentyn

0 commit comments

Comments
 (0)