当前位置: 首页 > news >正文

香橙派使用USB摄像头

文章目录

  • 香橙派使用USB摄像头的方法
    • USB摄像头测试
    • USB摄像头使用
      • 启动脚本
      • udev规则
      • 开机mjpg-streamer服务自启
      • 优化服务启动方式

香橙派使用USB摄像头的方法

USB摄像头测试

  1. 首先将USB摄像头插入到Orange Pi开发板的USB接口中

  2. 然后通过lsmod | grep uvcvideo命令可以看到内核自动加载了下面的模块

    image-20250421214725833

  3. 通过v4l2-ctl命令可以看到USB摄像头的设备节点信息为dev/video1(需要注意的是这里的video1可能会改变,下一次插入它显示的可能就为video0)

    #1.首先安装v4l-utils工具
    sudo apt-get update
    sudo apt-get install -y v4l-utils#2.使用v4l-untils工具查看摄像头设备节点
    orangepi@orangepizero2:~$ v4l2-ctl --list-devices
    cedrus (platform:cedrus):/dev/video0/dev/media0#这个是我的摄像头
    Q8 HD Webcam: Q8 HD Webcam (usb-5200000.usb-1):/dev/video1			#通常是第一个要用的设备节点信息	/dev/video2/dev/media1	
    
  4. 使用fswebcam测试USB摄像头

    • 安装fswebcam

      sudo apt-get update
      sudo apt-get install -y fswebcam
      
    • 安装完fswebcam后可以使用下面的命令来拍照

      • -d选项用于指定USB摄像头的设备节点
      • --no-banner用于去除照片的水印
      • -r选项用于指定照片的分辨率
      • -S选项用于设置与跳过前面的帧数
      • ./image.jpg用于设置生成照片的名字和路径
      sudo fswebcam -d /dev/video1 --no-banner -r 1280x720 -S 5 ./image.jpg
      
    • 在香橙派上拍照完成后,可以使用scp指令将照片传到Ubuntu上去查看

      scp image.jpg usrname@192.168.0.31:/home/username
      #根据实际情况修改用户名、IP地址和路径
      
    • 在Ubuntu中可以直接查看刚刚在香橙派上拍的照片

  5. 使用mjpg-streamer测试USB摄像头

    • 下载mjpg-streamer

      git clone https://gitee.com/leeboby/mjpg-streamer
      #这里选用国内的gitee,国外的GitHub对网络要求较高
      
    • 安装依赖的软件包

      #Ubuntu系统
      sudo apt-get install -y cmake libjpeg8-dev
      
    • 编译安装mjpg-streamer

      cd mjpg-streamer/mjpg-streamer-experimental/
      make -j4		#-j4表示使用所有板载内核来处理任务
      sudo make install
      
    • 然后输入下面的命令启动mjpg-streamer

      export LD_LIBRARY_PATH=.	#将当前路径添加到环境变量中
      sudo \
      ./mjpg_streamer -i "./input_uvc.so -d /dev/video1 -u -f 30" \
      -o "./output_http.so -w ./www"#这里的video1要根据上边执行v4l2-ctl --list-devices来确定
      
    • 然后在浏览器输入开发板IP地址+端口号就能查看摄像头输出的画面了

      image-20250422092817347

USB摄像头使用

上边已经介绍了怎么测试板子是否能够正确的连接USB摄像头,接下来介绍一下后续怎么使用它。

启动脚本

/mjpg-streamer/mjpg-streamer-experimental文件夹中默认就有一个启动的脚本start.sh,查看脚本内容发现有一句话和刚刚输入的测试命令很像

image-20250422000911024

直接将这条命令修改成如下内容:

./mjpg_streamer -i "./input_uvc.so -d /dev/video0 -u -f 30" -o "./output_http.so -w ./www"
#这里的/dev/video1不是固定的,修改完内容后保存退出

然后直接在当前目录运行./start.sh看看服务能否正常运行,同上在浏览器输入IP地址进行查看。

image-20240609162638988

image-20250422092911132

udev规则

简单介绍以下udev规则,udev规则就是当一个设备插入到板子中,内核时最先知晓的,这时候udev就给这个设备创建一个单独的文件,当这个设备拔走时,udev又会将这个文件自动删除。这样极大地方便了用户查找对应的设备文件,所以现在给摄像头编写udev规则,保证摄像头对应的设备文件时唯一的。这是维基百科关于udev的概述:udev - 维基百科,自由的百科全书

  1. 查看usb ID:lsusb

    image-20250422002525406

    通过拔插摄像头确定摄像头的设备ID是:1bcf:2281

  2. 查看usb设备的信息

    #首先使用v4l2-ctl指令查看usb摄像头的设备节点
    v4l2-ctl --list-devices
    Q8 HD Webcam: Q8 HD Webcam (usb-fc880000.usb-1):/dev/video1/dev/video2/dev/media0
    #然后使用指令查看usb设备信息,这里的video1不是固定的,是要根据上边的设备节点进行调整的
    udevadm info -a -p /sys/class/video4linux/video1looking at device '/devices/platform/soc/5200000.usb/usb2/2-1/2-1:1.0/video4linux/video1':KERNEL=="video1"SUBSYSTEM=="video4linux"DRIVER==""ATTR{dev_debug}=="0"ATTR{index}=="0"ATTR{name}=="Q8 HD Webcam: Q8 HD Webcam"ATTR{power/control}=="auto"ATTR{power/runtime_active_time}=="0"ATTR{power/runtime_status}=="unsupported"ATTR{power/runtime_suspended_time}=="0"looking at parent device '/devices/platform/soc/5200000.usb/usb2/2-1/2-1:1.0':KERNELS=="2-1:1.0"SUBSYSTEMS=="usb"DRIVERS=="uvcvideo"ATTRS{authorized}=="1"ATTRS{bAlternateSetting}==" 0"ATTRS{bInterfaceClass}=="0e"ATTRS{bInterfaceNumber}=="00"ATTRS{bInterfaceProtocol}=="00"ATTRS{bInterfaceSubClass}=="01"ATTRS{bNumEndpoints}=="01"ATTRS{iad_bFirstInterface}=="00"ATTRS{iad_bFunctionClass}=="0e"ATTRS{iad_bFunctionProtocol}=="00"ATTRS{iad_bFunctionSubClass}=="03"ATTRS{iad_bInterfaceCount}=="02"ATTRS{interface}=="Q8 HD Webcam"ATTRS{supports_autosuspend}=="1"looking at parent device '/devices/platform/soc/5200000.usb/usb2/2-1':KERNELS=="2-1"SUBSYSTEMS=="usb"DRIVERS=="usb"ATTRS{authorized}=="1"ATTRS{avoid_reset_quirk}=="0"ATTRS{bConfigurationValue}=="1"ATTRS{bDeviceClass}=="ef"ATTRS{bDeviceProtocol}=="01"ATTRS{bDeviceSubClass}=="02"ATTRS{bMaxPacketSize0}=="64"ATTRS{bMaxPower}=="500mA"ATTRS{bNumConfigurations}=="1"ATTRS{bNumInterfaces}==" 4"ATTRS{bcdDevice}=="0429"ATTRS{bmAttributes}=="80"ATTRS{busnum}=="2"ATTRS{configuration}==""ATTRS{devnum}=="2"ATTRS{devpath}=="1"ATTRS{devspec}=="(null)"ATTRS{idProduct}=="2281"ATTRS{idVendor}=="1bcf"ATTRS{ltm_capable}=="no"ATTRS{manufacturer}=="Q8 HD Webcam"ATTRS{maxchild}=="0"ATTRS{power/active_duration}=="4473204"ATTRS{power/autosuspend}=="2"ATTRS{power/autosuspend_delay_ms}=="2000"ATTRS{power/connected_duration}=="4478404"ATTRS{power/control}=="auto"ATTRS{power/level}=="auto"ATTRS{power/persist}=="1"ATTRS{power/runtime_active_time}=="4472866"ATTRS{power/runtime_status}=="active"ATTRS{power/runtime_suspended_time}=="5128"ATTRS{product}=="Q8 HD Webcam"ATTRS{quirks}=="0x0"ATTRS{removable}=="unknown"ATTRS{rx_lanes}=="1"ATTRS{speed}=="480"ATTRS{tx_lanes}=="1"ATTRS{urbnum}=="1115253"ATTRS{version}==" 2.00"#这里需要注意的是它会输出很多的信息,而且通过观察不难发现它输出的形式是逐级向父目录靠近的,这里我们只需要获取到它的几个关键值,使用grep指令过滤出关键信息,由于知道它是逐级向父目录靠近的,所有第一个拿到的就是摄像头对应的idProduct和idVendor
    orangepi@orangepizero2:~$ udevadm info -a -p /sys/class/video4linux/video1 | grep "ATTRS{idProduct}"ATTRS{idProduct}=="2281"ATTRS{idProduct}=="0002"
    orangepi@orangepizero2:~$ udevadm info -a -p /sys/class/video4linux/video1 | grep "ATTRS{idVendor}"ATTRS{idVendor}=="1bcf"ATTRS{idVendor}=="1d6b"#拿到几个关键的信息
    KERNEL=="video1"
    SUBSYSTEM=="video4linux"
    DRIVERS=="uvcvideo"
    ATTRS{idProduct}=="2281"
    ATTRS{idVendor}=="1bcf"
    #这几个地方都对应的摄像头的唯一标识
    
  3. 构建udev规则

    基于上述信息,编写唯一的规则来匹配摄像头设备。

    cd /etc/udev/rules.d
    ls		#查看当前目录下的udev规则,需要注意的是必须以.rules为后缀,否则不会生效
    orangepi@orangepizero2:/etc/udev/rules.d$ ls
    10-wifi-disable-powermanagement.rules  50-usb-realtek-net.rules 
    sudo vi orangepi_camera.rules
    # 匹配摄像头设备
    KERNEL=="video*", SUBSYSTEM=="video4linux", \ATTRS{idVendor}=="1bcf", ATTRS{idProduct}=="2281", \SYMLINK+="orangepi_camara"#KERNEL=="video*":
    #匹配所有名为 videoX 的设备(例如 video0, video1 等)。
    #SUBSYSTEM=="video4linux":
    #确保设备属于 video4linux 子系统。#ATTRS{idVendor}=="1bcf", ATTRS{idProduct}=="2281":
    #根据 USB 设备的 idVendor 和 idProduct 属性进一步确认设备的唯一性。
    #SYMLINK+="orangepi_camara":
    #创建一个符号链接 /dev/orangepi_camara,方便用户访问该设备。
  4. 测试 udev 规则

    • 重新加载udev规则

      sudo udevadm control --reload-rules
      sudo udevadm trigger
      
    • 验证符号链接

      检查 /dev/ 目录下是否生成了 orangepi_camara 符号链接:

      ls -l /dev/orangepi_camara#使用udev创建的一个符号连接/dev/orangepi_camera
      
    • 修改start.sh文件

      将里边的设备节点从/dev/video1改为/dev/orangepi_camera,这时候无论它的设备节点怎么变,只要运行这个脚本就能够启动mjpg-streamer服务

    • /home/orangepi路径底下新建一个mjpg.sh,跳转到start.sh所在的目录,然后执行start.sh

      vi start.sh#将下边这段内容加进去#/bin/bashcd /home/orangepi/mjpg-streamer/mjpg-streamer-experimental
      ./start.sh#保存后然后加权限
      sudo chmod +x mjpg.sh#运行看看能不能跑起mjpg-streamer服务
      ./mjpg.sh
      

      image-20250422101330002

