def findPossibleCharsInScene(imgThresh): listOfPossibleChars = [] # this will be the return value intCountOfPossibleChars = 0 imgThreshCopy = imgThresh.copy() #imgContours, contours, npaHierarchy = cv2.findContours(imgThreshCopy, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) contours, npahierachy = cv2.findContours( imgThreshCopy, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # find all contours height, width = imgThresh.shape imgContours = np.zeros((height, width, 3), np.uint8) for i in range(0, len(contours)): # for each contour if Main1.showSteps == True: # show steps ################################################### cv2.drawContours(imgContours, contours, i, Main1.SCALAR_WHITE) # end if # show steps ##################################################################### possibleChar = PossibleChar.PossibleChar(contours[i]) if DetectChars.checkIfPossibleChar( possibleChar ): # if contour is a possible char, note this does not compare to other chars (yet) . . . intCountOfPossibleChars = intCountOfPossibleChars + 1 # increment count of possible chars listOfPossibleChars.append( possibleChar) # and add to list of possible chars # end if # end for if Main1.showSteps == True: # show steps ####################################################### print("\nstep 2 - len(contours) = " + str(len(contours))) # 2362 with MCLRNF1 image print("step 2 - intCountOfPossibleChars = " + str(intCountOfPossibleChars)) # 131 with MCLRNF1 image cv2.imshow("2a", imgContours) # end if # show steps ######################################################################### return listOfPossibleChars
def main123(image): image = os.path.dirname(__file__) + "/LicPlateImages/" + image print("dfsadfas" + image) blnKNNTrainingSuccessful = DetectChars.loadKNNDataAndTrainKNN( ) # attempt KNN training if blnKNNTrainingSuccessful == False: # if KNN training was not successful print( "\nerror: KNN traning was not successful\n") # show error message return # and exit program # end if imgOriginalScene = cv2.imread(image) # open image if imgOriginalScene is None: # if image was not read successfully print("\nerror: image not read from file \n\n" ) # print error message to std out os.system("pause") # pause so user can see error message return # and exit program # end if listOfPossiblePlates = DetectPlates.detectPlatesInScene( imgOriginalScene) # detect plates listOfPossiblePlates = DetectChars.detectCharsInPlates( listOfPossiblePlates) # detect chars in plates print(listOfPossiblePlates) cv2.imshow("imgOriginalScene", imgOriginalScene) # show scene image if len(listOfPossiblePlates) == 0: # if no plates were found print("\nno license plates were detected\n" ) # inform user no plates were found else: # else # if we get in here list of possible plates has at leat one plate # sort the list of possible plates in DESCENDING order (most number of chars to least number of chars) listOfPossiblePlates.sort( key=lambda possiblePlate: len(possiblePlate.strChars), reverse=True) # suppose the plate with the most recognized chars (the first plate in sorted by string length descending order) is the actual plate licPlate = listOfPossiblePlates[0] cv2.imshow( "imgPlate", licPlate.imgPlate) # show crop of plate and threshold of plate cv2.imshow("imgThresh", licPlate.imgThresh) if len(licPlate.strChars) == 0: # if no chars were found in the plate print("\nno characters were detected\n\n") # show message return # and exit program # end if drawRedRectangleAroundPlate( imgOriginalScene, licPlate) # draw red rectangle around plate print("\nlicense plate read from image = " + licPlate.strChars + "\n") # write license plate text to std out print("----------------------------------------") writeLicensePlateCharsOnImage( imgOriginalScene, licPlate) # write license plate text on the image cv2.imshow("imgOriginalScene", imgOriginalScene) # re-show scene image cv2.imwrite("imgOriginalScene.png", imgOriginalScene) # write image out to file # end if else return licPlate.strChars
def extractPlate(imgOriginal, listOfMatchingChars): possiblePlate = PossiblePlate.PossiblePlate( ) # this will be the return value listOfMatchingChars.sort( key=lambda matchingChar: matchingChar.intCenterX ) # sort chars from left to right based on x position # calculate the center point of the plate fltPlateCenterX = ( listOfMatchingChars[0].intCenterX + listOfMatchingChars[len(listOfMatchingChars) - 1].intCenterX) / 2.0 fltPlateCenterY = ( listOfMatchingChars[0].intCenterY + listOfMatchingChars[len(listOfMatchingChars) - 1].intCenterY) / 2.0 ptPlateCenter = fltPlateCenterX, fltPlateCenterY # calculate plate width and height intPlateWidth = int( (listOfMatchingChars[len(listOfMatchingChars) - 1].intBoundingRectX + listOfMatchingChars[len(listOfMatchingChars) - 1].intBoundingRectWidth - listOfMatchingChars[0].intBoundingRectX) * PLATE_WIDTH_PADDING_FACTOR) intTotalOfCharHeights = 0 for matchingChar in listOfMatchingChars: intTotalOfCharHeights = intTotalOfCharHeights + matchingChar.intBoundingRectHeight # end for fltAverageCharHeight = intTotalOfCharHeights / len(listOfMatchingChars) intPlateHeight = int(fltAverageCharHeight * PLATE_HEIGHT_PADDING_FACTOR) # calculate correction angle of plate region fltOpposite = listOfMatchingChars[ len(listOfMatchingChars) - 1].intCenterY - listOfMatchingChars[0].intCenterY fltHypotenuse = DetectChars.distanceBetweenChars( listOfMatchingChars[0], listOfMatchingChars[len(listOfMatchingChars) - 1]) fltCorrectionAngleInRad = math.asin(fltOpposite / fltHypotenuse) fltCorrectionAngleInDeg = fltCorrectionAngleInRad * (180.0 / math.pi) # pack plate region center point, width and height, and correction angle into rotated rect member variable of plate possiblePlate.rrLocationOfPlateInScene = (tuple(ptPlateCenter), (intPlateWidth, intPlateHeight), fltCorrectionAngleInDeg) # final steps are to perform the actual rotation # get the rotation matrix for our calculated correction angle rotationMatrix = cv2.getRotationMatrix2D(tuple(ptPlateCenter), fltCorrectionAngleInDeg, 1.0) height, width, numChannels = imgOriginal.shape # unpack original image width and height imgRotated = cv2.warpAffine(imgOriginal, rotationMatrix, (width, height)) # rotate the entire image imgCropped = cv2.getRectSubPix(imgRotated, (intPlateWidth, intPlateHeight), tuple(ptPlateCenter)) possiblePlate.imgPlate = imgCropped # copy the cropped plate image into the applicable member variable of the possible plate return possiblePlate
def detectPlatesInScene(imgOriginalScene): listOfPossiblePlates = [] # this will be the return value height, width, numChannels = imgOriginalScene.shape imgGrayscaleScene = np.zeros((height, width, 1), np.uint8) imgThreshScene = np.zeros((height, width, 1), np.uint8) imgContours = np.zeros((height, width, 3), np.uint8) cv2.destroyAllWindows() if Main1.showSteps == True: # show steps ####################################################### cv2.imshow("0", imgOriginalScene) # end if # show steps ######################################################################### imgGrayscaleScene, imgThreshScene = Preprocess.preprocess( imgOriginalScene) # preprocess to get grayscale and threshold images if Main1.showSteps == True: # show steps ####################################################### cv2.imshow("1a", imgGrayscaleScene) cv2.imshow("1b", imgThreshScene) # end if # show steps ######################################################################### # find all possible chars in the scene, # this function first finds all contours, then only includes contours that could be chars (without comparison to other chars yet) listOfPossibleCharsInScene = findPossibleCharsInScene(imgThreshScene) if Main1.showSteps == True: # show steps ####################################################### print("step 2 - len(listOfPossibleCharsInScene) = " + str(len(listOfPossibleCharsInScene))) # 131 with MCLRNF1 image imgContours = np.zeros((height, width, 3), np.uint8) contours = [] for possibleChar in listOfPossibleCharsInScene: contours.append(possibleChar.contour) # end for cv2.drawContours(imgContours, contours, -1, Main1.SCALAR_WHITE) cv2.imshow("2b", imgContours) # end if # show steps ######################################################################### # given a list of all possible chars, find groups of matching chars # in the next steps each group of matching chars will attempt to be recognized as a plate listOfListsOfMatchingCharsInScene = DetectChars.findListOfListsOfMatchingChars( listOfPossibleCharsInScene) if Main1.showSteps == True: # show steps ####################################################### print("step 3 - listOfListsOfMatchingCharsInScene.Count = " + str( len(listOfListsOfMatchingCharsInScene))) # 13 with MCLRNF1 image imgContours = np.zeros((height, width, 3), np.uint8) for listOfMatchingChars in listOfListsOfMatchingCharsInScene: intRandomBlue = random.randint(0, 255) intRandomGreen = random.randint(0, 255) intRandomRed = random.randint(0, 255) contours = [] for matchingChar in listOfMatchingChars: contours.append(matchingChar.contour) # end for cv2.drawContours(imgContours, contours, -1, (intRandomBlue, intRandomGreen, intRandomRed)) # end for cv2.imshow("3", imgContours) # end if # show steps ######################################################################### for listOfMatchingChars in listOfListsOfMatchingCharsInScene: # for each group of matching chars possiblePlate = extractPlate( imgOriginalScene, listOfMatchingChars) # attempt to extract plate if possiblePlate.imgPlate is not None: # if plate was found listOfPossiblePlates.append( possiblePlate) # add to list of possible plates # end if # end for print("\n" + str(len(listOfPossiblePlates)) + " possible plates found") # 13 with MCLRNF1 image if Main1.showSteps == True: # show steps ####################################################### print("\n") cv2.imshow("4a", imgContours) for i in range(0, len(listOfPossiblePlates)): p2fRectPoints = cv2.boxPoints( listOfPossiblePlates[i].rrLocationOfPlateInScene) cv2.line(imgContours, tuple(p2fRectPoints[0]), tuple(p2fRectPoints[1]), Main1.SCALAR_RED, 2) cv2.line(imgContours, tuple(p2fRectPoints[1]), tuple(p2fRectPoints[2]), Main1.SCALAR_RED, 2) cv2.line(imgContours, tuple(p2fRectPoints[2]), tuple(p2fRectPoints[3]), Main1.SCALAR_RED, 2) cv2.line(imgContours, tuple(p2fRectPoints[3]), tuple(p2fRectPoints[0]), Main1.SCALAR_RED, 2) 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) # end if # show steps ######################################################################### return listOfPossiblePlates