Pankaj Munde commited on
Commit
dc0ac35
β€’
1 Parent(s): aed133e

Added Prediction Functionality.

Browse files
Files changed (3) hide show
  1. app.py +228 -0
  2. requirements.txt +30 -0
  3. static/FarmGyan logo_1.png +0 -0
app.py ADDED
@@ -0,0 +1,228 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import base64
3
+ import streamlit as st
4
+ from streamlit_option_menu import option_menu
5
+ import pandas as pd
6
+ from PIL import Image
7
+
8
+ import numpy as np
9
+ import torch
10
+ import cv2
11
+ from transformers import AutoImageProcessor, AutoModelForObjectDetection
12
+ import bbox_visualizer as bbv
13
+ from st_clickable_images import clickable_images
14
+ from glob import glob
15
+
16
+
17
+ MODEL_PATH = "pankaj-munde/FScout_v0.2"
18
+ # image_dir = "./Data/images/"
19
+ detr_preprocessor = AutoImageProcessor.from_pretrained(MODEL_PATH)
20
+ detr_model = AutoModelForObjectDetection.from_pretrained(MODEL_PATH)
21
+ colors = [[236, 112, 99], [165, 105, 189], [ 225, 9, 232], [ 255, 38, 8 ], [ 247, 249, 249 ], [170, 183, 184 ], [ 247, 249, 249 ], [ 247, 249, 249 ]]
22
+
23
+
24
+ # images_lst = os.listdir(image_dir)
25
+ # images = []
26
+ # for file in images_lst:
27
+ # ipath = os.path.join(os.path.abspath(image_dir), file)
28
+ # with open(ipath, "rb") as image:
29
+ # encoded = base64.b64encode(image.read()).decode()
30
+ # images.append(f"data:image/jpeg;base64,{encoded}")
31
+
32
+
33
+
34
+ def get_detr_predictions(image, thresh):
35
+ with torch.no_grad():
36
+ inputs = detr_preprocessor(images=image, return_tensors="pt")
37
+ outputs = detr_model(**inputs)
38
+ target_sizes = torch.tensor([image.size[::-1]])
39
+ results = detr_preprocessor.post_process_object_detection(
40
+ outputs, threshold=float(thresh), target_sizes=target_sizes)[0]
41
+ return results
42
+
43
+
44
+ def add_label(img,
45
+ label,
46
+ bbox,
47
+ draw_bg=True,
48
+ text_bg_color=(255, 255, 255),
49
+ text_color=(0, 0, 0),
50
+ top=True):
51
+ """adds label, inside or outside the rectangle
52
+
53
+ Parameters
54
+ ----------
55
+ img : ndarray
56
+ the image on which the label is to be written, preferably the image with the rectangular bounding box drawn
57
+ label : str
58
+ the text (label) to be written
59
+ bbox : list
60
+ a list containing x_min, y_min, x_max and y_max of the rectangle positions
61
+ draw_bg : bool, optional
62
+ if True, draws the background of the text, else just the text is written, by default True
63
+ text_bg_color : tuple, optional
64
+ the background color of the label that is filled, by default (255, 255, 255)
65
+ text_color : tuple, optional
66
+ color of the text (label) to be written, by default (0, 0, 0)
67
+ top : bool, optional
68
+ if True, writes the label on top of the bounding box, else inside, by default True
69
+
70
+ Returns
71
+ -------
72
+ ndarray
73
+ the image with the label written
74
+ """
75
+
76
+ text_width = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 1, 2)[0][0]
77
+
78
+ if top:
79
+ label_bg = [bbox[0], bbox[1], bbox[0] + text_width, bbox[1] + 30]
80
+ if draw_bg:
81
+ cv2.rectangle(img, (label_bg[0], label_bg[1]),
82
+ (label_bg[2] + 5, label_bg[3]), text_bg_color, -1)
83
+ cv2.putText(img, label, (bbox[0] + 5, bbox[1] - 5),
84
+ cv2.FONT_HERSHEY_SIMPLEX, 1, text_color, 2)
85
+
86
+ else:
87
+ label_bg = [bbox[0], bbox[1], bbox[0] + text_width, bbox[1] + 30]
88
+ if draw_bg:
89
+ cv2.rectangle(img, (label_bg[0], label_bg[1]),
90
+ (label_bg[2] + 5, label_bg[3]), text_bg_color, -1)
91
+ cv2.putText(img, label, (bbox[0] + 5, bbox[1] - 5 + 30),
92
+ cv2.FONT_HERSHEY_SIMPLEX, 1, text_color, 2)
93
+
94
+ return img
95
+
96
+
97
+ def image_checkup_v4(ipath, thresh, show_count):
98
+
99
+ imgOrig = ipath.convert("RGB")
100
+ image = imgOrig.copy()
101
+
102
+ # crop_name, crop_conf, crop_id = get_crop(image)
103
+
104
+ detr_results = get_detr_predictions(image, thresh)
105
+
106
+ final_results = []
107
+ all_predictions = {
108
+ "Name": "Detailed View",
109
+ "Value": ""
110
+ }
111
+
112
+ # result_data = {crop_name: crop_conf, "Inspection_data": []}
113
+ img_with_box = np.array(image).copy()
114
+ for idx, label_id in enumerate(detr_results["labels"].numpy()):
115
+ pred_score = round(detr_results["scores"].numpy()[idx], 2)
116
+ predicted_label = detr_model.config.id2label[label_id]
117
+ # if float(pred_score) > 50:
118
+
119
+ bbox = list(np.array(detr_results["boxes"].numpy()[idx], dtype=int))
120
+ img_with_box = bbv.draw_rectangle(img_with_box, bbox, bbox_color=colors[label_id])
121
+ # img_with_box = bbv.add_label(img_with_box, label=f"{predicted_label} : {pred_score}", bbox=bbox, top=False)
122
+ if show_count:
123
+ img_with_box = bbv.add_label(
124
+ img_with_box, f"{idx + 1}", bbox, draw_bg=True, top=True)
125
+
126
+ else:
127
+ img_with_box = bbv.add_label(
128
+ img_with_box, f"", bbox, draw_bg=False, top=True)
129
+
130
+ final_results.append(
131
+ {"prediction": predicted_label,
132
+ "confidence": pred_score,
133
+ "color": colors[label_id]
134
+ }
135
+ )
136
+
137
+ all_predictions["Value"] += f"\n{idx + 1}. {predicted_label.split('_')[-1]} - {round(pred_score, 2)}%\n"
138
+ if len(final_results) > 0:
139
+ df = pd.DataFrame(final_results)
140
+ info = df["prediction"].value_counts()
141
+ resized_seg = cv2.resize(img_with_box, imgOrig.size)
142
+ new_res = []
143
+
144
+ for k, v in dict(info).items():
145
+ tmp = {}
146
+ prd_id = detr_model.config.label2id[k]
147
+ tmp["Insect"] = k
148
+ tmp["Count"] = v
149
+ tmp["Color"] = colors[int(prd_id)]
150
+ new_res.append(tmp)
151
+
152
+ return new_res, resized_seg
153
+
154
+ return [], img_with_box
155
+
156
+
157
+
158
+ st.set_page_config(layout="wide")
159
+
160
+
161
+
162
+ def add_logo(logo_path, width, height):
163
+ """Read and return a resized logo"""
164
+ logo = Image.open(logo_path)
165
+ # modified_logo = logo.resize((width, height))
166
+ return logo
167
+
168
+
169
+ # st.write("<hr/>", unsafe_allow_html=True)
170
+
171
+ with st.sidebar:
172
+ my_logo = add_logo(logo_path="./static/FarmGyan logo_1.png", width=50, height=60)
173
+
174
+ st.image(my_logo)
175
+
176
+ ucol, bcol = st.columns([3, 2])
177
+ # st.write("<hr/>", unsafe_allow_html=True)
178
+
179
+ st.title(":seedling: FarmGyan | Insects Scouting")
180
+ st.write("<hr/>", unsafe_allow_html=True)
181
+
182
+ st.write("## πŸ–– Upload image for prediction")
183
+
184
+ uploaded_file = st.file_uploader("Choose an image file", type=["jpg", "jpeg", "png"])
185
+ st.write("<hr/>", unsafe_allow_html=True)
186
+
187
+ with st.spinner(text='In progress'):
188
+ st.sidebar.write("## βš™οΈ Configurations")
189
+ st.sidebar.write("<hr/>", unsafe_allow_html=True)
190
+
191
+ st.sidebar.write("#### Prediction Threshold")
192
+ thresh = st.sidebar.slider("Threshold", 0.0, 1.0, 0.7, 0.1)
193
+ st.sidebar.write("#### Boxes Count")
194
+ show_count = st.sidebar.checkbox("Show Count")
195
+ if uploaded_file is not None:
196
+ clicked = None
197
+ image = Image.open(uploaded_file).convert("RGB")
198
+ predicted_data, result_image = image_checkup_v4(image, thresh, show_count)
199
+ # print(predicted_data)
200
+
201
+ col, col1 = st.columns([2, 4])
202
+ feedback_submitted = False # Initialize the flag
203
+ with col:
204
+ st.subheader("πŸ’― Predicted Labels")
205
+ st.write(f"<h3>Total Count : {sum([d['Count'] for d in predicted_data])}</h3>", unsafe_allow_html=True)
206
+ for i, d in enumerate(predicted_data):
207
+ # Create HTML markup with style information
208
+
209
+ html_string = f"""
210
+ <div style="display: flex; align-items: center;">
211
+ <b style="margin-right: 15px">{i + 1}. </b>
212
+ <div style="background-color: rgb({d["Color"][0]}, {d["Color"][1]}, {d["Color"][2]}); width: 20px; height: 20px; border: 1px solid black; margin-right: 10px;"></div>
213
+ <p style="margin-top: 15px"><b>{d["Insect"]} : {d["Count"]} </b></p>
214
+ </div>
215
+ """
216
+
217
+ st.markdown(html_string, unsafe_allow_html=True)
218
+
219
+ st.write("<hr/>", unsafe_allow_html=True)
220
+
221
+ with col1:
222
+ st.subheader("πŸ€ Predicted Image")
223
+ st.write("<br/>", unsafe_allow_html=True)
224
+
225
+ st.image(result_image)
226
+
227
+
228
+
requirements.txt ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ accelerate==0.25.0
2
+ albumentations==1.3.1
3
+ bbox-visualizer==0.1.0
4
+ bitsandbytes==0.41.0
5
+ datasets==2.14.7
6
+ extra-streamlit-components==0.1.60
7
+ huggingface-hub==0.20.1
8
+ Jinja2==3.1.2
9
+ matplotlib==3.7.2
10
+ opencv-python
11
+ openpyxl==3.1.2
12
+ pandas==2.0.3
13
+ Pillow==10.0.0
14
+ plotly==5.17.0
15
+ safetensors==0.3.1
16
+ scikit-image==0.22.0
17
+ scikit-learn==1.3.0
18
+ scipy==1.11.4
19
+ seaborn==0.12.2
20
+ SQLAlchemy==2.0.24
21
+ st-clickable-images==0.0.3
22
+ streamlit==1.29.0
23
+ streamlit-authenticator==0.2.3
24
+ streamlit-option-menu==0.3.6
25
+ timm==0.9.12
26
+ tokenizers==0.15.0
27
+ torch==2.0.1
28
+ torchvision==0.15.2
29
+ tqdm==4.65.0
30
+ transformers==4.36.1
static/FarmGyan logo_1.png ADDED