i need some help with a project. Its about detecting red object in a determined green area. I have to dodge objects and reach the goal (in this case a blue area), also back to collect the objects with a servomotor and a clamp, all using a camera with OpenCv and the Irobot.
Well the code that i have until now can recognize the red objects, and move to them and stop when they are close. Also can rotate to left and right,i did it this way to try to center the object in the camera, dividing the screen into 3 parts, then I Pick it with the servo. But im getting out of ideas, when i run de python code, the process is very slow and and the detecting the of left and right side is very sensitive, i cant focus the object on the center. Also i dont have idea how to get the distance between the object and the irobot, in theory I can and dodge objects, but dont know how to get to the goal, or how to get back to them.
This is the python code:
import cv2
import numpy as np
import serial
from time import sleep
def serialCom(int):
ser = serial.Serial(port = "/dev/ttyACM0", baudrate=9600)
x = ser.readline()
ser.write(int)
x = ser.readline()
print 'Sending: ', x
# Recognizes how much red is in a given area by the parameters
def areaRed(img, xI, xF, yI, yF):
# counter red pixels
c = 0
red = 255
for i in range(xI, xF):
for j in range(yI, yF):
if img[i][j] == red:
c += 1
return c
def reconoce(lower_re, upper_re, lower_gree, upper_gree, lower_ble, upper_ble):
cap = cv2.VideoCapture(1)
while(1):
_, frame = cap.read()
# Converting BGR to HSV
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
hsv2 = cv2.cvtColor(frame , cv2.COLOR_BGR2HSV)
hsv3 = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
# Threshold the HSV image to get only red,blue and green colors
mask = cv2.inRange(hsv, lower_re, upper_re)
maskBlue = cv2.inRange(hsv2, lower_ble, upper_ble)
maskGreen = cv2.inRange(hsv3, lower_gree, upper_gree)
moments = cv2.moments(mask)
area = moments['m00']
blueMoment = cv2.moments(maskBlue)
blueArea = blueMoment['m00']
greenMoment = cv2.moments(maskGreen)
greenArea = greenMoment['m00']
# Determine the limits of the mask
x = mask.shape[0] - 1
y = mask.shape[1] - 1
# Determine the center point of the image
xC = x / 2
yC = y / 2
x3 = (x/3)/2
y3 = y/2
# Define the variables for the center values of the camera
xI, xF, yI, yF = xC - (xC / 4), xC + (xC / 4), yC - (yC / 4), yC + (yC / 4)
# define the ranges of the mask for the left and right side
right = areaRed(mask, xI + (x/4), xF + (x/4), yI + (x/4), yF + (x/4))
left = areaRed(mask, xI - (x/4), xF - (x/4), yI - (x/4), yF - (x/4))
centro = areaRed(mask, xI, xF, yI, yF)
if right > 700:
serialCom ("4")
print "turning right"
return mask
if left > 700:
serialCom("5")
print "turning left"
return mask
#if there is a red objet
if centro > 5000:
print 'i detect red'
#and in on the a green area
if greenArea > 10000000:
#we stop the irbot
serialCom("1")
print 'I found red and is in the area'
cv2.destroyAllWindows()
return mask
else:
#then we continue moving
serialCom("3")
print ''
else:
print "there is not red objet:v"
cv2.imshow('frame',frame)
cv2.imshow('red',mask)
k = cv2.waitKey(5) & 0xFF
if k == 27:
break
cv2.destroyAllWindows()
# The range of colors are defined for the HSV
lower_red = np.array([170,150,50])
upper_red = np.array([179,255,255])
lower_green = np.array([85,80,150])
upper_green = np.array([95,255,255])
lower_blue = np.array([100,100,100])
upper_blue = np.array([120,255,255])
while True:
img = reconoce(lower_red, upper_red, lower_green, upper_green, lower_blue, upper_blue)
cv2.imshow('Freeze image', img)
cv2.waitKey(10000)
cv2.destroyAllWindows()
This is the arduino code conecting the irobot with the opencv
#include <Roomba.h>
Roomba roomba(&Serial1);
int p=0;
void init()
{
roomba.driveDirect(-100,100);
roomba.driveDirect(-100,100);
delay(100);
roomba.driveDirect(100,-100);
delay(100);
}
void move()
{
roomba.driveDirect(50,50);
roomba.driveDirect(50,50);
}
void reverse()
{
roomba.driveDirect(-50,-50);
}
void left_rotation()
{
roomba.driveDirect(-30,30);
delay(1000);
}
void right_rotation()
{
roomba.driveDirect(30,-30);
delay(1000);
}
void stop()
{
roomba.driveDirect(0,0);
delay(500);
Serial.println("9");
}
void setup()
{
Serial.begin(9600);
roomba.start();
roomba.safeMode();
}
void loop()
{
if(Serial.available()>0)
{
p=Serial.read();
if(p == 51)
{
Serial.println("1");
move();
}
if(p==50)
{
Serial.println("2");
reverse();
delay(1000);
}
if(p==52)
{
Serial.println("4");
left_rotation();
delay(1000);
stop();
}
if(p==53)
{
Serial.println("5");
right_rotation();
delay(1000);
stop();
}
if(p==49)
{
Serial.println("3");
stop();
delay(1000);
}
}
delay(100);
}