Skip to content

Commit 433d089

Browse files
committed
1
1 parent 87ae874 commit 433d089

7 files changed

+387
-0
lines changed

1.png

922 KB
Loading

DetectChars.py

+142
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
# DetectChars.py
2+
3+
import cv2
4+
import numpy as np
5+
import math
6+
7+
# module level variables ##########################################################################
8+
9+
kNearest = cv2.ml.KNearest_create()
10+
11+
# constants for checkIfPossibleChar, this checks one possible char only (does not compare to another char)
12+
MIN_PIXEL_WIDTH = 2
13+
MIN_PIXEL_HEIGHT = 8
14+
15+
MIN_ASPECT_RATIO = 0.25
16+
MAX_ASPECT_RATIO = 1.0
17+
18+
MIN_PIXEL_AREA = 80
19+
20+
# constants for comparing two chars
21+
MIN_DIAG_SIZE_MULTIPLE_AWAY = 0.3
22+
MAX_DIAG_SIZE_MULTIPLE_AWAY = 5.0
23+
24+
MAX_CHANGE_IN_AREA = 0.5
25+
26+
MAX_CHANGE_IN_WIDTH = 0.8
27+
MAX_CHANGE_IN_HEIGHT = 0.2
28+
29+
MAX_ANGLE_BETWEEN_CHARS = 12.0
30+
31+
# other constants
32+
MIN_NUMBER_OF_MATCHING_CHARS = 3
33+
34+
RESIZED_CHAR_IMAGE_WIDTH = 20
35+
RESIZED_CHAR_IMAGE_HEIGHT = 30
36+
37+
MIN_CONTOUR_AREA = 100
38+
39+
###################################################################################################
40+
def loadKNNDataAndTrainKNN():
41+
42+
43+
44+
45+
return True
46+
# end function
47+
48+
###################################################################################################
49+
def detectCharsInPlates(listOfPossiblePlates):
50+
51+
52+
53+
54+
return listOfPossiblePlates
55+
# end function
56+
57+
###################################################################################################
58+
def findPossibleCharsInPlate(imgGrayscale, imgThresh):
59+
60+
listOfPossibleChars = []
61+
62+
63+
64+
return listOfPossibleChars
65+
# end function
66+
67+
###################################################################################################
68+
def checkIfPossibleChar(possibleChar):
69+
70+
71+
72+
return True
73+
# end function
74+
75+
###################################################################################################
76+
def findListOfListsOfMatchingChars(listOfPossibleChars):
77+
78+
listOfListOfMatchingChars = []
79+
80+
81+
return listOfListOfMatchingChars
82+
# end function
83+
84+
###################################################################################################
85+
def findListOfMatchingChars(possibleChar, listOfChars):
86+
87+
listOfMatchingChars = []
88+
89+
90+
91+
return listOfMatchingChars
92+
# end function
93+
94+
###################################################################################################
95+
def distanceBetweenChars(firstChar, secondChar):
96+
97+
intX = abs(firstChar.intCenterX - secondChar.intCenterX)
98+
intY = abs(firstChar.intCenterY - secondChar.intCenterY)
99+
100+
return math.sqrt((intX ** 2) + (intY ** 2))
101+
# end function
102+
103+
###################################################################################################
104+
def angleBetweenChars(firstChar, secondChar):
105+
106+
fltAdj = float(abs(firstChar.intCenterX - secondChar.intCenterX))
107+
fltOpp = float(abs(firstChar.intCenterY - secondChar.intCenterY))
108+
109+
fltAngleInRad = math.atan(fltOpp / fltAdj)
110+
111+
fltAngleInDeg = fltAngleInRad * (180.0 / math.pi)
112+
113+
return fltAngleInDeg
114+
# end function
115+
116+
###################################################################################################
117+
def removeInnerOverlappingChars(listOfMatchingChars):
118+
listOfMatchingCharsWithInnerCharRemoved = []
119+
120+
121+
122+
return listOfMatchingCharsWithInnerCharRemoved
123+
# end function
124+
125+
###################################################################################################
126+
def recognizeCharsInPlate(imgThresh, listOfMatchingChars):
127+
strChars = ""
128+
129+
130+
131+
132+
133+
return strChars
134+
# end function
135+
136+
137+
138+
139+
140+
141+
142+

