Saturday, May 2, 2020

Computer Vision 3- Image Processing/Manipulation

Learn A-Z Computer Vision In 15 Days 



In this lecture, we will about  Image Processing/Manipulation.

Blurring
import cv2
import matplotlib.pyplot as plt
import numpy as np 
%matplotlib inline

image = cv2.imread('Hill.jpg')
image_blur = cv2.blur(image,(5,5))


 fig,axes = plt.subplots(nrows= 1, ncols = 2,dpi=300 )
axes[0].imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
axes[1].imshow(cv2.cvtColor(image_blur, cv2.COLOR_BGR2RGB))
for ax in axes:
    ax.set_xticks([])
    ax.set_yticks([])


                              Original Image                                                                 Blurring


Gaussian Blurring
image_gaus_blur = cv2.GaussianBlur(image,(7,7),0)

fig,axes = plt.subplots(nrows= 1, ncols = 2,dpi=300 )
axes[0].imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
axes[1].imshow(cv2.cvtColor(image_gaus_blur, cv2.COLOR_BGR2RGB))

for ax in axes:
    ax.set_xticks([])
    ax.set_yticks([])

Original Image                                                               Gaussian Blurring


Math Behind Blur
  • Kernal_n*n moves over the image 
  • Multiplies each pixel by the corresponding entry in the kernel and takes the sum.
  • The sum becomes a new pixel value
# Create our sharpening kernel, we don't normalize since the values in the matrix sum to 1
kernel_5x5 = np.ones((5,5), np.float32)/25

# Applying different kernels to the input image
image_blur = cv2.filter2D(image,-1, kernel_3x3)

fig,axes = plt.subplots(nrows= 1, ncols = 2,dpi=300 )
axes[0].imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
axes[1].imshow(cv2.cvtColor(image_blur, cv2.COLOR_BGR2RGB))

for ax in axes:
    ax.set_xticks([])
    ax.set_yticks([])

Original Image                                                             Blurring


Sharpening
import cv2
import matplotlib.pyplot as plt
import numpy as np 
%matplotlib inline

image = cv2.imread('Hill.jpg')
# Create our shapening kernel, we don't normalize since the values in the matrix sum to 1
kernel_sharpen = np.array([[-1,-1,-1], 
                                               [-1,9,-1], 
                                               [-1,-1,-1]])
# Applying different kernels to the input image
image_sharpened = cv2.filter2D(image, -1, kernel_sharpening)

fig,axes = plt.subplots(nrows= 1, ncols = 2,dpi=300 )
axes[0].imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
axes[1].imshow(cv2.cvtColor(image_sharpened, cv2.COLOR_BGR2RGB))

for ax in axes:
    ax.set_xticks([])
    ax.set_yticks([])

Original Image                                                             Sharpening

Cropping
import cv2
import matplotlib.pyplot as plt
import numpy as np 
%matplotlib inline

image = cv2.imread('hill.jpg')

height, width = image.shape[:2]

# Top-Left  Coordinates  
xmin, ymin = int(height * .25), int(width * .25)
# Bottom-Right Coordinates 
xmax, ymax = int(height * .75), int(width * .75)
# Indexing to crop out the rectangle
image_cropped = image[xmin:xmax, ymin:ymax]

fig,axes = plt.subplots(nrows= 1, ncols = 2,dpi=300 )
axes[0].imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
axes[1].imshow(cv2.cvtColor(image_cropped, cv2.COLOR_BGR2RGB))

for ax in axes:
    ax.set_xticks([])
    ax.set_yticks([])

Original Image                                                             Cropping


Resize Image
Means to stretch and squeeze it as needed so it fits a given size. Width and height are modified independently. If the ratio between them is not the same in the original size and in the final size, the image will appear distorted.


import cv2
image = cv2.imread('hill.jpg')

# Original size of image 
# Display the (Height, Width) 
print(image.shape)
>> (700, 700, 3)

