| import cv2 |
| import tempfile |
| import gradio as gr |
| from ultralytics import YOLO |
| import pandas as pd |
| import plotly.graph_objects as go |
| import numpy as np |
|
|
| |
| label_mapping = { |
| 0: 'Hymenoptera', |
| 1: 'Mantodea', |
| 2: 'Odonata', |
| 3: 'Orthoptera', |
| 4: 'Coleoptera', |
| 5: 'Lepidoptera', |
| 6: 'Hemiptera' |
| } |
|
|
| def process_video(video_file): |
| |
| 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]) if box.id is not None else -1 |
|
|
| |
| 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) |
|
|
| |
| fig = go.Figure() |
|
|
| for insect_id, group in df_from_csv.groupby('insect_id'): |
| class_name = label_mapping[group.iloc[0]['class']] |
| color = 'rgb({}, {}, {})'.format(*np.random.randint(0, 256, 3)) |
| hover_text = group.apply(lambda row: f'Insect ID: {int(row["insect_id"])}, Class: {class_name}, Frame: {int(row["frame"])}', axis=1) |
| fig.add_trace(go.Scatter(x=group['frame'], y=group['insect_id'], mode='markers', marker=dict(color=color), name=f'{class_name} {insect_id}', |
| hoverinfo='text', hovertext=hover_text)) |
|
|
| fig.update_layout(title='Temporal distribution of insects', |
| xaxis_title='Frame', |
| yaxis_title='Insect ID', |
| hovermode='closest') |
|
|
| gallery_items = [(crop_path, f'{label} {insect_id}') for insect_id, (crop_path, label) in unique_insect_crops.items()] |
|
|
| return fig, gallery_items, csv_path |
|
|
| |
| example_video = "insect_trap_video_example.mp4" |
|
|
| inputs = gr.Video(label="Input Insect Trap Video", value=example_video) |
| outputs = [ |
| gr.Plot(label="Insect Detection Plot"), |
| gr.Gallery(label="Insect Gallery"), |
| gr.File(label="Download CSV") |
| ] |
|
|
| description = """ |
| Uncover the Secret Lives of Insects! ππ¦π·οΈ |
| |
| Upload your video now to track, visualize, and explore insect activity with our cutting-edge detection tool. You can get started with the example video. |
| """ |
|
|
| gr.Interface(fn=process_video, inputs=inputs, outputs=outputs, title= 'InsectSpy π΅οΈββοΈπ¦', description=description, examples=[example_video]).launch() |
|
|
|
|
|
|