我有一个使用 cv2 来捕获检测到的第一张脸并仅在 cv2 窗口中显示该区域的小型 python 脚本。一切都很好。
目前,视频源在最小化时将冻结。如果我将 cv2 窗口最小化到托盘,如何让我的脚本继续捕获视频?
编辑
我还想知道是否有更好的方法可以减少 CPU 的负载。当前运行此脚本将使用我的 cpu 的 14 - 20%。
from __future__ import division
from imutils.video import VideoStream
import face_recognition
import imutils
import cv2
POINTS = []
def landmarkTrackSmoothing(box, factor, maxPoints=30):
top = box[0][0]
bottom = box[0][1]
left = box[0][2]
right = box[0][3]
if len(POINTS) < maxPoints:
maxPoints = len(POINTS)
else:
del POINTS[0]
POINTS.append([top, bottom, left, right])
mean = [int((sum(col)/len(col))/factor) for col in zip(*POINTS)]
return mean
def cartoonFilter(roi):
# 1) Edges
gray = cv2.cvtColor(roi, cv2.COLOR_RGB2GRAY)
gray = cv2.medianBlur(gray, 5)
edges = cv2.adaptiveThreshold(
gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 9, 9)
# 2) Color
color = cv2.bilateralFilter(roi, 9, 300, 300)
# 3) Cartoon
return cv2.bitwise_and(color, color, mask=edges)
def OpenCamera():
vs = VideoStream(0 + cv2.CAP_DSHOW, framerate=120).start()
vs.stream.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
vs.stream.set(cv2.CAP_PROP_FRAME_HEIGHT, 1024)
roi = [0, 0, 0, 0]
prev = [0, 0, 0, 0]
# Add filter flags
cartoonEffect = False
# loop over frames from the video file stream
while True:
# grab the frame from the threaded video stream
frame = vs.read()
# downscale and convert to grayscale for fast processing
# of landmark locations
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gray = imutils.resize(frame, width=240)
# calculate upscale factor for landmark locations
factor = float(gray.shape[1]) / frame.shape[1]
# detect the (x, y)-coordinates of the bounding boxes
# corresponding to each face in the input frame, then
# the facial embeddings for each face
boxes = face_recognition.face_locations(gray)
box = list(map(list, boxes))
# t, b, l, r = 0, 0, 0, 0
# upscale landmark locations
for i in range(len(box)):
box = [landmarkTrackSmoothing(box, factor)]
# loop over the recognized faces
if (len(box) > 0):
i = 0
for (top, right, bottom, left) in box:
# grab frames from face coordinates
if (i == 0):
roi = frame[top:bottom, left:right]
prev = top, bottom, left, right
if cartoonEffect:
roi = cartoonFilter(roi)
i += 1
# check to see if we are supposed to display the output frame to
# the screen
if (len(box) == 0):
if (prev[0] > 0):
roi = frame[prev[0]:prev[1], prev[2]:prev[3]]
else:
roi = frame
cv2.namedWindow("Frame", cv2.WINDOW_NORMAL)
if (roi.any()):
cv2.imshow("Frame", roi)
cv2.resizeWindow("Frame", 512, 512)
# continue looping until quit: expandable to add dynamic key commands for filters
key = cv2.waitKey(1) & 0xFF
if key == ord("q"):
break
if key == ord('c'):
if cartoonEffect:
cartoonEffect = False
else:
cartoonEffect = True
# do a bit of cleanup on quit
cv2.destroyAllWindows()
vs.stop()
# Begin capturing
OpenCamera()