mediapipeの導入については、ドローンをmediapipeでジェスチャーコントロールを参照してください。(^^♪
次に、ロボットジェスチャーコントロールのコードをご紹介します。
カメラ映像はmediapipeで認識してます。VS CODEでそこでシリアル通信をし、Ardino IDEにシリアル値を送信します。
そのシリアル値をもとにサーボーモーターを制御していきます。
**備忘録**
Pythonスクリプト (Mediapipe + シリアル通信)
1 import cv2
2 import mediapipe as mp
3 import serial
4 import time
5
6 # シリアルポートの設定(Arduinoが接続されているポートに合わせる)
7 ser = serial.Serial(‘COM6’, 9600)
8 time.sleep(2) # シリアル接続が安定するまで待つ
9#mediapipeのコード
10 mp_pose = mp.solutions.pose
11 pose = mp_pose.Pose()
12 mp_drawing = mp.solutions.drawing_utils
13
14 cap = cv2.VideoCapture(0)
15
16 while cap.isOpened():
17 success, image = cap.read()
18 if not success:
19 break
20
21 image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
22 results = pose.process(image_rgb)
23
24 if results.pose_landmarks:
25 mp_drawing.draw_landmarks(image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS)
26
27 nose = results.pose_landmarks.landmark[0]#鼻のランドマークno.
28 left_wrist = results.pose_landmarks.landmark[15] # 左手首
29
30
31 # 鼻のx座標を0〜180の範囲に変換(サーボ1の角度範囲)
顔が左から右に移動するのに応じてサーボモーターを連動させるには、顔の位置(特に鼻のx座標)を継続的に追跡し、そのx座標の変化に基づいてサーボモーターの角度を変更する必要があります。
Mediapipeを使用して鼻のx座標を取得し、その値をArduinoに送信します。x座標の範囲は0.0から1.0なので、これを0から180の範囲にスケール変換してサーボの角度に対応させます。
Mediapipeのランドマーク座標系
*(注)Mediapipeの座標系では、x座標とy座標の値は0.0から1.0の範囲で正規化されていますが、画面の左上が原点 (0,0) で、右下が (1,1) になります。具体的には:
x
が 0.0 は画面の左端、1.0 は画面の右端y
が 0.0 は画面の上端、1.0 は画面の下端
32 nose_x = int(nose.x * 180)
33 nose_x = max(0, min(180, nose_x)) # 範囲外の値を修正
####1.min(180, nose_x)
###この部分は、nose_xと180のうち、小さい方の値を返します。
- nose_xが180より小さい場合:min(180, nose_x) は nose_x を返します。
- nose_xが180より大きい場合:min(180, nose_x) は 180 を返します。
###########結果、nose_xの最大値が180に制限されます。
######2. max(0, min(180, nose_x))
###次に、上記の結果と0のうち、大きい方の値を返します。
- min(180, nose_x) が0より大きい場合:max(0, min(180, nose_x)) は min(180, nose_x) を返します。
- min(180, nose_x) が0より小さい場合:max(0, min(180, nose_x)) は 0 を返します。
#####結果、nose_xの最小値が0に制限されます
34
35 # 手首のy座標を0〜180の範囲に変換(サーボ2の角度範囲)
36 wrist_y = int((1 – left_wrist.y) * 180) # 左手首を使用(右手首を使用する場合はright_wrist.yを使用)
wrist_y = int((1 – left_wrist.y) * 180)という計算式で1から引いている理由は、Mediapipeのランドマーク座標系におけるy座標の定義と、サーボモーターの角度範囲を合わせるためです。*(注)参照
サーボモーターの角度範囲
サーボモーターの角度範囲は通常0度から180度までです。
y座標の逆転
画面の座標系では上が0.0で下が1.0ですが、視覚的には上を0度、下を180度としてサーボモーターを制御するため、座標を逆転させる必要があります。これを実現するために 1 – left_wrist.y としています。具体的には:
left_wrist.y
が 0.0 のとき、上端にあり、サーボモーターは 180度left_wrist.y
が 1.0 のとき、下端にあり、サーボモーターは 0度
この逆転を考慮した式が wrist_y = int((1 - left_wrist.y) * 180)
です。
37 wrist_y = max(0, min(180, wrist_y)) # 範囲外の値を修正
38
39 # シリアル通信でデータを送信
40 ser.write(f”{nose_x},{wrist_y}\n”.encode())
# シリアル通信でデータを送信
ser.write(f”{nose_x}\n”.encode())
ser.write(f”{nose_x}\n”.encode()) は、シリアルポートを介してデータを送信するためのPythonコードです。
1. f”{nose_x}\n”
この部分は、Pythonのf文字列を使用して、nose_x
の値を文字列としてフォーマットしています。
- f”{nose_x}” は nose_xの値を文字列に変換します。 例えば、nose_xが90の場合、f”{nose_x}” は “90” となります。
- \n は改行文字を表します。 これにより、送信する文字列の末尾に改行が追加されます。
したがって、f”{nose_x}\n” は nose_xの値に改行文字を追加した文字列を生成します。
なぜf”stringをつかうかというと、
Pythonのf文字列(フォーマット済み文字列リテラル)を使用して、nose_x
の値を文字列としてフォーマットする理由は、データをシリアルポート経由で送信する際に、nose_x
の値を適切な形式で整形し、送り出すためです。
シリアル通信でデータを送る際には、数値データ(例えば、nose_x
の値)を文字列形式に変換する必要があります。シリアルポートでは、バイナリデータか文字列データを送ることができ、通常、文字列データとして送信するのが簡単です。f文字列を使用することで、nose_x
の数値を簡単に文字列に変換できます。シリアル通信では、送信データの区切りとして改行文字(\n
)を使うことが一般的です。受信側が改行文字を検出して1行のデータの終わりとみなすことで、データの区切りを認識します。f文字列を使うことで、改行文字を簡単に追加できます。
2. .encode()
この部分は、生成された文字列をバイト列(bytes)に変換します。
- .encode() は、デフォルトでUTF-8エンコーディングを使用して文字列をバイト列に変換します。 例えば、
"90\n"
をバイト列に変換すると b’90\n’ となります。
3. ser.write()
この部分は、シリアルポートを介してデータを送信するために使用されます。
- ser は、serial.Serialオブジェクトで、特定のシリアルポートに接続されています。
- write() メソッドは、バイト列をシリアルポートに書き込みます。
41
42 cv2.putText(image, f’Nose X: {nose_x}’, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2, cv2.LINE_AA)
43 cv2.putText(image, f’Wrist Y: {wrist_y}’, (10, 70), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2,
cv2.LINE_AA)
44
45 cv2.imshow(‘Pose Estimation’, image)
46 if cv2.waitKey(5) & 0xFF == 27:
47 break
48
49 cap.release()
50 cv2.destroyAllWindows()
51 ser.close()
Arduino IDEでサーボモーターを制御:Pythonスクリプトから受信した鼻のx座標に基づいてサーボモーターの角度を設定します。
include <Servo.h>
Servo myServo; // サーボオブジェクト
int pos = 90; // 初期位置
void setup() {
myServo.attach(12); // サーボをデジタルピン12に接続
Serial.begin(9600); // シリアル通信を開始
}
void loop() {
if (Serial.available() > 0) {
String data = Serial.readStringUntil(‘\n’); // シリアルデータを読み取る *\nは、改行コードまで取得。
pos = data.toInt(); // 受信データを整数に変換
//シリアル通信で受け取った文字列をString型オブジェクトに格納している場合は、toInt()を使用します。
toInt()は文字列を整数に変換するメソッド。変換結果は、long型で返されます。
pos = constrain(pos, 0, 180); // サーボの範囲に制限
//pos = constrain(x, a, b);posを0以上180以下の範囲に収めます。
xがa以上b以下のとき、xはそのまま返ります。xがaより小さい時は、a。 bより大きい時はbが返ります。
myServo.write(pos); // サーボの位置
}
投稿
- 空撮事始め (2021年6月18日)
- 航空法施行規則改正されました。令和3年6月1日 (2021年6月19日)
- Tello(Ryze Technology 社 POWERED BY DJI)の飛ばし方マニュアル (2021年7月5日)
- 趣味におすすめ!ドローン(Tello)のいろいろな楽しさをお伝えします。 (2021年7月5日)
- プログラミング言語って?Pythonの導入前にプログラミング言語の種類をおおまかにまとめてみました。 (2021年7月6日)
- ドローンのプログラミングらしき事をやってみる! はじめてのPython&IDEのインストール方法 (2021年7月7日)
- Tello の画像をOpenCVでPCに写してみる!!OpenCVの導入方法 (2021年7月9日)
- これだけは知っておこう!ドローンを飛ばすのに法律って関係あるの? (2021年7月15日)
- ドローンの空撮は最高!きままに撮ってみました(^^♪ 空撮Gallery集 (2021年7月30日)
- ドローンを飛ばすなら これだけは知っておこう!ドローンの飛行ルール(令和3年6月施行) (2021年7月30日)
- これだけは知っておこう!ドローン空撮には注意が必要です。映像等のインターネット上での注意事項。 (2021年7月30日)
- socket通信プログラムの部分を少しだけ解説してみました (2021年9月2日)
- OpenCVで遊んでみる。 PC内蔵webカメラから動画の撮影。 (2021年9月14日)
- PCでOpenCVで顔認識して遊んでみる。(^^♪ カスケード分類器の使い方 (2021年10月30日)
- ドローン・無人航空機の登録が義務化されます。リモートIDの付け方 (2021年12月14日)
- ドローンのプログラミングでOpenCVをつかい顔認識をしてみる (2022年1月9日)
- ドローン(Tello)を飛ばしてOpenCVで顔認識してみる改良版 (2022年2月21日)
- TelloでOpenCVで顔認識させたらFLIP(フリップ)させる(^^♪ (2022年5月2日)
- Pythonを使いTello(ドローン)でOpenCV(顔認識)から自動追尾をしてみる!☺ (2022年6月13日)
- フィンガーサインでドローン(Tello)を操縦してみた!MediaPipeを使用 (2022年9月29日)
- Pythonプログラミング・OpenCv&MediaPipeを使いドローン(Tello)を自由に操縦してみた! (2022年11月21日)
- Pythonで「Tello(ドローン)で自動追尾プログラミング」改良版を紹介します!これはいける! (2023年3月22日)
- OpenCVで遊んでみる。 PC内蔵カメラから映像の表示 と ドローンからの映像を表示をする (2023年4月13日)
- Telloとパソコンの通信の部分を少しわかりやすくしてみました (2023年4月13日)
- 100g未満のドローン、100g以上のドローンを飛ばすには?法律や準備しないといけないことは何? (2023年4月21日)
- mediapipe(メディアパイプ)& OpenCV・ Pythonでposeランドマーク検出Telloの自動操縦 (2023年5月8日)
- プログラミングで動かせるオススメ!ドローン・ロボット ベスト2選!! (2023年6月1日)
- 海外、子供に人気!プログランミングで動かせるドローンLitebeeWing紹介(パソコン接続方法解説)します。 (2023年7月2日)
- 講座用ダウンロード サイト (2023年7月7日)
- ドローン(Tello)を音声認識コントロールできる?パソコンで2か所Wi-Fi接続してGoogle Speech to Text (2023年7月9日)
- 最近はまっている 楽しーい気分転換アイテム ドローン&プログラミング学習用教材&ラジコン (2023年7月26日)
- Scratch(スクラッチ)ビデオモーションセンサーでTello(ドローン)操作 AR「拡張現実」? (2024年1月31日)
- スクラッチ(Scratch3-Tello) & (マイコンボード)micro:bitを使って、Telllo(ドローン)をコントロールしてみた(^^♪ (2024年5月5日)
- マイコンでドローン感知ロボットを作ってみました(^^♪ microbit & arduino (2024年6月1日)
- mediapipe & Arduino で 自称ロボットのジェスチャーコントロール (2024年6月5日)
- M5Stackを内蔵のESP32でWiFiサーバーとして使い、コードレスで無線ジェスチャーコントロールをしてみました(^^)/ (2024年6月12日)
- ロボットアーム(ベクトル内積を使った)ジェスチャーコントロール *目指せ老後の食事介助アーム* (2024年6月27日)
- LiteBee Wing/ SKY / Tello でドローンプログラミングを教えます。プログラミングしたい人集まれ(^^♪ (2024年7月3日)
- 自由研究に!「ドローンをつくろう!学ぼう!」by 神戸ロボットクラブ (2024年8月17日)