6
6
import random
7
7
8
8
import Main
9
+ import Preprocess
9
10
import PossibleChar
10
11
11
12
# module level variables ##########################################################################
@@ -85,7 +86,7 @@ def detectCharsInPlates(listOfPossiblePlates):
85
86
# at this point we can be sure the list of possible plates has at least one plate
86
87
87
88
for possiblePlate in listOfPossiblePlates :
88
- preprocess ( possiblePlate .imgPlate , possiblePlate .imgGrayscale , possiblePlate .imgThresh )
89
+ possiblePlate .imgGrayscale , possiblePlate .imgThresh = Preprocess . preprocess ( possiblePlate .imgPlate )
89
90
90
91
if Main .showSteps == True :
91
92
cv2 .imshow ("5a" , possiblePlate .imgPlate )
@@ -94,18 +95,19 @@ def detectCharsInPlates(listOfPossiblePlates):
94
95
# end if
95
96
96
97
# increase size of plate image for easier viewing and char detection
97
- cv2 .resize (possiblePlate .imgThresh , 0 , possiblePlate . imgThresh , 1.6 , 1.6 )
98
+ possiblePlate . imgThresh = cv2 .resize (possiblePlate .imgThresh , ( 0 , 0 ), fx = 1.6 , fy = 1.6 )
98
99
99
100
# threshold image to only black or white (eliminate grayscale)
100
- possiblePlate .imgThresh = cv2 .threshold (possiblePlate .imgThresh , 0.0 , 255.0 , CV_THRESH_BINARY | CV_THRESH_OTSU )
101
+ thresholdValue , possiblePlate .imgThresh = cv2 .threshold (possiblePlate .imgThresh , 0.0 , 255.0 , cv2 . THRESH_BINARY | cv2 . THRESH_OTSU )
101
102
102
103
if Main .showSteps == True :
103
104
cv2 .imshow ("5d" , possiblePlate .imgThresh )
104
105
# end if
105
106
106
- listOfPossibleCharsInPlate = findPossibleCharsInPlate (possiblePlate .imgGrayscale , possiblePlate .imgThresh );
107
+ listOfPossibleCharsInPlate = findPossibleCharsInPlate (possiblePlate .imgGrayscale , possiblePlate .imgThresh )
107
108
108
109
if Main .showSteps == True :
110
+ height , width , numChannels = possiblePlate .imgPlate .shape
109
111
imgContours = np .zeros ((height , width , 3 ), np .uint8 )
110
112
del contours [:] # clear the contours list
111
113
@@ -118,7 +120,7 @@ def detectCharsInPlates(listOfPossiblePlates):
118
120
cv2 .imshow ("6" , imgContours )
119
121
# end if
120
122
121
- listOfListsOfMatchingCharsInPlate = findListOfListsOfMatchingChars (vectorOfPossibleCharsInPlate )
123
+ listOfListsOfMatchingCharsInPlate = findListOfListsOfMatchingChars (listOfPossibleCharsInPlate )
122
124
123
125
if Main .showSteps == True :
124
126
imgContours = np .zeros ((height , width , 3 ), np .uint8 )
@@ -140,7 +142,7 @@ def detectCharsInPlates(listOfPossiblePlates):
140
142
if (len (listOfListsOfMatchingCharsInPlate ) == 0 ): # if no groups of matching chars were found in the plate
141
143
142
144
if Main .showSteps == True :
143
- print "chars found in plate number " + str (intPlateCounter ) + " = (none), click on any image and press a key to continue . . .\n "
145
+ print "chars found in plate number " + str (intPlateCounter ) + " = (none), click on any image and press a key to continue . . ."
144
146
intPlateCounter = intPlateCounter + 1
145
147
cv2 .destroyWindow ("8" )
146
148
cv2 .destroyWindow ("9" )
@@ -152,9 +154,9 @@ def detectCharsInPlates(listOfPossiblePlates):
152
154
continue # go back to top of for loop
153
155
# end if
154
156
155
- for listOfMatchingChars in listOfListsOfMatchingCharsInPlate :
156
- listOfMatchingChars .sort (key = lambda matchingChar : matchingChar .intCenterX )
157
- listOfMatchingChars = removeInnerOverlappingChars (listOfMatchingChars )
157
+ for listOfMatchingChars in listOfListsOfMatchingCharsInPlate : # within each list of matching chars
158
+ listOfMatchingChars .sort (key = lambda matchingChar : matchingChar .intCenterX ) # sort chars from left to right
159
+ listOfMatchingChars = removeInnerOverlappingChars (listOfMatchingChars ) # and remove inner overlapping chars
158
160
# end for
159
161
160
162
if Main .showSteps == True :
@@ -188,7 +190,7 @@ def detectCharsInPlates(listOfPossiblePlates):
188
190
# end if
189
191
# end for
190
192
191
- longestListOfMatchingCharsInPlate = listOfListOfMatchingCharsInPlate [intIndexOfLongestListOfChars ]
193
+ longestListOfMatchingCharsInPlate = listOfListsOfMatchingCharsInPlate [intIndexOfLongestListOfChars ]
192
194
193
195
if Main .showSteps == True :
194
196
imgContours = np .zeros ((height , width , 3 ), np .uint8 )
@@ -206,7 +208,7 @@ def detectCharsInPlates(listOfPossiblePlates):
206
208
possiblePlate .strChars = recognizeCharsInPlate (possiblePlate .imgThresh , longestListOfMatchingCharsInPlate )
207
209
208
210
if Main .showSteps == True :
209
- print "chars found in plate number " + str (intPlateCounter ) + " = " + possiblePlate .strChars + ", click on any image and press a key to continue . . .\n "
211
+ print "chars found in plate number " + str (intPlateCounter ) + " = " + possiblePlate .strChars + ", click on any image and press a key to continue . . ."
210
212
intPlateCounter = intPlateCounter + 1
211
213
cv2 .waitKey (0 )
212
214
# end if
@@ -227,9 +229,9 @@ def findPossibleCharsInPlate(imgGrayscale, imgThresh):
227
229
228
230
contours = []
229
231
230
- imgThreshCopy = imgThresh .clone ()
232
+ imgThreshCopy = imgThresh .copy ()
231
233
232
- cv2 .findContours (imgThreshCopy , contours , CV_RETR_LIST , CV_CHAIN_APPROX_SIMPLE )
234
+ imgContours , contours , npaHierarchy = cv2 .findContours (imgThreshCopy , cv2 . RETR_LIST , cv2 . CHAIN_APPROX_SIMPLE )
233
235
234
236
for contour in contours :
235
237
possibleChar = PossibleChar .PossibleChar (contour )
@@ -273,7 +275,7 @@ def findListOfListsOfMatchingChars(listOfPossibleChars):
273
275
274
276
listOfPossibleCharsWithCurrentMatchesRemoved = list (set (listOfPossibleChars ) - set (listOfMatchingChars ))
275
277
276
- recursiveListOfListsOfMatchingChars = findListOfListsOfMatchingChars (vectorOfPossibleCharsWithCurrentMatchesRemoved )
278
+ recursiveListOfListsOfMatchingChars = findListOfListsOfMatchingChars (listOfPossibleCharsWithCurrentMatchesRemoved )
277
279
278
280
for recursiveListOfMatchingChars in recursiveListOfListsOfMatchingChars :
279
281
listOfListsOfMatchingChars .append (recursiveListOfMatchingChars )
@@ -299,16 +301,17 @@ def findListOfMatchingChars(possibleChar, listOfChars):
299
301
300
302
fltAngleBetweenChars = angleBetweenChars (possibleChar , possibleMatchingChar )
301
303
302
- fltChangeInArea = abs (possibleMatchingChar .intRectArea - possibleChar .intRectArea ) / possibleChar .intRectArea
304
+ fltChangeInArea = float ( abs (possibleMatchingChar .intBoundingRectArea - possibleChar .intBoundingRectArea )) / float ( possibleChar .intBoundingRectArea )
303
305
304
- dblChangeInWidth = abs (possibleMatchingChar .boundingRect .Width - possibleChar .boundingRect .Width ) / possibleChar .boundingRect .Width
305
- dblChangeInHeight = abs (possibleMatchingChar .boundingRect .Height - possibleChar .boundingRect .Height ) / possibleChar .boundingRect .Height
306
+ fltChangeInWidth = float (abs (possibleMatchingChar .intBoundingRectWidth - possibleChar .intBoundingRectWidth )) / float (possibleChar .intBoundingRectWidth )
307
+ fltChangeInHeight = float (abs (possibleMatchingChar .intBoundingRectHeight - possibleChar .intBoundingRectHeight )) / float (possibleChar .intBoundingRectHeight )
308
+
309
+ if (fltDistanceBetweenChars < (possibleChar .fltDiagonalSize * MAX_DIAG_SIZE_MULTIPLE_AWAY ) and
310
+ fltAngleBetweenChars < MAX_ANGLE_BETWEEN_CHARS and
311
+ fltChangeInArea < MAX_CHANGE_IN_AREA and
312
+ fltChangeInWidth < MAX_CHANGE_IN_WIDTH and
313
+ fltChangeInHeight < MAX_CHANGE_IN_HEIGHT ):
306
314
307
- if (dblDistanceBetweenChars < (possibleChar .dblDiagonalSize * MAX_DIAG_SIZE_MULTIPLE_AWAY ) and
308
- dblAngleBetweenChars < MAX_ANGLE_BETWEEN_CHARS and
309
- dblChangeInArea < MAX_CHANGE_IN_AREA and
310
- dblChangeInWidth < MAX_CHANGE_IN_WIDTH and
311
- dblChangeInHeight < MAX_CHANGE_IN_HEIGHT ):
312
315
listOfMatchingChars .append (possibleMatchingChar )
313
316
# end if
314
317
# end for
@@ -327,11 +330,14 @@ def distanceBetweenChars(firstChar, secondChar):
327
330
328
331
###################################################################################################
329
332
def angleBetweenChars (firstChar , secondChar ):
330
-
331
333
fltAdj = float (abs (firstChar .intCenterX - secondChar .intCenterX ))
332
334
fltOpp = float (abs (firstChar .intCenterY - secondChar .intCenterY ))
333
335
334
- fltAngleInRad = math .atan (fltOpp / fltAdj )
336
+ if fltAdj != 0.0 :
337
+ fltAngleInRad = math .atan (fltOpp / fltAdj )
338
+ else :
339
+ fltAngleInRad = 1.5708
340
+ # end if
335
341
336
342
fltAngleInDeg = fltAngleInRad * (180.0 / math .pi )
337
343
@@ -344,10 +350,10 @@ def removeInnerOverlappingChars(listOfMatchingChars):
344
350
345
351
for currentChar in listOfMatchingChars :
346
352
for otherChar in listOfMatchingChars :
347
- if currentChar .contour == otherChar .contour :
348
- if distanceBetweenChars (currentChar , otherChar ) < (currentChar .dblDiagonalSize * MIN_DIAG_SIZE_MULTIPLE_AWAY ):
353
+ if currentChar .contour . all () == otherChar .contour . all () :
354
+ if distanceBetweenChars (currentChar , otherChar ) < (currentChar .fltDiagonalSize * MIN_DIAG_SIZE_MULTIPLE_AWAY ):
349
355
350
- if currentChar .intRectArea < otherChar .intRectArea :
356
+ if currentChar .intBoundingRectArea < otherChar .intBoundingRectArea :
351
357
if currentChar in listOfMatchingCharsWithInnerCharRemoved :
352
358
listOfMatchingCharsWithInnerCharRemoved .remove (currentChar )
353
359
# end if
@@ -368,7 +374,7 @@ def removeInnerOverlappingChars(listOfMatchingChars):
368
374
def recognizeCharsInPlate (imgThresh , listOfMatchingChars ):
369
375
strChars = "" # this will be the return value, the chars in the lic plate
370
376
371
- height , width , numChannels = imgThresh .shape
377
+ height , width = imgThresh .shape
372
378
373
379
imgThreshColor = np .zeros ((height , width , 3 ), np .uint8 )
374
380
@@ -377,17 +383,17 @@ def recognizeCharsInPlate(imgThresh, listOfMatchingChars):
377
383
cv2 .cvtColor (imgThresh , cv2 .COLOR_GRAY2BGR , imgThreshColor )
378
384
379
385
for currentChar in listOfMatchingChars :
380
- pt1 = tuple (currentChar .boundingRect . x , currentChar .boundingRect . y )
381
- pt2 = tuple ((currentChar .boundingRect . x + currentChar .boundingRect . width ), (currentChar .boundingRect . y + currentChar .boundingRect . height ))
386
+ pt1 = (currentChar .intBoundingRectX , currentChar .intBoundingRectY )
387
+ pt2 = ((currentChar .intBoundingRectX + currentChar .intBoundingRectWidth ), (currentChar .intBoundingRectY + currentChar .intBoundingRectHeight ))
382
388
383
389
cv2 .rectangle (imgThreshColor , pt1 , pt2 , Main .SCALAR_GREEN , 2 )
384
390
385
- imgROI = imgThresh [currentChar .boundingRect . y : currentChar .boundingRect . y + currentChar .boundingRect . height ,
386
- currentChar .boundingRect . x : currentChar .boundingRect . x + currentChar .boundingRect . width ]
391
+ imgROI = imgThresh [currentChar .intBoundingRectY : currentChar .intBoundingRectY + currentChar .intBoundingRectHeight ,
392
+ currentChar .intBoundingRectX : currentChar .intBoundingRectX + currentChar .intBoundingRectWidth ]
387
393
388
394
imgROIResized = cv2 .resize (imgROI , (RESIZED_CHAR_IMAGE_WIDTH , RESIZED_CHAR_IMAGE_HEIGHT ))
389
395
390
- npaROIResized = imgROIResized .reshape ((1 , RESIZED_IMAGE_WIDTH * RESIZED_IMAGE_HEIGHT ))
396
+ npaROIResized = imgROIResized .reshape ((1 , RESIZED_CHAR_IMAGE_WIDTH * RESIZED_CHAR_IMAGE_HEIGHT ))
391
397
392
398
npaROIResized = np .float32 (npaROIResized )
393
399
0 commit comments