16. 摄像头

16.1. 使能设备树插件

想要使能OV5640摄像头需要使能cam设备树插件, 如果还想要在LCD液晶屏上显示摄像头的内容还需要使能lcd的设备树插件, 如下所示

/boot/uEnv.txt
1
2
dtoverlay=/usr/lib/linux-image-4.19.94-stm-r1/overlays/stm-fire-cam.dtbo
dtoverlay=/usr/lib/linux-image-4.19.94-stm-r1/overlays/stm-fire-lcd.dtbo

16.2. v4l-utils工具使用

v4l-utils工具安装

1
 sudo apt install v4l-utils

查看可用的视频设备,其中/dev/video0对应OV5640的物理设备

1
2
3
4
5
6
7
8
 #执行命令
 v4l2-ctl --list-devices

 root@npi:~# v4l2-ctl --list-devices
 STM32 Camera Memory Interface (platform:dcmi):
         /dev/video0

 root@npi:~#

查看摄像头所有参数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
 #执行命令
 sudo v4l2-ctl -d  /dev/video0 --all


 #显示信息如下
 Driver Info:
         Driver name      : stm32-dcmi
         Card type        : STM32 Camera Memory Interface
         Bus info         : platform:dcmi
         Driver version   : 4.19.94
         Capabilities     : 0x85200001
                 Video Capture
                 Read/Write
                 Streaming
                 Extended Pix Format
                 Device Capabilities
         Device Caps      : 0x05200001
                 Video Capture
                 Read/Write
                 Streaming
                 Extended Pix Format
 Priority: 2
 Video input : 0 (Camera: ok)
 Format Video Capture:
         Width/Height      : 320/240
         Pixel Format      : 'JPEG' (JFIF JPEG)
         Field             : None
         Bytes per Line    : 320
         Size Image        : 76800
         Colorspace        : JPEG
         Transfer Function : sRGB
         YCbCr/HSV Encoding: ITU-R 601
         Quantization      : Full Range
         Flags             :
 Crop Capability Video Capture:
         Bounds      : Left 0, Top 0, Width 2592, Height 1944
         Default     : Left 0, Top 0, Width 2592, Height 1944
         Pixel Aspect: 1/1
 Crop: Left 0, Top 0, Width 320, Height 240
 Selection: crop, Left 0, Top 0, Width 320, Height 240, Flags:
 Selection: crop_default, Left 0, Top 0, Width 2592, Height 1944, Flags:
 Selection: crop_bounds, Left 0, Top 0, Width 2592, Height 1944, Flags:
 Streaming Parameters Video Capture:
         Capabilities     : timeperframe
         Frames per second: 30.000 (30/1)
         Read buffers     : 2

 User Controls

                        contrast 0x00980901 (int)    : min=0 max=255 step=1 default=0 value=0 flags=slider
                      saturation 0x00980902 (int)    : min=0 max=255 step=1 default=64 value=64 flags=slider
                             hue 0x00980903 (int)    : min=0 max=359 step=1 default=0 value=0 flags=slider
         white_balance_automatic 0x0098090c (bool)   : default=1 value=1 flags=update
                     red_balance 0x0098090e (int)    : min=0 max=4095 step=1 default=0 value=0 flags=inactive, slider
                    blue_balance 0x0098090f (int)    : min=0 max=4095 step=1 default=0 value=0 flags=inactive, slider
                        exposure 0x00980911 (int)    : min=0 max=65535 step=1 default=0 value=885 flags=inactive, volatile
                  gain_automatic 0x00980912 (bool)   : default=1 value=1 flags=update
                            gain 0x00980913 (int)    : min=0 max=1023 step=1 default=0 value=66 flags=inactive, volatile
                 horizontal_flip 0x00980914 (bool)   : default=0 value=0
                   vertical_flip 0x00980915 (bool)   : default=0 value=0
            power_line_frequency 0x00980918 (menu)   : min=0 max=3 default=1 value=1

 Camera Controls

                   auto_exposure 0x009a0901 (menu)   : min=0 max=1 default=0 value=0 flags=update

 Image Processing Controls

                  link_frequency 0x009f0901 (intmenu): min=0 max=0 default=0 value=0
                    test_pattern 0x009f0903 (menu)   : min=0 max=4 default=0 value=0

