Skip to main content

Pattern Matching in Python- OpenCV

Hello guys. Today we will learn a pattern matching algorithm in python using the OpenCV library. Check out the video below to get a gist of what we are going to build. I have black and white grid patterns with white as background and black foreground.



As usual, we will start by first importing the required libraries and define a variable to capture the video from my webcam.

import cv2
import numpy as np
cap = cv2.VideoCapture(0)

Now, we write a while loop and capture the image frames. Also, we need to mirror the frames so that we can see it right.

while 1:
    ret, frame = cap.read()         ##Read image frame    frame = cv2.flip(frame, +1)     ##Mirror image frame
    if not ret:                     ##If frame is not read then exit        break    if cv2.waitKey(1) == ord('s'):  ##While loop exit condition        break

In the third part, we have to convert the image frames into a binary image. But why binary images?  You must ask.

1. We want to build a fast algorithm, so do not burden the processor with unnecessary calculations.
2. The grid patterns are black and white in color. So there is no point in using a color image for pattern matching.

Suppose your ROI(defined later) is 400 x 400 pixels and you use the color image directly for pattern matching then, just take a look at the amount of calculation your processor will have to go through.

color image size = 400 x 400 x 3 = 480,000

These are the number of elements that your processor will have to deal with. Again each element will have 256 different color values.

So let us convert the colored image into a binary image. For that, we will first have to convert image into grayscale and then threshold it.

frame2 = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

ret, thresh1 = cv2.threshold(frame2, 150, 255, cv2.THRESH_BINARY)

To convert the image to grayscale, we have to use the cvtColor method. This method takes two arguments. The image we want to convert and the method to convert it into grayscale. To convert the gray image into binary we need to use the threshold method. This method takes 4 arguments. The image we want to convert, threshold value, maximum value, and thresholding method. After using the above method the result will look as shown below.


Now let's define the region of interest for our image. But what is Region Of Intrest(ROI)? ROI is the part of an image where we actually want to perform our computer vision algorithm. In general, not the whole image is useful. Most of it is noise.

My image size is 1280 x 720 px. So I defined the ROI of  180 x 200 px. We will extract ROI from the original image and perform the next steps on it.

x1 = 750        
x2 = 930        
y1 = 100
y2 = 300
cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 3)
cv2.imshow('Pattern Template', thresh1[y1:y2, x1:x2])

(x1,y1) and (x2, y2) are the start and end coordinates of the ROI.



Ready for the next step? This is an interesting one. But first, take a look at the amount of calculation that the CPU has to go through right now.

Total matrix elements = 180 x 200  = 36,000

Still, this is a large number too deal with. On PC this will run smoothly but on stand-alone systems dealing with 36000 matrix elements will take a considerable amount of time. The solution is to again reduce the number of pixels we are dealing with. But how?

Take a look at the pattern below.






I hope you got the idea. We are going to reduce 180 x 200 px to 9 x 9 px. Just divide 180 and 200 into 9 equal parts. That means each block of  20x22 pixels will contribute to a single element in the 9x9 matrix. The following code will do this task.

Pattern_Matrix = np.zeros((9, 9), np.uint8)
width = int((x2-x1)/9)
height = int((y2-y1)/9)
W1 = x1
H1 = y1
W2 = x1 + width
H2 = y1 + height

for i in range(0, 9):
    for j in range(0, 9):
        Sum = np.sum(thresh1[H1: H2, W1:W2])                    ##56100        if Sum > 56100:
            Pattern_Matrix[i, j] = 255        else:
            Pattern_Matrix[i, j] = 0        W1 = W2
        W2 = W2 + width
        #print('W1 = ' +str(W1))        #print('W2 = ' +str(W2))        #print('H1 = ' +str(H1))        #print('H2 = ' +str(H2))        #print("Sum = "+str(Sum))        Sum = 0    W1 = x1
    W2 = x1 + width
    H1 = H2
    H2 = H2 + height

You must ask what is that 56100 number in if condition? Well, if you take a block of 20x22 pixels and if all of them are white in color(i.e. 255 value) then what will be the sum of all those pixel values?

