树莓派(Raspberry Pi)中PiCamera+OpenCV的使用

树莓派(Raspberry Pi)中PiCamera+OpenCV的使用

参考:

Raspberry Pihttps://www.raspberrypi.org/
Index of Packageshttps://pypi.python.org/pypi/picamera


最新版本是 picamera 1.13http://picamera.readthedocs.io/en/release-1.13/

主要内容

  1. 简单测试相机模块是否可以使用
  2. 使用 picamera 进行图像拍摄
  3. capturecapture_continuous 介绍
  4. 使用 picamera 进行视频录制
  5. picamera + OpenCV
  6. OpenCV 无法操作树莓派原装摄像头解决方法

简单测试相机模块是否可以使用

使用命令 raspistill 可以测试树莓派相机模块,最简单的语句如下:

raspistill -o te.jpg

功能:打开摄像头预览,几秒后拍摄一张照片


使用 picamera 进行图像拍摄

使用 picamera 之前注意不要把文件名保存为 picamera.py

When trying out these scripts do not name your file picamera.py.
Naming scripts after existing Python modules will cause errors when you try and import those modules
(because Python checks the current directory before checking other paths).

打开摄像头进行预览

代码:

# -*- coding: utf-8 -*-

from time import sleep
from picamera import PiCamera

def open_preview():
    with PiCamera() as camera:
        camera.resolution = (320, 240)

        camera.start_preview()
        sleep(5)

if __name__ == '__main__':
    open_preview()

函数 open_preview() 用于打开摄像头进行预览

首先,获取一个 PiCamera 对象:

with PiCamera() as camera:

可以设置摄像头的分辨率,当前设为宽 320,高 240

camera.resolution = (320, 240)

打开摄像头进行预览:

camera.start_preview()

暂停 5 秒,即预览 5 秒:

sleep(5)

Note: 当结束摄像头操作后,务必确保调用 close 方法结束,有两种函数结构

camera = PiCamera()
try:
    # do something with the camera
    pass
finally:
    camera.close()

或者

with PiCamera() as camera:
    # do something with the camera
    pass

否则,有可能下次会无法打开,出现以下问题:

mmal: mmal_vc_component_enable: failed to enable component: ENOSPC
mmal: camera component couldn't be enabled
mmal: main: Failed to create camera component
mmal: Failed to run camera app. Please check for firmware updates

此为个人推测,摄像头并没有及时关闭导致(可通过相机模块的红灯判断摄像头是否开启)

对摄像头有一些常用的操作,比如设置分辨率,帧率,是否左右翻转,上下翻转:

def open_preview2():
    with PiCamera() as camera:
        camera.resolution = (320, 240)
        camera.framerate = 24
        camera.hflip = True
        camera.vflip = True

        camera.start_preview()
        sleep(5)

使用 picamera 还可以进行更多复杂功能的设置,比如设定摄像头的 ISO,曝光时间,亮度,对比度等等,可查看文档

拍摄图像

在预览的过程中可以将图片保存下来,函数实现如下:

def capture_preview():
    with PiCamera() as camera:
        camera.resolution = (320, 240)

        camera.start_preview()

        for i in range(5):
            sleep(i)

            camera.capture(str(i) + ".jpg", resize=(80, 60))

函数 capture_preview() 仅比 open_preview() 多了一条捕获图像函数:

camera.capture(str(i) + ".jpg")

还可以在捕获图像的时候进行图像缩放:

camera.capture("te.jpg", resize=(80, 60))

函数功能:捕获图像,命名为 te.jpg,同时缩放至宽 80,高 60

Note:当获取到 PiCamera() 对象后,就已经打开摄像头了,所以并不一定需要调用 camera.start_preview() 进行预览后才能保存图像

def capture_preview2():
    """
    打开摄像头,5秒后捕获一张图像
    :return:
    """
    with PiCamera() as camera:
        camera.resolution = (320, 240)

        sleep(5)

        camera.capture("no_preview.jpg")

capturecapture_continuous 介绍

函数 capture 原型:

capture(output, format=None, use_video_port=False, resize=None, splitter_port=0, bayer=False, **options)

源码:capture

功能:从摄像头中捕获图像,保存在 output

关键参数介绍:

  • output - 输出,如果为字符串,则作为文件名使用,比如 te.jpgte2.png等;如果不是字符串,那么必须是一个可读对象

  • format - 保存图像格式,默认为空,不为空,可使用以下格式:

