cv2 以最小化 window 捕获视频
cv2 capture video with minimized window
我有一个小 python 脚本,使用 cv2 捕获检测到的第一张脸,并仅在 cv2 window 中显示该区域。一切都很好。
目前,视频源在最小化时会冻结。
如果我将 cv2 window 最小化到托盘,我如何让我的脚本继续捕获视频?
编辑
我也想知道是否有更好的方法来减少 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()
我使用 haarcascade 而不是我正在做的事情,设法将我的 CPU 使用率减少到 1-10%。当 window 最小化时仍然无法 运行 相机捕捉。
最终解决方案。
import cv2
import dlib
import time
POINTS = []
def followFaceSmoothing(roi, maxPoints=30):
top = roi[0]
bottom = roi[1]
left = roi[2]
right = roi[3]
if len(POINTS) < maxPoints:
maxPoints = len(POINTS)
else:
del POINTS[0]
POINTS.append([top, bottom, left, right])
mean = [int((sum(col)/len(col))) for col in zip(*POINTS)]
return mean
# Initialize a face cascade using the frontal face haar cascade provided with
# the OpenCV library
faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
def detectAndTrackLargestFace():
# Capture video frames
capture = cv2.VideoCapture(0)
roi, lastroi = [], []
# Create opencv named window
cv2.namedWindow("Follow Face", cv2.WINDOW_NORMAL)
# Start the window thread for the window we are using
cv2.startWindowThread()
# Create the tracker we will use
tracker = dlib.correlation_tracker()
# The variable we use to keep track of the fact whether we are
# currently using the dlib tracker
trackingFace = 0
# Variable to track frame count so we can refresh landmark detection
frames = 0
try:
while True:
# Retrieve the latest image from the webcam
rc, img = capture.read()
# Check if a key was pressed and if it was Q, then destroy all
# opencv windows and exit the application
pressedKey = cv2.waitKey(2)
if pressedKey == ord('Q'):
cv2.destroyAllWindows()
exit(0)
elif pressedKey == ord('R'): # reset landmark detection to refresh img
roi = []
trackingFace = 0
# If we are not tracking a face, then try to detect one
if not trackingFace:
# convert the img to gray-based image
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# find all faces
faces = faceCascade.detectMultiScale(
gray, minNeighbors=10, minSize=(50, 50), maxSize=(300, 300))
# get largest face based on the largest
# area. initialize the required variables to 0
maxArea = 0
x = 0
y = 0
w = 0
h = 0
# Loop over faces and check if the area is the
# largest convert it to int fordlib tracker.
for (_x, _y, _w, _h) in faces:
if _w*_h > maxArea:
x = int(_x)
y = int(_y)
w = int(_w)
h = int(_h)
maxArea = w*h
# If one or more faces are found, initialize the tracker
# on the largest face
if maxArea > 0:
# Initialize the tracker
tracker.start_track(img,
dlib.rectangle(x-10,
y-20,
x+w+10,
y+h+20))
# Set the indicator variable when actively tracking region in the image
trackingFace = 1
time.sleep(0.06)
# Check if the tracker is actively tracking a region in the image
if trackingFace:
# Update the tracker and request quality of the tracking update
trackingQuality = tracker.update(img)
# determine the updated position of the tracked region and crop
if trackingQuality >= 8.75:
tracked_position = tracker.get_position()
t_x = int(tracked_position.left())
t_y = int(tracked_position.top())
t_w = int(tracked_position.width())
t_h = int(tracked_position.height())
roi = t_y, t_y+t_h, t_x, t_x+t_w
if (roi[0] > 0):
roi = followFaceSmoothing(roi)
lastroi = roi
else:
trackingFace = 0
# reset every 60 frames to refresh face tracking
frames += 1
if (frames > 59):
frames = 0
roi = []
trackingFace = 0
# show the image on the screen
if img.any():
if (len(lastroi) > 0):
img = img[lastroi[0]:lastroi[1], lastroi[2]:lastroi[3]]
cv2.imshow("Follow Face", img)
cv2.resizeWindow("Follow Face", 320, 320)
except:
pass
if __name__ == '__main__':
detectAndTrackLargestFace()
我有一个小 python 脚本,使用 cv2 捕获检测到的第一张脸,并仅在 cv2 window 中显示该区域。一切都很好。
目前,视频源在最小化时会冻结。 如果我将 cv2 window 最小化到托盘,我如何让我的脚本继续捕获视频?
编辑
我也想知道是否有更好的方法来减少 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()
我使用 haarcascade 而不是我正在做的事情,设法将我的 CPU 使用率减少到 1-10%。当 window 最小化时仍然无法 运行 相机捕捉。
最终解决方案。
import cv2
import dlib
import time
POINTS = []
def followFaceSmoothing(roi, maxPoints=30):
top = roi[0]
bottom = roi[1]
left = roi[2]
right = roi[3]
if len(POINTS) < maxPoints:
maxPoints = len(POINTS)
else:
del POINTS[0]
POINTS.append([top, bottom, left, right])
mean = [int((sum(col)/len(col))) for col in zip(*POINTS)]
return mean
# Initialize a face cascade using the frontal face haar cascade provided with
# the OpenCV library
faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
def detectAndTrackLargestFace():
# Capture video frames
capture = cv2.VideoCapture(0)
roi, lastroi = [], []
# Create opencv named window
cv2.namedWindow("Follow Face", cv2.WINDOW_NORMAL)
# Start the window thread for the window we are using
cv2.startWindowThread()
# Create the tracker we will use
tracker = dlib.correlation_tracker()
# The variable we use to keep track of the fact whether we are
# currently using the dlib tracker
trackingFace = 0
# Variable to track frame count so we can refresh landmark detection
frames = 0
try:
while True:
# Retrieve the latest image from the webcam
rc, img = capture.read()
# Check if a key was pressed and if it was Q, then destroy all
# opencv windows and exit the application
pressedKey = cv2.waitKey(2)
if pressedKey == ord('Q'):
cv2.destroyAllWindows()
exit(0)
elif pressedKey == ord('R'): # reset landmark detection to refresh img
roi = []
trackingFace = 0
# If we are not tracking a face, then try to detect one
if not trackingFace:
# convert the img to gray-based image
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# find all faces
faces = faceCascade.detectMultiScale(
gray, minNeighbors=10, minSize=(50, 50), maxSize=(300, 300))
# get largest face based on the largest
# area. initialize the required variables to 0
maxArea = 0
x = 0
y = 0
w = 0
h = 0
# Loop over faces and check if the area is the
# largest convert it to int fordlib tracker.
for (_x, _y, _w, _h) in faces:
if _w*_h > maxArea:
x = int(_x)
y = int(_y)
w = int(_w)
h = int(_h)
maxArea = w*h
# If one or more faces are found, initialize the tracker
# on the largest face
if maxArea > 0:
# Initialize the tracker
tracker.start_track(img,
dlib.rectangle(x-10,
y-20,
x+w+10,
y+h+20))
# Set the indicator variable when actively tracking region in the image
trackingFace = 1
time.sleep(0.06)
# Check if the tracker is actively tracking a region in the image
if trackingFace:
# Update the tracker and request quality of the tracking update
trackingQuality = tracker.update(img)
# determine the updated position of the tracked region and crop
if trackingQuality >= 8.75:
tracked_position = tracker.get_position()
t_x = int(tracked_position.left())
t_y = int(tracked_position.top())
t_w = int(tracked_position.width())
t_h = int(tracked_position.height())
roi = t_y, t_y+t_h, t_x, t_x+t_w
if (roi[0] > 0):
roi = followFaceSmoothing(roi)
lastroi = roi
else:
trackingFace = 0
# reset every 60 frames to refresh face tracking
frames += 1
if (frames > 59):
frames = 0
roi = []
trackingFace = 0
# show the image on the screen
if img.any():
if (len(lastroi) > 0):
img = img[lastroi[0]:lastroi[1], lastroi[2]:lastroi[3]]
cv2.imshow("Follow Face", img)
cv2.resizeWindow("Follow Face", 320, 320)
except:
pass
if __name__ == '__main__':
detectAndTrackLargestFace()