

RoboMaster 视觉组第三次培训
关于 OpenCV 的安装以及使用
views
| comments
前言#
本教程为 RoboMaster 视觉组第三次培训,主要内容为 OpenCV 的安装以及使用。
安装 OpenCV#
在安装 OpenCV 之前需要安装部分的依赖:
sudo apt install libgtk2.0-dev
bash一般来说,可以直接使用源代码对于 OpenCV 进行编译安装,代码如下:
wget https://github.com/opencv/opencv/archive/4.8.0.zip opencv-4.8.0.zip
unzip opencv-4.8.0.zip
cd opencv-4.8.0
mkdir build && cd build
cmake ..
make -j$(nproc)
sudo make install
bashOpenCV 是 C++ 的库,因此可以使用 CMakeList 来使用。
此时的 CMakeLists.txt 在依次的地方添加:
find_package(OpenCV REQUIRED)
include_directories(
${OpenCV_INCLUDE_DIRS}
)
target_link_libraries(test
${OpenCV_LIBS}
)
cmake此时在 main.cpp 中添加语句 #include <opencv2/core.hpp>
或者 #include <opencv4/opencv2/core.hpp>
并且进行编译,假如通过就没有问题。
OpenCV 基础#
图像的本质#
在计算机中,图像是以矩阵的形式存储的。彩色图片通常由三个通道(如 BGR)组成,而灰度图只有一个通道。OpenCV 使用 cv::Mat
数据类型来表示图像,它包含两部分数据:
- 矩阵头 (Matrix Header):包含矩阵的大小、存储方法、存储位置等信息。
- 指向像素值的指针:一个指向实际存储像素值的矩阵的指针。
cv::Mat
的常用构造与操作:
- 构造函数:
cv::Mat(rows, cols, type, Scalar(value))
是其经典构造函数,可以指定行、列、数据类型(如CV_8UC3
代表 8位无符号3通道图像)和初始值。 - 赋值与拷贝:
cv::Mat
支持直接通过等号赋值或拷贝构造。clone()
和copyTo()
函数可以实现底层矩阵的深度拷贝。 - 访问成员:
.rows
和.cols
:获取矩阵的行数和列数。.channels()
:获取图像的通道数。.empty()
:返回一个布尔值,判断矩阵是否为空。.at<Vec3b>(i, j)[t]
:访问坐标为 (i, j) 的像素点的第 t 个通道的值。
OpenCV 基本操作#
读取与显示#
- 读取图片:
cv::Mat src = imread("你的图片路径");
。 - 显示图片:
cv::imshow("窗口名", src);
。 - 等待按键:
cv::waitKey(0);
,如果参数为0,则无限等待直到有按键按下。 - 读取视频:
- 创建
cv::VideoCapture
对象:cv::VideoCapture capture;
。 - 打开视频文件:
capture.open("你的视频路径");
。 - 逐帧读取:在一个循环中使用
capture >> pic;
来读取下一帧。 - 循环播放:可以通过
capture.get(cv::CAP_PROP_FRAME_COUNT)
获取总帧数,判断播放结束后使用capture.set(cv::CAP_PROP_POS_FRAMES, 0)
回到视频开头。
- 创建
绘制图案#
在图像上绘制点、线、形状和文字对于调试和结果可视化至关重要。
- 数据结构:
cv::Point
是一个核心数据类型,用于表示点的坐标。 - 绘制圆形:
void circle(img, center, radius, color, thickness);
。 - 绘制直线:
void line(img, pt1, pt2, color, thickness);
。 - 绘制文字:
void putText(img, text, org, fontFace, fontScale, color, thickness);
。 - 绘制折线/多边形:
void polylines(img, pts, isClosed, color, thickness);
。
图像预处理#
预处理旨在对原始图像进行初步筛选和优化,以便后续的特征提取。
滤波 (Filtering)#
滤波是一种平滑处理,主要用于去除图像中的噪声。
- 均值滤波 (
blur
):使用一个所有元素值都相等的卷积核(如 3x3 大小的核,每个元素为 1/9)对图像进行卷积,将每个像素替换为其邻域像素的平均值。这会使图像变得模糊。 - 高斯滤波 (
GaussianBlur
):使用基于高斯函数生成的卷积核,中心点的权重最大,离中心越远的像素权重越小。这种方法在去除噪声的同时,能更好地保留图像的边缘信息。
二值化 (Binarization)#
二值化根据设定的阈值将图像转换为只有黑白两色的图像,以突出感兴趣的区域。
- 色彩空间转换:在二值化之前,通常需要将图像从 BGR 色彩空间转换到更符合人类视觉感知的 HSV 空间 (
cv::cvtColor(src, dst, cv::COLOR_BGR2HSV);
)。HSV 将颜色分为色相 (H)、饱和度 (S) 和亮度 (V)。 - 彩色二值化 (
inRange
):在 HSV 空间下,可以设定一个颜色范围的上限和下限,使用inRange
函数提取出这个范围内的所有像素,生成二值图。 - 灰度二值化 (
threshold
):首先将图像转为灰度图 (cv::cvtColor(img, gray_img, cv::COLOR_BGR2GRAY);
),然后使用threshold
函数,将灰度值在指定阈值范围内的像素设为白色,其余设为黑色。
形态学操作 (Morphological Operations)#
膨胀和腐蚀是常用于二值图像的形态学操作,用以优化形状或减少噪声。
- 膨胀 (
dilate
):扩展图像中的白色区域,可以用于填充小孔洞或连接断开的目标。 - 腐蚀 (
erode
):收缩图像中的白色区域,可以用于消除小的噪声点或分离粘连的物体。 - 开操作 (Opening):先进行腐蚀操作,然后进行膨胀操作。主要作用是去除小的噪声斑点,并分离连接的物体。
- 闭操作 (Closing):先进行膨胀操作,然后进行腐蚀操作。主要作用是填充物体内部的小孔洞,并连接邻近的物体。
图像特征获取#
在预处理后的二值图上,我们可以提取轮廓等形状特征。
寻找轮廓#
使用 findContours
函数可以检测出二值图像中所有物体的轮廓。
- 函数原型:
cv::findContours(image, contours, hierarchy, mode, method);
- 参数说明:
image
: 输入的必须是二值图像。contours
: 用于存储所有找到的轮廓,通常是vector<vector<Point>>
类型。hierarchy
: 存储轮廓之间的层级关系。mode
: 轮廓的检索模式,如RETR_EXTERNAL
(只检索最外层轮廓)或RETR_TREE
(检索所有轮廓并重建嵌套结构)。method
: 轮廓的逼近方法,如CHAIN_APPROX_SIMPLE
(压缩水平、垂直和对角线段,只保留端点)。
分析轮廓特征#
找到轮廓后,可以通过计算其几何特征来进行筛选和识别。
- 面积 (
contourArea
):计算轮廓的面积。 - 外接矩形 (
boundingRect
):找到包围轮廓的最小正立矩形,返回一个cv::Rect
对象,包含矩形的坐标和宽高。 - 长宽比:通过外接矩形的
width
和height
计算物体的长宽比 (aspectRatio = width / height
)。 - 面积比:通过计算轮廓面积与外接矩形面积的比值,可以用来区分不同形状的物体 (
areaRatio = contourArea / boundingRectArea
)。