开机mjpg-streamer服务自启

​ 要想实现开机自动启动mjpg-streamer服务需要先写一个脚本来运行当前这个目录下的start.sh,开启自启的文件存放在/etc/xdg/autostart文件夹下。进入到这个目录随后编写mjpg-streamer开机启动的脚本。

cd /etc/xdg/autostart/sudo vi mjpg-streamer.desktop			#新建启动脚本#添加以下内容
[Desktop Entry]
Name=mjpg-streamer
Comment=Start mjpg-streamer on boot
Exec=/home/orangepi/mjpg.sh
Path=/home/orangepi/
Type=Application
NoDisplay=true#重启系统
sudo reboot#查看mjpg-streamer服务是否启动
ps -aux | grep mjpg |grep -v greporangepi    2307  0.0  0.0   2308   816 ?        S    10:08   0:00 /bin/sh /home/orangepi/mjpg.sh
orangepi    2321  0.5  0.0 455696  5944 ?        Sl   10:08   0:02 ./mjpg_streamer -i ./input_uvc.so -d //dev/orangepi_camera -u -f 30 -o ./output_http.so -w ./www

优化服务启动方式

​ 上边的服务能够跑起来的前提是需要在板子还没有启动前将摄像头插入到板子中,如果先启动板子,那么udev规则就检测不到摄像头的设备节点,那么服务就启动失败。因为udev规则是设备插上去以后才生效的,如果没有插上去,规则不会执行,系统也不会报错。并且当中途需要拔掉摄像头再插回去还需要把原有的mjpg-streamer服务杀掉,重新手动运行mjpg.sh,这样才能后启动服务。所以这里优化它的启动方式:插上USB摄像头后启动服务,拔掉以后关闭服务,这样子就会比较方便了。

  1. 首先查看一下后台是否有mjpg-streamer的服务运行,如果有就杀掉它

    ps -aux|grep mjpg | grep -v grep#如果这里有mjpg的进程就杀掉它
    kill -9 $PID		#PID为进程号
    
  2. 然后删掉开机自动启动脚本和/home/orangepi/下的mjpg.sh

    sudo rm /etc/xdg/autostart/mjpg-streamer.desktoprm mjpg.sh
    
  3. 然后修改/home/orangepi/mjpg-streamer/mjpg-streamer-experimental这个文件夹底下的start.sh

    cd mjpg-streamer/mjpg-streamer-experimental/
    vi start.sh#!/bin/bashexport LD_LIBRARY_PATH=$(pwd)# 找出 USB 摄像头下的第一个 /dev/videoX 设备,并去除前后空格
    #将下边这段内容加进入
    VIDEO_DEVICE=$(v4l2-ctl --list-devices | awk '
    /usb/ {flag=1; next}
    /^[^ \t]/ {flag=0}
    flag && /\/dev\/video/ {print; exit}
    ' | sed 's/^[ \t]*//;s/[ \t]*$//')# 如果没找到就默认 /dev/video0
    [ -z "$VIDEO_DEVICE" ] && VIDEO_DEVICE="/dev/video0"echo "Using video device: $VIDEO_DEVICE"./mjpg_streamer -i "./input_uvc.so -d $VIDEO_DEVICE -u -f 30" -o "./output_http.so -w ./www"
    

    image-20250422111455427

  4. 测试start.sh是否能够正常运行

    #输出以下信息说明启动成功
    ./start.sh
    Using video device: /dev/video0
    MJPG Streamer Version: git rev: 85f89a8c321e799fabb1693c5d133f3fb48ee748i: Using V4L2 device.: /dev/video0i: Desired Resolution: 640 x 480i: Frames Per Second.: 30i: Format............: UYVYi: JPEG Quality......: 80i: TV-Norm...........: DEFAULTi: Could not obtain the requested pixelformat: UYVY , driver gave us: MJPG... will try to handle this by checking against supported formats.... Falling back to the faster MJPG mode (consider changing cmd line options).
    UVCIOC_CTRL_ADD - Error at Pan (relative): Inappropriate ioctl for device (25)
    UVCIOC_CTRL_ADD - Error at Tilt (relative): Inappropriate ioctl for device (25)
    UVCIOC_CTRL_ADD - Error at Pan Reset: Inappropriate ioctl for device (25)
    UVCIOC_CTRL_ADD - Error at Tilt Reset: Inappropriate ioctl for device (25)
    UVCIOC_CTRL_ADD - Error at Pan/tilt Reset: Inappropriate ioctl for device (25)
    UVCIOC_CTRL_ADD - Error at Focus (absolute): Inappropriate ioctl for device (25)
    UVCIOC_CTRL_MAP - Error at Pan (relative): Inappropriate ioctl for device (25)
    UVCIOC_CTRL_MAP - Error at Tilt (relative): Inappropriate ioctl for device (25)
    UVCIOC_CTRL_MAP - Error at Pan Reset: Inappropriate ioctl for device (25)
    UVCIOC_CTRL_MAP - Error at Tilt Reset: Inappropriate ioctl for device (25)
    UVCIOC_CTRL_MAP - Error at Pan/tilt Reset: Inappropriate ioctl for device (25)
    UVCIOC_CTRL_MAP - Error at Focus (absolute): Inappropriate ioctl for device (25)
    UVCIOC_CTRL_MAP - Error at LED1 Mode: Inappropriate ioctl for device (25)
    UVCIOC_CTRL_MAP - Error at LED1 Frequency: Inappropriate ioctl for device (25)
    UVCIOC_CTRL_MAP - Error at Disable video processing: Inappropriate ioctl for device (25)
    UVCIOC_CTRL_MAP - Error at Raw bits per pixel: Inappropriate ioctl for device (25)o: www-folder-path......: ./www/o: HTTP TCP port........: 8080o: HTTP Listen Address..: (null)o: username:password....: disabledo: commands.............: enabled#测试完以后Ctrl+C杀掉这个进程,要不然后续再启动出错,因为进程已经启动了
    
  5. 创建systemd服务

    sudo vi /etc/systemd/system/mjpg-streamer.service#添加以下内容
    #这里的mjpg-stream的路径若是不一样需要修改
    [Unit]
    Description=MJPG Streamer Service
    After=network.target[Service]
    Type=simple
    WorkingDirectory=/home/orangepi/mjpg-streamer/mjpg-streamer-experimental
    ExecStart=/home/orangepi/mjpg-streamer/mjpg-streamer-experimental/start.sh
    Restart=on-failure
    KillMode=control-group[Install]
    WantedBy=multi-user.target

    保存后,执行以下命令测试一下能否手动启动:

    sudo systemctl daemon-reexec
    sudo systemctl daemon-reload
    sudo systemctl start mjpg-streamer.service#查看进程是否启动
    orangepi@orangepi5plus:~$ ps -aux | grep mjpg | grep -v grep
    orangepi    3730  0.0  0.0   2308   832 ?        Ss   10:46   0:00 /bin/sh /home/orangepi/mjpg-streamer/mjpg-streamer-experimental/start.sh
    orangepi    3737  1.5  0.0 455696  6012 ?        Sl   10:46   0:02 ./mjpg_streamer -i ./input_uvc.so -d /dev/video0 -u -f 30 -o ./output_http.so -w ./www
  6. 改写udev规则

    sudo vi /etc/udev/rules.d/orangepi_camera.rules# 插入摄像头时启动 mjpg-streamer
    ACTION=="add", SUBSYSTEM=="video4linux", KERNEL=="video*", ATTRS{idVendor}=="1bcf", ATTRS{idProduct}=="2281", ATTRS{product}=="Q8 HD Webcam", RUN+="/bin/systemctl start mjpg-streamer.service"# 拔出摄像头时停止 mjpg-streamer
    ACTION=="remove", SUBSYSTEM=="video4linux", KERNEL=="video*", ATTRS{idVendor}=="1bcf", ATTRS{idProduct}=="2281", ATTRS{product}=="Q8 HD Webcam", RUN+="/bin/systemctl stop mjpg-streamer.service"

    应用规则并测试

    sudo udevadm control --reload-rules
    sudo udevadm trigger
    

    然后先运行journalctl 服务, 通过拔插摄像头来查看mjpg-streamer.service是否被自动启动。

    sudo journalctl -f
    

    这里我先拔掉摄像头,显示内容如下:

    image-20250422111739961

    然后再插上摄像头,显示内容如下:

    image-20250422112011411

    通过观察发现它确实是插上摄像头开始运行mjpg-streamer服务,拔掉摄像头停止运行mjpg-streamer服务。

    到这里就配置完成了!

http://www.xdnf.cn/news/82495.html

相关文章:

  • 【锂电池剩余寿命预测】LSTM长短期记忆神经网络锂电池剩余寿命预测(Matlab源码)
  • Trae国内版怎么用?Trae IDE 内置 MCP 市场配置使用指南
  • STM32提高篇: WIFI通讯
  • Unity 脚本使用(二)——UnityEngine.AI——NavMesh
  • vscode使用笔记
  • spdlog日志库使用教程(含踩坑问题解决)
  • 2.6 递归
  • 2025.4.22学习日记 JavaScript的常用事件
  • 多模态大语言模型arxiv论文略读(三十四)
  • QEMU源码全解析 —— 块设备虚拟化(21)
  • go中map和slice非线程安全
  • 不可变数据:基于持久化数据结构的状态管理
  • Seata 分布式事务 快速开始
  • 动态规划算法:完全背包类问题
  • 应用案例|兵器重工:某体系需求视图模型开发
  • [论文阅读]ConfusedPilot: Confused Deputy Risks in RAG-based LLMs
  • docker容器,mysql的日志文件怎么清理
  • 【安装neo4j-5.26.5社区版 完整过程】
  • matlab设置不同颜色的柱状图
  • 华为网路设备学习-19 路由策略
  • 植物大战僵尸杂交版v3.6最新版本(附下载链接)
  • ROS 快速入门教程01
  • 加油站小程序实战教程13充值规则配置
  • 健康生活新指南
  • Java转Go日记(六):TCP黏包
  • npm i 出现permission denied
  • 树莓派学习专题<8>:使用V4L2驱动获取摄像头数据--获取摄像头支持的分辨率
  • 【Nova UI】六、SASS 赋能组件库:通用方法与混入的变革力量
  • 安宝特分享|AR智能装备赋能企业效率跃升
  • 记录一次使用面向对象的C语言封装步进电机驱动