Created
April 29, 2020 12:30
-
-
Save y1255018/75b98a37e1cbd17bf10628ea6fb1b6ca to your computer and use it in GitHub Desktop.
face detect by opencv
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import cv2 | |
import math | |
from lib.ev3 import EV3 | |
def decode_fourcc(v): | |
# https://amdkkj.blogspot.com/2017/06/opencv-python-for-windows-playing-videos_17.html | |
v = int(v) | |
return "".join([chr((v >> 8 * i) & 0xFF) for i in range(4)]) | |
cap = cv2.VideoCapture(0) | |
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 800) | |
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 600) | |
print(decode_fourcc(cap.get(cv2.CAP_PROP_FOURCC))) | |
if cap.isOpened() == False: | |
print("camera cannot open") | |
sys.exit(1) | |
cv2.namedWindow('camera capture', cv2.WINDOW_KEEPRATIO | cv2.WINDOW_NORMAL) | |
cv2.resizeWindow('camera capture',800,600) | |
cascade_path = "haarcascade_frontalface_alt2.xml" | |
cascade = cv2.CascadeClassifier(cascade_path) | |
touch_port = EV3.PORT_2 | |
lmotor_port = EV3.PORT_B | |
rmotor_port = EV3.PORT_C | |
ev3 = EV3() | |
ev3.enable_watchdog_task() | |
ev3.motor_config(lmotor_port, EV3.LARGE_MOTOR) | |
ev3.motor_config(rmotor_port, EV3.LARGE_MOTOR) | |
ev3.sensor_config(touch_port, EV3.TOUCH_SENSOR) | |
class FaceToFace(): | |
def detect_face(self): | |
src = img_org | |
height = src.shape[0] | |
width = src.shape[1] | |
scale = 2; | |
dst = cv2.resize(src, (int(width / scale), int(height / scale))) | |
img_gray = cv2.cvtColor(dst, cv2.COLOR_RGB2GRAY) | |
faces = cascade.detectMultiScale(img_gray, scaleFactor=1.11, minNeighbors=3, minSize=(20, 20)) # 30,30 | |
faces = faces * scale # 縮小前のサイズに戻す | |
if len(faces) > 0: | |
for (x, y, w, h) in faces: | |
cv2.rectangle(src, (x, y), (x+w, y+h), (0, 0, 255), 2) | |
cv2.imshow('camera capture', src) | |
if len(faces) == 0: | |
return None | |
else: | |
r = faces[0] | |
return r | |
def rot_vel(self, r): # return target rotation_vel[rad/s] | |
if r is None: | |
return 0.0 | |
wid = img_org.shape[1]/2 # 画像の幅の半分の値 | |
pos_x_rate = (r[0] + r[2]/2 - wid)*1.0/wid | |
rot = -0.25*pos_x_rate*math.pi # 画面のキワに顔がある場合にpi/4[rad/s]に | |
return rot | |
def control(self): | |
r = self.detect_face() | |
if r is None: | |
rotvel = 0.0 | |
ev3.motor_steer(lmotor_port, rmotor_port, 0, 0) | |
else: | |
k = 1.2; # P gain | |
rotvel = k * -180 * self.rot_vel(r) / math.pi # [deg/s] | |
ev3.motor_steer(lmotor_port, rmotor_port, 15, int(rotvel)) | |
if __name__ == '__main__': | |
try: | |
fd = FaceToFace() | |
while True: | |
_, img_org = cap.read() | |
fd.control() | |
key = cv2.waitKey(1) | |
# カメラはESCキーで終了できるように。 | |
if key == 27: | |
break | |
# Break this loop when the touch sensor was pressed. | |
#if ev3.touch_sensor_is_pressed(touch_port): | |
# break | |
except KeyboardInterrupt: | |
print("Exit loop by ctrl-c") | |
# 一旦画像削除の命令 | |
cap.release() | |
# カメラが立ち上がっているので、全てのウィンドウを閉じる | |
cv2.destroyAllWindows() | |
ev3.motor_steer(lmotor_port, rmotor_port, 0, 0) | |
ev3.close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment