Python 如何使用numpy阵列切片从图像中获取非矩形形状
对于一个个人项目,我期待着项目只是眼睛从一个网络摄像头到背景直播流。目前,我已经成功地提取了一个包含眼睛的正方形,并通过在图像上使用numPy切片将其放置在不同的背景上,如本例所示(梅西图像): 我曾经考虑过使用一个面具来只留下眼睛,因为在我的代码中,我确实有一个凸面外壳来描述眼睛的形状。这种方法的问题是,我不希望眼睛处于视频流中的同一位置。我的目标是将眼睛投射到任意背景中的任意位置 理想情况下,我会使用前面提到的多声子坐标切片方法,这样我的问题就可以解决了,但我不确定这是否可行,因为我还没有在互联网上找到它Python 如何使用numpy阵列切片从图像中获取非矩形形状,python,numpy,cv2,dlib,eye-detection,Python,Numpy,Cv2,Dlib,Eye Detection,对于一个个人项目,我期待着项目只是眼睛从一个网络摄像头到背景直播流。目前,我已经成功地提取了一个包含眼睛的正方形,并通过在图像上使用numPy切片将其放置在不同的背景上,如本例所示(梅西图像): 我曾经考虑过使用一个面具来只留下眼睛,因为在我的代码中,我确实有一个凸面外壳来描述眼睛的形状。这种方法的问题是,我不希望眼睛处于视频流中的同一位置。我的目标是将眼睛投射到任意背景中的任意位置 理想情况下,我会使用前面提到的多声子坐标切片方法,这样我的问题就可以解决了,但我不确定这是否可行,因为我还没有在
# 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, (255), 1)
print('right:', rightEyeHull)
# mask = np.ones((1000, 2000)) # (height, width)
# myROI = [(750, 0), (900, 1000), (1000, 1000), (1500, 0)] # (x, y)
# cv2.fillConvexPoly(mask, [np.array(myROI)], 0)
# myROI = [(750, 0), (900, 1000), (1000, 1000), (1500, 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, 0, 255), 2)
cv2.putText(blackframe, "EAR: {:.2f}".format(ear), (300, 30),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 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()```
#python detect_blinks.py--shape predictor shape_predictor_68_face_landmarks.dat--video blink_demo.mp4
#python detect_blinks.py--形状预测器形状预测器面部地标.dat
#导入必要的包
从scipy.spatial导入距离作为距离
从imutils.video导入视频流
从imutils导入面\u utils
将numpy作为np导入
导入argparse
导入imutils
导入时间
导入dlib
进口cv2
def眼宽比(眼):
#计算两组数据之间的欧几里德距离
#垂直眼地标(x,y)-坐标
A=距离欧几里德(眼睛[1],眼睛[5])
B=距离欧几里德(眼睛[2],眼睛[4])
#计算水平线之间的欧氏距离
#眼睛地标(x,y)-坐标
C=距离欧几里德(眼睛[0],眼睛[3])
#计算眼睛的纵横比
ear=(A+B)/(2.0*C)
#返回眼睛纵横比
回音耳
#构造参数并解析参数
ap=argparse.ArgumentParser()
ap.add_参数(“-p”,“--shape predictor”,required=True,
help=“面部地标预测器路径”)
ap.add_参数(“-v”,”--video),type=str,default=“”,
help=“输入视频文件的路径”)
args=vars(ap.parse_args())
#定义两个常数,一个用于表示眼睛纵横比
#闪烁,然后第二个常数表示连续闪烁的次数
#帧眼睛必须低于阈值
眼距阈值=0.3
眼睛连续帧=2
#初始化帧计数器和总闪烁次数
计数器=0
总数=0
#初始化dlib的人脸检测器(基于HOG),然后创建
#面部标志预测器
打印(“[INFO]正在加载面部地标预测器…”)
探测器=dlib.获取正面探测器()
predictor=dlib.shape\u predictor(args[“shape\u predictor”])
#抓取左右两侧面部标志的索引
#分别是右眼
(lStart,lEnd)=面部特征。面部标志物[“左眼”]
(rStart,rEnd)=面部特征。面部标志物[“右眼”]
#启动视频流线程
打印(“[INFO]正在启动视频流线程…”)
#fileStream=True
vs=VideoStream(src=0).start()
#vs=VideoStream(usePiCamera=True).start()
fileStream=False
时间。睡眠(1.0)
#循环播放视频流中的帧
尽管如此:
#如果这是一个文件视频流,那么我们需要检查
#缓冲区中还有更多要处理的帧吗
如果fileStream而非vs.more():
打破
#从线程视频文件流中抓取帧,调整大小
#并将其转换为灰度
#渠道)
frame=vs.read()
frame=imutils.resize(frame,width=1080)
灰色=cv2.CVT颜色(边框,cv2.COLOR\u BGR2GRAY)
#检测灰度帧中的面
rects=检测器(灰色,0)
#环面检测
对于矩形中的矩形:
#确定面部区域的面部地标,然后
#将面部地标(x,y)-坐标转换为NumPy
#排列
形状=预测器(灰色、矩形)
形状=面形状。形状到形状(形状)
#提取左眼和右眼坐标,然后使用
#用于计算双眼的眼睛纵横比的坐标
leftEye=形状[lStart:lEnd]
右眼=形状[rStart:rEnd]
左眼=眼睛与纵横比(左眼)
右眼=眼睛与纵横比(右眼)
#平均双眼的眼睛长宽比
ear=(左耳+右耳)/2.0
#计算左眼和右眼的凸包,然后
#想象每一只眼睛
leftEyeHull=cv2.convexHull(左眼)
右眼外壳=cv2.凸面外壳(右眼)
#掩码=np.0(形状),数据类型=np.uint8)
cv2.图纸轮廓(框架,([leftEyeHull]),-1,(255),1)
cv2.图纸轮廓(框架,([rightEyeHull]),-1,(255),1)
打印('right:',rightEyeHull)
#掩模=np.ones((10002000))#(高度、宽度)
#我的投资回报率=[(750,0),(900,1000),(1000,1000),(1500,0)]#(x,y)
#cv2.fillConvexPoly(掩模,[np.array(myROI)],0)
#myROI=[(750,0)、(900,1000)、(1000,1000)、(1500,0)]
# # [[[454 380]] [[470 372]] [[487 371]] [[504 379]] [[487 383]] [[470 384]]]
#rEyeX=np.array([i[0]表示rightEyeHull[:,:,1]]中的i)
#ROIright=np.数组([(i[0]),用于rightEyeHull[:,:,:]中的i)
#打印('ROIright:',ROIright)
#检查眼睛纵横比是否低于眨眼
#阈值,如果是,则增加闪烁帧计数器
如果耳朵<眼睛>耳朵>脱粒:
计数器+=1
#否则,眼睛纵横比不低于眨眼
#门槛
其他:
#如果闭上眼睛的时间足够长
#然后增加闪烁的总次数
如果计数器>=眼睛连续帧:
总数+=1
#重置眼框计数器
计数器=0
#绘制帧上闪烁的总次数以及
#计算的帧的眼睛纵横比
blackframe=cv2.imread(“黑色背景kopie.jpg”)
rEyeX=np.array([i[0]表示右边的i