Sum = 20 x 22 x 255 = 112,200

If you divide this number by 2 we get 56100. This simply means that if in a 20x22 pixel block more than 50% pixels are white then consider that whole block as white and vise versa. We store the result in another 9x9 matrix.

And now it's time to compare the patterns. For that first, we need to save templates of patterns in our code.

Pattern_1 = np.array([  [0,   0,   0,   0,   0,   0,   0,   0, 0],                        [0, 255, 255, 255, 255, 255, 255, 255, 0],                        [0, 255, 255, 255,   0,   0,   0, 255, 0],                        [0, 255, 255, 255, 255, 255, 255, 255, 0],                        [0, 255, 255, 255,   0, 255, 255, 255, 0],                        [0, 255, 255, 255, 255, 255, 255, 255, 0],                        [0, 255,   0,   0,   0, 255, 255, 255, 0],                        [0, 255, 255, 255, 255, 255, 255, 255, 0],                        [0,   0,   0,   0,   0,   0,   0,   0, 0],                        ], dtype=np.uint8)

Pattern_2 = np.array([  [0,   0,   0,   0,   0,   0,   0,   0, 0],                        [0, 255, 255, 255, 255, 255, 255, 255, 0],                        [0, 255,   0, 255, 255, 255,   0, 255, 0],                        [0, 255, 255,   0, 255,   0, 255, 255, 0],                        [0, 255, 255, 255,   0, 255, 255, 255, 0],                        [0, 255, 255,   0, 255,   0, 255, 255, 0],                        [0, 255,   0, 255, 255, 255,   0, 255, 0],                        [0, 255, 255, 255, 255, 255, 255, 255, 0],                        [0,   0,   0,   0,   0,   0,   0,   0, 0],                        ], dtype=np.uint8)


Pattern_3 = np.array([  [0,   0,   0,   0,   0,   0,   0,   0, 0],                        [0, 255, 255, 255, 255, 255, 255, 255, 0],                        [0, 255,   0,   0,   0,   0,   0, 255, 0],                        [0, 255,   0, 255, 255, 255,   0, 255, 0],                        [0, 255,   0, 255, 255, 255,   0, 255, 0],                        [0, 255,   0, 255, 255, 255,   0, 255, 0],                        [0, 255,   0,   0,   0,   0,   0, 255, 0],                        [0, 255, 255, 255, 255, 255, 255, 255, 0],                        [0,   0,   0,   0,   0,   0,   0,   0, 0],                        ], dtype=np.uint8)

Pattern_4 = np.array([  [0,   0,   0,   0,   0,   0,   0,   0, 0],                        [0, 255, 255, 255, 255, 255,   0, 255, 0],                        [0, 255,   0, 255, 255, 255,   0, 255, 0],                        [0, 255, 255, 255, 255, 255,   0, 255, 0],                        [0,   0,   0,   0,   0,   0,   0,   0, 0],                        [0, 255,   0, 255, 255, 255, 255, 255, 0],                        [0, 255,   0, 255, 255, 255,   0, 255, 0],                        [0, 255,   0, 255, 255, 255, 255, 255, 0],                        [0,   0,   0,   0,   0,   0,   0,   0, 0],                        ], dtype=np.uint8)

The following code compares the image patterns with the saved templates. Remember, a match is found only when there is more than a 90% match.  Also, all the operations are performed on the binary image but the results are shown on the original image.

##*******************Pattern Comparison*********************##
for a in range(0, 9):
    for b in range (0, 9):
        if Pattern_Matrix[a, b] == Pattern_1[a, b]:
            Result_Count1 = Result_Count1 + 1        if Pattern_Matrix[a, b] == Pattern_2[a, b]:
            Result_Count2 = Result_Count2 + 1        if Pattern_Matrix[a, b] == Pattern_3[a, b]:
            Result_Count3 = Result_Count3 + 1        if Pattern_Matrix[a, b] == Pattern_4[a, b]:
            Result_Count4 = Result_Count4 + 1
