本章将介绍计算机视觉中最核心传感器-摄像头的基本使用,主要讲解了CSI摄像头,USB摄像头,网络摄像头的基本使用。

1 CSI摄像头

首先将讲解CSI摄像头的使用:

树莓派OpenCV系列教程2:摄像头的基本使用 - 树莓派OpenCV教程 微雪课堂 - 图1

1.1 picamera

树莓派自带的摄像头为CSI摄像头,在树莓派平台中,发行版的Raspbian默认安装了树莓派平台的picamera:

相关官方文档链接

执行该脚本将录制一段10秒的视频到本地:

  1. import picamera
  2. camera = picamera.PiCamera()
  3. camera.resolution = (640, 480)
  4. camera.start_recording('my_video.h264')
  5. camera.wait_recording(10)
  6. camera.stop_recording()

但由于picamera输出的数据是RGB格式的,需要通过Numpy转换为BGR格式,代码如下:

  1. import time
  2. import picamera
  3. import numpy as np
  4. import cv2
  5. with picamera.PiCamera() as camera:
  6. camera.resolution = (320, 240)
  7. camera.framerate = 24
  8. time.sleep(2)
  9. image = np.empty((240 * 320 * 3,), dtype=np.uint8)
  10. camera.capture(image, 'bgr')
  11. image = image.reshape((240, 320, 3))
  12. cv2.imshow("img", image)
  13. if(cv2.waitKey(0) == ord('q')):
  14. exit(0)

当然,picamera 也提供了PIRGBArray对象,用来保存RGB 图像数据,下面将在capture_continuous函数中,不断地把RGB转换成BGR图像,供OpenCV显示,以形成视频流。

  1. from picamera.array import PiRGBArray
  2. from picamera import PiCamera
  3. import time
  4. import cv2
  5. camera = PiCamera()
  6. camera.resolution = (640, 480)
  7. camera.framerate = 32
  8. rawCapture = PiRGBArray(camera)
  9. time.sleep(0.1)
  10. for frame in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True):
  11. image = frame.array
  12. cv2.imshow("Frame", image)
  13. rawCapture.truncate(0)
  14. if(cv2.waitKey(1) == ord('q')):
  15. cv2.destroyAllWindows()
  16. break;

但由于picamera为树莓派或兼容树莓派平台专用的库,且仅能供树莓派使用,下面将介绍更为通用的使用方法。

1.2 V4L2

目前,CSI摄像头可通过picamera等库进行调用,但在Raspbian系统中,并不属于一个video设备而存在,若想将CSI摄像头作为一个视频设备文件使用,则要开启V4L2(Video for Linux 2)模块以开启:

开启方法如下:

  1. sudo vim /etc/modules

在末尾添加一行:

  1. bcm2835-v4l2

此时,CSI摄像头便成为了一个video设备,此时在终端执行:

  1. ls -ltrh /dev/video*

便可查看到video设备,其中video0便是CSI摄像头:

树莓派OpenCV系列教程2:摄像头的基本使用 - 树莓派OpenCV教程 微雪课堂 - 图2

该video设备可同时供Python与C++调用,具体使用请参考《树莓派OpenCV系列教程1:开发环境搭建》的例程。

2 USB摄像头

树莓派除了支持CSI摄像头外,同样也支持USB摄像头:

树莓派OpenCV系列教程2:摄像头的基本使用 - 树莓派OpenCV教程 微雪课堂 - 图3

若采用USB摄像头,若摄像头本身免驱,接入树莓派后,将直接识别的video设备,在/dev下可找到对应的video设备,在中断,输入命令:

  1. ls -ltrh /dev/video*

即可查询到新接入的video设备。

但使用Python,C++使用摄像头,区分不同的摄像头时:

c++:

  1. VideoCapture cap(0);

python:

  1. cap = cv2.VideoCapture(0)

传入参数0代表使用CSI摄像头,传入其它参数代表使用其它video序号对应的USB摄像头。
具体使用请参考《1.OpenCV开发环境搭建》的例程。

3 网络摄像头

除了使用CSI摄像头,USB摄像头外,还可以将手机变成一个IP摄像头,具体方法如下:

在手机应用市场中,搜索这款名为IP摄像头的APP,图标如下:

树莓派OpenCV系列教程2:摄像头的基本使用 - 树莓派OpenCV教程 微雪课堂 - 图4

安装好后,连接wifi,确保树莓派和手机处在同一局域网内,手机打开IP摄像头软件,同时点击打开IP摄像头服务器,即可将手机变成一个IP摄像头。如下图所示:

树莓派OpenCV系列教程2:摄像头的基本使用 - 树莓派OpenCV教程 微雪课堂 - 图5

此时,在浏览器中打开该IP地址,输入用户名:admin,密码:admin,即可浏览摄像头画面:

树莓派OpenCV系列教程2:摄像头的基本使用 - 树莓派OpenCV教程 微雪课堂 - 图6

此时说明手机成为了一个IP摄像头,此摄像头可供OpenCV调用。

OpenCV调用IP摄像头的源程序如下:

3.1 Python3

  1. '''
  2. Waveshare OpenCV Tutorial
  3. 01_IP_Camera.py
  4. A demo to show whether The OpenCV and IP camera is well installed
  5. '''
  6. import numpy as np
  7. import cv2
  8. def main():
  9. print("OpenCV Version:{}".format(cv2.__version__))
  10. ip_camera_url = 'http://admin:admin@192.168.10.215:8081'
  11. cap = cv2.VideoCapture(ip_camera_url)
  12. if(not cap.isOpened()):
  13. print("can't open this camera")
  14. while(True):
  15. ret, FrameImage = cap.read()
  16. if ret == True:
  17. cv2.imshow('Camera Capture',FrameImage)
  18. if (cv2.waitKey(1)) == ord('q'):
  19. cap.release()
  20. break
  21. else:
  22. break
  23. if __name__ == '__main__':
  24. print(__doc__)
  25. main()
  26. cv2.destroyAllWindows()

运行效果如下图所示:
树莓派OpenCV系列教程2:摄像头的基本使用 - 树莓派OpenCV教程 微雪课堂 - 图7

3.2 C++

相应地,C++程序读取网络摄像头的程序如下:

  1. #include<iostream>
  2. #include<opencv2/opencv.hpp>
  3. #include<opencv2/highgui/highgui.hpp>
  4. #include<opencv2/imgproc/imgproc.hpp>
  5. using namespace std;
  6. using namespace cv;
  7. int main()
  8. {
  9. cout << "Waveshare OpenCV Tutorial"<< endl;
  10. cout << "00_Test_OpenCV"<cout << "A demo to show whether The OpenCV and IP camera is well installed" <cout << endl;
  11. cout << "OpenCV Version:" << CV_VERSION << endl;
  12. const string ip_camera_url = "http://admin:admin@192.168.10.215:8081";
  13. VideoCapture cap(ip_camera_url);
  14. if(!cap.isOpened())
  15. {
  16. cout<<"can't open this camera"<return -1;
  17. }
  18. Mat FrameImage;
  19. while(1)
  20. {
  21. cap>>FrameImage;
  22. imshow("Camera Capture",FrameImage);
  23. if(char(waitKey(1)) == 'q')
  24. {
  25. break;
  26. }
  27. }
  28. return 0;
  29. }

运行效果如下图所示:
树莓派OpenCV系列教程2:摄像头的基本使用 - 树莓派OpenCV教程 微雪课堂 - 图8