问题描述
对于个人项目,我希望将网络摄像头实时流中的眼睛投射到背景上。目前,我已成功提取出包含眼睛的正方形,并通过使用numPy切片将其放置在不同的背景上,如本示例(Messi图像)所示:https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_core/py_basic_ops/py_basic_ops.html#image-roi
我已经考虑过使用面具遮住眼睛,就像在我的代码中一样,我确实有一个凸包来描述眼睛的形状。这种方法的问题是我不希望眼睛与视频流中的位置相同。我的目标是将眼睛投射到任意背景下的随机位置上。
理想情况下,我将使用上述带有多边形坐标的切片方法来解决问题,但是我不确定这是否有可能,因为我无法在网上找到它。
# python detect_blinks.py --shape-predictor shape_predictor_68_face_landmarks.dat --video blink_detection_demo.mp4
# python detect_blinks.py --shape-predictor shape_predictor_68_face_landmarks.dat
# import the necessary packages
from scipy.spatial import distance as dist
from imutils.video import VideoStream
from imutils import face_utils
import numpy as np
import argparse
import imutils
import time
import dlib
import cv2
def eye_aspect_ratio(eye):
# compute the euclidean distances between the two sets of
# vertical eye landmarks (x,y)-coordinates
A = dist.euclidean(eye[1],eye[5])
B = dist.euclidean(eye[2],eye[4])
# compute the euclidean distance between the horizontal
# eye landmark (x,y)-coordinates
C = dist.euclidean(eye[0],eye[3])
# compute the eye aspect ratio
ear = (A + B) / (2.0 * C)
# return the eye aspect ratio
return ear
# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-p","--shape-predictor",required=True,help="path to facial landmark predictor")
ap.add_argument("-v","--video",type=str,default="",help="path to input video file")
args = vars(ap.parse_args())
# define two constants,one for the eye aspect ratio to indicate
# blink and then a second constant for the number of consecutive
# frames the eye must be below the threshold
EYE_AR_THRESH = 0.3
EYE_AR_CONSEC_FRAMES = 2
# initialize the frame counters and the total number of blinks
COUNTER = 0
TOTAL = 0
# initialize dlib's face detector (HOG-based) and then create
# the facial landmark predictor
print("[INFO] loading facial landmark predictor...")
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(args["shape_predictor"])
# grab the indexes of the facial landmarks for the left and
# right eye,respectively
(lStart,lEnd) = face_utils.FACIAL_LANDMARKS_IDXS["left_eye"]
(rStart,rEnd) = face_utils.FACIAL_LANDMARKS_IDXS["right_eye"]
# start the video stream thread
print("[INFO] starting video stream thread...")
#fileStream = True
vs = VideoStream(src=0).start()
# vs = VideoStream(usePiCamera=True).start()
fileStream = False
time.sleep(1.0)
# loop over frames from the video stream
while True:
# if this is a file video stream,then we need to check if
# there any more frames left in the buffer to process
if fileStream and not vs.more():
break
# grab the frame from the threaded video file stream,resize
# it,and convert it to grayscale
# channels)
frame = vs.read()
frame = imutils.resize(frame,width=1080)
gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
# detect faces in the grayscale frame
rects = detector(gray,0)
# loop over the face detections
for rect in rects:
# determine the facial landmarks for the face region,then
# convert the facial landmark (x,y)-coordinates to a NumPy
# array
shape = predictor(gray,rect)
shape = face_utils.shape_to_np(shape)
# extract the left and right eye coordinates,then use the
# coordinates to compute the eye aspect ratio for both eyes
leftEye = shape[lStart:lEnd]
rightEye = shape[rStart:rEnd]
leftEAR = eye_aspect_ratio(leftEye)
rightEAR = eye_aspect_ratio(rightEye)
# average the eye aspect ratio together for both eyes
ear = (leftEAR + rightEAR) / 2.0
# compute the convex hull for the left and right eye,then
# visualize each of the eyes
leftEyeHull = cv2.convexHull(leftEye)
rightEyeHull = cv2.convexHull(rightEye)
#mask = np.zeros(shape),dtype=np.uint8)
cv2.drawContours(frame,([leftEyeHull]),-1,(255),1)
cv2.drawContours(frame,([rightEyeHull]),1)
print('right:',rightEyeHull)
# mask = np.ones((1000,2000)) # (height,width)
# myROI = [(750,0),(900,1000),(1000,(1500,0)] # (x,y)
# cv2.fillConvexpoly(mask,[np.array(myROI)],0)
# myROI = [(750,0)]
# # [[[454 380]] [[470 372]] [[487 371]] [[504 379]] [[487 383]] [[470 384]]]
# rEyeX = np.array([i[0] for i in rightEyeHull[:,:,1]])
# ROIright = np.array([(i[0]) for i in rightEyeHull[:,:]])
# print('ROIright:',ROIright)
# check to see if the eye aspect ratio is below the blink
# threshold,and if so,increment the blink frame counter
if ear < EYE_AR_THRESH:
COUNTER += 1
# otherwise,the eye aspect ratio is not below the blink
# threshold
else:
# if the eyes were closed for a sufficient number of
# then increment the total number of blinks
if COUNTER >= EYE_AR_CONSEC_FRAMES:
TOTAL += 1
# reset the eye frame counter
COUNTER = 0
# draw the total number of blinks on the frame along with
# the computed eye aspect ratio for the frame
blackframe = cv2.imread("black-background kopie.jpg")
rEyeX = np.array([i[0] for i in rightEyeHull[:,1]])
rEyeY = np.array([i[0] for i in rightEyeHull[:,0]])
lEyeX = np.array([i[0] for i in leftEyeHull[:,1]])
lEyeY = np.array([i[0] for i in leftEyeHull[:,0]])
rEyeSquare = frame[min(rEyeX):max(rEyeX),min(rEyeY):max(rEyeY)]
lEyeSquare = frame[min(lEyeX):max(lEyeX),min(lEyeY):max(lEyeY)]
blackframe[min(rEyeX):max(rEyeX),min(rEyeY):max(rEyeY)] = rEyeSquare
blackframe[min(lEyeX):max(lEyeX),min(lEyeY):max(lEyeY)] = lEyeSquare
cv2.putText(blackframe,"Blinks: {}".format(TOTAL),(10,30),cv2.FONT_HERShey_SIMPLEX,0.7,(0,255),2)
cv2.putText(blackframe,"EAR: {:.2f}".format(ear),(300,2)
# show the frame
cv2.imshow("Frame",blackframe)
key = cv2.waitKey(1) & 0xFF
# if the `q` key was pressed,break from the loop
if key == ord("q"):
break
# do a bit of cleanup
cv2.destroyAllWindows()
vs.stop()```
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)