# resize to 3/4th of original image
image_rescale = cv2.resize(image, None, fx=0.75, fy=0.75)
# change size of image
print(image_rescale.shape)
>> (525, 525, 3)

cv2.imshow("Orginal_image",image)
cv2.imshow("Resize_image",image_rescale)
cv2.waitKey(0)
cv2.destroyAllWindows()

Scaling 
Means resizing, but by the same amount horizontally and vertically. The ratio between the width and height is not modified, therefore the final image is not distorted.

import cv2
image = cv2.imread('hill.jpg')

image_down_scale = cv2.pyrDown(image)
image_up_scale = cv2.pyrUp(smaller)

cv2.imshow('Original', image )
cv2.imshow('Smaller ', image_down_scale )
cv2.imshow('Larger ', image_up_scale  )
cv2.waitKey(0)
cv2.destroyAllWindows()

Rotation
import cv2
import matplotlib.pyplot as plt
import numpy as np 
%matplotlib inline

image = cv2.imread('hill.jpg')
height, width = image.shape[:2]
rotation_matrix = cv2.getRotationMatrix2D((width/2, height/2), 60, 0.5)
rotated_image = cv2.warpAffine(image, rotation_matrix, (width, height))

fig,axes = plt.subplots(nrows= 1, ncols = 2,dpi=300 )
axes[0].imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
axes[1].imshow(cv2.cvtColor(rotated_image, cv2.COLOR_BGR2RGB))

for ax in axes:
    ax.set_xticks([])
    ax.set_yticks([])

                            Original                                                               Rotation

# 0, for flipping the image around the x-axis (vertical flipping).
# > 0 for flipping around the y-axis (horizontal flipping).
# < 0 for flipping around both axes.
flipped = cv2.flip(image, 0)

fig,axes = plt.subplots(nrows= 1, ncols = 2,dpi=300 )
axes[0].imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
axes[1].imshow(cv2.cvtColor(flipped, cv2.COLOR_BGR2RGB))

for ax in axes:
    ax.set_xticks([])
    ax.set_yticks([])
Original Image                                                               Vertical Flip
       
Translation         
import cv2
import matplotlib.pyplot as plt
import numpy as np 
%matplotlib inline

image = cv2.imread('hill.jpg')
height, width = image.shape[:2]

half_height, half_width = height/2, width/2

#          | 1 0 Tx |
#  T  = | 0 1 Ty |
# T is our translation matrix
T = np.float32([[1, 0, -half_width], 
                [0, 1,-half_height]])

translated_image = cv2.warpAffine(image, T, (width, height))

fig,axes = plt.subplots(nrows= 1, ncols = 2,dpi=300 )
axes[0].imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
axes[1].imshow(cv2.cvtColor(translated_image, cv2.COLOR_BGR2RGB))

for ax in axes:
    ax.set_xticks([])
    ax.set_yticks([])

Original Image                                                  Translated Image


Brightening Image
import cv2
import matplotlib.pyplot as plt
import numpy as np 
%matplotlib inline)

# Create a matrix of ones, then multiply it by a scaler of 75
# This gives a matrix with the same dimensions of our image with all values being 75
M = np.ones(image.shape, dtype = "uint8") * 75 

# We use this to add this matrix M, to our image
# Notice the increase in brightness
bright_image = cv2.add(image, M)

fig,axes = plt.subplots(nrows= 1, ncols = 2,dpi=300 )
axes[0].imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
axes[1].imshow(cv2.cvtColor(bright_image, cv2.COLOR_BGR2RGB))

for ax in axes:
    ax.set_xticks([])
    ax.set_yticks([])
Original Image                                                    Bright Image 


 Darkening Image
import cv2
import matplotlib.pyplot as plt
import numpy as np 
%matplotlib inline)

# Create a matrix of ones, then multiply it by a scaler of 75
# This gives a matrix with the same dimensions of our image with all values being 75
M = np.ones(image.shape, dtype = "uint8") * 75 

