Vahe commited on
Commit
5482479
·
1 Parent(s): 69c8334

versionJan2024

Browse files
Files changed (5) hide show
  1. app.py +116 -84
  2. app_v1.py +128 -0
  3. models.py +70 -0
  4. odo_detector.tflite +3 -0
  5. 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
- 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")
@@ -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
- 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
 
 
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
- sympy==1.12
63
- tenacity==8.2.3
64
- thop==0.1.1.post2209072238
65
- tifffile==2023.12.9
66
- toml==0.10.2
67
- toolz==0.12.0
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