Coding4Fun Drone posts
- Introduction to DJI Tello
- Analyzing Python samples code from the official SDK
- Drone Hello World ! Takeoff and land
- Tips to connect to Drone WiFi in Windows 10
- Reading data from the Drone, Get battery level
- Sample for real time data read, Get Accelerometer data
- How the drone camera video feed works, using FFMPEG to display the feed
- Open the drone camera video feed using OpenCV
- Performance and OpenCV, measuring FPS
- Detect faces using the drone camera
- Detect a banana and land!
- Flip when a face is detected!
- How to connect to Internet and to the drone at the same time
- Video with real time demo using the drone, Python and Visual Studio Code
- Using custom vision to analyze drone camera images
- Drawing frames for detected objects in real-time in the drone camera feed
- Save detected objects to local files, images and JSON results
- Save the Drone camera feed into a local video file
- Overlay images into the Drone camera feed using OpenCV
- Instance Segmentation from the Drone Camera using OpenCV, TensorFlow and PixelLib
- Create a 3×3 grid on the camera frame to detect objects and calculate positions in the grid
- Create an Azure IoT Central Device Template to work with drone information
- Create a Drone Device for Azure IoT Central
- Send drone information to Azure IoT Central
In my post series I already wrote about how to detect faces. We can do this with a camera and OpenCV. However, a drone can also be moved on command, so let’s write some lines to detect a face, and calculate the orientation and distance of the detected face from the center camera of the camera.
In order to do this, 1st let’s draw a grid in the camera frame, and once a face is detected, let’s show the distance and orientation from the center.
Let’s start with a Grid. The idea is to create a 3×3 grid in the camera frame, and use the center cell as reference for the detected objects. The code to create a 3×3 grid is this one:
def displayGrid(frame): # Add a 3x3 Grid cv2.line(frame, (int(camera_Width/2)-centerZone, 0) , (int(camera_Width/2)-centerZone, camera_Heigth) , lineColor, lineThickness) cv2.line(frame, (int(camera_Width/2)+centerZone, 0) , (int(camera_Width/2)+centerZone, camera_Heigth) , lineColor, lineThickness) cv2.line(frame, (0, int(camera_Heigth / 2) - centerZone), (camera_Width, int(camera_Heigth / 2) - centerZone), lineColor, lineThickness) cv2.line(frame, (0, int(camera_Heigth / 2) + centerZone), (camera_Width, int(camera_Heigth / 2) + centerZone), lineColor, lineThickness) # Camera Settings camera_Width = 1024 # 1280 # 640 camera_Heigth = 780 # 960 # 480 centerZone = 100 # GridLine color green and thickness lineColor = (0, 255, 0) lineThickness = 2
We use the line() function on OpenCV, and do some calculations to get the starting and endpoint for the 4 lines for the grid: 2 vertical lines and 2 horizontal lines. For this demo, I’ll implement this in my main webcam.
Based on my face detection samples and other samples in GitHub (see references), now I’ll calculate the position of the detected face (with x, y, h, w) from the center of the camera:
def calculatePositionForDetectedFace(frame, x, y, h , w): # calculate direction and relative position of the face cx = int(x + (w / 2)) # Center X of the Face cy = int(y + (h / 2)) # Center Y of the Face if (cx <int(camera_Width/2) - centerZone): cv2.putText (frame, " LEFT " , (20, 50), cv2.FONT_HERSHEY_COMPLEX, 1 , colorGreen, 2) dir = 1 elif (cx > int(camera_Width / 2) + centerZone): cv2.putText(frame, " RIGHT ", (20, 50), cv2.FONT_HERSHEY_COMPLEX,1,colorGreen, 3) dir = 2 elif (cy < int(camera_Heigth / 2) - centerZone): cv2.putText(frame, " UP ", (20, 50), cv2.FONT_HERSHEY_COMPLEX,1,colorGreen, 3) dir = 3 elif (cy > int(camera_Heigth / 2) + centerZone): cv2.putText(frame, " DOWN ", (20, 50), cv2.FONT_HERSHEY_COMPLEX, 1,colorGreen, 3) dir = 4 else: dir=0 # display detected face frame, line from center and direction to go cv2.line (frame, (int(camera_Width/2),int(camera_Heigth/2)), (cx,cy), colorRed, messageThickness) cv2.rectangle(frame, (x, y), (x + w, y + h), colorBlue, messageThickness) cv2.putText (frame, str(int(x)) + " " + str(int(y)), (x - 20, y - 45), cv2.FONT_HERSHEY_COMPLEX,0.7, colorRed, messageThickness)
The output is similar to this one
And now with the base code completed, it’s time to add this logic to the drone samples !
Bonus: the complete code.
- How To Install OpenCV Win/Mac  | OpenCV Python Tutorials for Beginners 2020 https://www.youtube.com/watch?v=vDOkUHNdmKs