简介
OpenCV(Open Source Computer Vision Library)是一个涵盖了数百种计算机视觉算法的开源算法库。
OpenCV 具有模块化结构,这意味着该软件包包含多个共享或静态库。其中包含以下模块:
**Core functionality (core)**:一个定义基本数据结构的基础模块,包括密集多维数组 Mat 和所有其他模块使用的基本函数。
**Image Processing (imgproc)**:图像处理模块,包括线性和非线性图像过滤、几何图像变换(调整大小、仿射和透视变形、基于通用表的重新映射)、色彩空间转换、直方图等。
**Video Analysis (video)**:视频分析模块,包括运动估计、背景扣除和对象跟踪算法。
**Camera Calibration and 3D Reconstruction (calib3d)**:基本的多视图几何算法、单相机和立体相机校准、物体姿态估计、立体对应算法和 3D 重建元素。
**2D Features Framework (features2d)**:显著特征检测器、描述符和描述符匹配器。
**Object Detection (objdetect)**:检测预定义类的对象和实例(例如,面部、眼睛、杯子、人、汽车等)。
**High-level GUI (highgui)**:易于使用的界面和简单的 UI 功能。
**Video I/O (videoio)**: 易于使用的视频捕获和视频编解码器接口。
... 其他一些帮助模块,例如 FLANN 和 Google 测试包装器、Python 绑定等。
OpenCV 早期的 API 是使用 C 语言编写的,然而基于 C 语言的 API 目前已经废弃。目前 OpenCV API 已经是 C++ 编写的,因此你可以十分高效的在 C++ 项目中使用 OpenCV。除此之外,OpenCV 官方还提供了其它语言的 API 调用支持,例如 Java、Python 以及 Matlab。当然,你还可以选择其它的编程语言,例如 JavaScript、Rust 等,这些语言的社区也提供了方案来使用 OpenCV。
在本篇文章中,我们将主要使用 Python 语言来介绍 OpenCV 的一些基础功能。
下载安装
在对 OpenCV 有一个基础的了解之后,我们可以开始尝试在本地中配置 OpenCV 环境来进行一些简单的功能测试。
基础环境
首先我们在用户目录创建一个文件夹,这里我们将其命名为 OpenCV_Test。随后我们进入该目录。
mkdir ~/OpenCV_Test && cd OpenCV_Test
复制代码
我们需要创建一个 Python 的虚拟环境。
创建完成之后我们直接激活虚拟环境。
(可选)确保虚拟环境 pip 版本大于 19.3。
python -m pip install --upgrade pip
复制代码
在虚拟环境下载 opencv-contrib-python==4.8.1.78
(contrib 为包含了额外模块的版本)。
pip install opencv-contrib-python==4.8.1.78
复制代码
至此,我们已经完成了 OpenCV 的环境配置,现在可以在项目根目录下创建一个 opencv_test.py 文件,并追加以下内容。
import cv2 as cv
print(cv.__version__)
复制代码
在终端通过 python opencv_test.py
进行测试,如果终端成功输出版本号则代表安装成功。
由于在之后的内容中,我们需要使用到一些测试数据,因此我们需要将 OpenCV 仓库的 samples 拷贝到我们的项目根目录下。
你可以通过 Github 浏览这些数据 - https://github.com/opencv/opencv/tree/4.x/samples/data
然后直接下载压缩包,并将 samples 拷贝至项目根目录下。https://github.com/opencv/opencv/archive/refs/heads/4.x.zip
图像功能测试
该部分主要涉及到图像的读取,展示以及写入 API。
import cv2 as cv
import sys, os
# 添加当前目录下的samples/data作为数据搜索路径
cv.samples.addSamplesDataSearchPath(os.path.join(os.getcwd(), "samples", "data"))
# 读取样例数据中的图片
img = cv.imread(cv.samples.findFile("starry_night.jpg"))
if img is None:
sys.exit("Could not read the image.")
# 展示图片
cv.imshow("Display window", img)
k = cv.waitKey(0)
# 当按下 s 时,写入一张新的图片至当前目录
if k == ord("s"):
cv.imwrite("starry_night1.png", img)
复制代码
视频功能测试
从摄像头捕获视频
在该项任务中,我们通过摄像头捕获视频帧,并将其转为灰度帧展示出来。
import cv2 as cv
# 视频捕获对象,用于调用系统摄像头(测试环境为笔记本摄像头)
cap = cv.VideoCapture(0)
if not cap.isOpened():
print("Cannot open camera")
exit()
while True:
# 逐帧进行视频捕获
ret, frame = cap.read()
# 如果帧被捕获,ret 为 true
if not ret:
print("Can't receive frame (stream end?). Exiting ...")
break
# 将捕获的帧转为灰度
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
# 显示当前灰度帧
cv.imshow('frame', gray)
# 当按下 q 键时,结束捕获
if cv.waitKey(1) == ord('q'):
break
# 释放捕获对象
cap.release()
# 销毁所有窗口
cv.destroyAllWindows()
复制代码
从文件播放视频
在该项任务中,我们通过已有文件读取视频帧信息,并展示其灰度帧。
import cv2 as cv
import os
# 添加样例资源搜索路径
cv.samples.addSamplesDataSearchPath(os.path.join(os.getcwd(), "samples", "data"))
# 读取样例视频文件
cap = cv.VideoCapture(cv.samples.findFile('vtest.avi'))
while cap.isOpened():
# 逐帧读取视频
ret, frame = cap.read()
# 当帧读取成功,ret 为 true
if not ret:
print("Can't receive frame (stream end?). Exiting ...")
break
# 获取灰度帧
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
# 展示灰度帧
cv.imshow('frame', gray)
# 当按下 q 键时中断播放
if cv.waitKey(1) == ord('q'):
break
# 释放捕获对象以及窗口资源
cap.release()
cv.destroyAllWindows()
复制代码
录制视频的保存
在该项任务中,我们将使用摄像头捕获视频帧,并将每帧都垂直翻转,然后将其保存为新的视频文件。
import cv2 as cv
# 视频捕获窗口
cap = cv.VideoCapture(0)
# 定义编码器与视频写入对象
fourcc = cv.VideoWriter_fourcc(*'XVID')
# 输出名称,编码器,帧速率,帧尺寸
out = cv.VideoWriter('output.avi', fourcc, 20.0, (640, 480))
while cap.isOpened():
# 逐帧读取摄像头信息
ret, frame = cap.read()
# 正常读取 ret 为 true
if not ret:
print("Can't receive frame (stream end?). Exiting ...")
break
# 垂直翻转视频帧
frame = cv.flip(frame, 0)
# 写入翻转后的帧至输出文件
out.write(frame)
# 展示翻转后的帧信息
cv.imshow('frame', frame)
if cv.waitKey(1) == ord('q'):
break
# 释放全部资源
cap.release()
out.release()
cv.destroyAllWindows()
复制代码
图形的绘制
在该项任务中,我们将通过 OpenCV 绘制不同的几何图形。
直线
import numpy as np
import cv2 as cv
# 创建一个黑色背景
img = np.zeros((512, 512, 3), np.uint8)
# 在 img 绘制一条粗细为 5 px 的蓝色对角线
cv.line(img, (0, 0), (511, 511), (255, 0, 0), 5)
cv.imshow("img", img)
cv.waitKeyEx(0)
复制代码
矩形
# 在 img 绘制一条左上到右下坐标的蓝色矩形
cv.rectangle(img, (384,0), (510,128), (0,255,0), 3)
复制代码
圆
# 在 img 绘制一个基于圆心加半径的圆
cv.circle(img,(447,63), 63, (0,0,255), -1)
复制代码
椭圆
# 参数分别为图片、中心点,主副轴长度,椭圆逆时针旋转角度,椭圆弧的起始角度,椭圆弧的结束角度,画笔颜色等
cv.ellipse(img, (256, 256), (100, 50), 0, 0, 180, 255, -1)
复制代码
多边形
# 要绘制多边形,首先需要顶点坐标。将这些点放入形状为 ROWSx1x2 的数组中,其中 ROWS 是顶点数,其类型应为 int32
pts = np.array([[100, 100], [100, 200], [200, 200], [200, 100]], np.int32)
pts = pts.reshape((-1, 1, 2))
cv.polylines(img, [pts], True, (0, 255, 255))
复制代码
如果第三个参数为 False,您将得到连接所有点的折线,而不是闭合形状。
文字
# 参数分别为图片,文字,坐标,字体,字体缩放,颜色,粗细,线型
font = cv.FONT_HERSHEY_SIMPLEX
cv.putText(img, 'OpenCV', (10, 500), font, 4, (255, 255, 255), 2, cv.LINE_AA)
复制代码
结语
在结束这篇介绍 OpenCV 的文章之际,我们希望你已经对这一强大的计算机视觉库有了初步的了解。通过下载和安装 OpenCV,你已经迈出了探索计算机视觉世界的第一步。
在文章中,我们探讨了 OpenCV 的基础部分,包括图像处理、视频处理和图形绘制等方面的核心 API。这些功能为开发者提供了丰富的工具箱,可以用于解决各种计算机视觉问题,从简单的图像处理到复杂的目标检测和跟踪。
然而,OpenCV 是一个庞大而灵活的库,我们只触及了其中的冰山一角。我们鼓励你继续深入学习,探索 OpenCV 更高级的功能和技术。无论是在工业自动化、医学影像、安防监控还是虚拟现实等领域,OpenCV 都发挥着至关重要的作用。
作为一个开源项目,OpenCV 的社区一直在不断发展和改进。在进一步的学习之后,你也可以通过参与社区,贡献你的力量,使这个强大的工具变得更加完善。(提出有效 issues 以及文档的勘误也是一份贡献!)
在这个计算机视觉的精彩世界中,OpenCV 为你打开了大门。希望你能够在这个旅程中找到乐趣,创造出令人惊叹的视觉应用。
评论