PC から ssh -X 接続
$ source ./venv/bin/activate
(venv) $ cd ~/Tensorflow-YOLOv3
(venv) $ vi facing.py
#!/usr/bin/env python
##### モデル tiny YOLO の設定 #################
from core.utils import load_class_names, load_image, draw_boxes, draw_boxes_frame
from core.yolo_tiny import YOLOv3_tiny
from core.yolo import YOLOv3
# object のクラス
class_names, n_classes = load_class_names()
iou_threshold = 0.1
confidence_threshold = 0.25
model = YOLOv3_tiny(n_classes=n_classes, iou_threshold=iou_threshold, confidence_threshold=confidence_threshold)
import tensorflow as tf
inputs = tf.placeholder(tf.float32, [1, *model.input_size, 3])
detections = model(inputs)
saver = tf.train.Saver(tf.global_variables(scope=model.scope))
##### GoPiGo motor ##########################
from easygopigo3 import EasyGoPiGo3
egpg = EasyGoPiGo3()
from time import sleep
egpg.set_speed(10)
def rotation( t ):
print('t:' + str(t))
if t > 0:
egpg.right()
sleep(t)
else:
egpg.left()
sleep(-t)
egpg.stop()
##### カメラ映像画面の dx に対する GoPiGo 回転時間 t ##############
def pixel2t( dx ):
abs_dx = abs( dx )
if abs_dx < 60:
return round( dx * 3 / 50 )
elif abs_dx < 110:
return round( dx * 4.5 / 100 )
elif abs_dx < 160:
return round( dx * 6 / 150 )
elif abs_dx < 210:
return round( dx * 9 / 200 )
elif abs_dx < 310:
return round( dx * 12 / 300 )
else:
return round( 12 * dx / abs_dx )
##### カメラ取込画像 ##########################
# ヨコ, タテ
CAMERA_WIDTH = 640
CAMERA_HEIGHT = 480
# 中心
img_center_x = CAMERA_WIDTH/2
img_center_y = CAMERA_HEIGHT/2
##### トラッキング対象 #################
target_class = 'sports ball'
# 配列 class_names における target object の番号 target_n を求める
for n in range(len(class_names)):
if class_names[n] == target_class:
target_n = n
break
##### exit プロセス #################
import cv2
import sys
def destroy():
# GoPiGo クリーンアップ
egpg.reset_all()
#カメラキャプチャを停止
cap.release()
#ストリーミングウインドを閉じる
cv2.destroyAllWindows()
#プログラムを終了
sys.exit()
##### START ##########################
with tf.Session() as sess:
# モデル tiny YOLO の読み込み
saver.restore(sess, './weights/model-tiny.ckpt')
# カメラ映像の読み込み
# カメラの番号:0
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
# ヨコ,タテ
frame_size = (frame.shape[1], frame.shape[0])
resized_frame = cv2.resize(frame, dsize=tuple((x) for x in model.input_size[::-1]), interpolation=cv2.INTER_NEAREST)
result = sess.run(detections, feed_dict={inputs: [resized_frame]})
#カメラ映像の表示
draw_boxes_frame(frame, frame_size, result, class_names, model.input_size)
cv2.imshow('frame', frame)
#### target_class の検出 ####
boxes_dict = result[0]
boxes = boxes_dict[target_n]
resize_factor = (frame_size[0] / model.input_size[1], frame_size[1] / model.input_size[0])
if( len(boxes) != 0):
print("\nターゲット発見")
for box in boxes:
coordinates = box[:4]
coordinates = [int(coordinates[i] * resize_factor[i % 2]) for i in range(4)]
# object の中心
object_center_x = int((coordinates[0]+coordinates[2])/2)
# 画像中心からの object 中心のズレ
dx = object_center_x - img_center_x
print("中心ズレ:" + str(dx))
# dx > 20 ならば,GoPiGo の回転
if abs(dx) > 20:
rotation( pixel2t( dx ) )
# 残りの box は取り上げない
break
# <for box in boxes> ここまで
# <if( len(boxes) != 0)> ここまで
# 画像ウィンドウをアクティブにして 'q' キーを押すと, break
if cv2.waitKey(10) & 0xFF == ord('q'):
destroy()
|
(venv) $ chmod +x facing.py
(venv) $ ./facing.py
このプログラムを実行すると,カメラ画像の読み込みの遅延のために,つぎのようなことが起こる:
ターゲット発見
中心ズレ:184.0
t:8
ターゲット発見
中心ズレ:183.0
t:8
ターゲット発見
中心ズレ:183.0
t:8
ターゲット発見
中心ズレ:184.0
t:8
ターゲット発見
中心ズレ:184.0
t:8
ターゲット発見
中心ズレ:183.0
t:8
この場合,GoPiGo は 8 × 6 = 48 秒間,同一方向に回転を続けることになる。
このトラブル──同じ画像が繰り返し読み込まれる──は,ハードウェアの限界によるものなので,どうしようもない。
当座の対処として,object_center_x の値が前のループのときの値と ≦ 20 の違いしかないときは,rotation( pixel2t( dx ) ) をスキップするようにプログラムしておく。
また,egpg.set_speed(10) は遅過ぎるので,egpg.set_speed(50) に変更し,この変更に合わせて pixel2t( dx ) の定義の中の数値を変更する:
(venv) $ vi facing.py
#!/usr/bin/env python
##### モデル tiny YOLO の設定 #################
from core.utils import load_class_names, load_image, draw_boxes, draw_boxes_frame
from core.yolo_tiny import YOLOv3_tiny
from core.yolo import YOLOv3
# object のクラス
class_names, n_classes = load_class_names()
iou_threshold = 0.1
confidence_threshold = 0.25
model = YOLOv3_tiny(n_classes=n_classes, iou_threshold=iou_threshold, confidence_threshold=confidence_threshold)
import tensorflow as tf
inputs = tf.placeholder(tf.float32, [1, *model.input_size, 3])
detections = model(inputs)
saver = tf.train.Saver(tf.global_variables(scope=model.scope))
##### GoPiGo motor ##########################
from easygopigo3 import EasyGoPiGo3
egpg = EasyGoPiGo3()
from time import sleep
egpg.set_speed(50)
def rotation( t ):
print('t:' + str(t))
if t > 0:
egpg.right()
sleep(t)
else:
egpg.left()
sleep(-t)
egpg.stop()
##### カメラ映像画面の dx に対する GoPiGo 回転時間 t ##############
def pixel2t( dx ):
abs_dx = abs( dx )
if abs_dx < 60:
return dx * 0.6 / 50
elif abs_dx < 110:
return dx * 0.9 / 100
elif abs_dx < 160:
return dx * 1.2 / 150
elif abs_dx < 210:
return dx * 2.2 / 200
elif abs_dx < 310:
return dx * 2.4 / 300
else:
return 2.4 * dx / abs_dx
##### カメラ取込画像 ##########################
# ヨコ, タテ
CAMERA_WIDTH = 640
CAMERA_HEIGHT = 480
# 中心
img_center_x = CAMERA_WIDTH/2
##### トラッキング対象 #################
target_class = 'sports ball'
# 配列 class_names における target object の番号 target_n を求める
for n in range(len(class_names)):
if class_names[n] == target_class:
target_n = n
break
##### exit プロセス #################
import cv2
import sys
def destroy():
# GoPiGo クリーンアップ
egpg.reset_all()
#カメラキャプチャを停止
cap.release()
#ストリーミングウインドを閉じる
cv2.destroyAllWindows()
#プログラムを終了
sys.exit()
##### START ##########################
with tf.Session() as sess:
# モデル tiny YOLO の読み込み
saver.restore(sess, './weights/model-tiny.ckpt')
# カメラ映像の読み込み
# カメラの番号:0
cap = cv2.VideoCapture(0)
# 前回ループのときの object_center_x 値を留める変数
object_center_x_last = img_center_x
while True:
ret, frame = cap.read()
# ヨコ,タテ
frame_size = (frame.shape[1], frame.shape[0])
resized_frame = cv2.resize(frame, dsize=tuple((x) for x in model.input_size[::-1]), interpolation=cv2.INTER_NEAREST)
result = sess.run(detections, feed_dict={inputs: [resized_frame]})
#カメラ映像の表示
draw_boxes_frame(frame, frame_size, result, class_names, model.input_size)
cv2.imshow('frame', frame)
#### target_class の検出 ####
boxes_dict = result[0]
boxes = boxes_dict[target_n]
resize_factor = (frame_size[0] / model.input_size[1], frame_size[1] / model.input_size[0])
if( len(boxes) != 0):
for box in boxes:
coordinates = box[:4]
coordinates = [int(coordinates[i] * resize_factor[i % 2]) for i in range(4)]
# object の中心
object_center_x = int((coordinates[0]+coordinates[2])/2)
if abs( object_center_x - object_center_x_last ) > 20:
print("\nターゲット発見")
object_center_x_last = object_center_x
# 画像中心からの object 中心のズレ
dx = object_center_x - img_center_x
print("中心ズレ:" + str(dx))
# dx > 20 ならば,GoPiGo の回転
if abs(dx) > 20:
rotation( pixel2t( dx ) )
# 残りの box は取り上げない
break
# <for box in boxes> ここまで
# <if( len(boxes) != 0)> ここまで
# 画像ウィンドウをアクティブにして 'q' キーを押すと, break
if cv2.waitKey(10) & 0xFF == ord('q'):
destroy()
|
(venv) $ ./facing.py
|