Diferencia entre revisiones de «Linea camara»
De Proyecto Butiá
| Línea 12: | Línea 12: | ||
===Código=== | ===Código=== | ||
<source lang="python"> | <source lang="python"> | ||
| − | def | + | import pygame |
| − | + | import pygame.camera | |
| + | import pygame.surfarray as surfarray | ||
| + | import sys | ||
| + | sys.path.insert(0, '/usr/share/sugar/activities/TurtleBots.activity/plugins/butia') | ||
| + | from pygame.locals import * | ||
| + | from pybot import usb4butia | ||
| + | import time | ||
| + | |||
| + | pygame.init() | ||
| + | pygame.camera.init() | ||
| + | robot = usb4butia.USB4Butia() | ||
| + | robot.refresh() | ||
| + | |||
| + | def saveSurface(pixels, filename): | ||
| + | try: | ||
| + | surf = pygame.surfarray.make_surface(pixels) | ||
| + | except IndexError: | ||
| + | (width, height, colours) = pixels.shape | ||
| + | surf = pygame.display.set_mode((width, height)) | ||
| + | pygame.surfarray.blit_array(surf, pixels) | ||
| + | pygame.image.save(surf, filename) | ||
| + | |||
| + | def capturarImg(camara): | ||
| + | camara.start() | ||
| + | im = camara.get_image() | ||
| + | camara.stop() | ||
| + | return im | ||
| + | |||
| + | def inclinaciones(pixeles): | ||
| + | i = 0 | ||
| + | l = largoLista(pixeles) | ||
| + | l = l - 1 | ||
| + | incl = [] | ||
| + | while i < l: | ||
| + | incl.append(inclinacion(pixeles[i],pixeles[i + 1])) | ||
| + | i = i + 1 | ||
| + | return incl | ||
| + | |||
| + | def largoLista(lista): | ||
| + | i = 0 | ||
| + | for a in lista: | ||
| + | i = i + 1 | ||
| + | return i | ||
| + | |||
| + | def pendientesAfactores(pendientes): | ||
| + | i = 0 | ||
| + | l = largoLista(pendientes) | ||
| + | while i < l: | ||
| + | if pendientes[i] > 30 or pendientes[i] == 0: | ||
| + | pendientes[i] = 1 | ||
| + | elif pendientes[i] > 10: | ||
| + | pendientes[i] = 1.1 | ||
| + | elif pendientes[i] > 5: | ||
| + | pendientes[i] = 1.3 | ||
| + | elif pendientes[i] > 2: | ||
| + | pendientes[i] = 1.5 | ||
| + | elif pendientes[i] > 0: | ||
| + | pendientes[i] = 1.7 | ||
| + | elif pendientes[i] < -30: | ||
| + | pendientes[i] = 1 | ||
| + | elif pendientes[i] < -10: | ||
| + | pendientes[i] = 0.9 | ||
| + | elif pendientes[i] < -5: | ||
| + | pendientes[i] = 0.7 | ||
| + | elif pendientes[i] < -2: | ||
| + | pendientes[i] = 0.5 | ||
| + | else: | ||
| + | pendientes[i] = 0.3 | ||
| + | i += 1 | ||
| + | return pendientes | ||
| + | |||
| + | def calculoFactorVelocidad(pendientes): | ||
| + | suma = float(0) | ||
| + | largo = largoLista(pendientes) | ||
| + | for i in range(0, largo -1): | ||
| + | suma += pendientes[i] | ||
| + | suma = suma / largo | ||
| + | return suma | ||
| + | |||
| + | def inclinacion((x1,y1),(x2,y2)): | ||
| + | if x2 == x1: | ||
| + | m = 0 | ||
| + | else: | ||
| + | m = (y2 - y1) / (x2 - x1) | ||
| + | return m | ||
| + | |||
| + | def movimientoRobot(robot, f): | ||
| + | if f > 1: | ||
| + | if f == 2: | ||
| + | f = 0 | ||
| + | else: | ||
| + | f = f - 1 | ||
| + | f = 1 - f | ||
| + | velocidadDerecha = 200 * f | ||
| + | velocidadIzquierda = 200 | ||
| + | else: | ||
| + | velocidadDerecha = 200 | ||
| + | velocidadIzquierda = 200 * f | ||
| + | |||
| + | robot.set2MotorSpeed(1,int(velocidadDerecha),1,int(velocidadIzquierda)) | ||
| + | return 0 | ||
| + | |||
| + | def hallarPixelesIma(im, cant): | ||
| + | ima = surfarray.array3d(im) | ||
| + | pixeles = [] | ||
| + | w = im.get_width() | ||
| + | h = im.get_height() | ||
| + | x = h - 1 | ||
| + | while x >= 0: | ||
| + | i = 0 | ||
| + | while i < w and (int(ima[i][x][0]) + int(ima[i][x][1]) + int(ima[i][x][2])) / 3 > 120: | ||
| + | i = i + 1 | ||
| + | if i < w: | ||
| + | j = w - 1 | ||
| + | while j > 0 and (int(ima[j][x][0]) + int(ima[j][x][1]) + int(ima[j][x][2])) / 3 > 120: | ||
| + | j = j - 1 | ||
| + | y = (i + j) / 2 | ||
| + | pixeles.append((y,x)) | ||
| + | x = x - 30 | ||
| + | else: | ||
| + | x = x - 1 | ||
| + | return pixeles | ||
| + | |||
| + | def estaCentrado((x,y)): | ||
| + | return (x > 50 and x < 270) | ||
| + | |||
| + | def izquierda((x,y)): | ||
| + | return (x < 50) | ||
| + | |||
| + | def derecha((x,y)): | ||
| + | return (x > 270) | ||
| + | |||
| + | def calculoFactorDescentrado(p): | ||
| + | factorDescentrado = 1 | ||
| + | hayCentrados = False; | ||
| + | i = 0 | ||
| + | cantPixeles = largoLista(p) | ||
| + | while i < cantPixeles and not hayCentrados: | ||
| + | if estaCentrado(p[i]): | ||
| + | hayCentrado = True | ||
| + | i += 1 | ||
| + | if(not hayCentrados): | ||
| + | if(izquierda(p[0])): | ||
| + | factorDescentrado = 1.9 | ||
| + | elif(derecha(p[0])): | ||
| + | factorDescentrado = 0.1 | ||
| + | return factorDescentrado | ||
| + | |||
| + | def obtenerX((x,y)): | ||
| + | return x | ||
| + | |||
| + | def centradoFactor(k,p): | ||
| + | xs = 0 | ||
| + | for pix in p: | ||
| + | xs += obtenerX(pix) | ||
| + | xs = xs / largoLista(p) | ||
| + | if xs < 25: | ||
| + | k = 1.9 | ||
| + | elif xs < 55: | ||
| + | if k >= 1 and k < 1.6: | ||
| + | k = k + 0.4 | ||
| + | elif k < 1: | ||
| + | k = 1.5 | ||
| + | elif k < 1.7: | ||
| + | k = k + 0.3 | ||
| + | elif k < 1.8: | ||
| + | k = k + 0.2 | ||
| + | elif xs < 67: | ||
| + | if k >= 1 and k < 1.7: | ||
| + | k = k + 0.3 | ||
| + | elif k < 1: | ||
| + | k = 1.3 | ||
| + | elif xs > 130: | ||
| + | k = 0.1 | ||
| + | elif xs > 105: | ||
| + | if k <= 1 and k > 0.4: | ||
| + | k = k - 0.4 | ||
| + | elif k > 1: | ||
| + | k = 0.5 | ||
| + | elif k > 0.3: | ||
| + | k = k - 0.3 | ||
| + | elif k > 0.2: | ||
| + | k= k - 0.2 | ||
| + | elif xs > 93: | ||
| + | if k <= 1 and k > 0.3: | ||
| + | k = k - 0.3 | ||
| + | elif k > 1: | ||
| + | k = 0.7 | ||
| + | return k | ||
| + | |||
| + | |||
| + | camlist = pygame.camera.list_cameras() | ||
| + | if camlist: | ||
| + | while cantVeces < 500: | ||
| + | s = capturarImg(pygame.camera.Camera(camlist[0],(160,120))) | ||
| + | p = hallarPixelesIma(s,cantVeces) | ||
| + | pendientes = inclinaciones(p) | ||
| + | factores = pendientesAfactores(pendientes) | ||
| + | k = 1 | ||
| + | if largoLista(p) == 0: | ||
| + | robot.set2MotorSpeed(0,0,0,0) | ||
| + | else: | ||
| + | if largoLista(p) > 1: | ||
| + | k = calculoFactorVelocidad(factores) | ||
| + | k = centradoFactor(k,p) | ||
| + | movimientoRobot(robot, k) | ||
| − | |||
| − | |||
</source> | </source> | ||
Revisión del 21:12 1 jul 2015
Contenido
Introducción
Consiga: Realizar un seguidor de línea utilizando una cámara en lugar de un sensor de grises para captar el entorno.
Tutor: Federico Andrade
Grupo:
- Josefina Fasoli
- Gonzalo Herrera
- Camila Serena
Algoritmo
A partir de la imagen recabada por la cámara, se toman puntos del centro de la linea a seguir. Con los puntos identificados, se calculan las respectivas pendientes generadas, para luego promediarlas y transformar este nuevo valor en un factor f utilizado para calcular la velocidad de cada rueda, que permite que haga el movimiento correspondiente.
Código
import pygame
import pygame.camera
import pygame.surfarray as surfarray
import sys
sys.path.insert(0, '/usr/share/sugar/activities/TurtleBots.activity/plugins/butia')
from pygame.locals import *
from pybot import usb4butia
import time
pygame.init()
pygame.camera.init()
robot = usb4butia.USB4Butia()
robot.refresh()
def saveSurface(pixels, filename):
try:
surf = pygame.surfarray.make_surface(pixels)
except IndexError:
(width, height, colours) = pixels.shape
surf = pygame.display.set_mode((width, height))
pygame.surfarray.blit_array(surf, pixels)
pygame.image.save(surf, filename)
def capturarImg(camara):
camara.start()
im = camara.get_image()
camara.stop()
return im
def inclinaciones(pixeles):
i = 0
l = largoLista(pixeles)
l = l - 1
incl = []
while i < l:
incl.append(inclinacion(pixeles[i],pixeles[i + 1]))
i = i + 1
return incl
def largoLista(lista):
i = 0
for a in lista:
i = i + 1
return i
def pendientesAfactores(pendientes):
i = 0
l = largoLista(pendientes)
while i < l:
if pendientes[i] > 30 or pendientes[i] == 0:
pendientes[i] = 1
elif pendientes[i] > 10:
pendientes[i] = 1.1
elif pendientes[i] > 5:
pendientes[i] = 1.3
elif pendientes[i] > 2:
pendientes[i] = 1.5
elif pendientes[i] > 0:
pendientes[i] = 1.7
elif pendientes[i] < -30:
pendientes[i] = 1
elif pendientes[i] < -10:
pendientes[i] = 0.9
elif pendientes[i] < -5:
pendientes[i] = 0.7
elif pendientes[i] < -2:
pendientes[i] = 0.5
else:
pendientes[i] = 0.3
i += 1
return pendientes
def calculoFactorVelocidad(pendientes):
suma = float(0)
largo = largoLista(pendientes)
for i in range(0, largo -1):
suma += pendientes[i]
suma = suma / largo
return suma
def inclinacion((x1,y1),(x2,y2)):
if x2 == x1:
m = 0
else:
m = (y2 - y1) / (x2 - x1)
return m
def movimientoRobot(robot, f):
if f > 1:
if f == 2:
f = 0
else:
f = f - 1
f = 1 - f
velocidadDerecha = 200 * f
velocidadIzquierda = 200
else:
velocidadDerecha = 200
velocidadIzquierda = 200 * f
robot.set2MotorSpeed(1,int(velocidadDerecha),1,int(velocidadIzquierda))
return 0
def hallarPixelesIma(im, cant):
ima = surfarray.array3d(im)
pixeles = []
w = im.get_width()
h = im.get_height()
x = h - 1
while x >= 0:
i = 0
while i < w and (int(ima[i][x][0]) + int(ima[i][x][1]) + int(ima[i][x][2])) / 3 > 120:
i = i + 1
if i < w:
j = w - 1
while j > 0 and (int(ima[j][x][0]) + int(ima[j][x][1]) + int(ima[j][x][2])) / 3 > 120:
j = j - 1
y = (i + j) / 2
pixeles.append((y,x))
x = x - 30
else:
x = x - 1
return pixeles
def estaCentrado((x,y)):
return (x > 50 and x < 270)
def izquierda((x,y)):
return (x < 50)
def derecha((x,y)):
return (x > 270)
def calculoFactorDescentrado(p):
factorDescentrado = 1
hayCentrados = False;
i = 0
cantPixeles = largoLista(p)
while i < cantPixeles and not hayCentrados:
if estaCentrado(p[i]):
hayCentrado = True
i += 1
if(not hayCentrados):
if(izquierda(p[0])):
factorDescentrado = 1.9
elif(derecha(p[0])):
factorDescentrado = 0.1
return factorDescentrado
def obtenerX((x,y)):
return x
def centradoFactor(k,p):
xs = 0
for pix in p:
xs += obtenerX(pix)
xs = xs / largoLista(p)
if xs < 25:
k = 1.9
elif xs < 55:
if k >= 1 and k < 1.6:
k = k + 0.4
elif k < 1:
k = 1.5
elif k < 1.7:
k = k + 0.3
elif k < 1.8:
k = k + 0.2
elif xs < 67:
if k >= 1 and k < 1.7:
k = k + 0.3
elif k < 1:
k = 1.3
elif xs > 130:
k = 0.1
elif xs > 105:
if k <= 1 and k > 0.4:
k = k - 0.4
elif k > 1:
k = 0.5
elif k > 0.3:
k = k - 0.3
elif k > 0.2:
k= k - 0.2
elif xs > 93:
if k <= 1 and k > 0.3:
k = k - 0.3
elif k > 1:
k = 0.7
return k
camlist = pygame.camera.list_cameras()
if camlist:
while cantVeces < 500:
s = capturarImg(pygame.camera.Camera(camlist[0],(160,120)))
p = hallarPixelesIma(s,cantVeces)
pendientes = inclinaciones(p)
factores = pendientesAfactores(pendientes)
k = 1
if largoLista(p) == 0:
robot.set2MotorSpeed(0,0,0,0)
else:
if largoLista(p) > 1:
k = calculoFactorVelocidad(factores)
k = centradoFactor(k,p)
movimientoRobot(robot, k)Multimedia
Link a video de youtube:
Imágenes: