gpt4 book ai didi

python - 在 python + picamera + opencv 的线程内使用 "with"

转载 作者:太空宇宙 更新时间:2023-11-03 21:35:51 25 4
gpt4 key购买 nike

我正在使用带有 picamera 和 opencv python 模块的树莓派尝试进行一些快速捕获和处理。目前我正在使用 http://picamera.readthedocs.org/en/latest/recipes2.html#rapid-capture-and-processing 中的食谱将每个图像捕获到 BytesIO 流。然后,我在 ImageProccessor 类中添加了代码,以将每个流转换为 opencv 对象并“即时”进行一些分析。

因此我当前的代码看起来像这样:

import io
import time
import threading
import picamera
import cv2
import picamera.array
import numpy as np


# Create a pool of image processors
done = False
lock = threading.Lock()
pool = []

class ImageProcessor(threading.Thread):
def __init__(self):
super(ImageProcessor, self).__init__()
self.stream = io.BytesIO()
self.event = threading.Event()
self.terminated = False
self.start()

def run(self):
# This method runs in a separate thread
global done
while not self.terminated:
# Wait for an image to be written to the stream
if self.event.wait(1):
try:
self.stream.seek(0)
# Read the image and do some processing on it
# Construct a numpy array from the stream
data = np.fromstring(self.stream.getvalue(), dtype=np.uint8)
# "Decode" the image from the array, preserving colour
image = cv2.imdecode(data, 1)

# Here goes more opencv code doing image proccessing

# Set done to True if you want the script to terminate
# at some point
#done=True
finally:
# Reset the stream and event
self.stream.seek(0)
self.stream.truncate()
self.event.clear()
# Return ourselves to the pool
with lock:
pool.append(self)

def streams():
while not done:
with lock:
if pool:
processor = pool.pop()
else:
processor = None
if processor:
yield processor.stream
processor.event.set()
else:
# When the pool is starved, wait a while for it to refill
print ("Waiting")
time.sleep(0.1)

with picamera.PiCamera() as camera:
pool = [ImageProcessor() for i in range(4)]
camera.resolution = (640, 480)
camera.framerate = 30
camera.start_preview()
time.sleep(2)
camera.capture_sequence(streams(), use_video_port=True)

# Shut down the processors in an orderly fashion
while pool:
with lock:
processor = pool.pop()
processor.terminated = True
processor.join()

问题在于,这涉及到每张图像的 JPEG 编码和解码,这是有损且耗时的。建议的替代方法是捕获到 picamera.ar​​ray:http://picamera.readthedocs.org/en/latest/recipes1.html#capturing-to-an-opencv-object ,对于单个图像代码:

import time
import picamera
import picamera.array
import cv2

with picamera.PiCamera() as camera:
camera.start_preview()
time.sleep(2)
with picamera.array.PiRGBArray(camera) as stream:
camera.capture(stream, format='bgr')
# At this point the image is available as stream.array
image = stream.array

效果很好,但我不知道如何组合这两段代码,以便 ImageProcessor 类定义 picamera.ar​​ray 而不是 BytesIO 流。需要使用“with”语句来为 picamera.ar​​ray 生成流,这让我很困惑(我是 python 的新手...;))。感谢您的指点。天使

最佳答案

我发现你可以只引用picamera模块的源。

def raw_resolution(resolution):
"""
Round a (width, height) tuple up to the nearest multiple of 32 horizontally
and 16 vertically (as this is what the Pi's camera module does for
unencoded output).
"""
width, height = resolution
fwidth = (width + 31) // 32 * 32
fheight = (height + 15) // 16 * 16
return fwidth, fheight


def bytes_to_rgb(data, resolution):
"""
Converts a bytes objects containing RGB/BGR data to a `numpy`_ array.
"""
width, height = resolution
fwidth, fheight = raw_resolution(resolution)
if len(data) != (fwidth * fheight * 3):
raise PiCameraValueError(
'Incorrect buffer length for resolution %dx%d' % (width, height))
# Crop to the actual resolution
return np.frombuffer(data, dtype=np.uint8).\
reshape((fheight, fwidth, 3))[:height, :width, :]

可以调用转换

image = bytes_to_rgb(self.stream.getvalue(),resolution)

分辨率是(宽度,高度)。 camera 传递给 PiRGBArray 的原因是能够引用相机的分辨率。

关于python - 在 python + picamera + opencv 的线程内使用 "with",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29065624/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com