This project is a Parallelized Number Plate Detection System developed for Windows using Visual Studio. It utilizes OpenCV and OpenMP to efficiently detect number plates in images and recognize characters on them. The primary goal of this system is to speed up the process of detecting and recognizing number plates in images or video frames.
- Introduction
- Objectives
- Technology Stack
- Function Definitions
- Parallelism Decomposition
- Program Flow
- Usage Instructions
- Results
- Python Neural Network for Character Recognition
- License
In today's world, image processing and task automation play a crucial role in law enforcement. A number plate detection system can digitalize this process, providing convenience to law enforcement agencies. This system has various applications, from catching over-speeding drivers to tracking criminal vehicle movements. It can also be integrated into dashboard cameras to detect, recognize, and store number plates during traffic incidents.
Conventional (serialized) systems may face efficiency challenges when dealing with a large number of vehicles in a single camera frame. Parallelized systems offer the potential for more efficient and faster results. Additionally, character recognition in traditional systems can be computationally expensive, while using a pre-trained neural network can significantly speed up the process.
The objectives of this project are as follows:
-
Implement a C++ system capable of detecting multiple number plates from a video stream.
-
Crop the detected number plates from the video frame and individually process them to detect characters.
-
Recognize the characters in the image by employing a recognition engine based on a Neural Net.
-
Output a corresponding string of characters representing the recognized number plate.
-
Store the image and the recognized plate number for future use.
To ensure the program runs efficiently and provides significant speedups compared to traditional systems, OpenCV is used for image processing, and OpenMP is used to parallelize the entire process.
- C++ (Visual Studio)
- OpenMP library for parallelization
- OpenCV library for image processing
- Python (Used to create and train the Neural Net, and invoked to recognize characters using the pre-trained Neural Net)
Function Name | Use |
---|---|
void main() |
|
void processPlatesArray(Mat& frame, Mat& grey, vector & plates) |
|
void processSinglePlate(Mat& croppedPlate) |
|
void postProcessImg(Mat& dilatedImg, vector > contours, vector selected_ROI) |
|
string recognizeCharacter(Mat& croppedCharacter) |
|
void sortContours(vector >& contours) |
|
string execSystemCommand(const char* cmd) |
|
string char_to_str(char c) |
|
- Go to OpenCV Releases and download the Latest Release's EXE File.
- Create a folder ‘OpenCV’ in the C drive.
- Run the downloaded .exe file and select the extraction location as the folder you just created.
- Add the bin folder (C:\OpenCV\opencv\build\x64\vc15\bin) to the Environment Variables path.
- Restart your computer.
- Download the installer from Python Downloads for Windows.
- Run the installer and follow the setup steps.
- Make sure the 'Add Python to Path' option is checked during the setup process.
- Verify the Python installation by running "python -V" in the command line.
- Clone the project from GitHub.
- Run the Visual Studio Solution (.sln) file.
- Verify that OpenCV is added to the project properties.
- Go to Project > Properties.
- In VC++ Directories > Build Directories, add “C:\OpenCV\opencv\build\include”.
- In VC++ Directories > Library Directories, add “C:\OpenCV\opencv\build\x64\vc15\lib”.
- In Linker > Input > Additional Dependencies, add “opencv_world455d.lib”.
- Enable OpenMP in Visual Studio by going to Project > Properties > C/C++ > Language > OpenMP Support and enabling it to "Yes".
- Rename a batch of images to be detected in the form "plate (1)", "plate (2)", and so on.
- Go to Bulk Resize Photos and bulk resize all images to 960 x 540.
- In the project directory, navigate to Resources > Plates > test and paste all the renamed/resized images.
- Enter the number of images in the test directory.
- The output will be stored inside the "RecognitionOutput" folder in the project directory.
The test was run on a batch of 10 images, containing 11 number plates. The entire batch was processed for 100 iterations, and the results were averaged out in the end.
For one single batch, the average time was as follows:
- Serial Execution Time: 57.0827 seconds
- Parallel Execution Time: 18.1869 seconds
The parallelized implementation resulted in a speedup of approximately 313.86%.
Character recognition in this project is performed using a Python neural network script. The script uses a Perceptron model for character recognition.
The Python script reads a saved neural network object from the "Plates_NN.pickle" file, which contains the trained model's weights and biases. It then processes the input image and returns a prediction for the recognized character.
Here is an overview of the neuralnet.py script:
import numpy as np
import pandas as pd
import pickle
import sys
class Perceptron:
all_weights = []
all_bias = []
def __init__(self, weights, bias):
self.all_weights = weights
self.all_bias = bias
# Functions for weighted sum, sigmoid, and prediction
def get_weighted_sum(feature, weights, bias):
# Calculate the weighted sum of features
wSum = float(0.0)
for i in range(len(feature)):
wSum += float(feature[i] * weights[i])
wSum += float(bias)
return wSum
def sigmoid(w_sum):
# Apply sigmoid activation function
sig = 1 / (1 + np.exp(-w_sum))
return sig
def get_prediction(image, weights, bias):
# Get the prediction for the input image
w_sum = get_weighted_sum(image, weights, bias)
prediction = sigmoid(w_sum)
return prediction
def main(imgArray):
# Load the trained neural network from a file
file_to_read = open("Plates_NN.pickle", "rb")
loaded_object = pickle.load(file_to_read)
file_to_read.close()
image = np.array(imgArray) / 255
predictions_set = []
listOfLabels = ['A', 'B', 'C', ...] # List of possible characters
# Get predictions for all characters
for j in range(36):
prediction = get_prediction(image, loaded_object.all_weights[j], loaded_object.all_bias[j])
temp_tup = (listOfLabels[j], prediction)
predictions_set.append(temp_tup)
df = pd.DataFrame.from_records(predictions_set, columns=['Character', 'Prediction'])
df['Prediction'] = df['Prediction'].astype(float).round(6)
df.sort values(by=['Prediction'], inplace=True, ascending=False)
# Get the character with the highest prediction
topPrediction = str(df.iloc[0][0])
print(topPrediction)
main(list(map(float, sys.argv[1:])))
This project is licensed under the MIT License. See the LICENSE file for details.