函数 capture 支持图像格式如下:

'jpeg' - Write a JPEG file
'png' - Write a PNG file
'gif' - Write a GIF file
'bmp' - Write a Windows bitmap file
'yuv' - Write the raw image data to a file in YUV420 format
'rgb' - Write the raw image data to a file in 24-bit RGB format
'rgba' - Write the raw image data to a file in 32-bit RGBA format
'bgr' - Write the raw image data to a file in 24-bit BGR format
'bgra' - Write the raw image data to a file in 32-bit BGRA format
'raw' - Deprecated option for raw captures; the format is taken from the deprecated raw_format attribute

Note:当 output 指定图像格式后,如果 format 设置格式与其不一致,无法得到正常图像

  • use_video_port - 使用摄像头的图像或者视频端口进行图像捕获,默认为 False,表示使用图像端口。图像端口捕获速度慢(打开预览可知,捕获时会出现停顿现象),但是图像质量高;如果想要快速的捕获图像,使用视频端口,那么设为 True

如果想要不断捕获图像进行处理,使用图像端口如下:

# -*- coding: utf-8 -*-

from time import sleep
from picamera import PiCamera


def capture_images():
    """
    不断捕获图像
    :return:
    """
    with PiCamera() as camera:
    camera.resolution = (320, 240)
    sleep(2)

    num = 0
    while True:
        camera.capture(str(num) + ".jpg")

        print num
        num += 1

if __name__ == '__main__':
    capture_images()

想要速度更快,可以使用视频端口进行

camera.capture(str(num) + ".jpg", use_video_port=True)

picamera 也提供了一个不断捕获图像的函数 capture_continuous

函数原型:

capture_continuous(output, format=None, use_video_port=False, resize=None, splitter_port=0, burst=False, bayer=False, **options)

源码:capture_continuous

功能:不断从相机中捕获图像,该函数返回一个无穷迭代器。

参数 output - 如果是字符串,函数设定了两个替代项用于保存不同图像

  • {counter} - a simple incrementor that starts at 1 and increases by 1 for each image taken
  • {timestamp} - a datetime instance

使用方法比如:image{counter}.jpgimage{counter:02d}.jpgimage{timestamp}.jpg

具体可查看文档

示例函数:

import time
import picamera
with picamera.PiCamera() as camera:
    camera.start_preview()
    try:
    for i, filename in enumerate(
            camera.capture_continuous('image{counter:02d}.jpg')):
        print(filename)
        time.sleep(1)
        if i == 59:
            break
    finally:
    camera.stop_preview()

其他参数同 capture 一致


使用 picamera 进行视频录制

def record_video():
    """
    录制视频
    :return:
    """
    with PiCamera() as camera:
        camera.resolution = (320, 240)

        camera.start_preview()
        camera.start_recording('my.h264')

        camera.wait_recording(10)
        camera.stop_recording()

函数 record_video 进行视频录制

首先获取 PiCamera 对象:

with PiCamera() as camera:

可以设置分辨率,当前设为 (320, 240)

camera.resolution = (320, 240)

打开预览,便于视频录制:

camera.start_preview()

开始录制,录制内容保存为 my.h264

camera.start_recording('my.h264')

设置录制时间,当前录制 10 秒视频:

camera.wait_recording(10)

关闭摄像头,结束录制:

camera.stop_recording()

函数 start_recording 支持视频格式如下:

'h264' - Write an H.264 video stream
'mjpeg' - Write an M-JPEG video stream
'yuv' - Write the raw video data to a file in YUV420 format
'rgb' - Write the raw video data to a file in 24-bit RGB format
'rgba' - Write the raw video data to a file in 32-bit RGBA format
'bgr' - Write the raw video data to a file in 24-bit BGR format
'bgra' - Write the raw video data to a file in 32-bit BGRA format

Note:函数 start_preview 同样也不是必须的


picamera + OpenCV

经常使用 OpenCV 进行图像处理,需要 picamera 得到的图像转换为 OpenCV 能够处理的 numpy array 格式

捕获图像并显示:

# -*- coding: utf-8 -*-

import time
import picamera
import numpy as np
import cv2

