CP4291- IOT Lab Manual
CP4291- IOT Lab Manual
LABORATORY RECORD
Name : _______________________________________
Reg.No : _________________ Semester : ___________
Degree : _________________ Branch : _______
Subject Code/Name: _____________________________
1
BONAFIDE CERTIFICATE
Register No.
This is to Certify that this is a bonafide record of the work done by the above
student__________________________Semester M.E Degree in
_______________________________________________________________in the
_______________________________________________________________
Laboratory during the academic year 2022-2023.
Date:
2
List of content
S.no Date List of Experiment Pg.no Marks signature
web application
3
Ex.No:1A
LED Blink using Arduino
Date :
Aim:-
Components Required:-
1 - Breadboard
1 - Arduino Uno R3
1 - LED
1 - 330Ω Resistor
2 - Jumper
Procedure:-
Follow the circuit diagram and hook up the components on the breadboard as shown in the image
given below.
Note − To find out the polarity of an LED, look at it closely. The shorter of the two legs, towards the
flat edge of the bulb indicates the negative terminal.
4
Components like resistors need to have their terminals bent into 90° angles in order to fit the
breadboard sockets properly. You can also cut the terminals shorter.
Sketch
Open the Arduino IDE software on your computer. Coding in the Arduino language will control your
circuit. Open the new sketch File by clicking New.
5
Arduino Code:-
/*
Blink
Turns on an LED on for one second, then off for one second, repeatedly.
*/
// the setup function runs once when you press reset or power the board
void setup() { // initialize digital pin 13 as an output.
pinMode(2, OUTPUT);}
// the loop function runs over and over again forever
void loop() {
digitalWrite(2, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(2, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second}
Code to Note
pinMode(2, OUTPUT) − Before you can use one of Arduino’s pins, you need to tell Arduino Uno
R3 whether it is an INPUT or OUTPUT. We use a built-in “function” called pinMode() to do this.
digitalWrite(2, HIGH) − When you are using a pin as an OUTPUT, you can command it to be
HIGH (output 5 volts), or LOW (output 0 volts).
Result:-
You should see your LED turn on and off. If the required output is not seen, make sure you
have assembled the circuit correctly, and verified and uploaded the code to your board.
6
Ex.No:1B
LED Pattern using Arduino
Date :
Aim:-
Component needed:-
Arduino Uno x 1:
LED x 12:
Jumper wires:
7
Connections:-
Arduino Code:-d paste the code below in Arduino and click upload
void setup()
{
for (int pin = 2; pin <= 12; pin++)
{
pinMode(pin,OUTPUT);
}
}
//Main Loop - Switches different LED Patterns
void loop()
{
int pickme = random(1,20); // picks a random pattern of LED patterns
switch(pickme)
{
case 1:
onrun(random(20,50));
break;
case 2:
alternate(random(80,100));
break;
case 3:
offrun(random(20,50));
break;
case 4:
stack(random(30,50));
break;
case 5:
chaser(random(80,100));
8
break;
case 6:
fadealter(random(80,100));
break;
}
}
void clearall()
{
for (int pin = 2; pin <= 19; pin++)
{
digitalWrite(pin,LOW);
}
}
void fillall()
{
for (int pin = 2; pin <= 19; pin++)
{
digitalWrite(pin, HIGH);
}
}
//One ON LED Run and all other OFF
void onrun(int delaytime)
{
for(int pin = 2; pin <= 19; pin++)
{
clearall();
digitalWrite(pin, HIGH);
delay(delaytime);
}
for(int pin = 18; pin >= 2; pin--)
{
clearall();
digitalWrite(pin, HIGH);
delay(delaytime);
}
}
//One OFF LED Run and all other OFF
void offrun(int delaytime)
{
for(int pin = 2; pin <= 19; pin++)
{
fillall();
digitalWrite(pin, LOW);
delay(delaytime);
}
for(int pin = 18; pin >= 2; pin--)
{
fillall();
digitalWrite(pin, LOW);
delay(delaytime);
}
9
}
//Flashing all LEDs ON and OFF
void flash(int delaytime)
{
for(int i = 1; i <=20; i++)
{
clearall();
delay(delaytime);
fillall();
delay(delaytime);
}
}
//Flashing LED in Fade manner
void fadeflash(int delaytime)
{
clearall();
int newdelay = delaytime / 5;
for(int fade = 0; fade <= 255; fade += 5)
{
for(int pin = 2; pin <= 19; pin++)
{
analogWrite(pin, fade);
}
delay(newdelay);
}
for(int fade = 255; fade >= 0; fade -= 5)
{
for(int pin = 2; pin <= 19; pin++)
{
analogWrite(pin, fade);
}
delay(newdelay);
}
}
//Alternatively Fade & Brightens
void fadealter(int delaytime)
{
clearall();
int newdelay = delaytime / 5;
for(int fade = 0; fade <= 255; fade += 5)
{
for(int i = 2; i <= 18; i+=2)
{
analogWrite(i, fade);
}
for (int j = 3; j <= 19; j += 2)
{
analogWrite(j, 255-fade);
}
delay(newdelay);
}
10
for(int fade = 255; fade >= 0; fade -= 5)
{
for(int i = 2; i <= 18; i+=2)
{
analogWrite(i, fade);
}
for (int j = 3; j <= 19; j += 2)
{
analogWrite(j, 255-fade);
}
delay(newdelay);
}
}
//Alternate Flash - Similar to Flash but alternate LEDs
void alternate(int delaytime)
{
for (int n = 1; n <= 5; n++)
{
clearall();
for (int i = 2; i <= 18; i += 2)
{
digitalWrite(i, HIGH);
}
delay(delaytime);
clearall();
for (int j = 3; j <= 19; j += 2)
{
digitalWrite(j, HIGH);
}
delay(delaytime);
}
}
//Putting all LEDs one by one in a stack
void stack(int delaytime)
{
int stack = 0;
while(stack < 18)
{
for(int pos = 2; pos <= (19 - stack); pos++)
{
clearall();
digitalWrite(pos, HIGH);
drawstack(stack);
delay(delaytime);
}
stack++;
}
}
//Subfunction of the stack function
void drawstack(int stack)
{
11
for(int n = 19; n > (19 - stack); n--)
{
if(n >= 2)
{
digitalWrite(n, HIGH);
}
}
}
//One LED chases another LED front and back
void chaser(int delaytime)
{
int div = 40;
int flashtime = delaytime / div;
int A = random(2,7);
int B = random(7,12);
int Av = 1;
int Bv = 1;
if(random(0,2))
{
Av *= -1;
}
if(random(0,2))
{
Bv *= -1;
}
for(int time = 1; time < 100; time++)
{
if(abs(A-B) == 1 && (Av*Bv) == -1)
{
for(int f = 1; f < round(div/4); f++)
{
clearall();
delay(flashtime);
digitalWrite(A, HIGH);
digitalWrite(B, HIGH);
delay(flashtime);
}
Av *= -1;
Bv *= -1;
A += Av;
B += Bv;
}
else
{
clearall();
digitalWrite(A, HIGH);
digitalWrite(B, HIGH);
A += Av;
B += Bv;
delay(delaytime);
}
12
if(A < 2)
{
A = 3;
Av *= -1;
}
if(B > 19)
{
B = 18;
Bv *= -1;
}
if(A >= B)
{
A = B-1;
}
}
}
Result:-
I will see all the led patterns running randomly this is because we have implemented random
function for pattern selection.
13
Ex.No:2
LED Pattern with Push Button Control using Arduino
Date :
Aim:-
Components Required:-
Mini push button switch
5mm LED
jumper wires
Mini breadboard
Procedure:-
1.Insert LED into the Breadboard
Insert an LED into the breadboard with the Anode (positive leg) on the left and the Cathode (negative
leg on the right).
2.Insert a 220 ohm resistor
Insert a 220 Ohm Resistor so that one leg is inline with the LED's Cathode leg.Resistors are not
polarized, so orientation doesn't matter.This resistor will be used to limit the current going to our
LED.
14
3.Insert the button
Insert your push button so that one leg is in line with the other end of the resistor.Be sure to really
push down on the push button so that the bottom of the push button is flush with the breadboard (this
will feel like you're pushing too hard).
4.Connect pin 13 to the LED
15
6.Connect the push button to pin 7
void setup()
{
pinMode(ledPin,OUTPUT); // Set the LED Pin as an output
pinMode(buttonPin,INPUT_PULLUP); // Set the Tilt Switch as an input
}
void loop()
{
int digitalVal = digitalRead(buttonPin); // Take a reading
if(HIGH == digitalVal)
{
digitalWrite(ledPin,LOW); //Turn the LED off
}
else
{
digitalWrite(ledPin,HIGH);//Turn the LED on
}
}
When you run this code, the LED on Pin 13 will turn on when the button is held down. That is all.
int buttonState = 0;
int oldButtonState = LOW;
int ledState = LOW;
16
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
}
void loop() {
buttonState = digitalRead(buttonPin);
Result:-
Thus the LED Pattern with Push Button Control using Arduino Successfully Completed.
17
Ex.No:3 LM35 Temperature Sensor to display temperature values using
Date : Arduino
Aim:-
Components Required:-
Arduino Uno - 1
LM35 temperature sensor -1
LCD 16×2 -1
Breadboard -1
Jumper wires - 2
USB cable type A/B - 1
The LM35 device has an advantage over linear temperature sensors calibrated in Kelvin, as the
user is not required to subtract a large constant voltage from the output to obtain convenient
Centigrade scaling.
The LM35 device does not require any external calibration or trimming to provide typical
accuracies of ± ¼ °C at room temperature and ± ¾ °C over a full −55°C to 150°C temperature
range. Lower cost is assured by trimming and calibration at the wafer level.
The low output impedance, linear output, and precise inherent calibration of the LM35 device
make interfacing to readout or control circuitry especially easy.
The device is used with single power supplies, or with plus and minus supplies.
As the LM35 device draws only 60 μA from the supply, it has very low self-heating of less than
0.1°C in still air.
The LM35 device is rated to operate over a −55°C to 150°C temperature range, while the
LM35C device is rated for a −40°C to 110°C range (−10° with improved accuracy).
18
When you use a 3.3V Arduino, you need to use the following formula:
Voltage at pin in milliVolts = (reading from ADC) * (3300/1024)
This formula converts the ADC number 0-1023 to 0-3300mV (= 3.3V)
Convert the millivolts into the temperature in degrees Celsius and Fahrenheit:
Centigrade temperature = (analog voltage in mV) / 10
Fahrenheit temperature=[(Centigrade temperature )*1.8]+32
Features of LM35:-
Calibrated Directly in Celsius (Centigrade)
Output proportional to °C
Linear + 10-mV/°C Scale Factor
Operates From 4 V to 30 V
Less Than 60 μA Current Drain
Low-Impedance Output, 0.1 Ω for 1 mA Load
Low-Cost Due to Wafer-Level Trimming
Accuracy 0.5°C (at 25°C)
LM35 range temperature −55°C to 150°C
Low Self-Heating, 0.08°C in Still Air
Non-Linearity Only ±¼°C Typical
Suitable for Remote Applications
LM35 Applications:-
Temperature measurement in a specific environment
19
Temperature Sensor LM35 Specifications:-
20
LM35 Temperature Sensor Code:-
By clicking the button in the top right corner of the code field, you can copy the code. Copy and paste
it into Arduino IDE.
// Define to which pin of the Arduino the output of the LM35 is connected:
#define sensorPin A0
void setup()
{
Serial.begin(9600);
void loop() {
//Convert digital data into analog by multiplying by 5000 and dividing by 1024
Serial.print(temperatureC);
21
Serial.print(" \xC2\xB0"); // shows degree symbol
Serial.println("C");
Serial.print(temperatureF);
Serial.println("F");
Serial.print("\n");
}
Output:-
Result:-
Thus the LM35 Temperature Sensor to display temperature values using Arduino
Successfully Completed and output is verified.
22
Ex.No:4 Forest fire detection end node using Raspberry Pi device and
Date : sensor
Aim:-
Components Required:-
1 × Breadboard
1 × Arduino Uno
1 × Flame Sensor Module
1 × Buzzer
2 × Jumper
Fire Sensor:-
Buzzer:Circuit Diagram:-
23
Procedure:-
4. Set the Arduino board and port in Tools -> Board and Tools -> Port.
6. Upload the code by just clicking the right arrow present just next to verify.
Coding:
void setup()
pinMode(buzzerPin, OUTPUT);
pinMode(flamePin, INPUT);
Serial.begin(9600);
void loop()
Flame = digitalRead(flamePin);
if (Flame== LOW){
Serial.println("Fire is Detected");
digitalWrite(buzzerPin, HIGH);
else
24
{
digitalWrite(buzzerPin, LOW);
Result :
Successfully develop the application for Forest fire detection end node using Raspberry Pi
device and sensor.
25
Ex.No:5
Application for Home Intrusion detection web application
Date :
Aim:-
Componets Required:-
Ultrasonic sensor
Evive
Connection Wires
Procedure:-
Once you have made the restricted area it’s to make the actual system that senses the
intrusion and aware the owner.
For this purpose, the device that comes in our head first is the Ultrasonic System.
To one out of the four sides, we are going to attach the Ultrasonic Sensor as shown in the
figure.
Once you have fixed it, it is time to make the owner aware of the intrusion.
How are we going to do that?
We will fix LEDs on all the four walls or on all the Ice Cream Sticks, using Hot Glue.
The LEDs will be connected in a parallel connection.
Connect all the Anodes ( Positive leg) of the Anode together using a Copper Wire.
Similarly, connect all the cathode terminals of the LEDs, to one channel.
You can also add a base of paper or foam.
Thus, your assembly is completed all you need to do is complete its connection with evive
and upload the code.
Working:-
26
The specialty of the Ultrasonic Sensor is to detect the objects within a given range. Thus, as soon as
any human enters the restricted object, the sensor will detect this and send the signal to evive.
As soon as the signal triggers, all the LEDs on the walls lit up together. Not only the LEDs, but we
also have set up buzzer that will start buzzing as soon as the sensor detects the intrusion. Thus,
both LEDs and buzzer will be able to make the owner aware of the intrusion.
Code:-
#include<evive.h>
long duration;
int distance;
void setup() {
Serial.begin(9600);
tft_init(INITR_GREENTAB);
tft.setRotation(1);
tft.fillScreen(1);
tft.setCursor(25,10);
tft.setTextSize(2);
tft.setTextColor(ST7735_WHITE,ST7735_BLACK);
tft.print("STEMpedia");
tft.setCursor(15,50);
tft.setTextSize(1.8);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
27
tft.setCursor(55,60);
tft.print("SYSTEM");
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.setCursor(0,105);
tft.setTextSize(1.8);
tft.setCursor(30,115);
tft.setTextColor(ST7735_WHITE,ST7735_BLACK);
tft.print("thestempedia.com");
pinMode(buzz,OUTPUT);
pinMode(led,OUTPUT);
void loop() {
distance = calculateDistance();
Serial.print("distance = ");
Serial.println(distance);
if(digitalRead(40)==HIGH)
siren();
void siren()
28
{
delay_ms();
// Whoop down
delay_ms();
void delay_ms()
digitalWrite(led,HIGH);
delay(1);
digitalWrite(led,LOW);
int calculateDistance()
digitalWrite(trig, LOW);
delayMicroseconds(2);
digitalWrite(trig, HIGH);
29
delayMicroseconds(10);
digitalWrite(trig, LOW);
duration = pulseIn(echo, HIGH); // Reads the echoPin, returns the sound wave travel time in
microseconds
distance= duration*0.034/2;
return distance;
Output:-
Connect the LEDs and Ultrasonic Sensor as shown in the figure below:
Result :-
Successfully develop the application for Home intrusion detection in web application or IOT
completed and output is verified.
30
Ex.No:6 Application for Smart parking application using
Date :
python and Django for web application
Aim:
To develop an application for Smart parking system using python and Django for web application.
Components Required
Raspberry Pi 3 Model B
Raspberry Pi Camera Module
Ultrasonic Sensor – HC-SR04
SORACOM Air Global IoT SIM
Jumper Wires
31
Coding:
# DetectPlates.py
import cv2
import numpy as np
import math
import Main
import random
import Preprocess
import DetectChars
import PossiblePlate
##########################################################################
PLATE_WIDTH_PADDING_FACTOR = 1.3
PLATE_HEIGHT_PADDING_FACTOR = 1.5
#####################################################################################
##############
def detectPlatesInScene(imgOriginalScene):
listOfPossiblePlates = []
32
imgContours = np.zeros((height, width, 3), np.uint8)
cv2.destroyAllWindows()
#######################################################
cv2.imshow("0", imgOriginalScene)
#########################################################################
# preprocess to
#######################################################
cv2.imshow("1a", imgGrayscaleScene)
cv2.imshow("1b", imgThreshScene)
#########################################################################
# this function first finds all contours, then only includes contours that could be chars (without
listOfPossibleCharsInScene = findPossibleCharsInScene(imgThreshScene)
#######################################################
33
len(listOfPossibleCharsInScene))) # 131 with MCLRNF1 image
contours = []
contours.append(possibleChar.contour)
# end for
cv2.imshow("2b", imgContours)
#########################################################################
# in the next steps each group of matching chars will attempt to be recognized as a plate
listOfListsOfMatchingCharsInScene =
DetectChars.findListOfListsOfMatchingChars(listOfPossibleCharsInScene)
#######################################################
contours = []
34
for matchingChar in listOfMatchingChars:
contours.append(matchingChar.contour)
# end for
intRandomRed))
# end for
cv2.imshow("3", imgContours)
#########################################################################
matching chars
listOfPossiblePlates.append(possiblePlate)
# end if
# end for
#######################################################
35
print("\n")
cv2.imshow("4a", imgContours)
p2fRectPoints = cv2.boxPoints(listOfPossiblePlates[i].rrLocationOfPlateInScene)
cv2.imshow("4a", imgContours)
print("possible plate " + str(i) + ", click on any image and press a key to continue . . .")
cv2.imshow("4b", listOfPossiblePlates[i].imgPlate)
cv2.waitKey(0)
# end for
print("\nplate detection complete, click on any image and press a key to begin char recognition . .
.\n")
cv2.waitKey(0)
#########################################################################
return listOfPossiblePlates
# end function
#####################################################################################
##############
def findPossibleCharsInScene(imgThresh):
36
listOfPossibleChars = []
intCountOfPossibleChars = 0
imgThreshCopy = imgThresh.copy()
###################################################
#####################################################################
intCountOfPossibleChars = intCountOfPossibleChars + 1
chars
listOfPossibleChars.append(possibleChar)
37
# end if
# end for
#######################################################
image
cv2.imshow("2a", imgContours)
#########################################################################
return listOfPossibleChars
# end function
# DetectChars.py
import os
import cv2
import numpy as np
import math
import random
import Main
import Preprocess
import PossibleChar
##########################################################################
38
kNearest = cv2.ml.KNearest_create()
# constants for checkIfPossibleChar, this checks one possible char only (does not compare to another
char)
MIN_PIXEL_WIDTH = 2
MIN_PIXEL_HEIGHT = 8
MIN_ASPECT_RATIO = 0.25
MAX_ASPECT_RATIO = 1.0
MIN_PIXEL_AREA = 80
MIN_DIAG_SIZE_MULTIPLE_AWAY = 0.3
MAX_DIAG_SIZE_MULTIPLE_AWAY = 5.0
MAX_CHANGE_IN_AREA = 0.5
MAX_CHANGE_IN_WIDTH = 0.8
MAX_CHANGE_IN_HEIGHT = 0.2
MAX_ANGLE_BETWEEN_CHARS = 12.0
# other constants
MIN_NUMBER_OF_MATCHING_CHARS = 3RESIZED_CHAR_IMAGE_WIDTH = 20
RESIZED_CHAR_IMAGE_HEIGHT = 30
MIN_CONTOUR_AREA = 100
#####################################################################################
##############
def loadKNNDataAndTrainKNN():
allContoursWithData = []
39
# declare empty lists,
validContoursWithData = []
try:
# read in training
classifications
except:
os.system("pause")
return False
# end try
try:
# read in training
images
except:
os.system("pause")
return False
40
# and return False
# end try
kNearest.setDefaultK(1)
# set default K to 1
# train KNN
object
return True
# end function
#####################################################################################
##############
def detectCharsInPlates(listOfPossiblePlates):
intPlateCounter = 0
imgContours = None
contours = []
if len(listOfPossiblePlates) == 0:
return listOfPossiblePlates
# return
41
# end if
# at this point we can be sure the list of possible plates has at least one plate
# for each possible plate, this is a big for loop that takes
###################################################
cv2.imshow("5a", possiblePlate.imgPlate)
cv2.imshow("5b", possiblePlate.imgGrayscale)
cv2.imshow("5c", possiblePlate.imgThresh)
#####################################################################
# increase size of plate image for easier viewing and char detection
cv2.THRESH_BINARY | cv2.THRESH_OTSU)
###################################################
cv2.imshow("5d", possiblePlate.imgThresh)
#####################################################################
42
# find all possible chars in the plate,
# this function first finds all contours, then only includes contours that could be chars (without
listOfPossibleCharsInPlate = findPossibleCharsInPlate(possiblePlate.imgGrayscale,
possiblePlate.imgThresh)
###################################################
del contours[:]
contours.append(possibleChar.contour)
# end for
cv2.imshow("6", imgContours)
#####################################################################
# given a list of all possible chars, find groups of matching chars within the plate
listOfListsOfMatchingCharsInPlate = findListOfListsOfMatchingChars(listOfPossibleCharsInPlate)
###################################################
43
del contours[:]
contours.append(matchingChar.contour)
# end for
intRandomRed))
# end for
cv2.imshow("7", imgContours)
#####################################################################
if (len(listOfListsOfMatchingCharsInPlate) == 0):
###############################################
intPlateCounter) + " = (none), click on any image and press a key to continue . . .")
intPlateCounter = intPlateCounter + 1
cv2.destroyWindow("8")
cv2.destroyWindow("9")
44
cv2.destroyWindow("10")
cv2.waitKey(0)
#################################################################
possiblePlate.strChars = ""
continue
# end if
matching chars
matchingChar.intCenterX)
listOfListsOfMatchingCharsInPlate[i] =
removeInnerOverlappingChars(listOfListsOfMatchingCharsInPlate[i])
overlapping chars
# end for
###################################################
45
intRandomBlue = random.randint(0, 255)
del contours[:]
contours.append(matchingChar.contour)
# end for
intRandomRed))
# end for
#####################################################################
# within each possible plate, suppose the longest list of potential matching chars is the actual
list of chars
intLenOfLongestListOfChars = 0
intIndexOfLongestListOfChars = 0
# loop through all the vectors of matching chars, get the index of the one with the most chars
intLenOfLongestListOfChars = len(listOfListsOfMatchingCharsInPlate[i])
intIndexOfLongestListOfChars = i
# end if
# end for
46
# suppose that the longest list of matching chars within the plate is the actual list of chars
longestListOfMatchingCharsInPlate =
listOfListsOfMatchingCharsInPlate[intIndexOfLongestListOfChars]
###################################################
del contours[:]
contours.append(matchingChar.contour)
# end for
cv2.imshow("9", imgContours)
#####################################################################
possiblePlate.strChars = recognizeCharsInPlate(possiblePlate.imgThresh,
longestListOfMatchingCharsInPlate)
###################################################
intPlateCounter) + " = " + possiblePlate.strChars + ", click on any image and press a key to
continue . . .")
intPlateCounter = intPlateCounter + 1
cv2.waitKey(0)
47
# end if # show steps
#####################################################################
if Main.showSteps == True:
print("\nchar detection complete, click on any image and press a key to continue . . .\n")
cv2.waitKey(0)
# end if
return listOfPossiblePlates
# end
function##################################################################################
###
##############
listOfPossibleChars = []
contours = []
imgThreshCopy = imgThresh.copy()
cv2.CHAIN_APPROX_SIMPLE)
possibleChar = PossibleChar.PossibleChar(contour)
if checkIfPossibleChar(possibleChar):
48
# if contour is a possible char, note this does not
listOfPossibleChars.append(possibleChar)
# end if
# end if
return listOfPossibleChars
# end function
#####################################################################################
##############
def checkIfPossibleChar(possibleChar):
# this function is a 'first pass' that does a rough check on a contour to see if it could be a char,
# note that we are not (yet) comparing the char to other chars to look for a group
MAX_ASPECT_RATIO):
return True
else:
return False
# end if
# end function
49
#####################################################################################
##############
def findListOfListsOfMatchingChars(listOfPossibleChars):
# with this function, we start off with all the possible chars in one big list
# the purpose of this function is to re-arrange the one big list of chars into a list of lists of
matching chars,
# note that chars that are not found to be in a group of matches do not need to be considered
further
listOfListsOfMatchingChars = []
chars
# find all
listOfMatchingChars.append(possibleChar)
continue
# jump back to the top of the for loop and try again with next char, note
50
possible plate
# end if
# to save the list in any way since it did not have enough chars to be a
matching chars
listOfListsOfMatchingChars.append(listOfMatchingChars)
matching chars
listOfPossibleCharsWithCurrentMatchesRemoved = []
# remove the current list of matching chars from the big list so we don't use
# make sure to make a new big list for this since we don't want to change
listOfPossibleCharsWithCurrentMatchesRemoved = list(set(listOfPossibleChars) -
set(listOfMatchingChars))
recursiveListOfListsOfMatchingChars =
findListOfListsOfMatchingChars(listOfPossibleCharsWithCurrentMatchesRemoved)
# recursive call
listOfListsOfMatchingChars.append(recursiveListOfMatchingChars)
51
list of lists of matching chars
# end for
break
# exit for
# end for
return listOfListsOfMatchingChars
# end function
#####################################################################################
##############
# the purpose of this function is, given a possible char and a big list of possible chars,
# find all chars in the big list that are a match for the single possible char, and return those
listOfMatchingChars = []
exact same char as the char in the big list we are currently checking
# then we should not include it in the list of matches b/c that would end
continue
# so do not add to list of matches and jump back to top of for loop
52
# end if
possibleChar.intBoundingRectArea)) / float(possibleChar.intBoundingRectArea)
fltChangeInWidth = float(abs(possibleMatchingChar.intBoundingRectWidth -
possibleChar.intBoundingRectWidth)) / float(possibleChar.intBoundingRectWidth)
fltChangeInHeight = float(abs(possibleMatchingChar.intBoundingRectHeight -
possibleChar.intBoundingRectHeight)) / float(possibleChar.intBoundingRectHeight)
MAX_DIAG_SIZE_MULTIPLE_AWAY) and
listOfMatchingChars.append(possibleMatchingChar)
# end if
# end for
return listOfMatchingChars
# return result
53
# end function
#####################################################################################
##############
# end function
#####################################################################################
##############
# use basic trigonometry (SOH CAH TOA) to calculate angle between chars
if fltAdj != 0.0:
else:
fltAngleInRad = 1.5708
54
consistent with the C++ version of this program
# end if
return fltAngleInDeg
# end function
#####################################################################################
##############
# if we have two chars overlapping or to close to each other to possibly be separate chars, remove the
inner (smaller) char,# this is to prevent including the same char twice if two contours are found for the same
char,
# for example for the letter 'O' both the inner ring and the outer ring may be found as contours, but we
def removeInnerOverlappingChars(listOfMatchingChars):
listOfMatchingCharsWithInnerCharRemoved = list(listOfMatchingChars)
return value
if currentChar != otherChar:
# if current char and other char are not the same char . . .
55
MIN_DIAG_SIZE_MULTIPLE_AWAY):
# next we identify which char is smaller, then if that char was not already removed on
# if current
if currentChar in listOfMatchingCharsWithInnerCharRemoved:
# if current char
listOfMatchingCharsWithInnerCharRemoved.remove(currentChar)
# then remove
current char
char
# end if
else:
if otherChar in listOfMatchingCharsWithInnerCharRemoved:
listOfMatchingCharsWithInnerCharRemoved.remove(otherChar)
# then remove
other char
56
# end if
# end if
# end if
# end if
# end for
# end for
return listOfMatchingCharsWithInnerCharRemoved
# end function
#####################################################################################
##############
strChars = ""
# this will be the return value, the chars in the lic plate
# sort chars
# make color
57
# for each char in plate
(currentChar.intBoundingRectY + currentChar.intBoundingRectHeight))
currentChar.intBoundingRectHeight,
currentChar.intBoundingRectX : currentChar.intBoundingRectX +
currentChar.intBoundingRectWidth]
RESIZED_CHAR_IMAGE_HEIGHT))
RESIZED_CHAR_IMAGE_HEIGHT))
npaROIResized = np.float32(npaROIResized)
# finally
58
strCurrentChar = str(chr(int(npaResults[0][0])))
# end for
#######################################################
cv2.imshow("10", imgThreshColor)
#########################################################################
return strChars
# end function
#####################################################################################
##############
possiblePlate = PossiblePlate.PossiblePlate()
# sort chars
fltPlateCenterX = (listOfMatchingChars[0].intCenterX +
59
fltPlateCenterY = (listOfMatchingChars[0].intCenterY +
listOfMatchingChars[len(listOfMatchingChars) - 1].intBoundingRectWidth -
listOfMatchingChars[0].intBoundingRectX) * PLATE_WIDTH_PADDING_FACTOR)
intTotalOfCharHeights = 0
# end for
listOfMatchingChars[0].intCenterY
fltHypotenuse = DetectChars.distanceBetweenChars(listOfMatchingChars[0],
listOfMatchingChars[len(listOfMatchingChars) - 1])
# pack plate region center point, width and height, and correction angle into rotated rect member
variable of plate
fltCorrectionAngleInDeg )
60
# final steps are to perform the actual rotation
image
possiblePlate.imgPlate = imgCropped
return possiblePlate
# end function
Main.py
import cv2
import numpy as np
import os
import DetectChars
import DetectPlates
import PossiblePlate
##########################################################################SCALAR_BLAC
K = (0.0, 0.0, 0.0)
61
SCALAR_WHITE = (255.0, 255.0, 255.0)
showSteps = False
#####################################################################################
##############
def main():
blnKNNTrainingSuccessful = DetectChars.loadKNNDataAndTrainKNN()
# attempt KNN
training
if blnKNNTrainingSuccessful == False:
return
# end if
imgOriginalScene = cv2.imread("LicPlateImages/1.png")
# open image
if imgOriginalScene is None:
print("\nerror: image not read from file \n\n") # print error message to std out
os.system("pause")
62
# pause so user can see error message
return
# end if
listOfPossiblePlates = DetectPlates.detectPlatesInScene(imgOriginalScene)
# detect plates
listOfPossiblePlates = DetectChars.detectCharsInPlates(listOfPossiblePlates)
# detect chars in
plates
cv2.imshow("imgOriginalScene", imgOriginalScene)
if len(listOfPossiblePlates) == 0:
print("\nno license plates were detected\n") # inform user no plates were found
else:
# else
# sort the list of possible plates in DESCENDING order (most number of chars to least number
of chars)
# suppose the plate with the most recognized chars (the first plate in sorted by string length
licPlate = listOfPossiblePlates[0]
63
cv2.imshow("imgPlate", licPlate.imgPlate)
cv2.imshow("imgThresh", licPlate.imgThresh)
if len(licPlate.strChars) == 0:
return
# end if
drawRedRectangleAroundPlate(imgOriginalScene, licPlate)
plateout
print("\nlicense plate read from image = " + licPlate.strChars + "\n") # write license plate text to std
print("-
-")
writeLicensePlateCharsOnImage(imgOriginalScene, licPlate)
image
cv2.imshow("imgOriginalScene", imgOriginalScene)
cv2.imwrite("imgOriginalScene.png", imgOriginalScene)
# end if else
64
cv2.waitKey(0)
return
# end main
#####################################################################################
##############
p2fRectPoints = cv2.boxPoints(licPlate.rrLocationOfPlateInScene)
rect
# end function
#####################################################################################
##############
ptCenterOfTextAreaX = 0
# this will be the center of the area the text will be written
to
ptCenterOfTextAreaY = 0
65
ptLowerLeftTextOriginX = 0
# this will be the bottom left of the area that the text will
be written to
ptLowerLeftTextOriginY = 0
intFontFace = cv2.FONT_HERSHEY_SIMPLEX
# call getTextSize
# unpack roatated rect into center point, width and height, and angle
licPlate.rrLocationOfPlateInSceneintPlateCenterX = int(intPlateCenterX)
intPlateCenterY = int(intPlateCenterY)
ptCenterOfTextAreaX = int(intPlateCenterX)
as the plate
66
# if the license plate is in the
# write the
else:
of the image
# write the
# end if
# calculate the
67
# end function
#####################################################################################
##############
main()
# PossiblePlate.py
import cv2
import numpy as np
#####################################################################################
##############
class PossiblePlate:
# constructor
#################################################################################
self.imgPlate = None
self.imgGrayscale = None
self.imgThresh = None
self.rrLocationOfPlateInScene = None
self.strChars = ""
# end constructor
import cv2
import numpy as np
68
import math
##########################################################################
GAUSSIAN_SMOOTH_FILTER_SIZE = (5, 5)
ADAPTIVE_THRESH_BLOCK_SIZE = 19
ADAPTIVE_THRESH_WEIGHT = 9
#####################################################################################
##############
def preprocess(imgOriginal):
imgGrayscale = extractValue(imgOriginal)
imgMaxContrastGrayscale = maximizeContrast(imgGrayscale)
cv2.THRESH_BINARY_INV, ADAPTIVE_THRESH_BLOCK_SIZE,
ADAPTIVE_THRESH_WEIGHT)
# end function
#####################################################################################
##############
def extractValue(imgOriginal):
69
imgHSV = np.zeros((height, width, 3), np.uint8)
return imgValue
# end function
#####################################################################################
##############
def maximizeContrast(imgGrayscale):
return imgGrayscalePlusTopHatMinusBlackHat
# end function
# PossibleChar.py
import cv2
import numpy as np
import math
#####################################################################################
##############
70
class PossibleChar:
# constructor
#################################################################################
self.contour = _contour
self.boundingRect = cv2.boundingRect(self.contour)
self.intBoundingRectX = intX
self.intBoundingRectY = intY
self.intBoundingRectWidth = intWidth
self.intBoundingRectHeight = intHeight
# end constructor
# end class
71
Output:-
Result: -
Thus the web application was developed for Smart parking system using python
72