##print(Result_Count)
Match_Percentage1 = (Result_Count1 / 81) * 100Match_Percentage2 = (Result_Count2 / 81) * 100Match_Percentage3 = (Result_Count3 / 81) * 100Match_Percentage4 = (Result_Count4 / 81) * 100
Result_Count1 = 0Result_Count2 = 0Result_Count3 = 0Result_Count4 = 0
if Match_Percentage1 > 90:
    S = "Pattern 1  " + str(round(Match_Percentage1, 1)) + '%'    cv2.putText(frame, S, (5, 50), font, 2, (0, 0, 255), 2, cv2.LINE_AA)
elif Match_Percentage2 > 90:
    S = "Pattern 2  " + str(round(Match_Percentage2, 1)) + '%'    cv2.putText(frame, S, (5, 50), font, 2, (0, 0, 255), 2, cv2.LINE_AA)
elif Match_Percentage3 > 90:
    S = "Pattern 3  " + str(round(Match_Percentage3, 1)) + '%'    cv2.putText(frame, S, (5, 50), font, 2, (0, 0, 255), 2, cv2.LINE_AA)
elif Match_Percentage4 > 90:
    S = "Pattern 4  " + str(round(Match_Percentage4, 1)) + '%'    cv2.putText(frame, S, (5, 50), font, 2, (0, 0, 255), 2, cv2.LINE_AA)
else:
    cv2.putText(frame, "No Match Found", (5, 50), font, 2, (0, 0, 255), 2, cv2.LINE_AA)


This is it, guys. Let me know if you were able to do it. Enjoy Pattern Matching...!!!

For Full Code:- https://github.com/vibhor69meshram/Pattern-Matching


Comments

Post a Comment

Popular posts from this blog

Iris Detection | Python | OpenCv

 Hello there! Welcome to another blog. In this blog you are going to learn to detect iris using OpenCv python. Here is the video in case you missed it. So, let's get started. We will start by importing the necessary libraries. import cv2 import numpy as np Now, let us import the face and eye classifier files and set the camera resolution as follows. eye = cv2.CascadeClassifier( 'haarcascade_eye.xml' ) face = cv2.CascadeClassifier( 'haarcascade_frontalface_alt.xml' ) Kernal = np.ones(( 3 , 3 ) , np.uint8) #Declare kernal for morphology cap = cv2.VideoCapture( 0 ) cap.set(cv2.CAP_PROP_FRAME_WIDTH , 320 ) ##Set camera resolution cap.set(cv2.CAP_PROP_FRAME_HEIGHT , 240 ) In a while loop let us capture an image frame, flip it(in case your camera captures inverted images) and convert it into a gray scale image. ret , frame = cap.read() ##Read image frame frame = cv2.flip(frame , + 1 ) ##Flip the image in case your camera

Object Distance Calculation Using Contour Area Method In Python - Opencv

Today we will discuss how you can find the distance of an object from the camera using python OpenCV. Check out the video below. Before we continue, you should know how to detect a colored object. Click this link to check out my previous blog on object detection and tracking. I hope after checking out my previous blog, you are able to write your own code to detect and track objects. We will take forward the Object detection and tracking code to find the distance of an object from the camera. So let's start. Let us first understand the principle using which we will find the distance of the object from the camera. Principle:- Area enclosed by the contours of an object decreases as the object moves farther from the camera. This simply means that, if your object is near to the camera, the object will appear bigger. Thus the pixel area occupied by the object will be very large. As you move the object farther from the camera, the object size in the image will start to d

Object Detection And Tracking using Python - Opencv

Let us discuss today how you can detect and track an object in real-time. We will be using Python language and Opencv library for this purpose. Check out the video below. If you have read my previous blogs, you can directly skip down to the contour part. As usual, we need to make a few assumptions for the proper working of this application. This background is always static i.e. there is no addition or subtraction of objects in the background scene. The background-color is always constant. It does not change with time. The object that will be used for writing/painting is of a different color than the background to give us sufficient contrast between foreground and background. We are ready to begin now. Let us start by installing necessary python libraries for our project using  pip install.  We will be needing  Numpy  and  Opencv  libraries. Now create a python project and create a new script. Import the required libraries into python script as shown below. import cv2