# We use this to add this matrix M, to our image
# Notice the increase in brightness
bright_image = cv2.subtract(image, M)

fig,axes = plt.subplots(nrows= 1, ncols = 2,dpi=300 )
axes[0].imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
axes[1].imshow(cv2.cvtColor(dark_image, cv2.COLOR_BGR2RGB))

for ax in axes:
    ax.set_xticks([])
    ax.set_yticks([])
                        Original Image                                                           Dark Image


Thresholding
import cv2
import matplotlib.pyplot as plt
import numpy as np 
%matplotlib inline

# Load our image as grayscale 
image = cv2.imread('sudoku-puzzle.jpg',0)

# Values below 127 goes to 0 (black, everything above goes to 255 (white)
ret,thresh1 = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY)

# Values below 127 go to 255 and values above 127 go to 0 (reverse of above)
ret,thresh2 = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY_INV)

# Values above 127 are truncated (held) at 127 (the 255 argument is unused)
ret,thresh3 = cv2.threshold(image, 127, 255, cv2.THRESH_TRUNC)

# Values below 127 go to 0, above 127 are unchanged  
ret,thresh4 = cv2.threshold(image, 127, 255, cv2.THRESH_TOZERO)

# Resever of above, below 127 is unchanged, above 127 goes to 0
ret,thresh5 = cv2.threshold(image, 127, 255, cv2.THRESH_TOZERO_INV)

SMALL_SIZE = 5

plt.rc('font', size=SMALL_SIZE)          # controls default text sizes
plt.rc('axes', titlesize=SMALL_SIZE)     # fontsize of the axes title

fig,axes = plt.subplots(nrows= 3, ncols = 2,dpi=300 )

plt.subplots_adjust(top = 0.99, bottom=0.01, hspace=0.5, wspace=0.01)

axes[0][0].set_title('Original Image')
axes[0][0].imshow(image,cmap='gray' )

axes[0][1].set_title('Threshold Binary')
axes[0][1].imshow(thresh1,cmap='gray')

axes[1][0].set_title('Threshold Binary Inverse')
axes[1][0].imshow(thresh2,cmap='gray')

axes[1][1].set_title('THRESH TRUNC')
axes[1][1].imshow(thresh3,cmap='gray')

axes[2][0].set_title('THRESH TOZERO')
axes[2][0].imshow(thresh2,cmap='gray')

axes[2][1].set_title('THRESH TOZERO INV')
axes[2][1].imshow(thresh3,cmap='gray')



The biggest disadvantage of these methods. We have to provide the threshold value. There is a smarter way to set the value.

# AdaptiveThreshold
adapt_thresh = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 3, 5) 

# Otsu's thresholding after Gaussian filtering
_, otsu_thresh = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

fig,axes = plt.subplots(nrows= 1, ncols = 3,dpi=300 )

axes[0].set_title('Original Image')
axes[0].imshow(image,cmap='gray' )

axes[1].set_title('Adaptive Mean Thresholding')
axes[1].imshow(adapt_thresh,cmap='gray' )

axes[2].set_title('Guassian Otsus Thresholding')
axes[2].imshow(otsu_thresh,cmap='gray')


Gradient
import cv2
import matplotlib.pyplot as plt
import numpy as np 
%matplotlib inline

# Load our image as grayscale 
image = cv2.imread('sudoku-puzzle.jpg',0)
sobel_x = cv2.Sobel(image,cv2.CV_64F,1,0,ksize=5)
sobel_y = cv2.Sobel(image,cv2.CV_64F,0,1,ksize=5)
laplacian = cv2.Laplacian(image,cv2.CV_64F)

SMALL_SIZE = 5

plt.rc('font', size=SMALL_SIZE)          # controls default text sizes
plt.rc('axes', titlesize=SMALL_SIZE)     # fontsize of the axes title

fig,axes = plt.subplots(nrows= 2, ncols = 2,dpi=150)

