如何使用numpy数组切片从图像中获取非矩形形状

问题描述

对于个人项目,我希望将网络摄像头实时流中的眼睛投射到背景上。目前,我已成功提取出包含眼睛的正方形,并通过使用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 (将#修改为@)