查看摄像头所支持的分辨率

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
 #执行命令
 sudo v4l2-ctl --list-formats-ext -d /dev/video0

 #显示信息如下
 ioctl: VIDIOC_ENUM_FMT
 Type: Video Capture

 [0]: 'JPEG' (JFIF JPEG, compressed)
         Size: Discrete 176x144
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
         Size: Discrete 320x240
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
         Size: Discrete 640x480
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
                 Interval: Discrete 0.017s (60.000 fps)
         Size: Discrete 720x480
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
         Size: Discrete 720x576
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
         Size: Discrete 1024x768
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
         Size: Discrete 1280x720
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
         Size: Discrete 1920x1080
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
         Size: Discrete 2592x1944
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
 [1]: 'UYVY' (UYVY 4:2:2)
         Size: Discrete 176x144
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
         Size: Discrete 320x240
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
         Size: Discrete 640x480
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
                 Interval: Discrete 0.017s (60.000 fps)
         Size: Discrete 720x480
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
         Size: Discrete 720x576
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
         Size: Discrete 1024x768
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
         Size: Discrete 1280x720
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
         Size: Discrete 1920x1080
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
         Size: Discrete 2592x1944
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
 [2]: 'YUYV' (YUYV 4:2:2)
         Size: Discrete 176x144
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
         Size: Discrete 320x240
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
         Size: Discrete 640x480
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
                 Interval: Discrete 0.017s (60.000 fps)
         Size: Discrete 720x480
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
         Size: Discrete 720x576
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
         Size: Discrete 1024x768
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
         Size: Discrete 1280x720
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
         Size: Discrete 1920x1080
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
         Size: Discrete 2592x1944
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
 [3]: 'RGBP' (16-bit RGB 5-6-5)
         Size: Discrete 176x144
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
         Size: Discrete 320x240
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
         Size: Discrete 640x480
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
                 Interval: Discrete 0.017s (60.000 fps)
         Size: Discrete 720x480
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
         Size: Discrete 720x576
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
         Size: Discrete 1024x768
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
         Size: Discrete 1280x720
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
         Size: Discrete 1920x1080
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)
         Size: Discrete 2592x1944
                 Interval: Discrete 0.067s (15.000 fps)
                 Interval: Discrete 0.033s (30.000 fps)

16.3. 安装gstreamer

可以使用gstreamer对摄像头做个简单测试,安装命令如下,安装时间较长请耐心等待。

1
 sudo apt install libgstreamer1.0-0 gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-doc gstreamer1.0-tools

16.3.1. 简单测试

使用以下命令可对摄像头进行录制视频、拍照或将摄像头的拍摄到的视频显示到显示屏上。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
 #录制视频
 sudo gst-launch-1.0 -v v4l2src device=/dev/video0 ! "video/x-raw, format=(string)YUY2, width=(int)640,height=(int)480, framerate=(fraction)15/1" ! videoconvert ! avimux ! filesink location=test.avi

 #播放视频
 sudo gst-launch-1.0 filesrc location=test.avi ! decodebin !  videoconvert ! fbdevsink

 # 拍照
 # sudo gst-launch-1.0 v4l2src num-buffers=1 device=/dev/video0 ! jpegenc ! filesink location=test.jpg

 # 显示图片
 # sudo gst-launch-1.0 filesrc location=test.jpg ! "video/x-raw, format=(string)YUY2, width=(int)640,height=(int)480, framerate=(fraction)15/1" ! decodebin !  videoconvert ! fbdevsink

 #在LCD屏幕上显示摄像头的内容
 sudo gst-launch-1.0 -v v4l2src device=/dev/video0 ! "video/x-raw, format=(string)YUY2, width=(int)640, height=(int)480, framerate=(fraction)15/1" ! videoconvert ! fbdevsink

gst-launch-1.0 命令参考 https://gstreamer.freedesktop.org/documentation/tools/gst-launch.html?gi-language=c

16.4. 摄像头设备树插件

野火imx6ull提供了很多的设备树插件源码,若想要修改不同的引脚作为v5640摄像头的引脚, 可参考 野火设备树插件GitHub仓库 设备树插件 imx-fire-cam-overlay.dts ,源码如下所示

ebf_linux_kernel/arch/arm/boot/dts/overlays/stm-fire-cam-overlay.dts
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
/dts-v1/;
/plugin/;
//#include "../stm32mp157c.dtsi"
#include <dt-bindings/pinctrl/stm32-pinfunc.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/mfd/st,stpmic1.h>
#include <dt-bindings/gpio/gpio.h>

