├── testData ├── Final.JPG ├── SS1.png ├── car.jpg ├── car2.jpg ├── test.JPG ├── test.jpeg ├── test1.jpg ├── test2.jpg ├── test3.jpg ├── test4.JPG └── test4.jpg ├── README.md └── main.py /testData/Final.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onuzbee/Indian-Number-Plate-Recognition-System/HEAD/testData/Final.JPG -------------------------------------------------------------------------------- /testData/SS1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onuzbee/Indian-Number-Plate-Recognition-System/HEAD/testData/SS1.png -------------------------------------------------------------------------------- /testData/car.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onuzbee/Indian-Number-Plate-Recognition-System/HEAD/testData/car.jpg -------------------------------------------------------------------------------- /testData/car2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onuzbee/Indian-Number-Plate-Recognition-System/HEAD/testData/car2.jpg -------------------------------------------------------------------------------- /testData/test.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onuzbee/Indian-Number-Plate-Recognition-System/HEAD/testData/test.JPG -------------------------------------------------------------------------------- /testData/test.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onuzbee/Indian-Number-Plate-Recognition-System/HEAD/testData/test.jpeg -------------------------------------------------------------------------------- /testData/test1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onuzbee/Indian-Number-Plate-Recognition-System/HEAD/testData/test1.jpg -------------------------------------------------------------------------------- /testData/test2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onuzbee/Indian-Number-Plate-Recognition-System/HEAD/testData/test2.jpg -------------------------------------------------------------------------------- /testData/test3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onuzbee/Indian-Number-Plate-Recognition-System/HEAD/testData/test3.jpg -------------------------------------------------------------------------------- /testData/test4.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onuzbee/Indian-Number-Plate-Recognition-System/HEAD/testData/test4.JPG -------------------------------------------------------------------------------- /testData/test4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onuzbee/Indian-Number-Plate-Recognition-System/HEAD/testData/test4.jpg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Number-Plate-Recognition-System 2 | Computer Vision Project(EC353). 3 | 4 | ### Built Using: 5 | * Python 2.7 6 | * OpenCV 3.0.0 7 | * Tesseract 8 | ### Screenshot 9 | ![Screenshot](/testData/SS1.png) 10 | 11 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | 2 | import numpy as np 3 | import cv2 4 | from copy import deepcopy 5 | from PIL import Image 6 | import pytesseract as tess 7 | 8 | def preprocess(img): 9 | cv2.imshow("Input",img) 10 | imgBlurred = cv2.GaussianBlur(img, (5,5), 0) 11 | gray = cv2.cvtColor(imgBlurred, cv2.COLOR_BGR2GRAY) 12 | 13 | sobelx = cv2.Sobel(gray,cv2.CV_8U,1,0,ksize=3) 14 | #cv2.imshow("Sobel",sobelx) 15 | #cv2.waitKey(0) 16 | ret2,threshold_img = cv2.threshold(sobelx,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU) 17 | #cv2.imshow("Threshold",threshold_img) 18 | #cv2.waitKey(0) 19 | return threshold_img 20 | 21 | def cleanPlate(plate): 22 | print("CLEANING PLATE. . .") 23 | gray = cv2.cvtColor(plate, cv2.COLOR_BGR2GRAY) 24 | #kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3)) 25 | #thresh= cv2.dilate(gray, kernel, iterations=1) 26 | 27 | _, thresh = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY) 28 | im1,contours,hierarchy = cv2.findContours(thresh.copy(),cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) 29 | 30 | if contours: 31 | areas = [cv2.contourArea(c) for c in contours] 32 | max_index = np.argmax(areas) 33 | 34 | max_cnt = contours[max_index] 35 | max_cntArea = areas[max_index] 36 | x,y,w,h = cv2.boundingRect(max_cnt) 37 | 38 | if not ratioCheck(max_cntArea,w,h): 39 | return plate,None 40 | 41 | cleaned_final = thresh[y:y+h, x:x+w] 42 | #cv2.imshow("Function Test",cleaned_final) 43 | return cleaned_final,[x,y,w,h] 44 | 45 | else: 46 | return plate,None 47 | 48 | 49 | def extract_contours(threshold_img): 50 | element = cv2.getStructuringElement(shape=cv2.MORPH_RECT, ksize=(17, 3)) 51 | morph_img_threshold = threshold_img.copy() 52 | cv2.morphologyEx(src=threshold_img, op=cv2.MORPH_CLOSE, kernel=element, dst=morph_img_threshold) 53 | cv2.imshow("Morphed",morph_img_threshold) 54 | cv2.waitKey(0) 55 | 56 | im2,contours, hierarchy= cv2.findContours(morph_img_threshold,mode=cv2.RETR_EXTERNAL,method=cv2.CHAIN_APPROX_NONE) 57 | return contours 58 | 59 | 60 | def ratioCheck(area, width, height): 61 | ratio = float(width) / float(height) 62 | if ratio < 1: 63 | ratio = 1 / ratio 64 | 65 | aspect = 4.7272 66 | min = 15*aspect*15 # minimum area 67 | max = 125*aspect*125 # maximum area 68 | 69 | rmin = 3 70 | rmax = 6 71 | 72 | if (area < min or area > max) or (ratio < rmin or ratio > rmax): 73 | return False 74 | return True 75 | 76 | def isMaxWhite(plate): 77 | avg = np.mean(plate) 78 | if(avg>=115): 79 | return True 80 | else: 81 | return False 82 | 83 | def validateRotationAndRatio(rect): 84 | (x, y), (width, height), rect_angle = rect 85 | 86 | if(width>height): 87 | angle = -rect_angle 88 | else: 89 | angle = 90 + rect_angle 90 | 91 | if angle>15: 92 | return False 93 | 94 | if height == 0 or width == 0: 95 | return False 96 | 97 | area = height*width 98 | if not ratioCheck(area,width,height): 99 | return False 100 | else: 101 | return True 102 | 103 | 104 | 105 | def cleanAndRead(img,contours): 106 | #count=0 107 | for i,cnt in enumerate(contours): 108 | min_rect = cv2.minAreaRect(cnt) 109 | 110 | if validateRotationAndRatio(min_rect): 111 | 112 | x,y,w,h = cv2.boundingRect(cnt) 113 | plate_img = img[y:y+h,x:x+w] 114 | 115 | 116 | if(isMaxWhite(plate_img)): 117 | #count+=1 118 | clean_plate, rect = cleanPlate(plate_img) 119 | 120 | if rect: 121 | x1,y1,w1,h1 = rect 122 | x,y,w,h = x+x1,y+y1,w1,h1 123 | cv2.imshow("Cleaned Plate",clean_plate) 124 | cv2.waitKey(0) 125 | plate_im = Image.fromarray(clean_plate) 126 | text = tess.image_to_string(plate_im, lang='eng') 127 | print("Detected Text : ",text) 128 | img = cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2) 129 | cv2.imshow("Detected Plate",img) 130 | cv2.waitKey(0) 131 | 132 | #print "No. of final cont : " , count 133 | 134 | 135 | 136 | if __name__ == '__main__': 137 | print( "DETECTING PLATE . . .") 138 | 139 | #img = cv2.imread("testData/Final.JPG") 140 | img = cv2.imread("testData/test.jpeg") 141 | 142 | threshold_img = preprocess(img) 143 | contours= extract_contours(threshold_img) 144 | 145 | #if len(contours)!=0: 146 | #print len(contours) #Test 147 | # cv2.drawContours(img, contours, -1, (0,255,0), 1) 148 | # cv2.imshow("Contours",img) 149 | # cv2.waitKey(0) 150 | 151 | 152 | cleanAndRead(img,contours) 153 | --------------------------------------------------------------------------------