一、前言
OpenCV是计算机视觉领域一款热门的框架,人脸识别、二维码处理、深度学习中都能见到它的身影~
二、安装
1. C++版安装
在官网中下载OpenCV源码,本文以OpenCV – 4.5.5为例。
安装相关依赖
1 | sudo apt-get install libgtk2.0-dev |
解压至任意目录
1 | unzip opencv-4.5.5.zip |
进入解压后的文件夹,创建build
文件夹并进入
1 | cd opencv-4.5.5 |
CMake生成Makefile
1 | cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local/ .. |
编译OpenCV(-j
为线程数,视实际情况更改,太大可能会爆内存,实在不行就单线程吧hhh)
1 | make -j8 |
安装
1 | sudo make install |
验证(运行源码根目录下samples/cpp/example_cmake
后弹出Hello OpenCV
即为成功)
1 | cd ../samples/cpp/example_cmake |
2. Python版安装
通过pip
安装
1 | pip3 install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple |
三、基础用法
本文主要记录基于Python的OpenCV笔记
1. 导入OpenCV
1 | import cv2 |
2. 读取图片 - imread()
1 | img = cv2.imread("ari.jpg") |
第一个参数是图片的路径,绝对路径和相对路径均可。
第二个参数是可选参数,可填以下内容:
- cv2.IMREAD_COLOR(默认): 加载彩色图像。任何图像的透明度都将被忽略。
- cv2.IMREAD_GRAYSCALE:以灰度模式加载图像。
- cv2.IMREAD_UNCHANGED:保留读取图片原有颜色通道(包括透明通道)。
3. 显示图片 - imshow()
1 | cv2.imshow("ari", img) |
第一个参数是窗口的标题,第二个参数传入读取的img对象。
4. 调整窗口 - namedWindow()
1 | cv2.namedWindow("ari") |
第一个参数是窗口的标题。
第二个参数是可选参数,可填以下内容:
- cv2.WINDOW_NORMAL:可调整窗口大小。
- cv2.WINDOW_AUTOSIZE(默认):窗口内容图片为真实大小,窗口大小不可调整。
- cv2.WINDOW_OPENGL:支持OpenGL。
5. 等待按键 - waitKey()
1 | cv2.waitKey(0) |
当调用imshow()
后,需要再调用waitKey()控制窗口显示时间。
当参数≤0时,则窗口一直等待,返回 -1 或按键值,当为$time
时,则窗口显示$time
ms,在此期间按键则返回按键值,否则返回 -1 。
6. 保存图片 - imwrite()
1 | cv2.imwrite("ari_out.jpg", img) |
第一个参数是保存的路径及名称,第二个参数传入读取的img对象。
三、进阶操作
1. 读取网络摄像机rtsp流
1 | import cv2 |
2. 单目相机标定与坐标系转换
最近有一个项目需要将单目摄像机拍摄到的照片中的像素坐标转换为世界坐标,于是研究了一下相关的原理和代码。
1) 原理
在相机模型中,我们需要理解四个坐标系以及它们之间的关系:
- 像素坐标系(u, v)
- 图像坐标系(x, y)
- 相机坐标系(Xc, Yc, Zc)
- 世界坐标系(Xw, Yw, Zw)
如图:
a. 像素坐标系(u, v)与图像坐标系(x, y)转换
假设像素在u轴和v轴方向上的物理尺寸为dx和dy。
根据上图可以推导出该公式:
转换为矩阵形式:
b. 相机坐标系(Xc, Yc, Zc)与世界坐标系(Xw, Yw, Zw)转换
从世界坐标系变换到相机坐标系属于刚体变换,物体不会发生形变,只需进行旋转和平移。
如上图,R表示旋转矩阵,T表示旋转向量。
用矩阵表示其关系:
令:
因此可表示为
c. 相机坐标系(Xc, Yc, Zc)与图像坐标系(x, y)转换
如图,根据相似三角形原理,可得:
可变换为:
因此可用矩阵表示:
d. 综合公式
将上面的矩阵公式综合,即可得出以下公式:
其中,
称为相机内参。
称为相机外参。
e. 求解
我们的需求是根据像素坐标求世界坐标,而世界坐标系建立在地面,因此可令Zw=0。
即:
将相机外参展开:
化简可得:
将上式改写为AX=B的形式:
解出这个矩阵方程即可求解 世界坐标(Xw, Yw, 0) 以及 相机坐标系原点到所求点的直线距离Zc !
2) 实现
未完待续…