Using camera on a simulated drone Sphinx

Hi,

I am trying to implement object detection using simulated drone in Sphinx. Is it possible to use camera on a simulated drone? Ive attached my script but I am not sure how to configure the camera.

import olympe
import os
import cv2
import numpy as np
import time
from olympe.messages.ardrone3.Piloting import TakeOff, Landing, moveBy

DRONE_IP = os.environ.get(“DRONE_IP”, “10.202.0.1”)

def test_camera():
“”"
Check if the simulated drone camera is working by displaying the video feed.
“”"
# Open the simulated drone camera
cap = cv2.VideoCapture(“rtsp://192.168.42.1/live”)

if not cap.isOpened():
    print("Error: Simulated drone camera not working or not detected!")
    return False

print("Press 'q' to quit the camera test.")

while True:
    ret, frame = cap.read()
    if not ret:
        print("Error: Could not read frame from simulated drone camera!")
        break

    cv2.imshow("Simulated Drone Camera Test", frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()
return True

def detect_red_ball(frame):
“”"
Detects a red ball in the given frame and returns its position and radius.
“”"
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

# Adjusted HSV values for better detection
lower_red1 = np.array([0, 100, 50])
upper_red1 = np.array([10, 255, 255])
lower_red2 = np.array([160, 100, 50])
upper_red2 = np.array([180, 255, 255])

# Create masks for red color
mask1 = cv2.inRange(hsv, lower_red1, upper_red1)
mask2 = cv2.inRange(hsv, lower_red2, upper_red2)
mask = mask1 + mask2

# Clean up the mask
kernel = np.ones((5, 5), np.uint8)
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)

# Debugging: Visualize the mask
cv2.imshow("Red Mask", mask)

# Find contours
contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

for contour in contours:
    # Debugging: Display contour information
    area = cv2.contourArea(contour)
    (x, y), radius = cv2.minEnclosingCircle(contour)
    print(f"Contour Area: {area}, Radius: {radius}")
    if radius > 3:  # Reduced threshold for smaller objects
        print("Lada is detected")
        return int(x), int(y), radius

return None, None, None

def approach_red_ball(drone):
“”"
Moves the drone closer to a detected red ball.
“”"
cap = cv2.VideoCapture(“rtsp://192.168.42.1/live”) # Use the simulated drone camera
kp = 0.002 # Proportional control factor

while True:
    ret, frame = cap.read()
    if not ret:
        break

    # Detect the red ball
    x, y, radius = detect_red_ball(frame)
    frame_height, frame_width, _ = frame.shape

    if x is None or y is None:
        # Move forward slightly to get closer to the ball if not detected
        drone(moveBy(0.5, 0.0, 0.0, 0.0)).wait()
        continue

    # Calculate movement commands based on ball position
    vx = kp * (frame_width / 2 - x)  # Horizontal movement
    vz = kp * (frame_height / 2 - y)  # Vertical movement
    vy = 0.1  # Forward movement towards the ball

    # Check if the drone is close enough to the ball
    if radius >= 50:  # Threshold for proximity to the ball
        print("Close enough to the ball. Landing...")
        drone(Landing()).wait().success()
        break

    # Send movement commands to the drone
    drone(moveBy(vy, -vx, -vz, 0.0)).wait()

    # Visualize the detection
    cv2.circle(frame, (x, y), int(radius), (0, 255, 0), 2)
    cv2.circle(frame, (x, y), 2, (255, 0, 0), 3)
    cv2.putText(frame, "Red Ball", (x - 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)

    # Show the video feed
    cv2.imshow("Red Ball Detection", frame)

    # Exit the loop if 'q' is pressed
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

def test_takeoff():
drone = olympe.Drone(DRONE_IP)
drone.connect()

# Take off
assert drone(TakeOff()).wait().success()
time.sleep(5)

# Approach the red ball
try:
    approach_red_ball(drone)
except KeyboardInterrupt:
    print("Interrupted by user.")

# Land
assert drone(Landing()).wait().success()
drone.disconnect()

if name == “main”:
# Test the simulated drone camera first
if not test_camera():
print(“Exiting due to simulated drone camera issue.”)
else:
test_takeoff()

please, i would appreciate any help

Hello,

Sorry for the late reply.

With Sphinx, you can also use Olympe to capture video streaming. You can find detailed guidance here: Capture the video streaming and its metadata - 7.7
For your specific case, setting up the raw callback (raw_cb) should suffice.

Use this code to transform the YUV frame into an RGB frame:

cv2_cvt_color_flag = {
    olympe.VDEF_I420: cv2.COLOR_YUV2BGR_I420,
    olympe.VDEF_NV12: cv2.COLOR_YUV2BGR_NV12,
}[yuv_frame.format()]

Additionally, you can explore more examples here: olympe/src/olympe/doc/examples at master · Parrot-Developers/olympe · GitHub
rgb_frame = cv2.cvtColor(yuv_frame.as_ndarray(), cv2_cvt_color_flag)