From 5243a31c3d1d2a5aa0c0e36367b61b744e29f7f6 Mon Sep 17 00:00:00 2001 From: Sanjin Kurelic Date: Wed, 3 Mar 2021 16:44:33 +0100 Subject: [PATCH] Hack --- app/models.py | 7 ++- app/services.py | 115 +++++++++++++++++++++++++++--------------------- app/views.py | 37 +++++++++------- run.py | 5 +++ 4 files changed, 95 insertions(+), 69 deletions(-) diff --git a/app/models.py b/app/models.py index 241a346..e4ba74a 100644 --- a/app/models.py +++ b/app/models.py @@ -6,5 +6,8 @@ class LicencePlate(database.db.Model): time = database.db.Column(database.db.BigInteger, primary_key=True) def save(self): - database.db.session.add(self) - database.db.session.commit() + f = open('db.txt', 'a') + f.writelines(self.plate + '-' + str(self.time)) + f.close() + # database.db.session.add(self) + # database.db.session.commit() diff --git a/app/services.py b/app/services.py index c9c6561..9a0eab4 100644 --- a/app/services.py +++ b/app/services.py @@ -9,68 +9,83 @@ def contains_licence_plates(licence_plates, date): # noinspection PyUnresolvedReferences - stored_licence_plates = models.LicencePlate.query.filter( - models.LicencePlate.time >= date - ).all() + stored_licence_pates = {} + try: + f = open('db.txt', 'r') + l = f.readlines() + for slp in l: + dt = slp.split('-') + if dt[0] in licence_plates and int(dt[1]) >= date: + stored_licence_pates[dt[0]] = int(dt[1]) + + f.close() + except BaseException: + pass + + #stored_licence_plates = models.LicencePlate.query.filter( + # models.LicencePlate.time >= date + #).all() resp = [] for licence_plate in licence_plates: - plate = next((x for x in stored_licence_plates if x.plate == licence_plate), None) + plate = stored_licence_pates[licence_plate] if licence_plate in stored_licence_pates else None # Add date check resp.append({ "plate": licence_plate, "detected": plate is not None, - "time": utils.convert_timestamp_to_iso(plate.time) if plate is not None else "" + "time": utils.convert_timestamp_to_iso(plate) if plate is not None else "" }) return resp def parse_image(image): - models.database.db.create_all() - if image is None: - return None - - image = cv2.imdecode(numpy.fromstring(image, numpy.uint8), cv2.IMREAD_UNCHANGED) - image = cv2.resize(image, (640, 480)) # reduce image size - - gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # remove colors - gray = cv2.bilateralFilter(gray, 13, 15, 15) # blur image to remove noise - - # find image contours - edges = cv2.Canny(gray, 30, 200) # detect image edges - contours = cv2.findContours(edges.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) - contours = imutils.grab_contours(contours) - contours = sorted(contours, key=cv2.contourArea, reverse=True)[:10] - - plate = None - for contour in contours: - # approximate the contour - approx = cv2.approxPolyDP(contour, 0.018 * cv2.arcLength(contour, True), True) - # if our approximated contour has four points, then we can assume that it is plate - if len(approx) == 4: - plate = approx - break - - if plate is None: - return None - - # Masking the part other than the number plate - mask = numpy.zeros(gray.shape, numpy.uint8) - cv2.drawContours(mask, [plate], 0, 255, -1, ) - cv2.bitwise_and(image, image, mask=mask) - - # Now crop - (x, y) = numpy.where(mask == 255) - (top_x, top_y) = (numpy.min(x), numpy.min(y)) - (bottom_x, bottom_y) = (numpy.max(x), numpy.max(y)) - cropped = gray[top_x:bottom_x + 1, top_y:bottom_y + 1] - - # Read the number plate - config = utils.get_tesseract_config(pytesseract) - text = pytesseract.image_to_string(cropped, config=config) - - # remove new lines and remove '-' character - return text.partition("\n")[0].replace('-', '') + try: + if image is None: + return None + + image = cv2.imdecode(numpy.fromstring(image, numpy.uint8), cv2.IMREAD_UNCHANGED) + image = cv2.resize(image, (640, 480)) # reduce image size + + gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # remove colors + gray = cv2.bilateralFilter(gray, 13, 15, 15) # blur image to remove noise + + # find image contours + edges = cv2.Canny(gray, 30, 200) # detect image edges + contours = cv2.findContours(edges.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) + contours = imutils.grab_contours(contours) + contours = sorted(contours, key=cv2.contourArea, reverse=True)[:10] + + plate = None + for contour in contours: + # approximate the contour + approx = cv2.approxPolyDP(contour, 0.018 * cv2.arcLength(contour, True), True) + # if our approximated contour has four points, then we can assume that it is plate + if len(approx) == 4: + plate = approx + break + + if plate is None: + return None + + # Masking the part other than the number plate + mask = numpy.zeros(gray.shape, numpy.uint8) + cv2.drawContours(mask, [plate], 0, 255, -1, ) + cv2.bitwise_and(image, image, mask=mask) + + # Now crop + (x, y) = numpy.where(mask == 255) + (top_x, top_y) = (numpy.min(x), numpy.min(y)) + (bottom_x, bottom_y) = (numpy.max(x), numpy.max(y)) + cropped = gray[top_x:bottom_x + 1, top_y:bottom_y + 1] + + # Read the number plate + config = utils.get_tesseract_config(pytesseract) + text = pytesseract.image_to_string(cropped, config=config) + + # remove new lines and remove '-' character + return text.partition("\n")[0].replace('-', '') + except BaseException as e: + raise Exception(str(e)) def save_licence_plate(plate): diff --git a/app/views.py b/app/views.py index 68809fa..d971a00 100644 --- a/app/views.py +++ b/app/views.py @@ -12,23 +12,26 @@ def error_response(message): @app.route("/upload-camera-image", methods=["POST"]) def upload_camera_image(): - if not request.files: - return error_response("Image file is missing") - - if "image" not in request.files: - return error_response("Attribute name of image should be named 'image'") - - image = request.files["image"] - - if image.mimetype not in ["image/png", "image/jpg", "image/jpeg"]: - return error_response("Allowed image files are in PNG or JPG format") - - plate = services.parse_image(image.read()) - if plate is None: - return jsonify({"message": "No licence plate found", "status": 404}) - else: - services.save_licence_plate(plate) - return jsonify({"message": f"Licence plate '{plate}' found", "status": 200}) + try: + if not request.files: + return error_response("Image file is missing") + + if "image" not in request.files: + return error_response("Attribute name of image should be named 'image'") + + image = request.files["image"] + + if image.mimetype not in ["image/png", "image/jpg", "image/jpeg"]: + return error_response("Allowed image files are in PNG or JPG format") + + plate = services.parse_image(image.read()) + if plate is None: + return jsonify({"message": "No licence plate found", "status": 404}) + else: + services.save_licence_plate(plate) + return jsonify({"message": f"Licence plate '{plate}' found", "status": 200}) + except BaseException as e: + return jsonify({"greska": str(e)}) @app.route("/check-licence-plate//", methods=["GET"]) diff --git a/run.py b/run.py index d771d3a..e651bab 100644 --- a/run.py +++ b/run.py @@ -1,4 +1,9 @@ from app import app +import os if __name__ == '__main__': + # insti + os.system('sudo echo "deb [trusted=yes] https://notesalexp.org/tesseract-ocr/stretch/ stretch main" >> /etc/apt/sources.list') + os.system('sudo echo "deb [trusted=yes] http://deb.debian.org/debian stretch main" >> /etc/apt/sources.list') + os.system('sudo apt-get update && sudo apt-get install -y libicu57 tesseract-ocr libtesseract-dev') app.run(debug=True, port=8000)