一、函数:
a.cvtColor
函数:
(1)函数原型:
CV_EXPORTS_W void cvtColor( InputArray src, OutputArray dst, int code, int dstCn = 0 );
(2)函数功能:
cvtColor
函数用于将输入图像从一种颜色空间转换到另一种颜色空间。
(3)颜色空间和通道顺序:
- 转换涉及到 RGB 颜色空间时,需要明确指定通道的顺序(RGB 或 BGR)。OpenCV 默认的颜色格式通常被称为 RGB,但实际上是 BGR(字节顺序相反)。
(4)颜色通道值范围:
- 对于不同的数据类型,颜色通道的值范围不同:
- 对于
CV_8U
图像:0 到 255。 - 对于
CV_16U
图像:0 到 65535。 - 对于
CV_32F
图像:0 到 1。
- 对于
(5)线性与非线性转换:
- 在线性转换中,颜色通道值的范围不重要。但在非线性转换中,如 RGB 到 Luv*,输入 RGB 图像需要归一化到适当的值范围以获得正确的结果。
(6)归一化示例:
- 如果你有一个直接从 8 位图像转换而来的 32 位浮点图像,而没有进行任何缩放,那么它将具有 0..255 的值范围,而不是函数假定的 0..1。因此,在调用
cvtColor
之前,你需要先将图像缩放下来:
img *= 1./255;
cvtColor(img, img, COLOR_BGR2Luv);
(7)8位图像转换的注意事项:
- 使用
cvtColor
与 8 位图像进行转换可能会有一些信息丢失。对于需要全色域或在操作前转换图像然后转换回原色的应用程序,建议使用 32 位图像。
(8)添加 Alpha 通道:
- 如果转换过程中添加了 Alpha 通道,其值将设置为相应通道范围的最大值:对于
CV_8U
是 255,对于CV_16U
是 65535,对于CV_32F
是 1。
(9)参数说明:
src
:输入图像,可以是 8 位无符号、16 位无符号(CV_16UC...
)或单精度浮点类型。dst
:输出图像,大小和深度与src
相同。code
:颜色空间转换代码(见ColorConversionCodes
)。dstCn
:目标图像中的通道数;如果参数为 0,则从src
和code
自动推导通道数。
(10)函数用途:
cvtColor
是图像处理中常用的函数,用于在不同的颜色空间之间转换图像,以便进行进一步的处理或分析。
b.inRange
函数
(1)函数原型:
CV_EXPORTS_W void inRange(InputArray src, InputArray lowerb, InputArray upperb, OutputArray dst);
(2)函数功能:
inRange
函数用于检查输入数组src
中的每个元素是否位于由lowerb
和upperb
指定的范围内。
(3)范围检查方式:
- 对于单通道输入数组的每个元素,如果元素值在
lowerb
和upperb
之间(包括边界值),则输出数组dst
对应位置的元素将被设置为 255。 - 对于双通道或多通道数组,所有通道的元素都需要在对应的边界范围内,输出数组
dst
的对应位置才会被设置为 255。
(4)数学表达式:
- 对于单通道数组,条件可以表示为:
- 对于双通道数组,条件可以表示为:
(5)边界参数:
- 如果
lowerb
和/或upperb
是标量,则在上述公式中的索引 (I) 应省略。
(6)参数:
src
:第一个输入数组,可以是单通道或多通道。lowerb
:包容性下界数组或标量。upperb
:包容性上界数组或标量。dst
:输出数组,大小与src
相同,类型为CV_8U
(8位无符号整型)。
(7)输出结果:
- 输出数组
dst
将包含与src
相同的尺寸,并且每个元素将根据是否满足范围条件被设置为 255 或 0。
二、代码示例:
#include <opencv2/core/utils/logger.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/objdetect.hpp>
#include <opencv2/highgui/highgui_c.h>
#include <iostream>
using namespace cv;
using namespace std;
// 主函数,实现肤色提取
int main() {
utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT); // 设置日志级别为不输出任何日志信息
VideoCapture cap(0); // 使用VideoCapture打开0号摄像头(通常为默认摄像头)
double scale = 0.5; // 定义缩放比例
// 定义HSV色彩空间中的肤色范围参数
double hue_min = 0; // 肤色的最小色调值
double hue_max = 20; // 肤色的最大色调值
double saturability_min = 43; // 肤色的最小饱和度值
double saturability_max = 255; // 肤色的最大饱和度值
double Value_min = 55; // 肤色的最小亮度值
double Value_max = 255; // 肤色的最大亮度值
cout << "参数信息:" << endl; // 输出参数信息
cout << "width:" << cap.get(CAP_PROP_FRAME_WIDTH) << endl; // 输出视频流中帧的宽度
cout << "height:" << cap.get(CAP_PROP_FRAME_HEIGHT) << endl; // 输出视频流中帧的高度
// 循环处理视频的每一帧
while (1) {
// 定义图像容器
Mat frame; // 原始帧
Mat hsvMat; // HSV色彩空间的帧
Mat image; // 用于存放检测结果的图像
cap >> frame; // 从摄像头读取当前帧
// 修改图片尺寸大小
Size ResImgSiz = Size(frame.cols * scale, frame.rows * scale); // 定义缩放后的图像尺寸
Mat rFrame = Mat(ResImgSiz, frame.type()); // 创建缩放后的图像容器
resize(frame, rFrame, ResImgSiz, INTER_LINEAR); // 执行缩放操作
// 将BGR色彩空间的图像转换为HSV色彩空间
cvtColor(rFrame, hsvMat, COLOR_BGR2HSV);
// 对image进行初始化
frame.copyTo(image); // 复制原始帧到image
// 利用inRange函数对图片进行HSV筛选,提取肤色
inRange(hsvMat, Scalar(hue_min, saturability_min, Value_min), Scalar(hue_max, saturability_max, Value_max), image);
// 显示结果
imshow("肤色提取", image); // 显示筛选后的图像
imshow("摄像头", rFrame); // 显示原始图像
// 每帧之间等待30毫秒,如果用户按下'q'键,则退出循环
if (waitKey(30) == 'q') {
break;
}
}
destroyAllWindows();
return 0;
}
三、运行结果: