4、picamera基本使用方法
如果你是一个python程序员,那么你将轻松的掌握以下实例,请随时提出改进或新的实例。
4.1、捕捉一个图像输出至文件
使用capture方法可以轻松将捕捉到的图像输出至指定文件。
下面这个实例是捕捉一个分辨率为1024*768的图像,并将之输出到foo.jpg中:
import time
import picamera
with picamera.PiCamera() as camera:
camera.resolution = (1024, 768)
camera.start_preview()
#摄像头预热2秒
time.sleep(2)
camera.capture('foo.jpg')
需要注意的是,若目录中有同名文件,picamera将会重置该图片。
4.2、捕捉一个流
这个实例是通过capture()方法将捕捉的一个图像转成一个以jpeg解码的流(bytes流):
import io
import time
import picamera
# 创建一个流
my_stream = io.BytesIO()
with picamera.PiCamera() as camera:
camera.start_preview()
# 摄像头预热
time.sleep(2)
camera.capture(my_stream, 'jpeg')
需要注意的是,这不像输出到一个文件,该流捕捉以后会自动关闭脚本,因为在这个实例中没有对流进行其他操作。若对象有flush方法的话,在捕捉完毕后,会调用对象的flush方法,如下:
import time
import picamera
# 打开一个扩展名为jpg的文件
my_file = open('my_image.jpg', 'wb')
with picamera.PiCamera() as camera:
camera.start_preview()
time.sleep(2)
camera.capture(my_file)
# 在此时capture会调用my_file的flush方法,完成流封装。
# 但并未关闭文件,需要调用close进行关闭
my_file.close()
上边这个实例需要注意的是,我们并没有指定捕捉文件的解码格式,所以capture会获取输出的文件名的扩展名来寻找解码属性。
4.3、捕捉一个图像转化为PIL imag对象
首先我们要捕捉一个图像流,然后通过流读取将图像的数据转换成PIL image对象。
import io
import time
import picamera
from PIL import Image
# 创建一个流
stream = io.BytesIO()
with picamera.PiCamera() as camera:
camera.start_preview()
time.sleep(2)
camera.capture(stream, format='jpeg')
# 将指针指向流的开始
stream.seek(0)
image = Image.open(stream)
4.4、捕捉一个图像转化为open cv对象
首先我们捕捉一个图像流,然后将图像数据转换为open cv对象:
import io
import time
import picamera
import cv2
import numpy as np
# 创建一个流
stream = io.BytesIO()
with picamera.PiCamera() as camera:
camera.start_preview()
time.sleep(2)
camera.capture(stream, format='jpeg')
# 从流构建numpy
data = np.fromstring(stream.getvalue(), dtype=np.uint8)
# 通过opencv解码numpy
image = cv2.imdecode(data, 1)
# opencv解码后返回以RGB解码的图像数据
image = image[:, :, ::-1]
如果你不想使用有损JPEG编码,并希望加快这一解码过程的话,可以使用picamera自带的picamera.array模块。可以使用PiRGBArray类简单的捕获’brg’格式的数据。(假定RGB与BGR是分辨率相同的数据,只是具有相反的颜色)
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')
# 此时就可以获取到bgr的数据流了
image = stream.array
4.5、调整捕捉图像的分辨率
有时,我们需要将图片进行某种分析或处理,你希望尽可能的捕获比较小分辨率的图像,虽然这种分辨率的调整可以交给PIL或者opencv来完成,但是通过picamera可以更搞笑的完成这个操作:
import time
import picamera
with picamera.PiCamera() as camera:
camera.resolution = (1024, 768)
camera.start_preview()
# 摄像头预热
time.sleep(2)
camera.capture('foo.jpg', resize=(320, 240))
同时调整分辨率的参数也可以适用于捕获视频的start_recording()方法。
4.6、捕获连续图像
您可能希望连续捕捉到的图像的亮度、色彩与对比度上保持一致(例如,这个可能在延迟摄影中非常有用)。可以设置一些属性,确保在多个镜头中保持画面的一致。具体来说,您需要保证摄像头的曝光时间,白平衡和画面增益都是固定的。
- 设置曝光时间:shutter_speed
- 设置画面增益:首先将 exposure_mode设置为’off’然后将analog_gain和digital_gain设置在合理的范围值。
- 设置白平衡:将awb_mode设置为’off’,然后将awb_gains设置为red或者blue或者直接设置iso的值。
设置这些属性是非常专业的,并且非常难调整到合适的范围值。在白天,对于iso,100~200是一个简单的合理范围,而在低光环境下,需要调整到400~800。对于shutter_speed如果需要确定一个合理的范围值可以直接查询exposure_speed属性。对于曝光增益,通常只需要将analog_gain设置为大于1的值(analog_gain的默认值为1,但这将产生一个全黑的图像帧)。
下面的这个例子提供了一些简单配置的实例:
import time
import picamera
with picamera.PiCamera() as camera:
camera.resolution = (1280, 720)
camera.framerate = 30
# 等待摄像头预热,适应光线环境
time.sleep(