with picamera.PiCamera() as camera:
    camera.resolution = (320, 240)
    camera.framerate = 24
    time.sleep(2)
    image = np.empty((240 * 320 * 3,), dtype=np.uint8)
    camera.capture(image, 'bgr')
    image = image.reshape((240, 320, 3))

    cv2.imshow("img", image)
    cv2.waitKey(0)

使用视频端口(use_video_port=True)就无法捕获图像了,没搞懂

视频流:

# -*- coding: utf-8 -*-

import time
import picamera
import numpy as np
import cv2

with picamera.PiCamera() as camera:
    camera.resolution = (320, 240)
    camera.framerate = 24
    time.sleep(2)

    while True:
        image = np.empty((240 * 320 * 3,), dtype=np.uint8)
        camera.capture(image, format='bgr')
        image = image.reshape((240, 320, 3))

        cv2.imshow("img", image)
        cv2.waitKey(1)

上面这个效果不佳,使用 capture_continuous:

# -*- coding: utf-8 -*-

import io
from time import sleep
import picamera
import numpy as np
import cv2

with picamera.PiCamera() as camera:
    camera.resolution = (320, 240)
    sleep(1)

    stream = io.BytesIO()
    for foo in camera.capture_continuous(stream, format='jpeg', use_video_port=True):
        data = np.fromstring(stream.getvalue(), dtype=np.uint8)
        image = cv2.imdecode(data, cv2.CV_LOAD_IMAGE_UNCHANGED)

        cv2.imshow("img", image)
        cv2.waitKey(1)

        # Truncate the stream to the current position (in case
        # prior iterations output a longer image)
        stream.truncate()
        stream.seek(0)

picamera 也提供了 PIRGBArray 对象,用来保存 RGB 图像

类原型:

class picamera.array.PiRGBArray(camera, size=None)

源码:PIRGBArray

捕获单张:

# -*- coding: utf-8 -*-

import picamera
import picamera.array

with picamera.PiCamera() as camera:
    with picamera.array.PiRGBArray(camera) as output:
        camera.capture(output, 'rgb')
        print('Captured %dx%d image' % (
            output.array.shape[1], output.array.shape[0]))

        print type(output.array)

得到的 output.array 就是 numpy.ndarray 类型,可直接用于 opencv 处理

不过 opencv 中图像格式是 bgr ,所以还需要进行转换:

dst = cv2.cvtColor(output.array, cv2.COLOR_RGB2BGR)

Note:在 capture 函数中设置图像格式为 bgr 没有作用

如果想要重复使用 output,需要在下次捕获前使用函数 truncate(0)

# -*- coding: utf-8 -*-

import picamera
import picamera.array

with picamera.PiCamera() as camera:
    with picamera.array.PiRGBArray(camera) as output:
        camera.resolution = (1280, 720)
        camera.capture(output, 'rgb')
        print('Captured %dx%d image' % (
            output.array.shape[1], output.array.shape[0]))
        output.truncate(0)
        camera.resolution = (640, 480)
        camera.capture(output, 'rgb')
        print('Captured %dx%d image' % (
            output.array.shape[1], output.array.shape[0]))

完整代码如下:

# -*- coding: utf-8 -*-

import picamera
import picamera.array
import cv2
from time import sleep

with picamera.PiCamera() as camera:
    camera.resolution = (320, 240)
    sleep(1)

    with picamera.array.PiRGBArray(camera) as output:
        # camera.capture(output, 'rgb', use_video_port=True)
        for foo in camera.capture_continuous(output, 'rgb', use_video_port=True):
            print('Captured %dx%d image' % (
            output.array.shape[1], output.array.shape[0]))

            dst = cv2.cvtColor(output.array, cv2.COLOR_RGB2BGR)

            cv2.imshow("img", dst)
            cv2.waitKey(1)

            output.truncate(0)

OpenCV 无法操作树莓派原装摄像头解决方法

可以直接使用 opencv 调用摄像头

# -*- coding: utf-8 -*-

import cv2

cap = cv2.VideoCapture(0)
# cap.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, 320)
# cap.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, 240)

while True:
    # get a frame
    ret, frame = cap.read()
    print "frame.shape: {}".format(frame.shape)

    # show a frame
    cv2.imshow("capture", frame)
    cv2.waitKey(1)

但可能会出现无法打开摄像头,原因:树莓派摄像头模块没有video0

解决方法:

cd /etc/modules-load.d/

sudo vim modules.conf 

加入 bcm2835-v4l2

重启,即可

  • 42
    点赞
  • 247
    收藏
    觉得还不错? 一键收藏
  • 20
    评论
### 回答1: 树莓派是一款功能强大的微型计算机,而raspberrypi基于传感器开发套件可以帮助我们更好地利用树莓派进行编程。这套开发套件通常包括各种传感器,如温度传感器、湿度传感器、光线传感器、运动传感器等,以及它们所需的电子元件和连接线。 使用raspberrypi基于传感器开发套件,我们可以轻松地将传感器连接到树莓派上,并通过编写代码来获取传感器的数据。这些数据可以用于各种有趣的项目,如温度监测、智能家居系统、环境监测等。 例如,我们可以使用温度传感器来测量环境温度,并根据实时数据来控制风扇或空调的运行。使用光线传感器,我们可以根据光线强度自动调节屏幕亮度或灯光明暗。利用运动传感器,我们可以实现智能安防系统,当有人进入监测区域时,自动触发警报或拍摄照片。 除了这些应用,raspberrypi基于传感器开发套件还可以用于教育和学习编程。它提供了一个实践的平台,让学生能够亲自动手进行实验和项目开发。这样,他们可以通过编程来理解传感器的原理和工作方式,提高他们的动手能力和创造力。 总之,raspberrypi基于传感器开发套件为我们提供了一个丰富多样的编程平台。通过利用树莓派的强大功能以及各种传感器,我们可以开发出各种实用、有趣的项目,并且在学习过程提高自己的编程能力和创造力。 ### 回答2: RaspberryPi基于传感器开发套件可以让我们更好地使用树莓派进行编程和开发。树莓派是一款基于Linux系统的单板计算机,它具有丰富的GPIO针脚,可与各种传感器和外部设备连接。 使用传感器开发套件,我们可以利用树莓派的强大功能来与不同的传感器进行交互。例如,我们可以通过连接温湿度传感器来实时监测环境的温度和湿度变化。我们还可以连接光敏传感器来检测光线强度,或连接声音传感器来监测声音的大小。这些传感器可以帮助我们获取各种感知数据,用于各种项目和应用。 在编程方面,树莓派提供了多种编程语言和开发环境供我们选择,如Python和C语言。我们可以利用树莓派的GPIO库和传感器开发套件,编写程序来控制传感器的输出和读取传感器的数据。例如,我们可以编写一个程序来根据光敏传感器获取到的光线强度来控制LED灯的亮度。 此外,传感器开发套件还可以用于学习机器视觉和人工智能等领域。通过连接摄像头模块,我们可以使用树莓派进行图像识别和目标跟踪等任务。这为我们提供了一个实践和学习机器学习算法的平台。 总的来说,RaspberryPi基于传感器开发套件为我们提供了一个灵活且功能强大的平台,可以让我们玩转树莓派编程。无论是用于科技创作、物联网项目还是学习编程和电子技术,树莓派和传感器开发套件都是非常有用的工具。 ### 回答3: Raspberry Pi基于传感器开发套件让我们能够充分利用树莓派的强大功能,进行各种创意编程项目。借助这套开发套件,我们可以轻松地将各种传感器与树莓派连接起来,并通过编程控制与其交互。 这个开发套件通常包含了各种常用的传感器模块,比如温度传感器、湿度传感器、光敏传感器等等。我们只需要将这些传感器连接到树莓派的GPIO口,然后基于Python编程语言进行编程,就能够读取传感器的数据,进行各种有趣的操作。 例如,我们可以使用温度传感器监测环境温度,并编写程序将温度数据实时显示在树莓派上。或者,我们可以利用光敏传感器检测光线强度,并通过编写代码控制与光线相关的设备,比如控制LED灯的开启与关闭。 除了基础的传感器,树莓派的开发套件还包括一些高级功能模块,比如声音传感器、声音放大器、触摸传感器等等。借助这些模块,我们可以进行更加复杂的音乐创作、声控设备开发等项目。 总之,Raspberry Pi基于传感器开发套件为我们提供了一个便捷的方式来学习编程,并将所学应用到实际。无论是探索物联网、机器人学,还是设计各种有趣的交互装置,这套开发套件都是一个理想的选择。通过动手实践,我们能够深入了解树莓派的强大功能,并培养创造力和解决问题的能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值