Trabajando con OpenCV y la cámara de la Raspberry Pi

Como ya comentábamos en la entrada anterior, podemos hacer reconocimiento de imágenes, en concreto vamos a ver en esta entrada como hacer reconocimiento  de la posición de la mano con OpenCV. Para ello necesitamos conectar y habilitar la cámara de la Raspberry Pi, como indicamos en otra entrada anterior Sistema de vigilancia con Raspberry Pi.

Con el siguiente código podemos hacer que reconozca si la mano está abierta o cerrada:

# import the necessary packages
from imutils.video import VideoStream
import imutils
import cv2
import numpy as np
import math
import time
import sys

# initialize the video stream and allow the cammera sensor to warmup
vs = VideoStream(usePiCamera=True, resolution=(1296,972)).start()
time.sleep(2.0)
# loop over the frames from the video stream
while True:
img = vs.read()
cv2.rectangle(img,(300,300),(100,100),(0,255,0),0)
crop_img = img[100:300, 100:300]
grey = cv2.cvtColor(crop_img, cv2.COLOR_BGR2GRAY)
value = (37,37)
blurred = cv2.GaussianBlur(grey, value, 0)
_, thresh1 = cv2.threshold(blurred, 127, 255,
cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
_, contours, hierarchy = cv2.findContours(thresh1.copy(),cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)

max_area = -1
for i in range(len(contours)):
cnt=contours[i]
area = cv2.contourArea(cnt)
if(area>max_area):
max_area=area
ci=i
cnt=contours[ci]
x,y,w,h = cv2.boundingRect(cnt)
cv2.rectangle(crop_img,(x,y),(x+w,y+h),(0,0,255),0)
hull = cv2.convexHull(cnt)
drawing = np.zeros(crop_img.shape,np.uint8)
cv2.drawContours(drawing,[cnt],0,(0,255,0),0)
cv2.drawContours(drawing,[hull],0,(0,0,255),0)
hull = cv2.convexHull(cnt,returnPoints = False)
defects = cv2.convexityDefects(cnt,hull)
count_defects = 0
cv2.drawContours(thresh1, contours, -1, (0,255,0), 3)
for i in range(defects.shape[0]):
s,e,f,d = defects[i,0]
start = tuple(cnt[s][0])
end = tuple(cnt[e][0])
far = tuple(cnt[f][0])
a = math.sqrt((end[0] – start[0])**2 + (end[1] – start[1])**2)
b = math.sqrt((far[0] – start[0])**2 + (far[1] – start[1])**2)
c = math.sqrt((end[0] – far[0])**2 + (end[1] – far[1])**2)
angle = math.acos((b**2 + c**2 – a**2)/(2*b*c)) * 57
if angle <= 90:
count_defects += 1
cv2.circle(crop_img,far,1,[0,0,255],-1)
dist = cv2.pointPolygonTest(cnt,far,True)
cv2.line(crop_img,start,end,[0,255,0],2)
cv2.circle(crop_img,far,5,[0,0,255],-1)

if count_defects>3:
cv2.putText(img,”ABIERTA”, (50,50), cv2.FONT_HERSHEY_SIMPLEX, 2, 4)
else:
cv2.putText(img,”CERRADA”, (50,50), cv2.FONT_HERSHEY_SIMPLEX, 2, 4)

#cv2.imshow(‘drawing’, drawing)
#cv2.imshow(‘end’, crop_img)
cv2.imshow(‘Gesture’, img)
all_img = np.hstack((drawing, crop_img))
cv2.imshow(‘Contours’, all_img)
k = cv2.waitKey(10)
if k == 27:
cv2.destroyAllWindows()
vs.stop()
break

Lo primero que hacemos es iniciar la cámara de la Raspberry con una resolución concreta, para ir procesando cada imagen que vamos leyendo.

Dibujamos un cuadrado en la posición de la imagen donde estará la mano.

2016-08-19-171040_1824x984_scrot - copia.png

A continuación convertimos la imagen a escala de grises.

2016-08-19-171040_1824x984_scrot-copia-copia

Le aplicamos un filtro Gaussiano, que desenfoca la imágen de la siguiente forma:

bf.png

Después le aplicamos la función treshold, que nos devolvería un resultado similar al siguiente:
hand

Donde podemos localizar, y dibujar muy fácilmente el contorno de la imagen.

2016-08-19-171040_1824x984_scrot - copia (2)

Tras aplicar una serie de funciones matemáticas, podemos interpretar si la mano esta cerrada o abierta.

2016-08-19-171040_1824x984_scrot
Ejemplo Mano Abierta
2016-08-19-171718_1824x984_scrot
Ejemplo Mano Cerrada

Aquí os dejo un vídeo donde os muestra el funcionamiento de esta práctica (tiempo 2:29), además de otras.

 

 

Anuncios

Sistema de vigilancia con Raspberry Pi

Para seguir con las dos entradas anteriores, y con nuestro proyecto de domótica con Raspberry Pi vamos a explicar como hacer que cuando el sensor PIR detecte movimiento mande una foto capturada por la cámara de la Raspberry Pi al correo de gmail.

admin.schema

Partiendo del programa en python que teníamos para controlar el sensor PIR, vamos a modificar el código de tal forma que cuando se detecte movimiento en vez de escribir por pantalla “movimiento detectado”, ejecute en segundo plano otro programa en python que toma una foto con la cámara oficial de Raspberry Pi.

41vGRDyVq6L._SX425_
Raspberry Pi Camera

Para ello lo primero que tenemos que hacer es conectar la Cámara al CSI de la Raspberry Pi

Raspberry_Pi_CSI_Camera_Module_from_Mobile_Phone
Conexión cámara CSI Raspberry Pi

Y ejecutando en la Raspberry el comando

sudo raspi-config 

Habilitamos la cámara

EnableCamera
Enable Camera comando raspi-config

Instalamos la librería “picamera” con el siguiente comando

 sudo apt-get install python-picamera
Y ya podemos ejecutar el siguiente programa:
#!/usr/bin/env python
import os
from time import sleep
import picamera
import smtplib

ruta = ‘/home/pi/raispi/fotos/pic.jpg’
with picamera.PiCamera() as camera:
camera.start_preview()
#Hacer foto
camera.capture(ruta, format= ‘jpeg’, use_video_port=True)
camera.stop_preview()
camera.close()

#Mandarla como archivo adjunto al correo de gmail
os.system(“./mail.sh &”)

Que a su vez ejecuta en segundo plano lo siguiente:
echo “Imagen por persona detectada” | mutt -s “Movimiento detectado” destinatario@gmail.com -a /home/pi/raispi/fotos/pic.jpg
Dando permiso al programa anterior así como al .sh, con el comando
sudo chmod 777 foto_sensor.py
sudo chmod 777 mail.sh
dejamos la Raspberry Pi un poco oculta cerca de la entrada de casa, y ejecutamos el programa del sensor PIR y cada vez que detecte que alguien entra, tomará una foto y la mandara por correo.
ImagenPersonaDetectada

Sensor PIR

En este apartado del blog queremos hacer un enfoque más domótico y centrarnos en utilizar la Raspberry Pi con distintos sensores, para ir creando diferentes aspectos de una Smart Home.

admin.schema
Smart Home con Raspberry Pi

En estas primeras entradas de este apartado, vamos a utilizar un sensor PIR y la cámara oficial de la Raspberry Pi para hacer un sistema de vigilancia casero, que sea capaz de hacer fotos cuando detecte que alguien entra en casa, y mandarlas a nuestro correo de Gmail.

Lo primero de todo es explicar que es un sensor PIR de detección de movimiento:

PIR sensor
Sensor Pir HC-SR501

Un sensor PIR (Passive InfraRed) está formado por una lente de Fresnel, un detector de infrarrojos y otros circuitos de detección. La lente en el sensor se centra cualquier radiación infrarroja presente alrededor de ella. Nuestros cuerpos generan calor infrarrojo que es detectado por el sensor, tras lo cual emite una señal de 5 V. Según su hoja de características es capaz de detectar movimiento hasta unos 6-7 metros de distancia.

FuncionamientoPir
Funcionamiento Sensor PIR
EsquematicoSensorPir
Esquemático del sensor PIR HC-SR501

HC-SR501-Image

 

Cuando el sensor de movimiento PIR detecta una persona, se emite una señal de 5 V a la Raspberry Pi a través de su GPIO.

Las conexiones a hacer entre el sensor y la Raspberry Pi se muestran en el siguiente esquema:

ConexionesSensorPir
Conexiones Raspberry Pi y sensor PIR

FotoConexionesSensorPir

El programa a utilizar habiendo conectado la salida del sensor al GPIO 16 de la Raspberry Pi sería uno similar al siguiente:

#!/usr/bin/env python
import RPi.GPIO as GPIO
import time
import os
from time import gmtime, strftime
GPIO.setmode(GPIO.BCM)
PIR_PIN = 16
GPIO.setup(PIR_PIN, GPIO.IN)
time.sleep(5)
try:
while True:
if GPIO.input(PIR_PIN):
print (‘movimiento detectado\n’)
time.sleep(0.3)

except KeyboardInterrupt:
print “quit”
GPIO.cleanup()

Una vez en la carpeta donde hemos creado el fichero anterior, lo ejecutamos:

ResultadoSensorPir
resultado de ejecutar sensor_movimiento.py