Arduinoを使用した顔の追跡
コンポーネントと消耗品
> |
| × | 1 | |||
| × | 1 | ||||
| × | 2 | ||||
| × | 1 | ||||
| × | 1 |
アプリとオンラインサービス
| ||||
|
このプロジェクトについて
前のチュートリアルでは、「pyserial」モジュールを使用してArduinoとPythonの間で通信し、LEDを制御する方法を共有しました。まだご覧になっていない場合は、こちらをご覧ください:ARDUINOとPYTHON間のコミュニケーション!
また、オブジェクトの色を検出して画面上で追跡する方法については、こちらをご覧ください:OPENCVとPYTHONを使用した色の検出。
このチュートリアルでは、ArduinoとPythonを使用して顔を追跡し、カメラを顔に追従させる方法を紹介します。これは難しいように聞こえるかもしれませんが、そうではないと私を信じてください。必要なのは、ArduinoとPythonの基本的な知識だけです。
それでは始めましょう...
ステップ1:必要なもの
要件は最小限です。ここにあなたが必要とするすべてのパーツリストを提供しました:
ハードウェア要件:
- Arduino UNO(他のボードを使用できます)
- Webカメラ(ミニWebカメラ)
- サーボx2(マイクロサーボを使用しますが、標準サーボを使用できます)
- ブレッドボード(プロトタイピング用)
- サーボパンチルトキット(必要に応じて作成できます)
ソフトウェア要件:
- Python 2.7(インストールする必要があります。通常、Linux OSにはプリインストールされています)
- OpenCV(個別にダウンロードするか、「pip install」を使用してインストールできます)
- pyserial(pipでインストールできます)
- numpy。
- ハーカスケード。
すべてが収集されたら、インストール手順に進むことができます...
ステップ2:Python環境をセットアップする
Pythonのインストール:
<図> <図> <図>したがって、最初にPython2.7を起動して実行する必要があります。これを行うには、最初にpython2.7.14をダウンロードしてインストールします。正しくインストールされているかどうかを確認するには: Windowsサーチ>>「IDLE」と入力>> Enterキーを押します。 Pythonシェルがポップアップするはずです。
または
検索で「CMD」と入力し、Enterキーを押してコマンドプロンプトを開きます。 CMDで>> pythonと入力し、Enterキーを押します Pythonインターフェースが表示されます。
CMDでエラーが発生した場合でも、慌てる必要はありません。おそらく環境変数を設定する必要があります。このチュートリアルに従うことができますここ 環境変数を設定します。
Pythonでの「pyserial」、「OpenCV」、「numpy」のインストール:
これらのモジュールをインストールするには、pipinstallを使用します
最初にCMDを開き、次のコードを入力します。-
> pip install serial
> pip install opencv-python
> pip install numpy
これらのコマンドは、必要なモジュールをインストールします。これで、コーディング部分に移ることができます...
ステップ3:Pythonスクリプト <図>
コードの記述を開始する前に、最初に行うことは、すべてのコードを同じフォルダーに保存する必要があるため、新しいフォルダーを作成することです。したがって、新しいフォルダを作成し、任意の名前を付けます。下から「Haarcascade」をダウンロードして、フォルダに貼り付けます。
次に、メモ帳を開いて以下のスクリプトを記述し、haarcascadeと同じフォルダーに「face.py」として保存します。 (以下のファイルで提供したコードをダウンロードできます):
#import必要なすべてのモジュール
import numpy as np
import serial
import time
import sys
import cv2
#Setup arduinoの通信パス(「COM5」の代わりに、arduinoが接続されているポートを配置します)
arduino =serial.Serial( 'COM5'、9600)
time.sleep(2)
print( "Connected to arduino ...")
#顔検出のためにHaarcascadeをインポートする
face_cascade =cv2.CascadeClassifier( 'haarcascade_frontalface_default.xml')
#からビデオストリームをキャプチャするにはウェブカメラ。
cap =cv2.VideoCapture(0)
#キャプチャした画像を読み取り、灰色の画像に変換して顔を見つけます
1:
ret、img =cap.read ()
cv2.resizeWindow( 'img'、500,500)
cv2.line(img、(500,250)、(0,250)、(0,255,0)、1)
cv2.line( img、(250,0)、(250,500)、(0,255,0)、1)
cv2.circle(img、(250、250)、5、(255、255、255)、-1)
グレー=cv2.cvtColor(img、cv2.COLOR_BGR2GRAY)
面=face_cascade.detectMultiScale(グレー、1.3)
#顔を検出し、その周りに長方形を作成します。
顔の(x、y、w、h)の場合:
cv2.rectangle(img、(x、y)、(x + w 、y + h)、(0,255,0)、5)
roi_gray =gray [y:y + h、x:x + w]
roi_color =img [y:y + h、x: x + w]
arr ={y:y + h、x:x + w}
print(arr)
print( 'X:' + str(x) )
print( 'Y:' + str(y))
print( 'x + w:' + str(x + w))
print( 'y + h:' + str(y + h))
#roiの中心(長方形)
xx =int(x +(x + h))/ 2
yy =int(y +(y + w)) / 2
print(xx)
print(yy)
center =(xx、yy)
#arduinoにデータを送信
print( "Center of Rectangle is: "、center)
data =" X {0:d} Y {1:d} Z ".format(xx、yy)
print(" output ='"+ data +"' ")
arduino.write(data)
#ストリームを表示します。
cv2.imshow( 'img'、img)
# 'Esc'を押して実行を終了します
k =cv2.waitKey(30)&0xff
if k ==27:
休憩
これが完了したら、Arduinoのコードの記述に進みます...
haarcascade_frontalface_default.xml face.py
ステップ4:Arduinoコード <図>
Pythonスクリプトの準備ができたら、サーボを制御するためのarduinoスケッチが必要です。以下のコードを参照して、Arduino IDEに貼り付け、face.pyおよびhaarcascadeと同じフォルダーに「servo.ino」として保存します。コードをアップロードし、次のステップに進んで接続します。
(ダウンロード可能なファイルは以下のとおりです。)
#include
ServoservoVer; //垂直サーボ
サーボサーボホール; //水平サーボ
int x;
int y;
int prevX;
int prevY;
void setup()
{
シリアル.begin(9600);
servoVer.attach(5); //垂直サーボをピン5に接続します
servoHor.attach(6); //水平サーボをピン6に接続します
servoVer.write(90);
servoHor.write(90);
}
void Pos()
{
if(prevX!=x || prevY!=y)
{
intservoX =map(x、600、0、70、179);
intservoY =map(y 、450、0、179、95);
servoX =min(servoX、179);
servoX =max(servoX、70);
servoY =min(servoY、179);
servoY =max(servoY、95);
servoHor.write(servoX);
servoVer.write(servoY);
}
}
void loop()
{
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();
}
}
}
サーボ.ino
ステップ5:パンチルトメカニズム:- <図>
パンチルト用にすぐに入手できるキットを使用しました。必要に応じて、木材/プラスチックまたは3Dプリントを使用して自分で作成することもできます。
私が使ったものはかなり安く、組み立てがとても簡単です。ただし、その方法についての説明が必要な場合は、ここで見つけることができます。
ステップ6:接続を確立する <図> <図>
回路はとてもシンプルです。 arduinoに2つのサーボを接続するだけです。
- ピン5に垂直
- ピン6に対して水平
- + 5Vへの電力
- GNDへの接地
参考のために回路図を確認してください。
ステップ7:テスト
- すべてが完了したら、最後に行うことは、それが機能するかどうかをテストすることです。最初にテストするには、サーボがarduinoに正しく接続され、スケッチがアップロードされていることを確認します。
- スケッチをアップロードしたら、ポートがPythonに自由に接続できるようにIDEを閉じてください。
- ここで、Python IDLEで「face.py」を開き、「F5」を押してコードを実行します。 arduinoに接続するのに数秒かかります。そうすると、Webカメラをストリーミングしているウィンドウが表示されるはずです。これで、コードがあなたの顔を検出し、サーボがそれを追跡します。
- オブジェクトを移動すると、サーボも移動するはずです。カメラをサーボに接続するだけで、サーボと一緒に移動します。
あなたがそれを好きになることを願っています。何か新しいことを学びましょう。
ありがとうございます!
コード
- servo.ino
- コードスニペット#2
- コードスニペット#3
servo.ino Arduino
ファイルを開くときにエラーが発生しました。コードスニペット#2 プレーンテキスト
#import必要なすべてのモジュールimportnumpy as npimport serialimport timeimport sysimport cv2#Setup arduinoの通信パス(「COM5」の代わりに、arduinoが接続されているポートを配置します)arduino =serial.Serial( 'COM5'、9600 )time.sleep(2)print( "Connected to arduino ...")#顔検出用のHaarcascadeのインポートface_cascade =cv2.CascadeClassifier( 'haarcascade_frontalface_default.xml')#webcam.cap =cv2.VideoCaptureからビデオストリームをキャプチャするには(0)#キャプチャした画像を読み取り、グレー画像に変換して顔を見つけます1:ret、img =cap.read()cv2.resizeWindow( 'img'、500,500)cv2.line(img、(500,250)、(0,250 )、(0,255,0)、1)cv2.line(img、(250,0)、(250,500)、(0,255,0)、1)cv2.circle(img、(250、250)、5、(255 、255、255)、-1)gray =cv2.cvtColor(img、cv2.COLOR_BGR2GRAY)faces =face_cascade.detectMultiScale(gray、1.3)#顔を検出し、その周りに長方形を作成します。面の(x、y、w、h)の場合:cv2.rectangle(img、(x、y)、(x + w、y + h)、(0,255,0)、5)roi_gray =gray [y:y + h、x:x + w] roi_color =img [y:y + h、x:x + w] arr ={y:y + h、x:x + w} print(arr)print( 'X:' + str(x))print( 'Y:' + str(y))print( 'x + w:' + str(x + w))print( 'y + h:' + str(y + h)) #ROIの中心(長方形)xx =int(x +(x + h))/ 2 yy =int(y +(y + w))/ 2 print(xx)print(yy)center =(xx、yy)#送信data to arduino print( "Center of Rectangle is:"、center)data ="X {0:d} Y {1:d} Z" .format(xx、yy)print( "output ='" + data + "' ")arduino.write(data)#ストリームを表示します。 cv2.imshow( 'img'、img)#Hit'Esc 'を実行して実行を終了しますk =cv2.waitKey(30)&0xff if k ==27:break
コードスニペット#3 プレーンテキスト
#includeServoservoVer; //垂直ServoServoservoHor; //水平サーボintx; int y; int prevX; int prevY; void setup(){Serial.begin(9600); ServoVer.attach(5); //垂直サーボをピン5に接続servoHor.attach(6); //水平サーボをピン6に接続servoVer.write(90); ServoHor.write(90);} void Pos(){if(prevX!=x || prevY!=y){intservoX =map(x、600、0、70、179); intservoY =map(y、450、0、179、95); ServoX =min(servoX、179); ServoX =max(servoX、70); ServoY =min(servoY、179); ServoY =max(servoY、95); ServoHor.write(servoX); ServoVer.write(servoY); }} void loop(){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(); }}}
製造プロセス