SmitaMahajan commited on
Commit
e6f71a4
ยท
verified ยท
1 Parent(s): c18074f

Upload 3 files

Browse files
Files changed (3) hide show
  1. README.md +39 -12
  2. app.py +101 -0
  3. requirements.txt +4 -0
README.md CHANGED
@@ -1,12 +1,39 @@
1
- ---
2
- title: Model1 Object Distance Claculator
3
- emoji: ๐Ÿข
4
- colorFrom: green
5
- colorTo: gray
6
- sdk: gradio
7
- sdk_version: 5.35.0
8
- app_file: app.py
9
- pinned: false
10
- ---
11
-
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ๐Ÿ“ Real-World Object Distance Estimator
2
+
3
+ This app lets you measure **real-world distances** between any two objects in an image using:
4
+
5
+ - ๐Ÿง  YOLOv8 object detection
6
+ - ๐Ÿ“ Reference object with known size
7
+ - ๐Ÿงฎ Pixel and real-world (cm) distance calculation
8
+
9
+ ---
10
+
11
+ ## ๐Ÿ–ผ๏ธ How to Use
12
+
13
+ 1. **Upload** a real-world image (e.g., photo taken with your phone)
14
+ 2. **Enter the real-world width** of a known object (e.g., "TV = 100 cm")
15
+ 3. Click **Detect & Get Object List**
16
+ 4. Use the indexes to:
17
+ - Select the **reference object**
18
+ - Select the **two target objects** you want to measure
19
+ 5. Click **Calculate Distance**
20
+
21
+ ---
22
+
23
+ ## ๐Ÿ› ๏ธ Powered By
24
+
25
+ - [Ultralytics YOLOv8](https://github.com/ultralytics/ultralytics)
26
+ - [Gradio](https://gradio.app/)
27
+ - OpenCV & NumPy
28
+
29
+ ---
30
+
31
+ ## ๐Ÿ’ก Coming Soon
32
+
33
+ - Monocular depth estimation (MiDaS)
34
+ - Open-vocabulary object selection
35
+ - Automatic reference detection
36
+
37
+ ---
38
+
39
+ Try it out and let us know your feedback!
app.py ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app.py
2
+
3
+ from ultralytics import YOLO
4
+ import gradio as gr
5
+ import cv2
6
+ import numpy as np
7
+ from math import sqrt
8
+
9
+ # Load YOLOv8 model
10
+ model = YOLO("yolov8n.pt")
11
+
12
+ def get_center(bbox):
13
+ x1, y1, x2, y2 = bbox
14
+ return ((x1 + x2) / 2, (y1 + y2) / 2)
15
+
16
+ def calculate_distance(image, ref_index, ref_width_cm, obj1_index, obj2_index):
17
+ results = model.predict(image, verbose=False)
18
+ detections = results[0].boxes
19
+ class_names = model.names
20
+
21
+ if not detections:
22
+ return image, "No objects detected"
23
+
24
+ # Parse detected objects
25
+ objects = []
26
+ for box in detections:
27
+ cls_id = int(box.cls[0])
28
+ class_name = class_names[cls_id]
29
+ bbox = box.xyxy[0].tolist() # x1, y1, x2, y2
30
+ objects.append((class_name, bbox))
31
+
32
+ # Error handling
33
+ if ref_index >= len(objects) or obj1_index >= len(objects) or obj2_index >= len(objects):
34
+ return image, "Invalid object index selection"
35
+
36
+ # Reference object
37
+ _, ref_bbox = objects[ref_index]
38
+ ref_pixel_width = abs(ref_bbox[2] - ref_bbox[0])
39
+ pixels_per_cm = ref_pixel_width / ref_width_cm
40
+
41
+ # Target objects
42
+ name1, bbox1 = objects[obj1_index]
43
+ name2, bbox2 = objects[obj2_index]
44
+ center1 = get_center(bbox1)
45
+ center2 = get_center(bbox2)
46
+
47
+ # Pixel and real-world distances
48
+ pixel_distance = sqrt((center1[0] - center2[0])**2 + (center1[1] - center2[1])**2)
49
+ real_distance = pixel_distance / pixels_per_cm
50
+
51
+ # Annotate image
52
+ annotated = results[0].plot()
53
+
54
+ # Draw line between objects
55
+ cv2.line(annotated, (int(center1[0]), int(center1[1])), (int(center2[0]), int(center2[1])), (0, 255, 0), 2)
56
+ cv2.putText(annotated, f"{real_distance:.2f} cm", (int((center1[0] + center2[0]) / 2), int((center1[1] + center2[1]) / 2) - 10),
57
+ cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
58
+
59
+ # Convert to RGB for display
60
+ annotated_rgb = cv2.cvtColor(annotated, cv2.COLOR_BGR2RGB)
61
+
62
+ info = f"Pixel Distance: {pixel_distance:.2f}px\nReal-World Distance: {real_distance:.2f} cm"
63
+ return annotated_rgb, info
64
+
65
+ # Gradio Interface
66
+ def get_object_list(image):
67
+ results = model.predict(image, verbose=False)
68
+ detections = results[0].boxes
69
+ class_names = model.names
70
+
71
+ if not detections:
72
+ return []
73
+
74
+ return [model.names[int(box.cls[0])] for box in detections]
75
+
76
+ with gr.Blocks() as demo:
77
+ gr.Markdown("## ๐Ÿ“ Object Distance Estimator (YOLOv8 + Reference Object)")
78
+
79
+ with gr.Row():
80
+ with gr.Column():
81
+ image_input = gr.Image(type="numpy", label="Upload Image")
82
+ ref_width = gr.Number(label="Reference Object Width (cm)", value=30)
83
+ detect_btn = gr.Button("Detect & Get Object List")
84
+
85
+ object_list = gr.Textbox(label="Detected Objects (index: name)", interactive=False)
86
+
87
+ ref_index = gr.Number(label="Reference Object Index", value=0)
88
+ obj1_index = gr.Number(label="Object 1 Index", value=1)
89
+ obj2_index = gr.Number(label="Object 2 Index", value=2)
90
+ calculate_btn = gr.Button("Calculate Distance")
91
+
92
+ with gr.Column():
93
+ output_image = gr.Image(label="Annotated Image")
94
+ output_text = gr.Textbox(label="Distance Info")
95
+
96
+ detect_btn.click(fn=get_object_list, inputs=image_input, outputs=object_list)
97
+ calculate_btn.click(fn=calculate_distance,
98
+ inputs=[image_input, ref_index, ref_width, obj1_index, obj2_index],
99
+ outputs=[output_image, output_text])
100
+
101
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ ultralytics>=8.0.20
2
+ gradio>=4.16
3
+ opencv-python
4
+ numpy