[PYTHON] [Note] (Zupai) Suivi du visage avec Pan-Tilt HAT et caméra

Aperçu

pi@raspberrypi:~ $ python Python 2.7.9 (default, Sep 17 2016, 20:26:04) [GCC 4.9.2] on linux2 Type "help", "copyright", "credits" or "license" for more information.

from pantilthat import * angle_pan = 15 #angle:-90 - +90 angle_tilt = -30 #angle:-90 - +90 pan(angle_pan) tilt(angle_tilt) quit() pi@raspberrypi:~ $


## environnement
- Raspberry Pi 2 / 3
 --Camera Module V2.1 (a également fonctionné avec V1.3)
 --Raspbian: `2017-01-11-raspbian-jessie.img` (OpenCV affiche l'image de la caméra dans la fenêtre, donc ce n'est pas Lite)

## procédure
 1. Assemblage du kit Pan-Tilt [Assemblage du Pan-Tilt HAT](https://learn.pimoroni.com/tutorial/sandyj/assembling-pan-tilt-hat)
 https://learn.pimoroni.com/tutorial/sandyj/assembling-pan-tilt-hat <br> Je me demande si je peux le faire en regardant les photos.
 --Module Pan-Tilt fixé à la carte HAT
 ――La vis en nylon noir est longue, c'est donc une bonne idée de couper l'extrémité utilisée du boulon en nylon avec une paire de ciseaux ou de cisailles, ~)
 --Insérez le fil du servomoteur dans le connecteur arrière (GND = marron, 5V = rouge, PWM-jaune)
 - Pan (secouer l'épée) au canal 1 (SERVO1)
 --Tilt (secouer le cou verticalement) sur le canal 2 (SERVO2)
 --Assemblage de la base de fixation de la caméra
 ――Je pense que l'encoche sur la face avant est différente entre V1.3 et V2.1.
 ――La vis blanche est allongée, vous pouvez donc la couper (encore une fois, c'est une bonne idée de couper l'excédent de boulon en nylon avec une paire de ciseaux ou de cisailles.)
 - Fixez la base de fixation de la caméra au module Pan-Tilt
 --Le câble de la caméra monte
 --Neopixel stick ... Je ne l'ai pas acheté, alors sautez-le.
 --Insérez complètement le câble de la caméra.
 ――Environ 1 mm pour soulever les pièces (marron ou noir?) Au-dessus de la sortie de tarte à la râpe. Si vous mettez trop de force, il se cassera.
 - Branchez le câble de la caméra
 ――Lorsque vous le soulevez et l'enfoncez, il est fixé.
 --Insérez le chapeau dans la tarte à la râpe à 40 broches.

 2. Préparation du système de démarrage (habituel)
 --Raspbian
 --`sudo apt-get update && sudo apt-get upgrade -y` # Mise à jour du paquet

 3. Installez les packages liés à Pan-Tilt
`curl -sS https://get.pimoroni.com/pantilthat | bash`
 Lorsqu'on lui a demandé quelque chose, «y [Enter]

 4. Activer le module de caméra <br> `sudo raspi-config nonint do_camera 0 # 0: Activer / 1: Désactiver`


 5. `sudo reboot` # reboot
 6. Vérifiez le fonctionnement du module PanTilt
 --Ouvrez le terminal,
 --Démarrez python avec `python [Entrée]`
 ―― Par la suite, copiez
 
		```py
		from pantilthat import *
		angle_pan  = 15   #angle:-90 - +90
		angle_tilt = -30  #angle:-90 - +90
		pan(angle_pan)
		tilt(angle_tilt)
		quit()
		```
 -Est-ce que ça marche? Si vous changez le nombre, la direction change. Angle_pan = 0 / angle_tilt = 0 et vous vous sentez comme face à l'avant?



### Programme de démonstration de suivi de visage
https://github.com/pimoroni/PanTiltFacetracker


 1. Installez les paquets requis <br> `sudo apt-get install python-smbus python-opencv opencv-data`
2. git clone 

    ```bash
git clone https://github.com/pimoroni/PanTiltFacetracker
cd PanTiltFacetracker
  1. Exécutez
    . / Facetracker_lbp.py --Une fenêtre s'ouvre et l'image de la caméra s'affiche. --Lorsqu'un visage est détecté, le module Pan-Tilt se déplace de manière à être au centre.

Autre

--Journal

```shell-session:
pi@raspberrypi:~ $ curl -sS https://get.pimoroni.com/pantilthat | bash

This script will install everything needed to use
Pan-Tilt HAT

Always be careful when running scripts and commands
copied from the internet. Ensure they are from a
trusted source.

If you want to see what this script does before
running it, you should run:
\curl -sS https://get.pimoroni.com/pantilthat

Note: Pan-Tilt HAT requires I2C communication

Do you wish to continue? [y/N] y

Checking environment...
Updating apt indexes...
.........
Reading package lists...
.........

Checking hardware requirements...

I2C must be enabled for Pan-Tilt HAT to work
I2C is now enabled

Checking packages required by I2C interface...

Pan-Tilt HAT comes with examples and documentation that you may wish to install.
Performing a full install will ensure those resources are installed,
along with all required dependencies. It may however take a while!

Do you wish to perform a full install? [y/N] y
Checking install requirements...

Checking for dependencies...

Installing python-pantilthat...
install ok installed

Installing python3-pantilthat...
install ok installed


Checking for additional software...

python-picamera is already installed
python3-picamera is already installed

Downloading examples and documentation...
Resources for your Pan-Tilt HAT were copied to
/home/pi/Pimoroni/pantilthat

All done!

Enjoy your Pan-Tilt HAT!

pi@raspberrypi:~ $ sudo reboot
```

――La couleur est-elle étrange? Lorsque le rouge est projeté, il devient bleu et le bleu devient rouge. Le réglage de l'alignement RVB est-il incorrect? Impossible de définir la v4l2 depuis OpenCV? CV_CAP_PROP_FORMAT ?? Je ne sais pas comment le réparer, alors je l'ai changé pour utiliser PiCamera de Python.

- `sudo apt-get install python-picamera`

--Code qui a été foiré pour utiliser picamera.

	```py
	#!/usr/bin/env python
	## http://qiita.com/mt08/items/97d89a09e5129e10f88c

	from picamera.array import PiRGBArray
	from picamera import PiCamera
	import cv2, sys, time, os
	from pantilthat import *

	# Frame Size. Smaller is faster, but less accurate.
	# Wide and short is better, since moving your head
	# vertically is kinda hard!
	FRAME_W = 192
	FRAME_H = 112

	# Default Pan/Tilt for the camera in degrees.
	# Camera range is from -90 to 90
	cam_pan = 90
	cam_tilt = 60

	# Set up the CascadeClassifier for face tracking
	#cascPath = 'haarcascade_frontalface_default.xml' # sys.argv[1]
	cascPath = '/usr/share/opencv/lbpcascades/lbpcascade_frontalface.xml'
	faceCascade = cv2.CascadeClassifier(cascPath)

	# Set up the capture with our frame size
	camera = PiCamera()
	camera.resolution = (FRAME_W, FRAME_H)
	camera.framerate = 32
	rawCapture = PiRGBArray(camera, size=(FRAME_W, FRAME_H))
	time.sleep(0.1)

	# Turn the camera to the default position
	pan(cam_pan-90)
	tilt(cam_tilt-90)
	light_mode(WS2812)

	def lights(r,g,b,w):
		for x in range(18):
			set_pixel_rgbw(x,r if x in [3,4] else 0,g if x in [3,4] else 0,b,w if x in [0,1,6,7] else 0)
		show()

	lights(0,0,0,50)


	for image in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True):

		frame = image.array

		# This line lets you mount the camera the "right" way up, with neopixels above
		frame = cv2.flip(frame, -1)
		
		# Convert to greyscale for detection
		gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
		gray = cv2.equalizeHist( gray )

		# Do face detection
		faces = faceCascade.detectMultiScale(gray, 1.1, 3, 0, (10, 10))
	   
		# Slower method 
		'''faces = faceCascade.detectMultiScale(
			gray,
			scaleFactor=1.1,
			minNeighbors=4,
			minSize=(20, 20),
			flags=cv2.cv.CV_HAAR_SCALE_IMAGE | cv2.cv.CV_HAAR_FIND_BIGGEST_OBJECT | cv2.cv.CV_HAAR_DO_ROUGH_SEARCH
		)'''
		
		lights(50 if len(faces) == 0 else 0, 50 if len(faces) > 0 else 0,0,50)

		for (x, y, w, h) in faces:
			# Draw a green rectangle around the face
			cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)

			# Track first face
			
			# Get the center of the face
			x = x + (w/2)
			y = y + (h/2)

			# Correct relative to center of image
			turn_x  = float(x - (FRAME_W/2))
			turn_y  = float(y - (FRAME_H/2))

			# Convert to percentage offset
			turn_x  /= float(FRAME_W/2)
			turn_y  /= float(FRAME_H/2)

			# Scale offset to degrees
			turn_x   *= 2.5 # VFOV
			turn_y   *= 2.5 # HFOV
			cam_pan  += -turn_x
			cam_tilt += turn_y

			print(cam_pan-90, cam_tilt-90)

			# Clamp Pan/Tilt to 0 to 180 degrees
			cam_pan = max(0,min(180,cam_pan))
			cam_tilt = max(0,min(180,cam_tilt))

			# Update the servos
			pan(int(cam_pan-90))
			tilt(int(cam_tilt-90))

			break

		frame = cv2.resize(frame, (540,300))
		frame = cv2.flip(frame, 1)
	   
		# Display the image, with rectangle
		# on the Pi desktop 
		cv2.imshow('Video', frame)
		key = cv2.waitKey(1) & 0xFF

		# clear the stream in preparation for the next frame
		rawCapture.truncate(0)

		# if the `q` key was pressed, break from the loop
		if key == ord("q"):
			break
		
	# When everything is done, release the capture
	cv2.destroyAllWindows()




 TODO
 ――Voulez-vous publier un squeeze ou une vidéo animée?
 -Est-ce compatible avec la marque de l'homme qui rit?
 ――Détecter plusieurs visages et suivre le plus grand?






Recommended Posts

[Note] (Zupai) Suivi du visage avec Pan-Tilt HAT et caméra
Reconnaissance faciale avec caméra avec opencv3 + python2.7
Hello World et détection de visage avec opencv-python 4.2
Hello World et détection de visage avec OpenCV 4.3 + Python
Acquérir la position et l'orientation de la caméra avec le marqueur ArUco