Color Tracking (OpenCv + Python + Arduino)

This project will show how to detect figures and colors with Arduino and Python (OpenCV) and make the camera follow the figure with the color that must be previously segmented.





Hardware Requirement :

Software Requirement :



  • Installing 'pyserial' , 'OpenCV" and "numpy" in python :
  • To install these modules we will use use pip install
  • First open CMD and type the following codes
>pip install serial
>pip install opencv-python
>pip install numpy


Python Script

###################################
# Requirements
# pip install PySerial
# pip install opencv-python
###################################
# Import the module for access to the serial port
import serial
# Import the module for time-related functions
import time
# Importe the Opencv module
import cv2
# Imprt numpy to segment the image
import numpy as np
# Create te connection to arduino by serial port
arduino = serial.Serial('COM5', 9600)
# Wait two seconds for the connection to be made
time.sleep(2)
print("Connected to arduino...")
# Capture the video from the camera
video = cv2.VideoCapture(0)
# Create the windows that containsla TrackBars
# cv2.namedWindow('Trackbars')
# cv2.createTrackbar('hmin', 'Trackbars', 0, 179, lambda x:x)
# cv2.createTrackbar('smin', 'Trackbars', 0, 255, lambda x:x)
# cv2.createTrackbar('vmin', 'Trackbars', 0, 255, lambda x:x)
# cv2.createTrackbar('hmax', 'Trackbars', 0, 179, lambda x:x)
# cv2.createTrackbar('smax', 'Trackbars', 0, 255, lambda x:x)
# cv2.createTrackbar('vmax', 'Trackbars', 0, 255, lambda x:x)
while(True):
# Read the video and save in a frame
_, frame = video.read()
# Extract the center of the frame an save the ccordenates
(h, w) = frame.shape[:2]
centrox = w//2
centroy = h//2
# Changing Colorspaces to HSV
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# Insert a circle un the certer of the frame
cv2.circle(frame, (centrox, centroy), 7, (255, 255, 255), -1)
# Trackbars to segment the frame
# hmin = cv2.getTrackbarPos('hmin', 'Trackbars')
# smin = cv2.getTrackbarPos('smin', 'Trackbars')
# vmin = cv2.getTrackbarPos('vmin', 'Trackbars')
# hmax = cv2.getTrackbarPos('hmax', 'Trackbars')
# smax = cv2.getTrackbarPos('smax', 'Trackbars')
# vmax = cv2.getTrackbarPos('vmax', 'Trackbars')
# lower_blue = np.array([hmin, smin, vmin])
# upper_blue = np.array([hmax, smax, vmax])
# Create array tah conthen the the hsm max and min values
lower_blue = np.array([22, 109, 145])
upper_blue = np.array([75, 183, 196])
# Segment the image
segmentacion = cv2.inRange(hsv, lower_blue, upper_blue)
# Get the moments
momentos = cv2.moments(segmentacion)
if(momentos['m00'] != 0):
# Determinate the center that semented shape
cx = int(momentos['m10'] / momentos['m00'])
cy = int(momentos['m01'] / momentos['m00'])
# Create the data that contains the corrdenates X an Y center
data = "X{0:d}Y{1:d}Z".format(cx, cy)
print ("Coordenadas = '" +data+ "'")
# Sen the Data to Aurduino
arduino.write(str.encode(data))
# Show The frames
cv2.imshow('Frame', frame)
cv2.imshow('Segmentacion', segmentacion)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
video.release()
# Close all windows
cv2.destroyAllWindows()
# Clos the cominication serial
arduino.close()


Arduino Script:

// Import the servo Library
#include <Servo.h>

// Create the Vertical Servo variable
Servo servoVer;
// Create the Horizontal Servo variable
Servo servoHor; 

// Coordenates x and y 
int x;
int y;

// Previos coordenates x and y
int prevX;
int prevY;

void setup()
{
  Serial.begin(9600);
  // Attach Vertical Servo to Pin 5
  servoVer.attach(5);
  // Attach Horizontal Servo to Pin 6
  servoHor.attach(6);
  // Start the servos in position 90
  servoVer.write(90);
  servoHor.write(90);
}

// Method to move the servos
void Pos()
{
  // Verify the possition
  if(prevX != x || prevY != y)
  {
    // map a number from one range to another
    int servoX = map(x, 640, 0, 70, 179);
    int servoY = map(y, 480, 0, 179, 95);

    // Calculates the minimum of two numbers in X
    servoX = min(servoX, 179);
    // Calculates the maximum of two numbers in X
    servoX = max(servoX, 70);
    // Calculates the minimum of two numbers in Y
    servoY = min(servoY, 179);
    // Calculates the maximum of two numbers in Y
    servoY = max(servoY, 95);

    // Move the servos
    servoHor.write(servoX);
    servoVer.write(servoY);
  }
}

void loop()
{
  // Verify that the serias is aviable
  if(Serial.available() > 0)
  {
    // Read the xoordenates in X
    if(Serial.read() == 'X')
    {
      x = Serial.parseInt();
      // Read the xoordenates in Y
      if(Serial.read() == 'Y')
      {
        y = Serial.parseInt();
        // Call the method tho move the servos
        Pos();
      }
    }
    while(Serial.available() > 0)
    {
      Serial.read();
    }
  }
}

Comentarios