plt.tight_layout()

axes[0][0].set_title('Original Image')
axes[0][0].imshow(image,cmap='gray' )

axes[0][1].set_title('Sobel_x')
axes[0][1].imshow(sobel_x,cmap='gray')

axes[1][0].set_title('Sobel_y')
axes[1][0].imshow(sobel_y,cmap='gray')

axes[1][1].set_title('THRESH TRUNC')
axes[1][1].imshow(laplacian,cmap='gray')




Morphological Operator
import cv2
import matplotlib.pyplot as plt
import numpy as np 
%matplotlib inline

# Load our image as grayscale 
image = cv2.imread('Mayank.png',0)

kernel = np.ones((5,5), np.uint8)
# Dilation remove the Black noise from the Foreground
dilation = cv2.dilate(image, kernel, iterations = 1)


kernel = np.ones((5,5), np.uint8)

# Erosion remove the white noise from the image
erosion = cv2.erode(image, kernel, iterations = 1)

plt.rc('xtick', labelsize=3) 
plt.rc('ytick', labelsize=3) 

fig,axes = plt.subplots(nrows= 1, ncols = 2,dpi=500 )

axes[0].set_title('Original Image')
axes[0].imshow(image,cmap='gray' )

axes[1].set_title('Erosion')
axes[1].imshow(erosion,cmap='gray' )


Closing 

Dilation followed by Erosion ( Remove Dark Noise)

kernel = np.ones((5,5), np.uint8)
closing = cv2.morphologyEx(image, cv2.MORPH_CLOSE, kernel)

plt.rc('xtick', labelsize=3) 
plt.rc('ytick', labelsize=3) 

fig,axes = plt.subplots(nrows= 1, ncols = 2,dpi=500 )

axes[0].set_title('Original Image')
axes[0].imshow(image,cmap='gray' )

axes[1].set_title('closing')
axes[1].imshow(closing,cmap='gray')

Opening

Erosion followed by Dilation  ( Remove White Noise)

kernel = np.ones((3,3), np.uint8)
opening = cv2.morphologyEx(image, cv2.MORPH_OPEN, kernel)

plt.rc('xtick', labelsize=3) 
plt.rc('ytick', labelsize=3) 

fig,axes = plt.subplots(nrows= 1, ncols = 2,dpi=500 )

axes[0].set_title('Original Image')
axes[0].imshow(image,cmap='gray' )

axes[1].set_title('opening')
axes[1].imshow(opening,cmap='gray' )

Bitwise Operator
# Draw the Rectangle & Circle

import cv2
import numpy as np

mask_for_rectangle = np.zeros((450,750,3), np.uint8)  #(height,width)

mask_for_circle = np.zeros((450,750,3), np.uint8)

cv2.rectangle(mask_for_rectangle,(150,100), (400, 300), (255,255,255), -1)
cv2.circle(mask_for_circle,(400,200), 150, (255,255,255), -1)


fig,axes = plt.subplots(nrows= 1, ncols = 2,dpi=300 )
axes[0].imshow(cv2.cvtColor(mask_for_rectangle, cv2.COLOR_BGR2RGB))
axes[1].imshow(cv2.cvtColor(mask_for_circle, cv2.COLOR_BGR2RGB))

for ax in axes:
    ax.set_xticks([])
    ax.set_yticks([])


Union
union = cv2.bitwise_or(mask_for_circle,mask_for_rectangle)

plt.imshow(cv2.cvtColor(union, cv2.COLOR_BGR2RGB))

Intersection
intersection = cv2.bitwise_and(mask_for_circle,mask_for_rectangle)

plt.imshow(cv2.cvtColor(intersection, cv2.COLOR_BGR2RGB))

XOR
xor = cv2.bitwise_xor(mask_for_circle,mask_for_rectangle)

plt.imshow(cv2.cvtColor(xor, cv2.COLOR_BGR2RGB))

