PC から ssh -X 接続
$ source ./venv/bin/activate
(venv) $ cd ~/Tensorflow-YOLOv3
(venv) $ vi reach.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))
##### ターゲット #################
target_class = 'bottle'
# 配列 class_names における target object の番号 target_n を求める
for n in range(len(class_names)):
if class_names[n] == target_class:
target_n = n
break
##### カメラ取込画像 ##########################
# ヨコ, タテ
CAMERA_WIDTH = 640
CAMERA_HEIGHT = 480
# 中心
ImgCenter_x = CAMERA_WIDTH/2
###### GPIO ####################################
import RPi.GPIO as GPIO
# Set the GPIO pins as numbering
GPIO.setmode(GPIO.BOARD)
###### Sensor ####################################
TrigPin = 22
EchoPin = 18
# Set the TrigPin's mode is output
GPIO.setup(TrigPin,GPIO.OUT)
GPIO.output(TrigPin, GPIO.LOW)
# Set the EchoPin's mode is input, and ON→ HIGH
GPIO.setup(EchoPin, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
###### Distance from obstacle where GoPiGo should stop : 20cm
distance_to_stop = 30
###### 距離計測 ####################################
import time
def dist_read():
# 10us pulse to TrigPin
time.sleep(0.3)
GPIO.output(TrigPin, GPIO.HIGH)
time.sleep(0.00001)
GPIO.output(TrigPin, GPIO.LOW)
# 超音波発信
# EchoPin が LOW から HIGH に変わる時刻 signaloff
while GPIO.input(EchoPin) == GPIO.LOW:
signaloff = time.time()
# EchoPin が HIGH から LOW に変わる時刻 signalon
while GPIO.input(EchoPin) == GPIO.HIGH:
signalon = time.time()
# EchoPin が HIGH だった時間
timepassed = signalon - signaloff
distance = timepassed * 17000
return round(distance)
##### GoPiGo motor ##########################
from easygopigo3 import EasyGoPiGo3
egpg = EasyGoPiGo3()
import time
## 回転 ####################
def rotation( t ):
egpg.set_speed(50)
print('rotation t:' + str(t))
if t > 0:
egpg.right()
time.sleep(t)
else:
egpg.left()
time.sleep(-t)
egpg.stop()
## カメラ映像画面の dx に対する GoPiGo 回転時間 t
# 車輪モータの set_speed 値が 50 のとき
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
## 前進 ###############
# go forward 1sec
def go_fwd():
egpg.set_speed(100)
egpg.forward()
time.sleep(1)
egpg.stop()
##### exit プロセス #################
import cv2
import sys
def bye():
input('キー入力で, プログラム終了...')
egpg.stop()
# Release resource
GPIO.cleanup()
egpg.reset_all()
#カメラキャプチャを停止
cap.release()
#ストリーミングウインドを閉じる
cv2.destroyAllWindows()
#プログラムを終了
sys.exit()
#####################################################
##### Program starts from here ##########################
#####################################################
with tf.Session() as sess:
# モデル tiny YOLO の読み込み
saver.restore(sess, './weights/model-tiny.ckpt')
# カメラ映像の読み込み (カメラ番号は 0)
cap = cv2.VideoCapture(0)
# 前回ループのときの target_center_x 値を留める変数 (初期値 ImgCenter_x)
target_center_x_last = ImgCenter_x
# target が 20回続けて検出されないときは,終了する
miss = 0
action = ''
while True:
######## YOLO ##################################
# カメラ映像
ret, frame = cap.read()
# ヨコ,タテ
frame_size = (frame.shape[1], frame.shape[0])
# object 検出
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 を検出 ##################################
if action == '':
miss += 1
if miss > 20:
print('target lost !\n')
bye()
else:
miss = 0
action = ''
# target 検出枠
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])
# target が検出されたら
if( len(boxes) != 0):
print('ターゲット検出')
for box in boxes:
coordinates = box[:4]
coordinates = [int(coordinates[i] * resize_factor[i % 2]) for i in range(4)]
# target の中心
target_center_x = int((coordinates[0]+coordinates[2])/2)
# 画像中心からの object 中心のズレ
dx = target_center_x - ImgCenter_x
if abs(dx) < 20:
print("中心ズレ:" + str(dx) + '\n')
action = 'still'
else:
if abs( target_center_x - target_center_x_last ) > 20:
target_center_x_last = target_center_x
print('中心ズレ:' + str(dx))
# abs(dx) > 20 ならば,GoPiGo の回転へ
if abs(dx) > 20:
action = 'turn'
# 残りの box は取り上げない
break
# <for box in boxes> ここまで
# <if( len(boxes) != 0)> ここまで
else:
print('ターゲット検出せず\n')
#print('action : ' + action + '\n')
######## target の方向にターン ##################################
if action == 'turn':
print('向き変更開始')
rotation( pixel2t( dx ) )
print('向き変更終了\n')
######## target との距離を測る ##################################
if action != '':
dist = dist_read()
print('distance : ' + str(dist) + 'cm')
if dist > 450:
print('target lost !\n')
bye()
if dist < distance_to_stop:
print('Arrived !\n')
bye()
######## target に向かって前進 ##################################
print('move forward')
go_fwd()
print('stop\n')
######## プログラムを途中終了する ##################################
if cv2.waitKey(10) & 0xFF == ord('q'):
bye()
|
$ chmod +x reach.py
$ ./reach.py
ターゲット検出
中心ズレ:166.0
向き変更開始
rotation t:1.8260000000000003
向き変更終了
distance : 100cm
move forward
stop
ターゲット検出
ターゲット検出
ターゲット検出
ターゲット検出
ターゲット検出
ターゲット検出
中心ズレ:-60.0
向き変更開始
rotation t:-0.54
向き変更終了
distance : 92cm
move forward
stop
ターゲット検出
ターゲット検出
ターゲット検出
ターゲット検出
ターゲット検出
ターゲット検出
中心ズレ:9.0
distance : 87cm
move forward
stop
ターゲット検出
中心ズレ:10.0
distance : 81cm
move forward
stop
ターゲット検出
中心ズレ:10.0
distance : 78cm
move forward
stop
ターゲット検出
中心ズレ:10.0
distance : 74cm
move forward
stop
ターゲット検出
中心ズレ:10.0
distance : 68cm
move forward
stop
ターゲット検出
中心ズレ:10.0
distance : 65cm
move forward
stop
ターゲット検出
中心ズレ:31.0
向き変更開始
rotation t:0.37199999999999994
向き変更終了
distance : 57cm
move forward
stop
ターゲット検出
ターゲット検出
ターゲット検出
ターゲット検出
中心ズレ:65.0
向き変更開始
rotation t:0.585
向き変更終了
distance : 52cm
move forward
stop
ターゲット検出
中心ズレ:93.0
向き変更開始
rotation t:0.8370000000000001
向き変更終了
distance : 47cm
move forward
stop
ターゲット検出
中心ズレ:69.0
向き変更開始
rotation t:0.621
向き変更終了
distance : 42cm
move forward
stop
ターゲット検出
ターゲット検出
ターゲット検出
ターゲット検出
中心ズレ:34.0
向き変更開始
rotation t:0.408
向き変更終了
distance : 83cm
move forward
stop
ターゲット検出
中心ズレ:-62.0
向き変更開始
rotation t:-0.558
向き変更終了
distance : 78cm
move forward
stop
ターゲット検出
中心ズレ:-136.0
向き変更開始
rotation t:-1.0879999999999999
向き変更終了
distance : 25cm
Arrived !
キー入力で, プログラム終了...
$
|