omarash2016 commited on
Commit
b14f4c6
·
verified ·
1 Parent(s): 134c62f

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +127 -0
  2. labels.txt +81 -0
app.py ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, HTTPException
2
+ from fastapi.responses import StreamingResponse, JSONResponse
3
+ from io import BytesIO
4
+ from PIL import Image
5
+ import cv2
6
+ import supervision as sv
7
+ from inference import get_model
8
+
9
+ app = FastAPI()
10
+
11
+ # Load the pre-trained model once when the server starts
12
+ model = get_model(model_id="yolov11n-640")
13
+
14
+ def gen_frames():
15
+ # Open the default camera (index 0)
16
+ cap = cv2.VideoCapture(0)
17
+ if not cap.isOpened():
18
+ raise HTTPException(status_code=500, detail="Could not open video device")
19
+
20
+ while True:
21
+ success, frame = cap.read()
22
+ if not success:
23
+ break
24
+
25
+ # Convert the frame from BGR (OpenCV default) to RGB
26
+ frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
27
+ # Convert the numpy array to a PIL Image
28
+ pil_img = Image.fromarray(frame_rgb)
29
+
30
+ # Run inference on the current frame (model.infer returns a list, so we take the first element)
31
+ try:
32
+ results = model.infer(pil_img)[0]
33
+ except Exception as e:
34
+ # If inference fails, skip this frame
35
+ print(f"Inference error: {e}")
36
+ continue
37
+
38
+ # Convert inference results to a Supervision detections object
39
+ detections = sv.Detections.from_inference(results)
40
+
41
+ # Create annotators for bounding boxes and labels
42
+ bounding_box_annotator = sv.BoxAnnotator()
43
+ label_annotator = sv.LabelAnnotator()
44
+
45
+ # Annotate the frame with bounding boxes and labels
46
+ annotated_image = bounding_box_annotator.annotate(scene=pil_img, detections=detections)
47
+ annotated_image = label_annotator.annotate(scene=annotated_image, detections=detections)
48
+
49
+ # Save the annotated image to an in-memory buffer in JPEG format
50
+ buf = BytesIO()
51
+ annotated_image.save(buf, format="JPEG")
52
+ buf.seek(0)
53
+ frame_bytes = buf.read()
54
+
55
+ # Yield the frame in MJPEG format
56
+ yield (b'--frame\r\n'
57
+ b'Content-Type: image/jpeg\r\n\r\n' + frame_bytes + b'\r\n')
58
+
59
+ # Release the camera when the loop ends
60
+ cap.release()
61
+
62
+ @app.get("/live_feed")
63
+ async def live_feed():
64
+ """
65
+ Streams a live feed from the camera with inference annotations.
66
+ Access via: http://localhost:8000/live_feed
67
+ """
68
+ return StreamingResponse(
69
+ gen_frames(),
70
+ media_type="multipart/x-mixed-replace; boundary=frame"
71
+ )
72
+
73
+ @app.get("/detect_classes")
74
+ async def detect_classes():
75
+ """
76
+ Detects and returns the labels of the detected classes in the current camera frame as JSON.
77
+ Updates every 30 frames.
78
+ Access via: http://localhost:8000/detect_classes
79
+ """
80
+ # Open the default camera (index 0)
81
+ cap = cv2.VideoCapture(0)
82
+ if not cap.isOpened():
83
+ raise HTTPException(status_code=500, detail="Could not open video device")
84
+
85
+ frame_count = 0
86
+ all_class_ids = []
87
+
88
+ while frame_count < 3:
89
+ success, frame = cap.read()
90
+ if not success:
91
+ cap.release()
92
+ raise HTTPException(status_code=500, detail="Failed to read frame from camera")
93
+
94
+ # Convert the frame from BGR (OpenCV default) to RGB
95
+ frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
96
+ # Convert the numpy array to a PIL Image
97
+ pil_img = Image.fromarray(frame_rgb)
98
+
99
+ # Run inference on the current frame (model.infer returns a list, so we take the first element)
100
+ try:
101
+ results = model.infer(pil_img)[0]
102
+ except Exception as e:
103
+ print(f"Inference error: {e}")
104
+ continue
105
+
106
+ # Convert inference results to a Supervision detections object
107
+ detections = sv.Detections.from_inference(results)
108
+
109
+ # Collect class IDs from the current frame
110
+ if detections.class_id is not None:
111
+ all_class_ids.extend(detections.class_id.tolist())
112
+
113
+ frame_count += 1
114
+
115
+ # Release the camera
116
+ cap.release()
117
+
118
+ # Extract unique detected class labels from all collected class IDs
119
+ unique_class_ids = set(all_class_ids)
120
+ class_labels = [model.class_names[class_id] for class_id in unique_class_ids]
121
+
122
+ # Return the detected class labels as JSON
123
+ return JSONResponse(content={"detected_classes": class_labels})
124
+
125
+ if __name__ == "__main__":
126
+ import uvicorn
127
+ uvicorn.run(app, host="0.0.0.0", port=8000)
labels.txt ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ person
2
+ bicycle
3
+ car
4
+ motorcycle
5
+ airplane
6
+ bus
7
+ train
8
+ truck
9
+ boat
10
+ traffic light
11
+ fire hydrant
12
+ stop sign
13
+ parking meter
14
+ bench
15
+ bird
16
+ cat
17
+ dog
18
+ horse
19
+ sheep
20
+ cow
21
+ elephant
22
+ bear
23
+ zebra
24
+ giraffe
25
+ backpack
26
+ umbrella
27
+ handbag
28
+ tie
29
+ suitcase
30
+ frisbee
31
+ skis
32
+ snowboard
33
+ sports ball
34
+ kite
35
+ baseball bat
36
+ baseball glove
37
+ skateboard
38
+ surfboard
39
+ tennis racket
40
+ bottle
41
+ wine glass
42
+ cup
43
+ fork
44
+ knife
45
+ spoon
46
+ bowl
47
+ banana
48
+ apple
49
+ sandwich
50
+ orange
51
+ broccoli
52
+ carrot
53
+ hot dog
54
+ pizza
55
+ donut
56
+ cake
57
+ chair
58
+ couch
59
+ potted plant
60
+ bed
61
+ dining table
62
+ toilet
63
+ tv
64
+ laptop
65
+ mouse
66
+ remote
67
+ keyboard
68
+ cell phone
69
+ microwave
70
+ oven
71
+ toaster
72
+ sink
73
+ refrigerator
74
+ book
75
+ clock
76
+ vase
77
+ scissors
78
+ teddy bear
79
+ hair drier
80
+ toothbrush
81
+