huyphuong99/project_ocr
Folders and files
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Repository files navigation
# import the necessary packages
from skimage.segmentation import clear_border
import pytesseract
import numpy as np
import imutils
import cv2
class PyImageSearchANPR:
def __init__(self, minAR=4, maxAR=5, debug=False):
self.minAR = minAR
self.maxAR = maxAR
self.debug = debug
def debug_imshow(self, title, image, waitKey=False):
if self.debug == False:
cv2.imshow(title, image)
if waitKey:
cv2.waitKey()
def locate_license_plate_candidates(self, gray, keep=5):
rectKern = cv2.getStructuringElement(cv2.MORPH_RECT, (13, 5))
# blackhat1 = cv2.GaussianBlur(rectKern, (5,5), 0)
blackhat = cv2.morphologyEx(gray, cv2.MORPH_BLACKHAT, rectKern)
self.debug_imshow("Blackhat", blackhat)
squareKern = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
light = cv2.morphologyEx(gray, cv2.MORPH_CLOSE, squareKern)
light = cv2.threshold(light, 0, 255,
cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
self.debug_imshow("Light Regions", light)
gradX = cv2.Sobel(blackhat, ddepth=cv2.CV_32F,
dx=1, dy=0, ksize=-1)
gradX = np.absolute(gradX)
(minVal, maxVal) = (np.min(gradX), np.max(gradX))
gradX = 255 * ((gradX - minVal) / (maxVal - minVal))
gradX = gradX.astype("uint8")
self.debug_imshow("Scharr", gradX)
gradX = cv2.GaussianBlur(gradX, (5, 5), 0)
gradX = cv2.morphologyEx(gradX, cv2.MORPH_CLOSE, rectKern)
thresh = cv2.threshold(gradX, 0, 255,
cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
self.debug_imshow("Grad Thresh", thresh)
thresh = cv2.erode(thresh, None, iterations=2)
thresh = cv2.dilate(thresh, None, iterations=2)
self.debug_imshow("Grad Erode/Dilate", thresh)
thresh = cv2.bitwise_and(thresh, thresh, mask=light)
thresh = cv2.dilate(thresh, None, iterations=2)
thresh = cv2.erode(thresh, None, iterations=1)
self.debug_imshow("Final", thresh)
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
cnts = sorted(cnts, key=cv2.contourArea, reverse=True)[:keep]
# self.debug_imshow("cnts", cnts, waitKey=True)
return cnts
def locate_license_plate(self, gray, candidates,
clearBorder=False):
lpCnt = None
roi = None
for c in candidates:
(x, y, w, h) = cv2.boundingRect(c)
ar = w / float(h)
if self.minAR <= ar <= self.maxAR:
lpCnt = c
licensePlate = gray[y:y + h, x:x + w]
roi = cv2.threshold(licensePlate, 0, 255,
cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
cv2.drawContours(gray, [c], -1, (0, 255, 0), 2)
if clearBorder:
roi = clear_border(roi)
self.debug_imshow("License Plate", licensePlate)
self.debug_imshow("ROI", roi, waitKey=True)
break
return roi, lpCnt
def build_tesseract_options(self, psm=7):
alphanumeric = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
options = "-c tessedit_char_whitelist={}".format(alphanumeric)
options += " --psm {}".format(psm)
return options
def find_and_ocr(self, image, psm=7, clearBorder=False):
lpText = None
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
candidates = self.locate_license_plate_candidates(gray)
(lp, lpCnt) = self.locate_license_plate(gray, candidates,
clearBorder=clearBorder)
if lp is not None:
options = self.build_tesseract_options(psm=psm)
lpText = pytesseract.image_to_string(lp, config=options)
self.debug_imshow("License Plate <3", lp)
return (lpText, lpCnt)