google street viewを自動操縦してみる

# きっかけ
ランニングマシンと連動して、ストリートビューで疑似ランニングを実現したい！
→とりあえず自動操縦してみる？？（自動で前進）

備忘録＆アウトプットの練習として執筆。
もはやただのメモ。
マークアップ記法難しいなぁ。

# 仕組み
・ブラウザで表示したストリートビューをキーボード操作で動かす
・キーボード操作はpyautoguiで自動化
・左折、右折はハンドジェスチャーで

# 操縦方法
1.ブラウザで走りたい地点のストリートビューを表示
※HTMLで専用ページ作った

2.自動操縦用のpythonコードをコマンドラインで実行
※今回はanacondaのpromptで実行
※バッチファイルにして、実行簡略化

3.自動で前進、ピースサインで左折、4本指で右折


# 自動操縦pythonコード
かなり無駄多め。

```main_2-1.py
import cv2
import mediapipe as mp
import os
import pyautogui
import time
import webbrowser
import pygetwindow as gw
import keyboard

from selenium import webdriver

 
######################################
# handDetector クラス
######################################
class handDetector():
 
	# 初期化処理
	def __init__(self, mode=False, maxHands = 2, modelComplexity = 1, detectionCon = 0.5, trackCon = 0.5):
		self.mode = mode
		self.maxHands = maxHands
		self.modelComplexity = modelComplexity
		self.detectionCon = detectionCon
		self.trackCon = trackCon
 
		self.mpHands = mp.solutions.hands
		self.hands = self.mpHands.Hands(self.mode, self.maxHands, self.modelComplexity, 
							self.detectionCon, self.trackCon)
		self.mpDraw = mp.solutions.drawing_utils
 
	# ランドマークを描画する
	def DrawLandmarks(self, img, draw = True):
		imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
		self.results = self.hands.process(imgRGB)
 
		if self.results.multi_hand_landmarks:
			for handLms in self.results.multi_hand_landmarks:
				if draw:
					self.mpDraw.draw_landmarks(img, handLms, 
							self.mpHands.HAND_CONNECTIONS)
		return img
	
	# ポジション座標を取得する
	def GetPosition(self, img, handNo = 0, draw = True):
 
		PositionList = []
		if self.results.multi_hand_landmarks:
			myHand = self.results.multi_hand_landmarks[handNo]
			for id, lm in enumerate(myHand.landmark):
				h, w, c = img.shape
				cx, cy = int(lm.x * w), int(lm.y * h)
				PositionList.append([id, cx, cy])
				if draw:
					cv2.circle(img, (cx, cy), 10, (255, 0, 255), cv2.FILLED)
 
		return PositionList
 
######################################
# 内部変数の定義
######################################
wCam, hCam = 600, 400          # USB カメラで取り込むイメージサイズ
tipIds = [4, 8, 12, 16, 20]     # 親指、人差し指 ～ 小指 のインデックス
wipeX = wCam            # ワイプの横サイズ
wipeY = hCam             # ワイプの縦サイズ
maxFingerIndex = 1              # 指の数

# カメラ準備 ###############################################################
# VideoCapture インスタンスを生成し縦横のサイズを設定する
cap = cv2.VideoCapture(0)

cap.set(cv2.CAP_PROP_FRAME_WIDTH, wCam)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, hCam)
 
#画面サイズ取得 
scr_w,scr_h= pyautogui.size()

cent_x = scr_w/2
cent_y = scr_h/2

w_title = 'auto_run_2023'

######################################


pyautogui.alert(text="escで終了します",title='確認',button='OK')

# handDetector クラスのインスタンスを生成する
detector = handDetector(detectionCon = 0.5)
 
while True:
 
	# USB カメラの映像を読み出す
	success, imgVideo = cap.read()
 
	# 映像にランドマークを描画する
	img = detector.DrawLandmarks(imgVideo)
 
	# 座標データを取得する
	Positionlist = detector.GetPosition(img, draw = False)
 
	# 座標データを出力する
	print(Positionlist)

	
	
	
	# 指定された番号の操作を行う
	
	if  keyboard.is_pressed('esc'):
		pyautogui.alert(text="終了します",title='確認',button='OK')
		break
		
	elif maxFingerIndex == 2:
		success, pyautogui.keyDown('left')
		
	elif maxFingerIndex == 4:
		success, pyautogui.keyDown('right')
	
	else:	
		pyautogui.moveTo(cent_x,cent_y)
		pyautogui.click()
		pyautogui.press('w' , interval= 0.5)
	
	# ポジションデータが取得できているかどうかチェック
	if len(Positionlist) != 0:
 
		fingers = []
 
		# 親指の時
		if Positionlist[tipIds[0]][1] > Positionlist[tipIds[0] - 2][1]:
			maxFingerIndex = 5
 
		# 親指以外の 4 本の時
		else:
			for id in range(1, 5):
				if Positionlist[tipIds[id]][2] < Positionlist[tipIds[id] - 2][2]:
					# print("Index finger open")
					maxFingerIndex = id
	
 
	# 映像を表示する
	
	cv2.imshow(w_title, img)
	# Window位置の変更　第1引数：Windowの名前　第2引数：x 第3引数：y
	cv2.moveWindow(w_title, scr_w-600,scr_h-400)
 
	key = cv2.waitKey(1)
	if key == 27: # ESC で映像を停止する
		break
```
# おまけ
ストリートビューへ飛ぶページ
中央ボタンをクリックで各地へジャンプ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3063371/1d8f30dc-e189-f567-d563-fc85407fefab.png)


# 参考にしたサイト
大変お世話になりました。
【自動操縦関連】
・https://www.nsfarm.life/page2021/acl2021BlogMediapipeWipe.html
・https://github.com/Kazuhito00/simple-virtual-mouse-using-mediapipe

【HTML関連】
・https://nawmin.com/
・https://125naroom.com/
・https://fonts.google.com/