|
import cv2 |
|
import tempfile |
|
import gradio as gr |
|
from ultralytics import YOLO |
|
import pandas as pd |
|
import matplotlib.pyplot as plt |
|
|
|
|
|
label_mapping = { |
|
0: 'Hymenoptera', |
|
1: 'Mantodea', |
|
2: 'Odonata', |
|
3: 'Orthoptera', |
|
4: 'Coleoptera', |
|
5: 'Lepidoptera', |
|
6: 'Hemiptera' |
|
} |
|
|
|
def process_video(video_file): |
|
|
|
colors = [ |
|
(255, 0, 0), |
|
(50, 205, 50), |
|
(0, 0, 255), |
|
(255, 255, 0), |
|
(255, 0, 255), |
|
(255, 140, 0), |
|
(128, 0, 128), |
|
(0, 128, 128) |
|
] |
|
|
|
|
|
model = YOLO("insect_detection4.pt") |
|
|
|
|
|
cap = cv2.VideoCapture(video_file) |
|
|
|
|
|
columns = ["frame", "insect_id", "class", "x", "y", "w", "h"] |
|
df = pd.DataFrame(columns=columns) |
|
|
|
frame_id = 0 |
|
unique_insect_crops = {} |
|
|
|
|
|
while cap.isOpened(): |
|
|
|
success, frame = cap.read() |
|
|
|
if success: |
|
frame_id += 1 |
|
|
|
|
|
results = model.track(frame, persist=True, tracker="insect_tracker.yaml") |
|
|
|
for result in results: |
|
boxes = result.boxes.cpu().numpy() |
|
confidences = boxes.conf |
|
class_ids = boxes.cls |
|
|
|
for i, box in enumerate(boxes): |
|
class_id = int(class_ids[i]) |
|
confidence = confidences[i] |
|
insect_id = int(box.id[0]) |
|
|
|
|
|
new_row = pd.DataFrame({ |
|
"frame": [frame_id], |
|
"insect_id": [insect_id], |
|
"class": [class_id], |
|
"x": [box.xywh[0][0]], |
|
"y": [box.xywh[0][1]], |
|
"w": [box.xywh[0][2]], |
|
"h": [box.xywh[0][3]] |
|
}) |
|
df = pd.concat([df, new_row], ignore_index=True) |
|
|
|
|
|
if insect_id not in unique_insect_crops: |
|
x_center, y_center, width, height = box.xywh[0] |
|
x1 = int(x_center - width / 2) |
|
y1 = int(y_center - height / 2) |
|
x2 = int(x_center + width / 2) |
|
y2 = int(y_center + height / 2) |
|
insect_crop = frame[y1:y2, x1:x2] |
|
crop_path = tempfile.mktemp(suffix=".png") |
|
cv2.imwrite(crop_path, insect_crop) |
|
unique_insect_crops[insect_id] = (crop_path, label_mapping[class_id]) |
|
|
|
else: |
|
break |
|
|
|
|
|
cap.release() |
|
|
|
|
|
csv_path = tempfile.mktemp(suffix=".csv") |
|
df.to_csv(csv_path, index=False) |
|
|
|
|
|
df_from_csv = pd.read_csv(csv_path) |
|
|
|
|
|
plt.figure(figsize=(10, 6)) |
|
for insect_id in df_from_csv['insect_id'].unique(): |
|
frames = df_from_csv[df_from_csv['insect_id'] == insect_id]['frame'] |
|
insect_class = label_mapping[df_from_csv[df_from_csv['insect_id'] == insect_id]['class'].values[0]] |
|
plt.plot(frames, [insect_id] * len(frames), 'o-', label=f'{insect_class} {insect_id}') |
|
|
|
plt.xlabel('Frame') |
|
plt.ylabel('Insect ID') |
|
plt.title('Temporal distribution of insects') |
|
plt.legend() |
|
plt.grid(True) |
|
|
|
|
|
plot_path = tempfile.mktemp(suffix=".png") |
|
plt.savefig(plot_path) |
|
plt.close() |
|
|
|
gallery_items = [(crop_path, f'{label} {insect_id}') for insect_id, (crop_path, label) in unique_insect_crops.items()] |
|
|
|
return plot_path, gallery_items, csv_path |
|
|
|
|
|
example_video = "path_to_example_video.mp4" |
|
|
|
inputs = gr.Video(label="Input Insect Trap Video", value=example_video) |
|
outputs = [ |
|
gr.Image(label="Insect Detection Plot"), |
|
gr.Gallery(label="Unique Insect Crops"), |
|
gr.File(label="Download CSV") |
|
] |
|
|
|
gr.Interface(fn=process_video, inputs=inputs, outputs=outputs, examples=[example_video]).launch() |
|
|
|
|