Hi,
My repo for the project I am creating is: GitHub - IIPeteII/car-license-plate-recognition-clean.
I have a requirements.txt file along with the app.py file, the other .ipynb files are where I created the initial code for checks and then copied over to the .py file.
Here’s the gist of my issue
I am trying to create a computer vision model that takes an uploaded file from the user (a picture in .jpg format).
This variable: uploaded_file is used in the subsequent code:
st.subheader('License plate detection model')
#Extract plate function
def extract_plate(img): # the function detects and perfors blurring on the number plate.
plate_img = img.copy()
#Loads the data required for detecting the license plates from cascade classifier.
plate_cascade = cv2.CascadeClassifier('indian_license_plate.xml')
# detects numberplates and returns the coordinates and dimensions of detected license plate's contours.
plate_rect = plate_cascade.detectMultiScale(plate_img, scaleFactor = 1.3, minNeighbors = 7)
for (x,y,w,h) in plate_rect:
#a,b = (int(0.02*img.shape[0]), int(0.025*img.shape[1])) #parameter tuning #Check this later!
#plate = plate_img[y+a:y+h-a, x+b:x+w-b, :]
plate = plate_img[y:y+h, x:x+w, :] #don't need the parameter tuning stuff
# finally representing the detected contours by drawing rectangles around the edges.
cv2.rectangle(plate_img, (x,y), (x+w, y+h), (51,51,255), 3)
return plate_img, plate # returning the processed image.
#Apply extraction function
dk_test_img = cv2.imread(uploaded_file) #set to work with uploaded file currently
plate_img_out, plate_out = extract_plate(dk_test_img)
#Match contours
def find_contours(dimensions, img) :
# Find all contours in the image
cntrs, _ = cv2.findContours(img.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# Retrieve potential dimensions
lower_width = dimensions[0]
upper_width = dimensions[1]
lower_height = dimensions[2]
upper_height = dimensions[3]
# Check largest 5 or 15 contours for license plate or character respectively
cntrs = sorted(cntrs, key=cv2.contourArea, reverse=True)[:15]
ii = cv2.imread('contour.jpg')
x_cntr_list = []
target_contours = []
img_res = []
for cntr in cntrs :
#detects contour in binary image and returns the coordinates of rectangle enclosing it
intX, intY, intWidth, intHeight = cv2.boundingRect(cntr)
#checking the dimensions of the contour to filter out the characters by contour's size
if intWidth > lower_width and intWidth < upper_width and intHeight > lower_height and intHeight < upper_height :
x_cntr_list.append(intX) #stores the x coordinate of the character's contour, to used later for indexing the contours
char_copy = np.zeros((44,24))
#extracting each character using the enclosing rectangle's coordinates.
char = img[intY:intY+intHeight, intX:intX+intWidth]
char = cv2.resize(char, (20, 40))
cv2.rectangle(ii, (intX,intY), (intWidth+intX, intY+intHeight), (50,21,200), 2)
plt.imshow(ii, cmap='gray')
# Make result formatted for classification: invert colors
char = cv2.subtract(255, char)
# Resize the image to 24x44 with black border
char_copy[2:42, 2:22] = char
char_copy[0:2, :] = 0
char_copy[:, 0:2] = 0
char_copy[42:44, :] = 0
char_copy[:, 22:24] = 0
img_res.append(char_copy) #List that stores the character's binary image (unsorted)
#Return characters on ascending order with respect to the x-coordinate (most-left character first)
plt.show()
#arbitrary function that stores sorted list of character indeces
indices = sorted(range(len(x_cntr_list)), key=lambda k: x_cntr_list[k])
img_res_copy = []
for idx in indices:
img_res_copy.append(img_res[idx])# stores character images according to their index
img_res = np.array(img_res_copy)
return img_res
#Find characters function
def segment_characters(image) :
# Preprocess cropped license plate image
img_lp = cv2.resize(image, (333, 75))
img_gray_lp = cv2.cvtColor(img_lp, cv2.COLOR_BGR2GRAY)
_, img_binary_lp = cv2.threshold(img_gray_lp, 200, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
img_binary_lp = cv2.erode(img_binary_lp, (3,3))
img_binary_lp = cv2.dilate(img_binary_lp, (3,3))
LP_WIDTH = img_binary_lp.shape[0]
LP_HEIGHT = img_binary_lp.shape[1]
# Make borders white
img_binary_lp[0:3,:] = 255
img_binary_lp[:,0:3] = 255
img_binary_lp[72:75,:] = 255
img_binary_lp[:,330:333] = 255
# Estimations of character contours sizes of cropped license plates
dimensions = [LP_WIDTH/6,
LP_WIDTH/2,
LP_HEIGHT/10,
2*LP_HEIGHT/3]
plt.imshow(img_binary_lp, cmap='gray')
plt.show()
cv2.imwrite('contour.jpg',img_binary_lp)
# Get contours within cropped license plate
char_list = find_contours(dimensions, img_binary_lp)
return char_list
char = segment_characters(plate_out)
However my logs are giving me the following issues
[ WARN:21@4861.850] global /io/opencv/modules/imgcodecs/src/loadsave.cpp (239) findDecoder imread_(''): can't open/read file: check file path/integrity
2022-11-26 19:33:26.382 Uncaught app exception
Traceback (most recent call last):
File "/home/appuser/venv/lib/python3.10/site-packages/streamlit/runtime/scriptrunner/script_runner.py", line 564, in _run_script
exec(code, module.__dict__)
File "/app/car-license-plate-recognition-clean/app.py", line 111, in <module>
plate_img_out, plate_out = extract_plate(dk_test_img)
File "/app/car-license-plate-recognition-clean/app.py", line 92, in extract_plate
plate_img = img.copy()
AttributeError: 'NoneType' object has no attribute 'copy'
I also get the error:
[ WARN:29@8560.858] global /io/opencv/modules/imgcodecs/src/loadsave.cpp (239) findDecoder imread_(''): can't open/read file: check file path/integrity
2022-11-26 20:35:05.391 Uncaught app exception
Traceback (most recent call last):
File "/home/appuser/venv/lib/python3.10/site-packages/streamlit/runtime/scriptrunner/script_runner.py", line 564, in _run_script
exec(code, module.__dict__)
File "/app/car-license-plate-recognition-clean/app.py", line 112, in <module>
plate_img_out, plate_out = extract_plate(dk_test_img)
File "/app/car-license-plate-recognition-clean/app.py", line 93, in extract_plate
plate_img = img.copy()
AttributeError: 'NoneType' object has no attribute 'copy'
2022-11-26 20:35:23.977 Uncaught app exception
Traceback (most recent call last):
File "/home/appuser/venv/lib/python3.10/site-packages/streamlit/runtime/scriptrunner/script_runner.py", line 564, in _run_script
exec(code, module.__dict__)
File "/app/car-license-plate-recognition-clean/app.py", line 111, in <module>
dk_test_img = cv2.imread(uploaded_file) #set to work with uploaded file currently
TypeError: Can't convert object to 'str' for 'filename'
This is my first time deploying and I suspect that it has to do with the extract function where plate_img = img.copy(). Part of me also suspect that the .xml file in the CascadeClassifier is a culprit.
and idea what I should do or if I’m doing major mistakes?