import time
import cv2
import threading
import requests
from ultralytics import YOLO
# Constant
VIDEO_FRAMES_TO_SKIP = 10 # the no. of frames we skip for each frame we will process
VIRTUAL_SENSOR_IP_ADDRESS = "192.168.0.135"
VIDEO_URL_USERNAME = "admin"
VIDEO_URL_PASSWORD = "admin"
VIDEO_STREAM_URL = f"http://{VIDEO_URL_USERNAME}:{VIDEO_URL_PASSWORD}@192.168.0.229:8081/video"
# Global variables for communication between threads
lock = threading.Lock()
obj_location = None
# Function to send an HTTP request with the location of the detected object
def send_request():
global obj_location
while True:
with lock:
x_percent = 0
y_percent = 0
w_percent = 0
h_percent = 0
if obj_location is not None:
x_percent, y_percent, w_percent, h_percent = obj_location
url = f"http://{VIRTUAL_SENSOR_IP_ADDRESS}/set?t=c&r={round(x_percent * 1024 / 100)}&g={round(w_percent * 1024 / 100)}&b={round(h_percent * 1024 / 100)}"
#print(f"Sending request to {url}")
requests.get(url)
obj_location = None
time.sleep(0.5)
# Load the pre-trained YOLOv8 model
model = YOLO("yolov8n.pt")
# Open a video capture object
cap = cv2.VideoCapture(0)
#cap = cv2.VideoCapture(VIDEO_STREAM_URL)
# Start the secondary thread to send HTTP requests
thread = threading.Thread(target=send_request)
thread.daemon = True
thread.start()
frameCount = 0
while True:
# Read a frame from the video capture
ret, frame = cap.read()
if not ret:
break
frameCount = frameCount + 1
if (frameCount % VIDEO_FRAMES_TO_SKIP) != 0:
#print( f"{frameCount} Skip" )
continue
(h,w) = frame.shape[:2]
frameCount = 0
# Flip the image so that it will display as a mirror image
flipped_frame = cv2.flip(frame, 1)
# Perform object detection
results = model.predict(flipped_frame)
# Iterate over the detected objects and draw the text on the bounding box
for box in results[0].boxes:
# Get the class label and confidence score
classification_index = box.cls
class_label = model.names[ int(classification_index) ]
confidence = box.conf[0]
# Draw the bounding box on the frame
obj = box.xyxy[0]
#if class_label=="bottle" and confidence > 0.5:
if confidence > 0.5:
cv2.rectangle(flipped_frame, (int(obj[0]), int(obj[1])), (int(obj[2]), int(obj[3])), (0, 255, 0), 2)
# calculate center_x, center_y
obj_center = (int((obj[0] + obj[2]) / 2), int((obj[1] + obj[3]) / 2))
obj_size = (int(obj[2] - obj[0]), int(obj[3] - obj[1]))
x_loc_percent = int((obj_center[0] / w) * 100)
y_loc_percent = int((obj_center[1] / h) * 100)
w_percent = int((obj_size[0] / h) * 100 ) # note that this is normalized as a % of the frame's height
h_percent = int((obj_size[1] / h) * 100 )
#print(x_loc_percent, y_loc_percent, w_percent, h_percent)
with lock:
obj_location = (x_loc_percent, y_loc_percent, w_percent, h_percent)
# Draw the text on the bounding box
text = f"{class_label}: {confidence:.2f}"
cv2.putText(flipped_frame, text, (int(obj[0]), int(obj[1]) - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
cv2.putText(flipped_frame, f"({w_percent}%, {h_percent}%) @ ({x_loc_percent}%, {y_loc_percent}%)", (int(obj[0]), int(obj[1]) - 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
# Show the output frame
cv2.imshow("Frame", flipped_frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# Release the video capture object and close all windows
cap.release()
cv2.destroyAllWindows()