简介
- 通过多线程的方式,将读取摄像头和深度学习模型推理分开来执行
- 使用
Python
和 C++
分别进行实现
Python
"""
使用python多线程获取视频流,并异步进行模型推理
"""
import time
import copy
from threading import Thread, Lock
import cv2
frame = None
flag = 0
lock = Lock()
def handle_frame():
"""
线程函数,对视频帧进行推理
"""
img = None
key = 0
infer_count = 0
while True:
if flag == -1:
return
if key != flag:
lock.acquire()
key = flag
img = copy.deepcopy(frame)
lock.release()
time.sleep(3)
infer_count += 1
print("Infer num:", infer_count)
print(img.shape)
def main():
"""
主进程函数,读取摄像头的视频流
"""
camera = cv2.VideoCapture(0)
width = 640
height = 480
camera.set(cv2.CAP_PROP_FRAME_WIDTH, width)
camera.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
t = Thread(target=handle_frame)
t.start()
frame_count = 0
while camera.isOpened():
lock.acquire()
global frame, flag
ret, frame = camera.read()
flag += 1
lock.release()
frame_count += 1
print("Frame:", frame_count)
kk = cv2.waitKey(1)
if kk == ord("q"):
flag = -1
break
else:
cv2.imshow("camera", frame)
t.join()
camera.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
main()
C++
#include <iostream>
#include <thread>
#include <mutex>
#include <opencv2/opencv.hpp>
using namespace std;
cv::Mat frame;
volatile int flag = 0;
mutex mtx;
void handleFrame()
{
cv::Mat img;
int key = 0;
int inferCount = 0;
while (true)
{
if (flag == -1) return;
if (key != flag)
{
mtx.lock();
key = flag;
img = frame.clone();
mtx.unlock();
this_thread::sleep_for(chrono::seconds(3));
inferCount++;
cout << "Infer num: " << inferCount << endl;
}
}
}
int main()
{
cv::VideoCapture cap(0);
if (!cap.isOpened())
{
cout << "Camera open failed." << endl;
return -1;
}
int width = 640;
int height = 480;
cap.set(cv::CAP_PROP_FRAME_WIDTH, width);
cap.set(cv::CAP_PROP_FRAME_HEIGHT, height);
thread t(handleFrame);
int frameCount = 0;
while (true)
{
if (mtx.try_lock())
{
cap.read(frame);
flag++;
mtx.unlock();
}
frameCount++;
cout << "Frame num: " << frameCount << endl;
cv::imshow("Camera", frame);
if (cv::waitKey(1) == 'q')
{
flag = -1;
break;
}
}
t.join();
cap.release();
cv::destroyAllWindows();
return 0;
}