繁体   English   中英

制作更快的视频捕捉 opencv

[英]Make faster videocapture 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 自行工作并将帧发送到交换 class,然后允许图像处理抓取帧并在 CV2 继续正常工作时以自己的速度工作。

这是用于 OCR 图像处理的 class 的(缩短)版本。 您可以在 start() 中看到我正在创建一个指向 ocr() 进程的线程。 这是您的性别识别过程可以 go 的地方。

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 class,它以自己的节奏在不同的线程中抓取帧。 然后,图像处理 class (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 显示您的网络摄像头,同时在后台进行图像处理。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM