树莓派3B/4B安装CSI摄像头及安装驱动使用最佳实践

xingyun86 2021-4-8 3013

树莓派3B/4B安装CSI摄像头及安装驱动使用最佳实践

1.买的硬件张这个样子的(CSI接口摄像头):

 正视图(摄像头的卡扣一定不要装反了,否则树莓派会无法识别到摄像头)                                                        

后视图(蓝色所处正反面不要装反,否则也会出问题)


树莓派一端的连接如下:(这里是树莓派3B,这个位置的接口黑色卡扣是可以拉起来一点,然后把摄像头排线的一端插入,注意蓝色部分是朝向树莓派USB接口的方向)



2.检测树莓派当前的摄像头设备列表

$ ls /dev/video*
/dev/video10  /dev/video11  /dev/video12  /dev/video13  /dev/video14  /dev/video15  /dev/video16
备注:(如果安装成功显示如下.)
$ ls /dev/video*
/dev/video0  /dev/video11  /dev/video12  /dev/video13  /dev/video14  /dev/video15  /dev/video16

3.树莓派下配置文件添加模块

 $ sudo vi /etc/modules
 ==============================(辅助线,无需理会)
 # /etc/modules: kernel modules to load at boot time.
 #
 # This file contains the names of kernel modules that should be loaded
 # at boot time, one per line. Lines beginning with "#" are ignored.
 i2c-dev
 bcm2835-v4l2 #这里新增一行
 ==============================(辅助线,无需理会)

4.树莓派开启摄像头配置项

$ sudo raspi-config


继续下一步


选择【是】继续


继续下一步,已经启用摄像头接口:


选择【Finish】。


重启即可。

5.检测是否安装摄像头模块成功

$ ls /dev/video*
/dev/video0  /dev/video11  /dev/video12  /dev/video13  /dev/video14  /dev/video15  /dev/video16
如果无/dev/video0,则表示安装失败。
注意:检查摄像头的排线是否连接反了,或者是摄像头的卡扣连接反了

6.如果安装已经成功,则可以用一下命令进行测试

摄像头截图保存到image.jpg
$ raspistill -o image.jpg
如果无错误,则ok。如果出错,再次确认第5步是否完成(注意,摄像头设备一定是/dev/video0).

7.安装Python-opencv实现rtmp推流

参考《python3安装opencv

8.编写python代码测试

raspivid + ffmpeg推流到rtmp

raspivid -o - -t 0 -vf -hf -w 640 -h 480 -fps 25 -b 500000 | ffmpeg -re -ar 44100 -ac 2 -acodec pcm_s16le -f s16le -ac 2 -i /dev/video0 -f h264 -i - -vcodec copy -acodec aac -ab 128k -g 50 -s 640x480 -strict experimental -f flv rtmp://0.0.0.0:1935/hls/live

import cv2
import queue
import os
import numpy as np
from threading import Thread
import datetime,_thread
import subprocess as sp
import time
# 使用线程锁,防止线程死锁
mutex = _thread.allocate_lock()
# 存图片的队列
frame_queue = queue.Queue()
# 推流的地址,前端通过这个地址拉流,主机的IP,2019是ffmpeg在nginx中设置的端口号
rtmpUrl="rtmp://192.168.40.145:2019/live/1"
# 用于推流的配置,参数比较多,可网上查询理解
command=['ffmpeg',
                '-y',
                '-f', 'rawvideo',
                '-vcodec','rawvideo',
                '-pix_fmt', 'bgr24',
                '-s', "{}x{}".format(640, 480),# 图片分辨率
                '-r', str(25.0),# 视频帧率
                '-i', '-',
                '-c:v', 'libx264',
                '-pix_fmt', 'yuv420p',
                '-preset', 'ultrafast',
                '-f', 'flv',
                rtmpUrl]
 
def Video():
# 调用相机拍图的函数
    vid = cv2.VideoCapture(0)
    if not vid.isOpened():
        raise IOError("Couldn't open webcam or video")
    while (vid.isOpened()):
        return_value, frame = vid.read()
 
        # 原始图片推入队列中
        frame_queue.put(frame)
 
 
def push_frame():
    # 推流函数
 
    # 防止多线程时 command 未被设置
    while True:
        if len(command) > 0:
            # 管道配置,其中用到管道
            p = sp.Popen(command, stdin=sp.PIPE)
            break
 
    while True:
        if frame_queue.empty() != True:
            #从队列中取出图片
            frame = frame_queue.get()
 
            # process frame
            # 你处理图片的代码
            # 将图片从队列中取出来做处理,然后再通过管道推送到服务器上
          
            # write to pipe
            # 将处理后的图片通过管道推送到服务器上,frame是处理后的图片
            p.stdin.write(frame.tostring())
 
def run():
     #使用两个线程处理
 
    thread1 = Thread(target=Video,)
    thread1.start()
    thread2 = Thread(target=push_frame,)
    thread2.start()
    
if __name__ == '__main__': 
    run()


×
打赏作者
最新回复 (0)
查看全部
全部楼主
返回