Hey there, tech enthusiasts! Ever wondered how to measure the distance between objects using just your camera and some computer vision magic? Well, you’re in luck! Today, we’ll break down some nifty code that does just that. By the end of this post, you’ll be able to track and measure the distance between colored objects in real time. Let’s dive in!
Code
First things first, here’s the complete code we’ll be working with. Don’t worry if it looks overwhelming at first; we’ll break it down step-by-step.
import cv2
import numpy as np
import math
import cvzone
# Function to calculate distance between two points
def distance(x1, y1, x2, y2):
return math.sqrt((x1 - x2)**2 + (y1 - y2)**2)
path = "https://192.168.1.2:8080/video"
cap = cv2.VideoCapture(path)
while True:
ret, frame = cap.read()
# Convert the frame to HSV color space
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# Define the lower and upper range of green color
lower_green = np.array([40, 40, 40])
upper_green = np.array([80, 255, 255])
# Define the lower and upper range of red color
lower_red = np.array([0, 100, 100])
upper_red = np.array([10, 255, 255])
# Create a mask for green color
mask_green = cv2.inRange(hsv, lower_green, upper_green)
# Create a mask for black color
mask_red = cv2.inRange(hsv, lower_red, upper_red)
# Find the contours of green color
contours_green, _ = cv2.findContours(mask_green, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# Find the contours of black color
contours_red, _ = cv2.findContours(mask_red, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# put filled circle point on the center of the contour
g_point = None
r_point = None
for cnt in contours_green:
area = cv2.contourArea(cnt)
if area > 500:
x, y, _, _ = cv2.boundingRect(cnt)
g_point = (x, y)
cv2.circle(frame, (x, y), 20, (0, 255, 0), -1)
for cnt in contours_red:
area = cv2.contourArea(cnt)
if area > 500:
x, y, _, _ = cv2.boundingRect(cnt)
r_point = (x, y)
cv2.circle(frame, (x, y), 20, (0, 0, 255), -1)
# Calculate the distance between green and red color balls
if g_point and r_point:
dist = distance(g_point[0], g_point[1], r_point[0], r_point[1]) / 100
cv2.line(frame, g_point, r_point, (0, 0, 0), 3)
# put text at center of the line
center = ((g_point[0] + r_point[0]) // 2 - 100)
cv2.putText(frame, f"Distance: {round(dist, 2)}", (center, g_point[1]-25), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 3)
# Display the output
cv2.imshow("Output", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
Breaking Down the Code
Alright, let’s break it down into bite-sized pieces:
1. Importing Libraries
import cv2
import numpy as np
import math
import cvzone
Here, we import the necessary libraries. cv2
is for OpenCV, numpy
for numerical operations, math
for mathematical functions, and cvzone
for some handy OpenCV functions.
2. Defining the Distance Function
def distance(x1, y1, x2, y2):
return math.sqrt((x1 - x2)**2 + (y1 - y2)**2)
This function calculates the distance between two points using the Euclidean distance formula. It’s a basic math trick to measure the straight-line distance between two coordinates.
3. Setting Up the Video Capture
path = "https://192.168.1.2:8080/video"
cap = cv2.VideoCapture(path)
Here we are using our mobile phone camera to capture video. You can also setup it by using IP Webcam or Droid application from the app store.
4. The Main Loop
while True:
ret, frame = cap.read()
This loop runs continuously, reading frames from the video stream.
5. Converting to HSV
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
We convert the frame from BGR (default color space for OpenCV) to HSV (Hue, Saturation, Value) because it’s easier to filter colors in this space.
6. Defining Color Ranges
lower_green = np.array([40, 40, 40])
upper_green = np.array([80, 255, 255])
lower_red = np.array([0, 100, 100])
upper_red = np.array([10, 255, 255])
These ranges define the colors we want to track. Adjust these values to match the colors you’re tracking.
7. Creating Masks
mask_green = cv2.inRange(hsv, lower_green, upper_green)
mask_red = cv2.inRange(hsv, lower_red, upper_red)
Masks are created to isolate the green and red colors in the frame.
8. Finding Contours
contours_green, _ = cv2.findContours(mask_green, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours_red, _ = cv2.findContours(mask_red, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
We find contours (the outlines) of the green and red objects in the masks.
9. Drawing Circles and Calculating Distance
g_point = None
r_point = None
for cnt in contours_green:
area = cv2.contourArea(cnt)
if area > 500:
x, y, _, _ = cv2.boundingRect(cnt)
g_point = (x, y)
cv2.circle(frame, (x, y), 20, (0, 255, 0), -1)
for cnt in contours_red:
area = cv2.contourArea(cnt)
if area > 500:
x, y, _, _ = cv2.boundingRect(cnt)
r_point = (x, y)
cv2.circle(frame, (x, y), 20, (0, 0, 255), -1)
if g_point and r_point:
dist = distance(g_point[0], g_point[1], r_point[0], r_point[1]) / 100
cv2.line(frame, g_point, r_point, (0, 0, 0), 3)
center = ((g_point[0] + r_point[0]) // 2 - 100)
cv2.putText(frame, f"Distance: {round(dist, 2)}", (center, g_point[1]-25), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 3)
Here, we loop through the contours, find their centers, and draw filled circles at those points. If both green and red points are detected, we calculate the distance and draw a line between them, displaying the distance on the frame.
10. Displaying the Output
cv2.imshow("Output", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
Finally, we display the processed frame. The loop continues until you press ‘q’, then it releases the camera and closes all windows.
Conclusion
And there you have it! You’ve just learned how to measure the distance between objects using your camera and a bit of Python magic. This code is a fantastic starting point for more complex computer vision projects. Try tweaking the color ranges, or even add more colors to track multiple objects. Happy coding!
If you have any questions or need further clarification, feel free to drop a comment. Let’s keep the tech talk rolling!
Very interesting info!Perfect just what I was looking for!