From 1aa018f7d59e777c461310faa57a7c784f53c9da Mon Sep 17 00:00:00 2001 From: Mathieu Broillet Date: Wed, 17 Jul 2024 22:02:50 +0200 Subject: [PATCH 1/2] improved webui --- alpr_api.py | 31 +++++++++++++++++ static/{logo.webp => logo_black.webp} | Bin static/logo_white.webp | Bin 0 -> 3186 bytes static/styles.css | 25 -------------- templates/index.html | 47 +++++++++++++++++++------- 5 files changed, 65 insertions(+), 38 deletions(-) rename static/{logo.webp => logo_black.webp} (100%) create mode 100644 static/logo_white.webp delete mode 100644 static/styles.css diff --git a/alpr_api.py b/alpr_api.py index 8a07908..8d58c9f 100644 --- a/alpr_api.py +++ b/alpr_api.py @@ -137,6 +137,37 @@ def create_rest_server_flask(): result = process_image(image) result = convert_to_cpai_compatible(result) + if len(result['predictions']) == 0: + print("No plate found in the image, trying to split the image") + + width, height = image.size + cell_width = width // 3 + cell_height = height // 3 + + # Define which cells to process (2, 4, 5, 6, 8, 9) + cells_to_process = [2, 4, 5, 6, 8, 9] + + # Loop through each cell + for cell_index in range(1, 10): + # Calculate row and column of the cell + row = (cell_index - 1) // 3 + col = (cell_index - 1) % 3 + + # Calculate bounding box of the cell + left = col * cell_width + upper = row * cell_height + right = left + cell_width + lower = upper + cell_height + + # Check if this cell should be processed + if cell_index in cells_to_process: + # Extract the cell as a new image + cell_image = image.crop((left, upper, right, lower)) + + + + cell_image.show() + return jsonify(result) else: return jsonify({'error': 'Endpoint not implemented'}), 404 diff --git a/static/logo.webp b/static/logo_black.webp similarity index 100% rename from static/logo.webp rename to static/logo_black.webp diff --git a/static/logo_white.webp b/static/logo_white.webp new file mode 100644 index 0000000000000000000000000000000000000000..4b7ed5e2e23307ba1595ec423df1085152489d47 GIT binary patch literal 3186 zcmV-&42|iGmA0Cx;&z=HpaNOBCDukjIk;b zg_-#rZ)ScSZ*`0@nm^90je9efQCJ&e+?!j^Ssi1Ht)0ZoyyR>jV{9#_G&3hzjIp{< zd?bC?ml;KzNKchpYA2FY>m+r+b_g?wagy znyUkub=G#|a=AJHLuYmOBj6BHJ<#vWteJo&aRtzK-2||av0-D zG4H!+#!k`zQ@1m-W&*C(C?*)Xt=X;v#_|;71hD^8f;MO3aw$ikD^K!IYD~`lUC6l7|I3L0Hc?r5ongYlT-p>!4K@9B=x}SS+Zg86PqbV9ZVB+E0qVJFA_xq9D?Q*z|JS!zHyR(KK0-i zS*HQolpjvUv`P3Kz_l)+G6F+wUd|c-n~lKEOU~Z+x1}2BcV^b~K)Tw+wotN-iJ@}(T8vk- zGR9aQC$~Q&qDe8vYF5PgIO}B6K=S7~o>1MkL#aFUJwfg5It1OVLkQ*hQ;4_c za9!#Cbog4lo!6C~^#7Coe`4%bP&gp21^@t1Dgd1UDv$wY06v{cpG+mBBBCPITOhC# ziD_>9e3*&rP|N&q{2l!O@|XP2OW;9_vfSmD$1i)g+5hNtLT49HpDd4HAG@BwAFu@I z=mC@inP?RhzMHbpDTcQZ1g7)xar{HD&oOsOzMv_M<=GhgL<5-2>R#cPw|dpf=Rl7) z`qd;$nmlN?&rdqHb0O!EvS#8X(D8-4Bjs%ge3u2!Hi*9zQ7^tz_xu4JHhKM z_4J!j6AF+7Zlew&ogOpIcj!j~&npO;1KH=o6VUAmY75v0eZWm;f|lv<4<9AM3hr&3 zgDHV!U7f5^j*@ovP@=5x1Y+;Si7X9=Z+&ppqm`Dv0OUcl$iTsr1DR+P;WoErpj1-& zZp%QZrS#pFcmM$Y{;q5%GIB+4hxEGnP-R7lx6+iA!6RKu?|{l^-0%DcH!Cob)A^E3 zs~P(^tz397eDHnegEJ8m@UMlnvFS+8Acx*VZ6WX+n}hLex6}FF->g$_z^m`sVr#U> zb52;3o{OfMSJyz|Y3jC0H{fypD-P0)8|TO0HmWkO&2wrn z5v!Y`*-+;g%j$IM?d%bVnp>SlbWPr#Mb=d;@GGFJ+Yh5)yZIbb8%{Yl-9Nv(_^N}} z5#b&nq7L7OLm9V3`N{W>9W*hF2(V?;o-3vXPNS>CX)&>YN)iD4!5hlAX;MiWB-0g_owpj_A2O=! z9nm+^e3Gb-{s-jyZXK`9)bg6u6l1n=Ul0KBH|yJHZ)12eG!H%_zOn(M2l*F1D{{&O?xc$AS7n>2%#8DjEJov62HsLeAg4g zopIU0Tn|FzLB!y)d`o9O2-wKwN`~@@u9rsqC>R5tT_r(}N{2{Vem` z6lQT)tNq9~T%;q*sUL@P`%}#5CT={=OQ9f2Kr2+R=Q~2kVh9HVownW7*iC@KCTk>7 z8lK!kCOi|_jz5oo8it@<-&@Ff4JndUC@N5PKmL~N@WV_IC(qJJe{}nxXyFrb)=y!< zzCZxe?OH{h)^3-y9WL)Dr_=25Q;P8YTEwg8)!YzRfIS3_gM2{0+RJB^S3Hm((+~uH zZqfa0BN*B3CZn8hnW@`&wRhCqW}a2){=?KQySt-W9t=ZR<2tfcGrDU)odRdCoLA!Q z%hCp-e_4)xBMwlVILz2&s4j(xer)(@$(9}ea2us`67~XK@em}`G^dz}HqXtfFxGT- zA;+Nl9^BOb+lUn`O#guoC6^2ft2U<=+l+B>VkiolEcQtu%C?r4Z{7|FO0nWH*Qnu4 zxKeQ{@NFxupQTxS#hq$Md=~(GJ?>XBe4E>mRM%`z;OZmCHI?^SJ_0a`17aaYqdIF} zG=^Vej)3Q>MfVpjb+iR(AvjpDEQ+k5?jOWINkB`)?XBePn5rusTnGmYNqRHFvSQ-L zT6@6b{TJ!~z!9~?gwI;8bpFG5`mEKVtLvvGo_B>@Wu|5@|4Y+GD| z^^XMg7(G0Ql3H*xF5_J8iuw|d`$(}b_Eb_IW}U0(jgNM`{SqQ(JVS5MQCS?Iq^aL1 Y6(!I||8T$m_ Image Upload - + - +
- Logo + +
-
-

