diff --git a/alpr_api.py b/alpr_api.py index f35ec69..b178fa4 100644 --- a/alpr_api.py +++ b/alpr_api.py @@ -119,10 +119,28 @@ def create_rest_server_flask(): @app.route('/v1/image/alpr', methods=['POST']) def alpr(): + """ + This function is called when a POST request is made to the /v1/image/alpr endpoint. + The function receives an image and processes it using the ultimateALPR SDK. + + Parameters: + - upload: The image to be processed + - grid_size: The number of cells to split the image into (e.g. 4) + - wanted_cells: The cells to process in the grid separated by commas (e.g. 1,2,3,4) (max: grid_sizeĀ²) + """ interference = time.time() if 'upload' not in request.files: return jsonify({'error': 'No image found'}) + if 'grid_size' in request.form and request.form['grid_size'].isdigit(): + grid_size = int(request.form['grid_size']) + else: + grid_size = None + if 'wanted_cells' in request.form and request.form['wanted_cells']: + wanted_cells = request.form['wanted_cells'].split(',') + wanted_cells = [int(cell) for cell in wanted_cells] + else: + wanted_cells = None image = request.files['upload'] if image.filename == '': @@ -135,7 +153,7 @@ def create_rest_server_flask(): if not result['predictions']: print("No plate found in the image, attempting to split the image") - predictions_found = find_best_plate_with_split(image) + predictions_found = find_best_plate_with_split(image, grid_size, wanted_cells) if predictions_found: result['predictions'].append(max(predictions_found, key=lambda x: x['confidence'])) @@ -195,19 +213,21 @@ def convert_to_cpai_compatible(result): return response -def find_best_plate_with_split(image, split_size=4, wanted_cells=None): +def find_best_plate_with_split(image: Image, grid_size: int = None, wanted_cells: str = None): + if grid_size is None: + grid_size = 3 if wanted_cells is None: - wanted_cells = [5, 6, 7, 9, 10, 11, 14, 15] # TODO: use params not specifc to my use case + wanted_cells = list(range(1, grid_size * grid_size + 1)) predictions_found = [] width, height = image.size - cell_width = width // split_size - cell_height = height // split_size + cell_width = width // grid_size + cell_height = height // grid_size - for cell_index in range(1, split_size * split_size + 1): - row = (cell_index - 1) // split_size - col = (cell_index - 1) % split_size + for cell_index in range(1, grid_size * grid_size + 1): + row = (cell_index - 1) // grid_size + col = (cell_index - 1) % grid_size left = col * cell_width upper = row * cell_height right = left + cell_width diff --git a/build_alpr_api.sh b/build_alpr_api.sh index 97cc8ab..551dc85 100755 --- a/build_alpr_api.sh +++ b/build_alpr_api.sh @@ -1 +1,2 @@ -pyinstaller --noconfirm --onefile --console --add-data libs:. --add-data assets:assets --add-data static:static --add-data templates:templates --name easy-local-alpr-1.1.0-openvinocpu_linux_x86_64 "alpr_api.py" +pyinstaller --noconfirm --console --add-data libs:. --add-data assets:assets --add-data static:static --add-data templates:templates --name easy-local-alpr-1.1.0-openvinocpu_linux_x86_64 "alpr_api.py" +# optional: --onefile \ No newline at end of file diff --git a/templates/index.html b/templates/index.html index b48b23e..5a0c015 100644 --- a/templates/index.html +++ b/templates/index.html @@ -14,6 +14,25 @@ background-size: 20px 20px; font-family: 'Google Sans', sans-serif; } + .loading-circle { + border: 4px solid rgba(0, 0, 0, 0.1); + border-left-color: #000; + border-radius: 50%; + width: 24px; + height: 24px; + animation: spin 1s linear infinite; + } + @keyframes spin { + to { transform: rotate(360deg); } + } + input[type="text"], input[type="number"] { + background-color: white; + color: black; + } + input[type="text"].dark, input[type="number"].dark { + background-color: #3b3b3b; + color: white; + } @@ -36,10 +55,21 @@ +
+ + +
+
+ + +
- +

Response

@@ -73,12 +103,22 @@ function toggleLogo() { const logo = document.getElementById('logo'); const logoDark = document.getElementById('logoDark'); + const upload = document.getElementById('upload'); + const gridSize = document.getElementById('grid_size'); + const wantedCells = document.getElementById('wanted_cells'); + if (prefersDarkScheme.matches) { logo.style.display = 'none'; logoDark.style.display = 'block'; + upload.classList.add('dark'); + gridSize.classList.add('dark'); + wantedCells.classList.add('dark'); } else { logo.style.display = 'block'; logoDark.style.display = 'none'; + upload.classList.remove('dark'); + gridSize.classList.remove('dark'); + wantedCells.classList.remove('dark'); } } @@ -89,6 +129,9 @@ $('#uploadForm').on('submit', function (e) { e.preventDefault(); var formData = new FormData(this); + $('#submitButton').prop('disabled', true); + $('#loadingCircle').removeClass('hidden'); + $.ajax({ url: '/v1/image/alpr', type: 'POST', @@ -101,6 +144,10 @@ error: function (xhr, status, error) { var err = JSON.parse(xhr.responseText); $('#responseBox').text(JSON.stringify(err, null, 2)); + }, + complete: function () { + $('#submitButton').prop('disabled', false); + $('#loadingCircle').addClass('hidden'); } }); });