NOT
Not = cv2.bitwise_not(mask_for_circle)

plt.imshow(cv2.cvtColor(Not, cv2.COLOR_BGR2RGB))

Blending

import cv2
import matplotlib.pyplot as plt
import numpy as np 
%matplotlib inline

image_1 = cv2.imread('hill.jpg')
image_2 = cv2.imread('india.png')


plt.rc('xtick', labelsize=3) 
plt.rc('ytick', labelsize=3) 

fig,axes = plt.subplots(nrows= 1, ncols = 2,dpi=500 )

axes[0].set_title('Image_1')
axes[0].imshow(cv2.cvtColor(image_1, cv2.COLOR_BGR2RGB))

axes[1].set_title('Image_2')
axes[1].imshow(cv2.cvtColor(image_2, cv2.COLOR_BGR2RGB))



# Both the images should have the same size
image_2 = cv2.resize(image_2, (image_1.shape[1],image_1.shape[0]))

# Blending the image
blended_image = cv2.addWeighted(src1 = image_1, alpha = 0.7 ,src2 = image_2, beta = 0.3, gamma = 0)

fig = plt.figure(figsize=(10,8))
ax = fig.add_subplot(111)
ax.imshow(cv2.cvtColor(blended_image, cv2.COLOR_BGR2RGB))



2nd Method

import cv2
import matplotlib.pyplot as plt
import numpy as np 
%matplotlib inline

image_1 = cv2.imread('hill.jpg')
image_2 = cv2.imread('india.png')


plt.rc('xtick', labelsize=3) 
plt.rc('ytick', labelsize=3) 

fig,axes = plt.subplots(nrows= 1, ncols = 2,dpi=500 )

axes[0].set_title('Image_1')
axes[0].imshow(cv2.cvtColor(image_1, cv2.COLOR_BGR2RGB))

axes[1].set_title('Image_2')
axes[1].imshow(cv2.cvtColor(image_2, cv2.COLOR_BGR2RGB))


# Both the images should have the same size
image_2 = cv2.resize(image_2, (image_1.shape[1],image_1.shape[0]))

# Generate the Image_2 Mask 
_, otsu_thresh_mask = cv2.threshold(cv2.cvtColor(image_2,cv2.COLOR_BGR2GRAY), 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)


fig = plt.figure(figsize=(10,8))
ax = fig.add_subplot(111)
ax.imshow(cv2.cvtColor(otsu_thresh_mask, cv2.COLOR_BGR2RGB))






# Remove the mask i.e INDIA from the image_1 
image_1[otsu_thresh_mask == 0] = [0, 0, 0]                                                                                                  # Remove the  background  from the image_2                                                                                image_2[otsu_thresh_mask != 0] = [0, 0, 0]



plt.rc('xtick', labelsize=3) 
plt.rc('ytick', labelsize=3) 

fig,axes = plt.subplots(nrows= 1, ncols = 2,dpi=500 )

axes[0].set_title('Image_1')
axes[0].imshow(cv2.cvtColor(image_1, cv2.COLOR_BGR2RGB))

axes[1].set_title('Image_2')
axes[1].imshow(cv2.cvtColor(image_2, cv2.COLOR_BGR2RGB))



blended_image = image_1 + image_2


fig = plt.figure(figsize=(10,8))
ax = fig.add_subplot(111)
ax.imshow(cv2.cvtColor(blended_image, cv2.COLOR_BGR2RGB))




In the next blog, we will discuss the Basic video with OpenCV. 
https://sngurukuls247.blogspot.com/2020/05/computer-vision-4-video-basics-with.html

.                                                                                                                                        

Follow the link below to access Free Python Lectures-

https://www.youtube.com/channel/UCENc9qI7_r8KMf6-_1R1xnw

Instagram-
https://www.instagram.com/python.india/

Feel free contact me on-
Email - sn.gurukul24.7uk@gmail.com

No comments:

Post a Comment