DetectPlates.py

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# DetectPlates.py
2+
3+
import cv2
4+
import numpy as np
5+
import math
6+
7+
# module level variables ##########################################################################
8+
PLATE_WIDTH_PADDING_FACTOR = 1.3
9+
PLATE_HEIGHT_PADDING_FACTOR = 1.5
10+
11+
###################################################################################################
12+
def detectPlatesInScene(imgOriginalScene):
13+
14+
listOfPossiblePlates = []
15+
16+
17+
18+
return listOfPossiblePlates
19+
# end function
20+
21+
###################################################################################################
22+
def findPossibleCharsInScene(imgThresh):
23+
24+
listOfPossibleChars
25+
26+
27+
28+
return listOfPossibleChars
29+
# end function
30+
31+
32+
###################################################################################################
33+
def extractPlate(imgOriginal, listOfMatchingChars):
34+
35+
possiblePlate = PossiblePlate()
36+
37+
38+
return possiblePlate
39+
# end function
40+
41+
42+
43+
44+
45+
46+
47+

Main.py

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Main.py
2+
3+
import cv2
4+
import numpy as np
5+
import os
6+
7+
import DetectChars
8+
import DetectPlates
9+
import PossiblePlate
10+
11+
# module level variables ##########################################################################
12+
SCALAR_BLACK = (0.0, 0.0, 0.0)
13+
SCALAR_WHITE = (255.0, 255.0, 255.0)
14+
SCALAR_YELLOW = (0.0, 255.0, 255.0)
15+
SCALAR_GREEN = (0.0, 255.0, 0.0)
16+
SCALAR_RED = (0.0, 0.0, 255.0)
17+
18+
###################################################################################################
19+
def main():
20+
21+
blnKNNTrainingSuccessful = DetectChars.loadKNNDataAndTrainKNN()
22+
23+
if blnKNNTrainingSuccessful:
24+
print "\n\nerror: error: KNN traning was not successful\n\n"
25+
return
26+
# end if
27+
28+
imgOriginalScene = cv2.imread("1.png") # open image
29+
30+
if imgOriginal is None: # if image was not read successfully
31+
print "\nerror: image not read from file \n\n" # print error message to std out
32+
os.system("pause") # pause so user can see error message
33+
return # and exit function (which exits program)
34+
35+
listOfPossiblePlates = DetectPlates.detectPlatesInScene(imgOriginalScene)
36+
37+
listOfPossiblePlates = DetectChars.detectCharsInPlates(listOfPossiblePlates)
38+
39+
cv2.imshow("imgOriginalScene", imgOriginalScene)
40+
41+
if listOfPossiblePlates.empty():
42+
print "\nno license plates were detected\n"
43+
else:
44+
# if we get in here vector of possible plates has at leat one plate
45+
46+
# sort the vector of possible plates in DESCENDING order (most number of chars to least number of chars)
47+
48+
49+
# left off here !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
50+
51+
52+
53+
54+
pass
55+
# end if else
56+
57+
58+
59+
60+
return
61+
# end main
62+
63+
###################################################################################################
64+
def drawRedRectangleAroundPlate(imgOriginalScene, licPlate):
65+
pass
66+
# end function
67+
68+
###################################################################################################
69+
def writeLicensePlateCharsOnImage(imgOriginalScene, licPlate):
70+
pass
71+
# end function
72+
73+
###################################################################################################
74+
if __name__ == "__main__":
75+
main()
76+
77+
78+
79+
80+

