Oculus GoのゲームをUnityで作る★その1
Oculus GoのゲームをUnityで組んでみる
コントローラ取得
Unityでゲームを作るのに必ず必要なことがあります。 それはコントローラからの入力をスクリプトで取得することです。 まず、コントローラ入力を取得する方法を調べたのでメモとして書いておきます。
元の記事 https://qiita.com/ry-kgy/items/2b783b969c874ef4cc64
バックボタン
バックボタン入力取得
OVRInput.Get(OVRInput.Button.Back)
トリガー
トリガーを押した入力の取得
OVRInput.GetDown(OVRInput.Button.PrimaryIndexTrigger)
トリガーを離した入力の取得
OVRInput.GetUp(OVRInput.Button.PrimaryIndexTrigger)
タッチパッド
クリックの入力取得
OVRInput.Get(OVRInput.Button.PrimaryTouchpad)
Up方向の入力取得
OVRInput.Get(OVRInput.Button.Up)
Down方向の入力取得
OVRInput.Get(OVRInput.Button.Down)
Left方向の入力取得
OVRInput.Get(OVRInput.Button.Left)
Right方向の入力取得
OVRInput.Get(OVRInput.Button.Right)
位置
位置の取得
Vector2 vector = OVRInput.Get(OVRInput.Axis2D.PrimaryTouchpad)
次回簡単な実装に挑戦
入力系統は以上ですので、あとはUnityでシンプルなゲームを作っていきたいと思います。 アンドロイドでビルドすれば動作するようなので、 次回以降は実際にゲームを組み、Oculus Go実機での動作確認を進めていきます。
OpenCVの基本操作の一部
OpenCVをPythonで操作する基本的な話をメモ的に記載します。
ヒストグラム
import cv2 import matplotlib.pyplot as plt img = cv2.imread("画像データのPath") #カラー画像の場合 color_list = ["blue", "green", "red"] for i,j in enumerate(color_list): hist = cv2.calcHist([img], [i], None, [256], [0, 256]) plt.plot(hist, color = j) #グレースケール画像の場合 img_gray = cv2.imread("画像データのPath", 0) hist2 = cv2.calcHist([img_gray], [0], None, [256], [0,256]) plt.plot(hist2) #ヒストグラムの均一化 img_eq = cv2.equalizeHist(img) hist_e = cv2.calcHist([img_eq], [0], None, [256], [0, 256]) plt.plot(hist_e)
γ変換
画面を明るくしたり暗くしたりする処理
import numpy as np #明るくするにはgamma > 1 gamma = 1.5 gamma_cvt = np.zeros((256, 1), dtype=np.uint8) for i in range(256): gamma_cvt[i][0] = 255 * (float(i)/255) ** (1.0/gamma) img_gamma = cv2.LUT(img, gamma_cvt) #暗くするにはgamma < 1 gamma = 0.4 gamma_cvt = np.zeros((256, 1), dtype=np.uint8) for i in range(256): gamma_cvt[i][0] = 255 * (float(i)/255) ** (1.0/gamma) img_gamma = cv2.LUT(img, gamma_cvt)
以上、簡単な操作の一部でした。
PythonでOpenCVを使ってみた
画像を開く、保存する
import cv2 img = cv2.imread("画像ファイルPath") cv2.imwrite("保存ファイルPath", img)
動画を開く、保存する
import cv2 video = cv2.VideoCapture("動画ファイルPath") if cap.isOpened() == False: sys.exit() ret, frame = cap.read() h, w = frame.shape[:2] fourcc = cv2.VideoWriter_fourcc(*"XVID") dst = cv2.VideoWriter("保存ファイルPath", fourcc, 30.0, (w,h))
リサイズ
import cv2 img = cv2.imread("画像ファイルPath") size = (300, 200) #変更後のサイズを指定する img_resize = cv2.resize(img, size)
以上の簡単な操作を行いました。
フルスクラッチで単回帰分析をやってみる
機械学習の理解を深める
Pythonにはsklearnという便利な機械学習ライブラリがあります。 ただ、内部の計算に触れることは大事だと思うのです。 というわけで今回は単回帰分析をsklearnを使わずに実装します。
計算の準備
計算式の確認をします。 単回帰なのでパラメータは一つです。 パラメータをaとすると、
上記のようになります。
簡単な計算式ですので、簡単に実装できます。例えば、pandasのデータフレームを使えば、
次のように実装できると思います。
xx = x * x xy = x * y a = xy.sum() / xx.sum()
簡単にパラメータが求められます。 データからの予測値は
上記の式で求めることができます。 実際にデータを扱うときはすこしデータに手を加えて、 値から平均を引いた値を使って計算しやすくするなどの工夫をしたほうがいいと思います。
TensorFlowでMNISTを使ってみる
今回やったこと
TensorFlowのチュートリアルを今回やってみました。 MNISTというかなり有名な数字画像の識別問題をやってみます。
どうやったか?
チュートリアルに倣ってsoftmaxと勾配降下法を使いました。 ミニバッチでランダムにサンプルを選んで学習させてマシンへの負担を減らしています。
PythonでのコードはTensorFlowのチュートリアルにあるので省略します。
結果は92%の識別精度が出ました!
特別なことを特にしていないのにすごい精度ですね。
99%以上の精度を出す方法もあることが知られていますが、
それはDeepLearningを使っているそうです。
MNISTは何回かコード書いて遊んでますが、TensorFlowを使うとコーディング楽ですね。
DeepQ-NetworkでOpenAI Gymに挑戦!
DeepQ-Networkとは
一言で言うと多層のQネットワークです。 Qネットワークに隠れ層を追加して多層化したもので、 今回はExperience Replayというアルゴリズムを使って実装していきます。 メモリにステート、アクション、次のステート、次のアクションを記録していきます。 メモリの上限を超えたら端から消していくDouble Ended Queueと呼ばれる構造を使いたいと思います。
今回はカートポールというOpenAI Gymの有名なゲームに挑戦します。
Pythonでサクサクと実装していきます。 コードを全部載せると長いので省略して書いていきます。
#Q-Networkのクラス class QNetwork: def __init__(self,learning_rate=0.01,state_size=4,action_size=2,hidden_size=10,name="QNetwork"): with tf.variable_scope(name): self.inputs_ = tf.placeholder(tf.float32,[None,state_size],name="inputs") self.actions_ = tf.placeholder(tf.int32,[None],name="actions") one_hot_actions = tf.one_hot(self.actions_,action_size) self.targetQs_ = tf.placeholder(tf.float32,[None],name="target") self.fc1 = tf.contrib.layers.fully_connected(self.inputs_,hidden_size) self.fc2 = tf.contrib.layers.fully_connected(self.fc1,hidden_size) self.output = tf.contrib.layers.fully_connected(self.fc2,action_size,activation_fn=None) self.Q = tf.reduce_sum(tf.multiply(self.output,one_hot_actions),axis=1) self.loss = tf.reduce_mean(tf.square(self.targetQs_-self.Q)) self.opt = tf.train.AdamOptimizer(learning_rate).minimize(self.loss)
#MemoryObjectのクラス from collections import deque class Memory: def __init__(self,max_size=2000): self.buffer = deque(maxlen=max_size) def add(self,experience): self.buffer.append(experience) def sample(self,batch_size): idx = np.random.choice(np.arange(len(self.buffer)),size=batch_size,replace=False) return [self.buffer[i] for i in idx]
#Experience Memory env.reset() state,reward,done,_ = env.step(env.action_space.sample()) memory = Memory(max_size=memory_size) for i in range(pretrain_length): action = env.action_space.sample() next_state,reward,done,_ = env.step(action) if done: next_state = np.zeros(state.shape) memory.add((state,action,reward,next_state)) env.reset() state,reward,done,_ = env.step(env.action_space.sample()) else: memory.add((state,action,reward,next_state)) state = next_state
隠れ層は64個、トレーニング回数は2000回とします。
トレーニングが完了したらいつものように、ゲームを実行してみます。
ゲームのスコアは199.0でした!
最大スコアが200なのでうまく学習してくれたことがわかります。
強化学習は面白いですね!