使更快的视频捕获opencv



所以我创建了一个神经网络(CNN(,可以使用opencv实时预测一个人的性别,一切都很完美,但是,当我运行代码opencv有太多滞后时,我的网络摄像头并没有那么糟糕,这是我的代码

'''
Real-time Face Gender Recognition using Conv-Nueral Network (CNN) and Cv2
Here we predict the save model that it is train
'''
from tensorflow.keras.preprocessing.image import img_to_array
from tensorflow.keras.models import load_model
import numpy as np
import cv2
import os
import cvlib as cv
import imutils
# load the model
model = load_model('gender_detection.model')
# open webcams and initiate the camara
webcam = cv2.VideoCapture(0, cv2.CAP_DSHOW)
classes = ['hombre', 'mujer']
# loop through frames
while webcam.isOpened():
# read frame from webcam
status, frame = webcam.read()
#webcam.set(cv2.CAP_PROP_FPS, 1000)
frame = cv2.flip(frame, 1)
# apply face detection
face, confidence = cv.detect_face(frame) # this detects that there is a face in the camara, cvlib does, but not if it is a man that detects the neural network
# loop through detected faces
for idx, f in enumerate(face):
# get corner points of face rectangle
# this only will draw a rectangle when the cvlib detects the face with the vars giving up there
startX, startY = f[0], f[1]
endX, endY = f[2], f[3]
# draw the rectangle over the face
cv2.rectangle(frame, (startX, startY), (endX, endY), (0,255,0), 2)
# crop the detected face region
face_crop = np.copy(frame[startY:endY, startX:endX])
if face_crop.shape[0] < 10 or face_crop.shape[1] < 10:
continue
# preprocessing for gender detection model
face_crop = cv2.resize(face_crop, (96,96))
face_crop = face_crop.astype("float") / 255.0
face_crop = img_to_array(face_crop)
face_crop = np.expand_dims(face_crop, axis=0)
# apply gender detection face with the model
conf = model.predict(face_crop)[0]
# get label with max acc
idx = np.argmax(conf)
label = classes[idx]
label = "{}: {:.2f}".format(label, conf[idx] * 100)
Y = startY - 10 if startY - 10 > 10 else startY + 10
# write label and confidence above the face rectangle
cv2.putText(frame, label, (startX, Y), cv2.FONT_HERSHEY_SIMPLEX,
0.7, (0,255,0), 2)
# display output
cv2.imshow("Gender Detection", frame)
# press "Q" to stop
if cv2.waitKey(1) & 0xFF == ord('q'):
break

#realese resources
webcam.release()
cv2.destroyAllWindows()

我也尝试过使用cv2.CAP_PROB_FPS,但这只是一点点帮助,并没有多大帮助。

我在使用带有文本检测的openCV视频捕获时也遇到过同样的问题。这不是网络摄像头的质量,而是openCV只能以你在性别检测中处理帧的速度向你显示帧。对我有效的解决方案是使用多线程。

您可以创建一个用于OpenCV视频捕获的线程,然后创建另一个用于图像处理的线程。需要注意的是:如果不改变图像处理本身,就无法神奇地使图像处理更快。它需要多长时间。你可以做的是允许openCV自己工作,并将帧发送到交换类,然后允许图像处理获取帧,并在CV2正常运行时以自己的速度工作。

这是我的OCR图像处理课程的(缩短版(。您可以看到,在start((中,我正在创建一个指向ocr((进程的线程。这就是你的性别识别过程可以进行的地方。

class OCR:
# def __init__(self, exchange: VideoStream, language=None):
def __init__(self):
self.exchange = None
# init stuff for OCR not relevant to my example, but note that it 
# takes a VideoStream class called exchange which is where this class 
# grabs frames to process
def start(self):
Thread(target=self.ocr, args=()).start()
return self
def set_exchange(self, video_stream):
self.exchange = video_stream
def ocr(self):
while not self.stopped:
if self.exchange is not None:
frame = self.exchange.frame
# # # OCR stuff goes here

现在是VideoStream类,它在不同的线程中以自己的速度获取帧。然后,图像处理类(OCR(可以按照自己的速度处理这些帧,并且两者不会影响彼此的性能。

class VideoStream:
"""Class for CV2 video capture. The start() method will create a new 
thread to read the video stream"""
def __init__(self, src=0):
self.stream = cv2.VideoCapture(src)
(self.grabbed, self.frame) = self.stream.read()
# self._boxes = None
self.stopped = False
def start(self):
Thread(target=self.get, args=()).start()
return self
def get(self):
while not self.stopped:
(self.grabbed, self.frame) = self.stream.read()
def get_video_dimensions(self):
width = self.stream.get(cv2.CAP_PROP_FRAME_WIDTH)
height = self.stream.get(cv2.CAP_PROP_FRAME_HEIGHT)
return int(width), int(height)
def stop_process(self):
self.stopped = True

然后,您可以像往常一样执行CV2 imshow循环。

exchange = VideoStream(0).start()
ocr = OCR().start()
ocr.set_exchange(exchange)
while True:  # Begins a loop for the real-time OCR display
pressed_key = cv2.waitKey(1) & 0xFF
if pressed_key == ord('q'):
stop_stream_ocr(exchange, ocr)
break
frame = exchange.frame 
cv2.imshow("Video Get Frame", frame)
cps1.increment()

请注意,您无法真正控制线程CV2决定在其内部工作中使用什么,但这种方法将允许您以自然的fps显示网络摄像头,同时在后台进行图像处理。

最新更新