原文出处: http://xugaoxiang.com/post/121
软硬件环境
- macOS High Sierra
- opencv 3.3.1
- anaconda3 & python 3.6.4
生产者消费者问题
Producer-Consumer problem,也称有限缓冲问题(Bounded-buffer problem),是一个多线程同步问题的经典案例,生产者负责生成一定量的数据放到缓冲区中;消费者在同一个缓冲区中消耗生产者生成的数据。该问题的关键就是要保证生产者不会再缓冲区满时加入数据,而消费者也不会再缓冲区空时消费数据。
在OpenCV中的应用
OpenCV的工作流: 输入 –> 处理 –> 输出,如果处理过程是相对耗时且耗资源的话,就需要在多线程中来处理,那就变成了典型的生产者消费者问题了。
代码实践
# -*- coding: utf-8 -*-
# @Time : 5/1/18 4:02 PM
# @Author : xugaoxiang
# @Email : [email protected]
# @File : main.py
# @Software: PyCharm
from queue import Queue
import threading
import cv2
import time, random
class Producer(threading.Thread):
def __init__(self, frame_queue):
super(Producer, self).__init__()
self.frame_queue = frame_queue
def run(self):
print('in producer')
cap = cv2.VideoCapture('rtsp://admin:[email protected]:554/ISAPI/streaming/channels/102')
print('cap is open',cap.isOpened())
while True:
ret,image = cap.read()
print('get frame = ',ret)
if (ret == True):
# 如果是定长队列,需要判断当前队列中数据,不满时才塞入数据
self.frame_queue.put(image)
else:
cap = cv2.VideoCapture('rtsp://admin:[email protected]:554/ISAPI/streaming/channels/102')
print('cap is open',cap.isOpened())
class Consumer(threading.Thread):
def __init__(self, frame_queue):
super(Consumer, self).__init__()
self.frame_queue = frame_queue
def run(self):
print('in consumer')
while True:
print('frame_queue size=',self.frame_queue.qsize())
# 如果是定长队列,需要判断当前队列中数据,不空时才取出数据
frame = self.frame_queue.get()
cv2.imshow('cap video',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
videoWriter.release()
cap.release()
cv2.destroyAllWindows()
break
if __name__ == '__main__':
#定义队列,也就是数据缓冲区,可以指定队列大小,默认创建的是无限大的队列
frame_queue = Queue()
producer = Producer(frame_queue)
producer.daemon = True
producer.start()
print('run Consumer')
consumer = Consumer(frame_queue)
consumer.daemon = True
consumer.start()
producer.join()
consumer.join()