Spaces:
Sleeping
Sleeping
versionJan2024
Browse files- app.py +116 -84
- app_v1.py +128 -0
- models.py +70 -0
- odo_detector.tflite +3 -0
- requirements.txt +6 -72
app.py
CHANGED
|
@@ -1,21 +1,22 @@
|
|
| 1 |
import streamlit as st
|
| 2 |
import cv2
|
| 3 |
import numpy as np
|
| 4 |
-
from PIL import Image
|
| 5 |
-
import imutils
|
| 6 |
-
import easyocr
|
| 7 |
-
import os
|
| 8 |
-
import pathlib
|
| 9 |
-
import platform
|
| 10 |
-
from xyxy_converter import yolov5_to_image_coordinates
|
| 11 |
-
import shutil
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
|
|
|
| 19 |
|
| 20 |
def main():
|
| 21 |
st.title("Odometer value extractor with Streamlit")
|
|
@@ -32,6 +33,37 @@ def main():
|
|
| 32 |
resized_image = resized_image.astype(np.uint8)
|
| 33 |
cv2.imwrite('odometer_image.jpg', resized_image)
|
| 34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
# detect(
|
| 36 |
# weights='yolov5\runs\train\exp\weights\best.pt',
|
| 37 |
# source='odometer_image.jpg',
|
|
@@ -44,83 +76,83 @@ def main():
|
|
| 44 |
# exist_ok=True
|
| 45 |
# )
|
| 46 |
|
| 47 |
-
# os.system('wandb disabled')
|
| 48 |
-
|
| 49 |
-
os.chdir(YOLO_PATH)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
|
| 51 |
# try:
|
|
|
|
| 52 |
# shutil.rmtree('runs/detect/temp_exp')
|
| 53 |
# except:
|
| 54 |
# pass
|
| 55 |
|
| 56 |
-
|
| 57 |
-
#
|
| 58 |
-
|
| 59 |
-
python detect.py \
|
| 60 |
-
--weights {MODEL_PATH} \
|
| 61 |
-
--source {image_path} \
|
| 62 |
-
--img 640 \
|
| 63 |
-
--conf 0.4 \
|
| 64 |
-
--name temp_exp \
|
| 65 |
-
--hide-labels \
|
| 66 |
-
--hide-conf \
|
| 67 |
-
--save-txt \
|
| 68 |
-
--exist-ok \
|
| 69 |
-
--save-conf
|
| 70 |
-
'''
|
| 71 |
-
|
| 72 |
-
# Run the command
|
| 73 |
-
os.system(command)
|
| 74 |
-
|
| 75 |
-
# st.write('The detection is completed!!!')
|
| 76 |
-
|
| 77 |
-
os.chdir(CUR_DIR)
|
| 78 |
-
|
| 79 |
-
# st.write(os.path.exists('yolov5/runs/detect/temp_exp'))
|
| 80 |
-
|
| 81 |
-
if os.path.exists('yolov5/runs/detect/temp_exp'):
|
| 82 |
-
processed_image = cv2.imread('yolov5/runs/detect/temp_exp/odometer_image.jpg')
|
| 83 |
-
# st.write('Image boxed and loaded')
|
| 84 |
-
text_files = os.listdir('yolov5/runs/detect/temp_exp/labels')
|
| 85 |
-
original_img = cv2.imread('odometer_image.jpg')
|
| 86 |
-
gray = cv2.cvtColor(original_img, cv2.COLOR_BGR2GRAY)
|
| 87 |
-
|
| 88 |
-
if len(text_files) == 0:
|
| 89 |
-
display_text = "An odometer is not detected in the image!!!"
|
| 90 |
-
else:
|
| 91 |
-
text_file_path = f'yolov5/runs/detect/temp_exp/labels/{text_files[0]}'
|
| 92 |
-
x1, y1, x2, y2 = yolov5_to_image_coordinates(text_file_path)
|
| 93 |
-
# st.write(x1, y1, x2, y2)
|
| 94 |
-
cropped_image = gray[x1:x2, y1:y2]
|
| 95 |
-
|
| 96 |
-
reader = easyocr.Reader(['en'])
|
| 97 |
-
result = reader.readtext(cropped_image)
|
| 98 |
-
|
| 99 |
-
if len(result) != 0:
|
| 100 |
-
odometer_value = sorted(result, key=lambda x: x[2], reverse=True)[0][1]
|
| 101 |
-
display_text = f"Odometer value: {odometer_value}"
|
| 102 |
-
else:
|
| 103 |
-
odometer_value = 'not detected'
|
| 104 |
-
display_text = f"The odometer value is {odometer_value}!!!"
|
| 105 |
-
else:
|
| 106 |
-
display_text = "An odometer is not detected in the image!!!"
|
| 107 |
-
processed_image = cv2.imread('odometer_image.jpg')
|
| 108 |
-
|
| 109 |
-
try:
|
| 110 |
-
shutil.rmtree('odometer_image.jpg')
|
| 111 |
-
shutil.rmtree('runs/detect/temp_exp')
|
| 112 |
-
except:
|
| 113 |
-
pass
|
| 114 |
-
|
| 115 |
-
# Resize or preprocess the image as needed for your model
|
| 116 |
-
# For example, resizing to a specific input size
|
| 117 |
-
# processed_image = cv2.resize(image_np, (224, 224))
|
| 118 |
|
| 119 |
-
# Process the image using your deep learning model
|
| 120 |
-
# processed_image = process_image(image_np)
|
| 121 |
|
| 122 |
-
# Display the processed image
|
| 123 |
-
st.image(processed_image, caption=f"{display_text}", use_column_width=True)
|
| 124 |
|
| 125 |
st.session_state.pop("odometer")
|
| 126 |
|
|
|
|
| 1 |
import streamlit as st
|
| 2 |
import cv2
|
| 3 |
import numpy as np
|
| 4 |
+
from PIL import Image, ImageDraw
|
| 5 |
+
# import imutils
|
| 6 |
+
# import easyocr
|
| 7 |
+
# import os
|
| 8 |
+
# import pathlib
|
| 9 |
+
# import platform
|
| 10 |
+
# from xyxy_converter import yolov5_to_image_coordinates
|
| 11 |
+
# import shutil
|
| 12 |
+
from models import get_odometer_xy
|
| 13 |
+
|
| 14 |
+
# system_platform = platform.system()
|
| 15 |
+
# if system_platform == 'Windows': pathlib.PosixPath = pathlib.WindowsPath
|
| 16 |
+
|
| 17 |
+
# CUR_DIR = os.getcwd()
|
| 18 |
+
# YOLO_PATH = f"{CUR_DIR}/yolov5"
|
| 19 |
+
# MODEL_PATH = "runs/train/exp/weights/best.pt"
|
| 20 |
|
| 21 |
def main():
|
| 22 |
st.title("Odometer value extractor with Streamlit")
|
|
|
|
| 33 |
resized_image = resized_image.astype(np.uint8)
|
| 34 |
cv2.imwrite('odometer_image.jpg', resized_image)
|
| 35 |
|
| 36 |
+
# original_img = cv2.imread('odometer_image.jpg')
|
| 37 |
+
gray = cv2.cvtColor(resized_image, cv2.COLOR_BGR2GRAY)
|
| 38 |
+
|
| 39 |
+
x1, y1, x2, y2, odo_confidence = get_odometer_xy(
|
| 40 |
+
model_path='odo_detector.tflite',
|
| 41 |
+
image_path='odometer_image.jpg'
|
| 42 |
+
)
|
| 43 |
+
|
| 44 |
+
st.write(odo_confidence)
|
| 45 |
+
|
| 46 |
+
if odo_confidence == 0:
|
| 47 |
+
display_text = "An odometer is not detected in the image!!!"
|
| 48 |
+
st.image('odometer_image.jpg', caption=f"{display_text}", use_column_width=True)
|
| 49 |
+
else:
|
| 50 |
+
cropped_image = gray[y1:y2, x1:x2]
|
| 51 |
+
cv2.imwrite('odometer_number_image.jpg', cropped_image)
|
| 52 |
+
display_text = 'Here is the zoomed odometer value'
|
| 53 |
+
st.image('odometer_number_image.jpg', caption=f"{display_text}", use_column_width=True)
|
| 54 |
+
|
| 55 |
+
image = Image.open('odometer_image.jpg')
|
| 56 |
+
image_resized = image.resize((640, 640))
|
| 57 |
+
draw = ImageDraw.Draw(image_resized)
|
| 58 |
+
draw.rectangle([x1, y1, x2, y2], outline="red", width=2)
|
| 59 |
+
class_name = 'odometer'
|
| 60 |
+
text = f"Class: {class_name}, Confidence: {odo_confidence:.2f}"
|
| 61 |
+
draw.text((x1, y1), text, fill="red")
|
| 62 |
+
# Saving Images
|
| 63 |
+
image_resized.save('odometer_highlighted_image.jpg')
|
| 64 |
+
display_text = 'Here is the odometer on the image.'
|
| 65 |
+
st.image('odometer_highlighted_image.jpg', caption=f"{display_text}", use_column_width=True)
|
| 66 |
+
|
| 67 |
# detect(
|
| 68 |
# weights='yolov5\runs\train\exp\weights\best.pt',
|
| 69 |
# source='odometer_image.jpg',
|
|
|
|
| 76 |
# exist_ok=True
|
| 77 |
# )
|
| 78 |
|
| 79 |
+
# # os.system('wandb disabled')
|
| 80 |
+
|
| 81 |
+
# os.chdir(YOLO_PATH)
|
| 82 |
+
|
| 83 |
+
# # try:
|
| 84 |
+
# # shutil.rmtree('runs/detect/temp_exp')
|
| 85 |
+
# # except:
|
| 86 |
+
# # pass
|
| 87 |
+
|
| 88 |
+
# image_path = "../odometer_image.jpg"
|
| 89 |
+
# # command = f"python detect.py --weights {MODEL_PATH} --source {image_path} --img 640 --conf 0.4 --name 'temp_exp' --hide-labels --hide-conf --save-txt --exist-ok"
|
| 90 |
+
# command = f'''
|
| 91 |
+
# python detect.py \
|
| 92 |
+
# --weights {MODEL_PATH} \
|
| 93 |
+
# --source {image_path} \
|
| 94 |
+
# --img 640 \
|
| 95 |
+
# --conf 0.4 \
|
| 96 |
+
# --name temp_exp \
|
| 97 |
+
# --hide-labels \
|
| 98 |
+
# --hide-conf \
|
| 99 |
+
# --save-txt \
|
| 100 |
+
# --exist-ok \
|
| 101 |
+
# --save-conf
|
| 102 |
+
# '''
|
| 103 |
+
|
| 104 |
+
# # Run the command
|
| 105 |
+
# os.system(command)
|
| 106 |
+
|
| 107 |
+
# # st.write('The detection is completed!!!')
|
| 108 |
+
|
| 109 |
+
# os.chdir(CUR_DIR)
|
| 110 |
+
|
| 111 |
+
# # st.write(os.path.exists('yolov5/runs/detect/temp_exp'))
|
| 112 |
+
|
| 113 |
+
# if os.path.exists('yolov5/runs/detect/temp_exp'):
|
| 114 |
+
# processed_image = cv2.imread('yolov5/runs/detect/temp_exp/odometer_image.jpg')
|
| 115 |
+
# # st.write('Image boxed and loaded')
|
| 116 |
+
# text_files = os.listdir('yolov5/runs/detect/temp_exp/labels')
|
| 117 |
+
# original_img = cv2.imread('odometer_image.jpg')
|
| 118 |
+
# gray = cv2.cvtColor(original_img, cv2.COLOR_BGR2GRAY)
|
| 119 |
+
|
| 120 |
+
# if len(text_files) == 0:
|
| 121 |
+
# display_text = "An odometer is not detected in the image!!!"
|
| 122 |
+
# else:
|
| 123 |
+
# text_file_path = f'yolov5/runs/detect/temp_exp/labels/{text_files[0]}'
|
| 124 |
+
# x1, y1, x2, y2 = yolov5_to_image_coordinates(text_file_path)
|
| 125 |
+
# # st.write(x1, y1, x2, y2)
|
| 126 |
+
# cropped_image = gray[x1:x2, y1:y2]
|
| 127 |
+
|
| 128 |
+
# reader = easyocr.Reader(['en'])
|
| 129 |
+
# result = reader.readtext(cropped_image)
|
| 130 |
+
|
| 131 |
+
# if len(result) != 0:
|
| 132 |
+
# odometer_value = sorted(result, key=lambda x: x[2], reverse=True)[0][1]
|
| 133 |
+
# display_text = f"Odometer value: {odometer_value}"
|
| 134 |
+
# else:
|
| 135 |
+
# odometer_value = 'not detected'
|
| 136 |
+
# display_text = f"The odometer value is {odometer_value}!!!"
|
| 137 |
+
# else:
|
| 138 |
+
# display_text = "An odometer is not detected in the image!!!"
|
| 139 |
+
# processed_image = cv2.imread('odometer_image.jpg')
|
| 140 |
|
| 141 |
# try:
|
| 142 |
+
# shutil.rmtree('odometer_image.jpg')
|
| 143 |
# shutil.rmtree('runs/detect/temp_exp')
|
| 144 |
# except:
|
| 145 |
# pass
|
| 146 |
|
| 147 |
+
# # Resize or preprocess the image as needed for your model
|
| 148 |
+
# # For example, resizing to a specific input size
|
| 149 |
+
# # processed_image = cv2.resize(image_np, (224, 224))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 150 |
|
| 151 |
+
# # Process the image using your deep learning model
|
| 152 |
+
# # processed_image = process_image(image_np)
|
| 153 |
|
| 154 |
+
# # Display the processed image
|
| 155 |
+
# st.image(processed_image, caption=f"{display_text}", use_column_width=True)
|
| 156 |
|
| 157 |
st.session_state.pop("odometer")
|
| 158 |
|
app_v1.py
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
import cv2
|
| 3 |
+
import numpy as np
|
| 4 |
+
from PIL import Image
|
| 5 |
+
import imutils
|
| 6 |
+
import easyocr
|
| 7 |
+
import os
|
| 8 |
+
import pathlib
|
| 9 |
+
import platform
|
| 10 |
+
from xyxy_converter import yolov5_to_image_coordinates
|
| 11 |
+
import shutil
|
| 12 |
+
|
| 13 |
+
system_platform = platform.system()
|
| 14 |
+
if system_platform == 'Windows': pathlib.PosixPath = pathlib.WindowsPath
|
| 15 |
+
|
| 16 |
+
CUR_DIR = os.getcwd()
|
| 17 |
+
YOLO_PATH = f"{CUR_DIR}/yolov5"
|
| 18 |
+
MODEL_PATH = "runs/train/exp/weights/best.pt"
|
| 19 |
+
|
| 20 |
+
def main():
|
| 21 |
+
st.title("Odometer value extractor with Streamlit")
|
| 22 |
+
|
| 23 |
+
# Use st.camera to capture images from the user's camera
|
| 24 |
+
img_file_buffer = st.camera_input(label='Please, take a photo of odometer', key="odometer")
|
| 25 |
+
|
| 26 |
+
# Check if an image is captured
|
| 27 |
+
if img_file_buffer is not None:
|
| 28 |
+
# Convert the image to a NumPy array
|
| 29 |
+
image = Image.open(img_file_buffer)
|
| 30 |
+
image_np = np.array(image)
|
| 31 |
+
resized_image = cv2.resize(image_np, (640, 640))
|
| 32 |
+
resized_image = resized_image.astype(np.uint8)
|
| 33 |
+
cv2.imwrite('odometer_image.jpg', resized_image)
|
| 34 |
+
|
| 35 |
+
# detect(
|
| 36 |
+
# weights='yolov5\runs\train\exp\weights\best.pt',
|
| 37 |
+
# source='odometer_image.jpg',
|
| 38 |
+
# img=640,
|
| 39 |
+
# conf=0.4,
|
| 40 |
+
# name='temp_exp',
|
| 41 |
+
# hide_labels=True,
|
| 42 |
+
# hide_conf=True,
|
| 43 |
+
# save_txt=True,
|
| 44 |
+
# exist_ok=True
|
| 45 |
+
# )
|
| 46 |
+
|
| 47 |
+
# os.system('wandb disabled')
|
| 48 |
+
|
| 49 |
+
os.chdir(YOLO_PATH)
|
| 50 |
+
|
| 51 |
+
# try:
|
| 52 |
+
# shutil.rmtree('runs/detect/temp_exp')
|
| 53 |
+
# except:
|
| 54 |
+
# pass
|
| 55 |
+
|
| 56 |
+
image_path = "../odometer_image.jpg"
|
| 57 |
+
# command = f"python detect.py --weights {MODEL_PATH} --source {image_path} --img 640 --conf 0.4 --name 'temp_exp' --hide-labels --hide-conf --save-txt --exist-ok"
|
| 58 |
+
command = f'''
|
| 59 |
+
python detect.py \
|
| 60 |
+
--weights {MODEL_PATH} \
|
| 61 |
+
--source {image_path} \
|
| 62 |
+
--img 640 \
|
| 63 |
+
--conf 0.4 \
|
| 64 |
+
--name temp_exp \
|
| 65 |
+
--hide-labels \
|
| 66 |
+
--hide-conf \
|
| 67 |
+
--save-txt \
|
| 68 |
+
--exist-ok \
|
| 69 |
+
--save-conf
|
| 70 |
+
'''
|
| 71 |
+
|
| 72 |
+
# Run the command
|
| 73 |
+
os.system(command)
|
| 74 |
+
|
| 75 |
+
# st.write('The detection is completed!!!')
|
| 76 |
+
|
| 77 |
+
os.chdir(CUR_DIR)
|
| 78 |
+
|
| 79 |
+
# st.write(os.path.exists('yolov5/runs/detect/temp_exp'))
|
| 80 |
+
|
| 81 |
+
if os.path.exists('yolov5/runs/detect/temp_exp'):
|
| 82 |
+
processed_image = cv2.imread('yolov5/runs/detect/temp_exp/odometer_image.jpg')
|
| 83 |
+
# st.write('Image boxed and loaded')
|
| 84 |
+
text_files = os.listdir('yolov5/runs/detect/temp_exp/labels')
|
| 85 |
+
original_img = cv2.imread('odometer_image.jpg')
|
| 86 |
+
gray = cv2.cvtColor(original_img, cv2.COLOR_BGR2GRAY)
|
| 87 |
+
|
| 88 |
+
if len(text_files) == 0:
|
| 89 |
+
display_text = "An odometer is not detected in the image!!!"
|
| 90 |
+
else:
|
| 91 |
+
text_file_path = f'yolov5/runs/detect/temp_exp/labels/{text_files[0]}'
|
| 92 |
+
x1, y1, x2, y2 = yolov5_to_image_coordinates(text_file_path)
|
| 93 |
+
# st.write(x1, y1, x2, y2)
|
| 94 |
+
cropped_image = gray[x1:x2, y1:y2]
|
| 95 |
+
|
| 96 |
+
reader = easyocr.Reader(['en'])
|
| 97 |
+
result = reader.readtext(cropped_image)
|
| 98 |
+
|
| 99 |
+
if len(result) != 0:
|
| 100 |
+
odometer_value = sorted(result, key=lambda x: x[2], reverse=True)[0][1]
|
| 101 |
+
display_text = f"Odometer value: {odometer_value}"
|
| 102 |
+
else:
|
| 103 |
+
odometer_value = 'not detected'
|
| 104 |
+
display_text = f"The odometer value is {odometer_value}!!!"
|
| 105 |
+
else:
|
| 106 |
+
display_text = "An odometer is not detected in the image!!!"
|
| 107 |
+
processed_image = cv2.imread('odometer_image.jpg')
|
| 108 |
+
|
| 109 |
+
try:
|
| 110 |
+
shutil.rmtree('odometer_image.jpg')
|
| 111 |
+
shutil.rmtree('runs/detect/temp_exp')
|
| 112 |
+
except:
|
| 113 |
+
pass
|
| 114 |
+
|
| 115 |
+
# Resize or preprocess the image as needed for your model
|
| 116 |
+
# For example, resizing to a specific input size
|
| 117 |
+
# processed_image = cv2.resize(image_np, (224, 224))
|
| 118 |
+
|
| 119 |
+
# Process the image using your deep learning model
|
| 120 |
+
# processed_image = process_image(image_np)
|
| 121 |
+
|
| 122 |
+
# Display the processed image
|
| 123 |
+
st.image(processed_image, caption=f"{display_text}", use_column_width=True)
|
| 124 |
+
|
| 125 |
+
st.session_state.pop("odometer")
|
| 126 |
+
|
| 127 |
+
if __name__ == "__main__":
|
| 128 |
+
main()
|
models.py
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import tensorflow as tf
|
| 2 |
+
import numpy as np
|
| 3 |
+
from PIL import Image
|
| 4 |
+
|
| 5 |
+
def get_odometer_xy(model_path, image_path):
|
| 6 |
+
#model_path = 'odo_detector.tflite'
|
| 7 |
+
interpreter = tf.lite.Interpreter(model_path=model_path)
|
| 8 |
+
interpreter.allocate_tensors()
|
| 9 |
+
|
| 10 |
+
input_details = interpreter.get_input_details()
|
| 11 |
+
output_details = interpreter.get_output_details()
|
| 12 |
+
|
| 13 |
+
# Obtain the height and width of the corresponding image from the input tensor
|
| 14 |
+
image_height = input_details[0]['shape'][1] # 640
|
| 15 |
+
image_width = input_details[0]['shape'][2] # 640
|
| 16 |
+
|
| 17 |
+
# Image Preparation
|
| 18 |
+
# image_name = 'car.jpg'
|
| 19 |
+
image = Image.open(image_path)
|
| 20 |
+
image_resized = image.resize((image_width, image_height)) # Resize the image to the corresponding size of the input tensor and store it in a new variable
|
| 21 |
+
|
| 22 |
+
image_np = np.array(image_resized) #
|
| 23 |
+
image_np = np.true_divide(image_np, 255, dtype=np.float32)
|
| 24 |
+
image_np = image_np[np.newaxis, :]
|
| 25 |
+
|
| 26 |
+
# inference
|
| 27 |
+
interpreter.set_tensor(input_details[0]['index'], image_np)
|
| 28 |
+
interpreter.invoke()
|
| 29 |
+
|
| 30 |
+
# Obtaining output results
|
| 31 |
+
output = interpreter.get_tensor(output_details[0]['index'])
|
| 32 |
+
output = output[0]
|
| 33 |
+
output = output.T
|
| 34 |
+
|
| 35 |
+
boxes_xywh = output[:, :4] #Get coordinates of bounding box, first 4 columns of output tensor
|
| 36 |
+
scores = output[:, 4]#np.max(output[..., 5:], axis=1) #Get score value, 5th column of output tensor
|
| 37 |
+
classes = np.zeros(len(scores))#np.argmax(output[..., 5:], axis=1) # Get the class value, get the 6th and subsequent columns of the output tensor, and store the largest value in the output tensor.
|
| 38 |
+
|
| 39 |
+
# Threshold Setting
|
| 40 |
+
# threshold = 0.7
|
| 41 |
+
final_score = 0
|
| 42 |
+
x_center, y_center, width, height = 0, 0, 0, 0
|
| 43 |
+
class_name = 'odometer'
|
| 44 |
+
|
| 45 |
+
# Bounding boxes, scores, and classes are drawn on the image
|
| 46 |
+
# draw = ImageDraw.Draw(image_resized)
|
| 47 |
+
|
| 48 |
+
for box, score, cls in zip(boxes_xywh, scores, classes):
|
| 49 |
+
if score >= final_score:
|
| 50 |
+
x_center, y_center, width, height = box
|
| 51 |
+
final_score = score
|
| 52 |
+
class_name = cls
|
| 53 |
+
else:
|
| 54 |
+
pass
|
| 55 |
+
|
| 56 |
+
x1 = int((x_center - width / 2) * image_width)
|
| 57 |
+
y1 = int((y_center - height / 2) * image_height)
|
| 58 |
+
x2 = int((x_center + width / 2) * image_width)
|
| 59 |
+
y2 = int((y_center + height / 2) * image_height)
|
| 60 |
+
|
| 61 |
+
# draw.rectangle([x1, y1, x2, y2], outline="red", width=2)
|
| 62 |
+
# text = f"Class: {class_name}, Score: {final_score:.2f}"
|
| 63 |
+
# draw.text((x1, y1), text, fill="red")
|
| 64 |
+
|
| 65 |
+
# Saving Images
|
| 66 |
+
# image_resized.save('test_img.jpg')
|
| 67 |
+
|
| 68 |
+
return x1, y1, x2, y2, final_score
|
| 69 |
+
|
| 70 |
+
|
odo_detector.tflite
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:98eee28ce3552c3e780150c7461ca0975236b82cf4884e67d484eb9daa98473b
|
| 3 |
+
size 6191514
|
requirements.txt
CHANGED
|
@@ -1,79 +1,13 @@
|
|
| 1 |
-
altair==5.2.0
|
| 2 |
-
attrs==23.2.0
|
| 3 |
-
blinker==1.7.0
|
| 4 |
-
cachetools==5.3.2
|
| 5 |
-
certifi==2023.11.17
|
| 6 |
-
charset-normalizer==3.3.2
|
| 7 |
-
click==8.1.7
|
| 8 |
-
colorama==0.4.6
|
| 9 |
-
contourpy==1.2.0
|
| 10 |
-
cycler==0.12.1
|
| 11 |
-
easyocr==1.7.1
|
| 12 |
-
filelock==3.13.1
|
| 13 |
-
fonttools==4.47.0
|
| 14 |
-
fsspec==2023.12.2
|
| 15 |
-
gitdb==4.0.11
|
| 16 |
-
GitPython==3.1.40
|
| 17 |
-
idna==3.6
|
| 18 |
imageio==2.33.1
|
| 19 |
-
importlib-metadata==6.11.0
|
| 20 |
-
imutils==0.5.4
|
| 21 |
-
Jinja2==3.1.2
|
| 22 |
-
jsonschema==4.20.0
|
| 23 |
-
jsonschema-specifications==2023.12.1
|
| 24 |
-
kiwisolver==1.4.5
|
| 25 |
-
lazy_loader==0.3
|
| 26 |
-
markdown-it-py==3.0.0
|
| 27 |
-
MarkupSafe==2.1.3
|
| 28 |
matplotlib==3.8.2
|
| 29 |
-
mdurl==0.1.2
|
| 30 |
-
mpmath==1.3.0
|
| 31 |
-
networkx==3.2.1
|
| 32 |
-
ninja==1.11.1.1
|
| 33 |
numpy==1.26.3
|
| 34 |
opencv-python==4.9.0.80
|
| 35 |
opencv-python-headless==4.9.0.80
|
| 36 |
-
packaging==23.2
|
| 37 |
-
pandas==2.1.4
|
| 38 |
pillow==10.2.0
|
| 39 |
-
protobuf==4.25.1
|
| 40 |
-
psutil==5.9.7
|
| 41 |
-
py-cpuinfo==9.0.0
|
| 42 |
-
pyarrow==14.0.2
|
| 43 |
-
pyclipper==1.3.0.post5
|
| 44 |
-
pydeck==0.8.1b0
|
| 45 |
-
Pygments==2.17.2
|
| 46 |
-
pyparsing==3.1.1
|
| 47 |
-
python-bidi==0.4.2
|
| 48 |
-
python-dateutil==2.8.2
|
| 49 |
-
pytz==2023.3.post1
|
| 50 |
-
PyYAML==6.0.1
|
| 51 |
-
referencing==0.32.0
|
| 52 |
-
requests==2.31.0
|
| 53 |
-
rich==13.7.0
|
| 54 |
-
rpds-py==0.16.2
|
| 55 |
-
scikit-image==0.22.0
|
| 56 |
-
scipy==1.11.4
|
| 57 |
-
seaborn==0.13.1
|
| 58 |
-
shapely==2.0.2
|
| 59 |
-
six==1.16.0
|
| 60 |
-
smmap==5.0.1
|
| 61 |
streamlit==1.29.0
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
torch==2.1.2
|
| 69 |
-
torchvision==0.16.2
|
| 70 |
-
tornado==6.4
|
| 71 |
-
tqdm==4.66.1
|
| 72 |
-
typing_extensions==4.9.0
|
| 73 |
-
tzdata==2023.4
|
| 74 |
-
tzlocal==5.2
|
| 75 |
-
ultralytics==8.0.234
|
| 76 |
-
urllib3==2.1.0
|
| 77 |
-
validators==0.22.0
|
| 78 |
-
watchdog==3.0.0
|
| 79 |
-
zipp==3.17.0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
imageio==2.33.1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
matplotlib==3.8.2
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
numpy==1.26.3
|
| 4 |
opencv-python==4.9.0.80
|
| 5 |
opencv-python-headless==4.9.0.80
|
|
|
|
|
|
|
| 6 |
pillow==10.2.0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
streamlit==1.29.0
|
| 8 |
+
tensorboard==2.15.1
|
| 9 |
+
tensorboard-data-server==0.7.2
|
| 10 |
+
tensorflow==2.15.0
|
| 11 |
+
tensorflow-estimator==2.15.0
|
| 12 |
+
tensorflow-intel==2.15.0
|
| 13 |
+
tensorflow-io-gcs-filesystem==0.31.0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|