/{
     fragment@0 {
         target=<&i2c2>;
         __overlay__ {
             #address-cells = <1>;
             #size-cells = <0>;
             ov5640: camera@3c {
                 compatible = "ovti,ov5640";
                 reg = <0x3c>;
                 clocks = <&clk_ext_camera>;
                 clock-names = "xclk";
                 DOVDD-supply = <&v2v8>;
                 powerdown-gpios = <&gpioi 8 (GPIO_ACTIVE_HIGH | GPIO_PUSH_PULL)>;
                 reset-gpios = <&gpioi 11 (GPIO_ACTIVE_LOW | GPIO_PUSH_PULL)>;
                 rotation = <180>;
                 status = "okay";

                 port {
                     ov5640_0: endpoint {
                         remote-endpoint = <&dcmi_0>;
                         bus-width = <8>;
                         data-shift = <2>; /* lines 9:2 are used */
                         hsync-active = <0>;
                         vsync-active = <0>;
                         pclk-sample = <1>;
                         pclk-max-frequency = <77000000>;
                     };
                 };
             };
         };
     };

     fragment@1{
         target-path="/";
         __overlay__{
             clocks {
                 clk_ext_camera: clk-ext-camera {
                     #clock-cells = <0>;
                     compatible = "fixed-clock";
                     clock-frequency = <24000000>;
                 };
             };
         };
     };

     fragment@2{
         target=<&dcmi>;
         __overlay__{
             status = "okay";
             pinctrl-names = "default", "sleep";
             pinctrl-0 = <&dcmi_pins_a>;
             pinctrl-1 = <&dcmi_sleep_pins_a>;

             port {
                 dcmi_0: endpoint {
                     remote-endpoint = <&ov5640_0>;
                     bus-width = <8>;
                     hsync-active = <0>;
                     vsync-active = <0>;
                     pclk-sample = <1>;
                     pclk-max-frequency = <77000000>;
                 };
             };
         };
     };

     fragment@3{
         target=<&pinctrl>;
         __overlay__{
             dcmi_pins_a: dcmi-0 {
             pins {
                 pinmux = <STM32_PINMUX('A', 4,  AF13)>,/* DCMI_HSYNC */
                         <STM32_PINMUX('B', 7,  AF13)>,/* DCMI_VSYNC */
                         <STM32_PINMUX('A', 6,  AF13)>,/* DCMI_PIXCLK */
                         <STM32_PINMUX('H', 9,  AF13)>,/* DCMI_D0 */
                         <STM32_PINMUX('H', 10, AF13)>,/* DCMI_D1 */
                         <STM32_PINMUX('H', 11, AF13)>,/* DCMI_D2 */
                         <STM32_PINMUX('E', 1, AF13)>,/* DCMI_D3 */
                         <STM32_PINMUX('E', 11, AF13)>,/* DCMI_D4 */
                         <STM32_PINMUX('D', 3,  AF13)>,/* DCMI_D5 */
                         <STM32_PINMUX('E', 5,  AF13)>,/* DCMI_D6 */
                         <STM32_PINMUX('B', 9,  AF13)>;/* DCMI_D7 */
                 bias-disable;
                 };
             };

             dcmi_sleep_pins_a: dcmi-sleep-0 {
                 pins {
                     pinmux = <STM32_PINMUX('A', 4,  ANALOG)>,/* DCMI_HSYNC */
                             <STM32_PINMUX('B', 7,  ANALOG)>,/* DCMI_VSYNC */
                             <STM32_PINMUX('A', 6,  ANALOG)>,/* DCMI_PIXCLK */
                             <STM32_PINMUX('H', 9,  ANALOG)>,/* DCMI_D0 */
                             <STM32_PINMUX('H', 10, ANALOG)>,/* DCMI_D1 */
                             <STM32_PINMUX('H', 11, ANALOG)>,/* DCMI_D2 */
                             <STM32_PINMUX('E', 1, ANALOG)>,/* DCMI_D3 */
                             <STM32_PINMUX('E', 11, ANALOG)>,/* DCMI_D4 */
                             <STM32_PINMUX('D', 3,  ANALOG)>,/* DCMI_D5 */
                             <STM32_PINMUX('E', 5,  ANALOG)>,/* DCMI_D6 */
                             <STM32_PINMUX('B', 9,  ANALOG)>;/* DCMI_D7 */
                 };
             };
         };
     };
};

若想更改使用具有csi功能的引脚只需修改上面的标记部分的内容即可。

16.5. USB免驱摄像头

当插入UVC(全称USB Video Class)免驱摄像头时, 内核将会打印信息,使用lsusb再次查看lsusb设备时可发现多了一个新的USB设备。 同时在 /dev/ 目录下将多出新的video设备,其中 /dev/video1 则为USB摄像头设备, 不同板子的摄像头设备文件可能不同。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
 root@npi:~# lsusb
 Bus 001 Device 002: ID 1a40:0101 Terminus Technology Inc. Hub
 Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
 root@npi:~# [ 1988.776119] usb 1-1.3: new high-speed USB device number 4 using ci_hdrc
 [ 1991.298210] uvcvideo: Found UVC 1.00 device HD Pro Webcam C920 (046d:082d)
 [ 1991.324787] input: HD Pro Webcam C920 as /devices/soc0/soc/2100000.aips-bus/2184200.usb/ci_hdrc.1/usb1/1-1/1-1.3/1-1.3:1.0/input/input3

 root@npi:~# lsusb
 Bus 001 Device 004: ID 046d:082d Logitech, Inc. HD Pro Webcam C920
 Bus 001 Device 002: ID 1a40:0101 Terminus Technology Inc. Hub
 Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

 root@npi:~# ls -l  /dev/video*
 crw-rw---- 1 root video 81, 0 Feb  2 10:36 /dev/video0
 crw-rw---- 1 root video 81, 1 Feb  2 10:36 /dev/video1
 crw-rw---- 1 root video 81, 2 Feb  2 10:36 /dev/video2

若提示找不到lsusb命令,可使用 sudo apt install usbutils 安装usbutils。

关于USB摄像头的相关操作与章节前面介绍的OV5640摄像头控制方式完全相同,请参照章节前面说明。