Hello Everyone,
I am new to arduino coding and I am trying to detect an object based on its color using python script and arduino script. I am using python 3.7 and arduino uno board. My problem is whenever the object appears infront of the camera the servos start to misbehave and start moving in random direction. please help me out here:
Python script:
import serial
import time
import cv2
import numpy as np
color = input("Input Color: yellow, blue, red, green: ")
# cap = cv2.VideoCapture(0)
cap = cv2.VideoCapture(0)
ser = serial.Serial("COM4", 9600, timeout=2) #data transfer to ardiuno through port
# ser.open()
posX = 90
posY = 90
while True:
_, frame = cap.read()
frame = cv2.flip(frame, 1)
hsv_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
#color range
if color == 'red':
low = np.array([161,155,84])
high = np.array([179,255,255])
#low_red = np.array([161,155,84])
#high_red = np.array([179,255,255])
elif color == 'blue':
low = np.array([38, 86, 0])
high = np.array([121, 255, 255])
elif color == 'yellow':
low = np.array([0, 116, 125])
high = np.array([225, 255, 255])
elif color == 'green':
low = np.array([44,32,0])
high = np.array([107, 185, 246])
red_mask = cv2.inRange(hsv_frame, low, high)
contours, _ = cv2.findContours(red_mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours = sorted(contours, key = lambda x: cv2.contourArea(x), reverse = True)
rows, cols, _ = frame.shape
print(rows, cols)
x_center = int(rows/2)
y_center = int(cols/2)
for cnt in contours:
(x, y, w, h) = cv2.boundingRect(cnt)
cv2.rectangle(frame, (x,y), (x+w,y+h), (0,255,0), 2)
x_medium = int((x + x + w)/2)
y_medium = int((y + y + h)/2)
cv2.line(frame, (x_medium, 0), (x_medium, 480), (0,255,0), 2)
cv2.line(frame, (0, y_medium), (cols ,y_medium), (0,255,0), 2)
center = (x_medium, y_medium)
print("center: ", center)
#######################data to be transfered to ardiuno
data = "X{0:.0f}Y{1:.0f}Z".format(x_medium, y_medium)
print("output: ", data)
# ser.write(data)
ser.write((str(data)).encode('utf-8'))
break
print("for loop out")
cv2.imshow("Main Frame", frame)
#cv2.imshow("Main Frame", hsv_frame)
key = cv2.waitKey(1)
if key == ord('s'):
break
cap.release()
cv2.destroyAllWindows()
Arduino script:
#include <Servo.h>
Servo servoVer; //Vertical Servo
Servo servoHor; //Horizontal Servo
int x;
int y;
int prevX;
int prevY;
int pos = 0;
void setup()
{
Serial.begin(9600);
servoVer.attach(5); //Attach Vertical Servo to Pin 5
servoHor.attach(6); //Attach Horizontal Servo to Pin 6
servoVer.write(90);
servoHor.write(90);
}
void Pos()
{
if (prevX != x || prevY != y)
{
int servoX = map(x, 480, 0, 0, 180);
int servoY = map(y, 640, 0, 180, 0);
servoX = min(servoX, 180);
servoX = max(servoX, 0);
servoY = min(servoY, 180);
servoY = max(servoY, 0);
prevX = servoX;
prevY = servoY;
servoHor.write(servoX);
servoVer.write(servoY);
}
}
void something(){
for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
servoHor.write(pos); // tell servo to go to position in variable 'pos'
delay(5); // waits 15ms for the servo to reach the position
}
}
void track(){
delay(1000);
if(Serial.available() > 0)
{
if (Serial.read() == 'X')
{
x = Serial.parseInt();
if (Serial.read() == 'Y')
{
y = Serial.parseInt();
Pos();
}
}
while (Serial.available() > 0)
{
Serial.read();
}
}
}
void loop()
{
if ( ! Serial.available() )
{
something();
}
else
{
track();
}
}