Upload Image for ALPR

+
+

Upload Image for ALPR

- +
-
- +
-

Response

-

+            

Response

+

         
@@ -68,6 +69,26 @@ } } + // Check for dark mode and switch logo accordingly + const prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)"); + function toggleLogo() { + const logo = document.getElementById('logo'); + const logoDark = document.getElementById('logoDark'); + if (prefersDarkScheme.matches) { + logo.style.display = 'none'; + logoDark.style.display = 'block'; + } else { + logo.style.display = 'block'; + logoDark.style.display = 'none'; + } + } + + // Initial call to set logo based on dark mode preference + toggleLogo(); + + // Listen for changes in dark mode preference + prefersDarkScheme.addEventListener('change', toggleLogo); + $(document).ready(function () { $('#uploadForm').on('submit', function (e) { e.preventDefault(); From 549aba963a1c0cf93ceaf045e7711bf8ea84a2d8 Mon Sep 17 00:00:00 2001 From: Mathieu Broillet Date: Wed, 17 Jul 2024 22:24:32 +0200 Subject: [PATCH 2/2] add splitting system (3x3) if nothing found --- alpr_api.py | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/alpr_api.py b/alpr_api.py index 8d58c9f..086ce01 100644 --- a/alpr_api.py +++ b/alpr_api.py @@ -2,6 +2,7 @@ import json import os import sys import threading +import time from time import sleep import ultimateAlprSdk @@ -126,6 +127,7 @@ def create_rest_server_flask(): def alpr(domain, module): # Only care about the ALPR endpoint if domain == 'image' and module == 'alpr': + interference = time.time() if 'upload' not in request.files: return jsonify({'error': 'No image found'}) @@ -134,12 +136,13 @@ def create_rest_server_flask(): return jsonify({'error': 'No selected file'}) image = Image.open(image) - result = process_image(image) - result = convert_to_cpai_compatible(result) + result = convert_to_cpai_compatible(process_image(image)) if len(result['predictions']) == 0: print("No plate found in the image, trying to split the image") + predictions_found = [] + width, height = image.size cell_width = width // 3 cell_height = height // 3 @@ -164,10 +167,34 @@ def create_rest_server_flask(): # Extract the cell as a new image cell_image = image.crop((left, upper, right, lower)) + result_cell = json.loads(process_image(cell_image)) + if 'plates' in result_cell: + for plate in result_cell['plates']: + warpedBox = plate['warpedBox'] + x_coords = warpedBox[0::2] + y_coords = warpedBox[1::2] + x_min = min(x_coords) + left + x_max = max(x_coords) + left + y_min = min(y_coords) + upper + y_max = max(y_coords) + upper - cell_image.show() + predictions_found.append({ + 'confidence': plate['confidences'][0] / 100, + 'label': "Plate: " + plate['text'], + 'plate': plate['text'], + 'x_min': x_min, + 'x_max': x_max, + 'y_min': y_min, + 'y_max': y_max + }) + if len(predictions_found) > 0: + # add the prediction with the highest confidence + result['predictions'].append(max(predictions_found, key=lambda x: x['confidence'])) + + result['processMs'] = round((time.time() - interference) * 1000, 2) + result['inferenceMs'] = result['processMs'] # same as processMs return jsonify(result) else: return jsonify({'error': 'Endpoint not implemented'}), 404