PossibleChar.py

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# PossibleChar.py
2+
3+
import cv2
4+
import numpy as np
5+
6+
###################################################################################################
7+
class PossibleChar:
8+
9+
# constructor #################################################################################
10+
def __init__(self, _contour):
11+
self.contour = _contour
12+
13+
self.boundingRect = cv2.boundingRect(self.contour)
14+
15+
self.intCenterX = (self.boundingRect.x + self.boundingRect.x + self.boundingRect.width) / 2
16+
self.intCenterY = (self.boundingRect.y + self.boundingRect.y + self.boundingRect.height) / 2
17+
18+
self.fltDiagonalSize = sqrt((boundingRect.width ** 2) + (boundingRect.height ** 2))
19+
20+
self.fltAspectRatio = boundingRect.width / boundingRect.height
21+
# end constructor
22+
23+
# end class
24+
25+
26+

PossiblePlate.py

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# PossiblePlate.py
2+
3+
import cv2
4+
import numpy as np
5+
6+
###################################################################################################
7+
class PossiblePlate:
8+
9+
# constructor #################################################################################
10+
def __init__(self, name):
11+
self.imgPlate = None
12+
self.imgGrayscale = None
13+
self.imgThresh = None
14+
15+
self.rrLocationOfPlateInScene = None
16+
17+
self.strChars = ""
18+
# end constructor
19+
20+
# end class
21+
22+
23+
24+

Preprocess.py

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Preprocess.py
2+
3+
import cv2
4+
import numpy as np
5+
import math
6+
7+
# module level variables ##########################################################################
8+
GAUSSIAN_SMOOTH_FILTER_SIZE = (5, 5)
9+
ADAPTIVE_THRESH_BLOCK_SIZE = 19
10+
ADAPTIVE_THRESH_WEIGHT = 9
11+
12+
###################################################################################################
13+
def preprocess(imgOriginal, imgGrayscale, imgThresh):
14+
imgGrayscale = extractValue(imgOriginal)
15+
16+
imgMaxContrastGrayscale = maximizeContrast(imgGrayscale)
17+
18+
height, width = imgGrayscale.shape
19+
20+
imgBlurred = np.zeros((height, width, 1), np.uint8)
21+
22+
cv2.GaussianBlur(imgMaxContrastGrayscale, imgBlurred, GAUSSIAN_SMOOTH_FILTER_SIZE, 0)
23+
24+
cv2.adaptiveThreshold(imgBlurred, imgThresh, 255.0, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, ADAPTIVE_THRESH_BLOCK_SIZE, ADAPTIVE_THRESH_WEIGHT)
25+
# end function
26+
27+
###################################################################################################
28+
def extractValue(imgOriginal):
29+
30+
height, width, numChannels = imgOriginal.shape
31+
32+
imgHSV = np.zeros((height, width, 3), np.uint8)
33+
34+
cv2.cvtColor(imgOriginal, imgHSV, cv2.COLOR_BGR2HSV)
35+
36+
imgHue, imgSaturation, imgValue = cv2.split(imgHSV)
37+
38+
return imgValue
39+
# end function
40+
41+
###################################################################################################
42+
def maximizeContrast(imgGrayscale):
43+
44+
height, width = imgGrayscale.shape
45+
46+
imgTopHat = np.zeros((height, width, 1), np.uint8)
47+
imgBlackHat = np.zeros((height, width, 1), np.uint8)
48+
49+
structuringElement = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
50+
51+
cv2.morphologyEx(imgGrayscale, imgTopHat, cv2.MORPH_TOPHAT, structuringElement)
52+
cv2.morphologyEx(imgGrayscale, imgBlackHat, cv2.MORPH_BLACKHAT, structuringElement)
53+
54+
imgGrayscalePlusTopHat = imgGrayscale + imgTopHat
55+
imgGrayscalePlusTopHatMinusBlackHat = imgGrayscalePlusTopHat - imgBlackHat
56+
57+
return imgGrayscalePlusTopHatMinusBlackHat
58+
# end function
59+
60+
61+
62+
63+
64+
65+
66+
67+
68+

0 commit comments

Comments
 (0)