Initially developed by Intel, OpenCV is an open-source computer vision cross-platform library for real-time image processing and which has become a standard tool for all things related to computer vision applications. In 2000, the first version of OpenCV was released; since then, its functionality has been very much enriched and simplified by the scientific community. Later in 2012, a nonprofit foundation OpenCV.org took the initiative for maintaining a support site for developers and users.
It is available on most operating systems like Linux, Windows, Android, iOS and some more. The first implementation was in the C programming language. However, the library has a full interface for other programming languages like Python, Java, MATLAB/Octave. Also, the wrapper for other languages has been developed to encourage the adoption by the programmers.
The application of OpenCV covers areas such as segmentation and recognition, object identification, facial recognition, motion tracking, gesture recognition, image stitching, High Dynamic Range (HDR) imaging, augmented reality, etc. Moreover, it supports application areas such as statistical machine learning functions. Today in this article, we will see the basic image processing using OpenCV, and we will implement some filters using the Python programming language.
Sign up for your weekly dose of what's up in emerging technology.
Implementation of Various Filters using OpenCV
Import all dependencies:
To start with OpenCV, you need to install it using the following command. Run this command either in the terminal window or in the Jupyter Notebook preceding the exclamation mark.
! pip install opencv-python import cv2 import numpy as np import matplotlib.pyplot as plt
Helper function consists of matplotlib functionality used to compare the images.
Download our Mobile App
def compare_image(image1, image2): plt.figure(figsize=(9,9)) plt.subplot(1,2,1) plt.imshow(image1) plt.title('Orignal') plt.axis('off') plt.subplot(1,2,2) plt.imshow(image2) plt.title('Modified') plt.axis('off') plt.tight_layout()
Load the image:
By default OpenCV reads the image in BGR format, to see the image in the original format i,e. RGB we need to convert it.
img = cv2.imread('/content/original.jpg') img2 = cv2.cvtColor(img,cv2.COLOR_BGR2RGB) compare_image(img2,img)
cv2.filter2D() is used to perform convolution operation with 2D image and the kernel(N x M dimensional matrix) is used. Filtering with such kernel results in operation: suppose you have defined a 10 x 10 kernel and all the pixels falling under this window are first multiplied and summed up the result is divided by 100 this is nothing but the averaging of the pixel and this same operation is carried out for all the pixels.
To know more about the convolution operation, read this article.
Let’s implement the above convolutional filter.
kernel = np.ones((10,10),np.float32)/100 cnv = cv2.filter2D(img2, -1, kernel) compare_image(img2,cnv)
Image smoothing is achieved by convolving the image with different filters. It is useful for removing the high-frequency content such as noise and edges from the image, resulting in blurred edges when these filters are applied. OpenCV comes with four main filters as below;
The averaging is done by simply convolving the image with a normalized box filter. It takes the average of all pixels under the kernel window and replaces the central element with this average. This is achieved as follow;
## Average Filtering blur = cv2.blur(img2,(10,10)) compare_image(img2,blur)
- Median Filtering:
cv2.medianBlur() computes the median of all the pixels under the kernel window and replaces the central value with the median value. This filter is highly used to remove noise from the image. To demonstrate the operation of this filter, we have introduced noise to the image by using the skimage library; later, the median filter is applied to the noisy image.
from skimage.util import random_noise ## adding noise noise_img = random_noise(img2, mode='s&p',amount=0.3) noise_img = np.array(255*noise_img, dtype = 'uint8') ## median filter median = cv2.medianBlur(noise_img,5) compare_image(noise_img,median)
- Bilateral Filtering:
The previous filters blur the image, but the bilateral filter tends to blur the image preserving the edges between the objects. In addition, while blurring the image, the bilateral filter considers the nearby pixel intensity values and considers whether the pixel is on edge or not; this makes the operation of this filter a bit slow.
In the below example, we can see how the filter has blurred images by preserving the edges of the mobile phones.
## bilateral filtering img = cv2.imread('/content/history_of_mobile_phones.jpg') img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB) blur = cv2.bilateralFilter(img,20,200,300) compare_image(img,blur)
Canny Edge Detection:
The canny edge detector is the edge detection operation that operates on multi-stage algorithms to detect a wide range of edges in the image. The process involves: applies the Gaussian filter to a smooth image, finds the intensity gradient of the image, applies gradient magnitude thresholding to get rid of spurious response to edge detection, applies a double threshold to determine potential edges, and tracks the edges by hysteresis.
cv2.canny() is used to detect the edges;
## edge detection park = cv2.imread('/content/new-zealand-parks.jpg') park = cv2.cvtColor(park,cv2.COLOR_BGR2RGB) edge = cv2.Canny(park,100,200) compare_image(park,edge)
Contour is the curve joining all continuous points along the boundary having the same color or intensity. This is the most useful tool for object detection and shapes analysis.
Let’s find contours for our mobile phones;
from google.colab.patches import cv2_imshow ## Contours im = cv2.imread('/content/history_of_mobile_phones.jpg',cv2.IMREAD_COLOR) imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY) ret,thresh = cv2.threshold(imgray,127,255,cv2.THRESH_BINARY) contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) cv2.drawContours(im,contours,-1,(0,255,0),3) cv2_imshow(im)
As you can see the contours are also drawn for the shadows of phones, it can detect even small changes in pixels.
Morphological filters are some simple operations based on image shape. These filters need two inputs: image and kernel, which decides the nature of the operation.
It is just like soil erosion; it erodes the boundary, it warns away the boundaries of foreground objects, i.e., tries to keep the foreground white. So the operation follows as the kernel slides over the image, and a pixel of the image is considered one only if all the pixels under the kernel are 1; otherwise, it is eroded.
# erosion img = cv2.imread('/content/kama_ingredients_updated_600x400_0071_banyan_leaf.jpg',0) img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB) kernel = np.ones((5,5),np.uint8) erosion = cv2.erode(img,kernel,iterations=1) compare_image(img,erosion)
By performing the erosion, we can see all the vanes of the leaf clearly.
It is just the opposite of erosion; here, the pixel is considered as one if at least one pixel under the kernel is one, so in this case, it increases the white region in the image. Dilation is also helpful in joining the broken part of an object.
# Dilation dia = cv2.dilate(img,kernel,iterations=1) compare_image(img,dia)
- Morphological Gradient:
It is the difference between the dilation and erosion, and the result looks like the object’s outline.
# gradient grad = cv2.morphologyEx(img,cv2.MORPH_GRADIENT, kernel) compare_image(img,grad)
From this article, we have seen how to load an image. The OpenCV reads the image in the default manner, i.e., it reads the image in BGR format and later has different filters like image smoothing, basic convolution operation, Contours mapping, Edge detection, Morphological transformation. One can leverage the power of these filters in real-world applications like erosion filters can be used to visualize the object in a more detailed way.