1. 简介
OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉和机器学习软件库,由一系列 C 函数和少量 C++ 类构成,同时提供了 Python、Java、MATLAB 等语言的接口,广泛应用于图像和视频的处理、分析以及机器学习领域。opencv支持最广泛的两种语言为python和c++,本文以c++为例进行讲解。
2. 基础用法
2.1 opencv的基本模块
openv包含多个模块,每个模块专注于不同的任务,本小节仅对笔者项目中所用到的模块进行介绍。
2.1.1 core模块
其提供基本数据结构和函数,如图像存储、矩阵操作、文件 I/O 等。数据结构如下:
-
Mat:用于存储图像和矩阵数据。 -
Point、Size、Rect:用于表示点、尺寸和矩形区域。 -
Scalar:用于表示颜色或像素值
2.1.2 Imgproc 模块
imgproc 模块提供了图像处理功能,包括滤波、几何变换、颜色空间转换等。常用类和函数有:cvtColor, GaussianBlur, Canny, threshold, resize, warpAffine。
2.1.3 Imgcodecs模块
该模块用于图像文件的读取和保存,支持多种图像格式。常用的类和函数有:imread, imwrite, imdecode, imencode。
2.1.4 Videoio模块
该模块用于视频输入输出功能,支持多种视频格式和摄像头,常用的类和函数为:VideoCapture, VideoWriter, CAP_PROP_FRAME_WIDTH, CAP_PROP_FRAME_HEIGHT。
2.2 图片的创建、显示、读取、保存
首先,图片在程序里边就是一个二维数组,每一个格子代表一个像素点,0为纯黑,255为纯白。创建图像的API如下所示:
cpp
/*创建一个6x8的灰度图,所有像素填100,CV_8UC1代表8位无符号,1个通道*/
cv::Mat image(6, 8, CV_8UC1, cv::Scalar(100));
/*创建一个6x8的红色图像,3个通道*/
cv::Mat newImage(480, 640, CV_8UC3, cv::Scalar(0, 0, 255));
需要注意的是:灰度图指的是1个通道,彩色图有3个通道。
图像显示的API如下,第一个参数为窗口名称,第二个参数为需要显示的图像;waitkey函数与显示函数是固定搭配,因为需要调用该函数来刷新窗口,参数为0代表无限等待用户按键:
cpp
cv::imshow("Display Window", image);
cv::waitKey(0); // 等待按键按下
图像读取的API如下:
cpp
/*第一个参数代表图像路径,第二个参数代表读图的形式
*IMREAD_GRAYSCALE代表灰度图,IMREAD_COLOR代表彩色图像
*/
cv::Mat image = cv::imread(image_path, cv::IMREAD_GRAYSCALE);
图像保存的API如下:
cpp
/*第一个参数是保存图像的路径,第二个参数是要保存的图像*/
cv::imwrite("output.jpg", image);
2.3 图像的裁剪
用法如下,其中roi指的是感兴趣区域,表示从大图里边裁剪出一小块出来,仅观测这一小块:
cpp
// 形式1:直接指定坐标和尺寸
Rect roi(100, 100, 200, 200);//(x, y, width, height)
/*从原图image裁剪出由
*矩形roi指定的子区域,并
*将子区域赋值
*/
Mat croppedImage = image(roi);
// 形式2:从某个结构体(如 checkpoint.roi)中读取数据
cv::Rect roi_rect(
checkpoint.roi.x,
checkpoint.roi.y,
checkpoint.roi.width,
checkpoint.roi.height
);
Mat croppedImage = image(roi_rect);
需要注意的是:使用image函数裁剪的是彩色图像,如果要裁剪灰色图像,需要用函数gray。
2.4 灰度均值
灰度均值指的是把roi里边的所有像素值加起来除以像素个数,得到平均亮度。用法如下:
cpp
/*计算灰度均值,roi可以是灰度图或者彩色图
*函数返回scalar对象
*scalar指的是4个double值的容器
*通常用来存储:
*灰度图:只用第 0 个元素(索引 [0])存放灰度均值,
*[1]、[2]、[3] 均为 0。
*彩色图(BGR 顺序):[0] 为蓝色通道均值,[1] 为绿色,
*[2] 为红色,[3] 为 0。
*mean_with_label[0]:取 Scalar 的第一个元素,
*即 ROI 的灰度均值(假设 roi 是单通道灰度图)
*/
cv::Scalar mean_with_label = cv::mean(roi);
std::cout << "ROI 灰度均值: " << mean_with_label[0] << std::endl;
2.5 阈值检测
此处指的是最简单的灰度阈值检测,代表设定一个阈值,用灰度均值与设定阈值进行比较,大于阈值为OK,否则为NG。用法如下:
cpp
std::cout << "=== 检测原理 ===" << std::endl;
double threshold = 120.0;
std::cout << "设定阈值: " << threshold << std::endl;
std::cout << "有标签: 均值=" << mean_with_label[0]
<< (mean_with_label[0] >= threshold ? " >= 阈值 -> OK" : " < 阈值 -> NG")
<< std::endl;
std::cout << "没标签: 均值=" << mean_without_label[0]
<< (mean_without_label[0] >= threshold ? " >= 阈值 -> OK" : " < 阈值 -> NG")
<< std::endl;
3. 总结
本文仅分享自己在项目中所用到的一些opencv的基础用法。实际上opencv还有很多用法,建议在做项目时用到再进行学习。