opencv基础篇 ——(五)颜色通道
在 OpenCV 中,颜色通道指的是图像的不同颜色分量,通常用于表示图像的颜色信息。在彩色图像中,通常使用 RGB(红、绿、蓝)颜色模型来表示颜色通道。每个颜色通道都对应于图像中的一个颜色分量。
split
函数说明
void split(const Mat& src, Mat* mvbegin);
void split(InputArray m, OutputArrayOfArrays mv);
- src: 输入参数,表示一个 多通道 的 cv::Mat 类型图像。通常,这指的是 RGB、BGR、RGBA、BGRA 等彩色图像,或者是 HSV、YUV 等其他色彩空间的图像。每个像素包含多个通道(如红、绿、蓝三个通道或加上透明度通道)。
- mvbegin 或 mv: 输出参数,表示一个指向一系列 cv::Mat 对象的指针数组(或 std::vector 容器)。cv::split 将把输入图像 src 中的各个通道分别存储到这些输出矩阵中。每个输出矩阵都是单通道的,其尺寸、类型与原图像的对应通道完全相同。
功能与用法
cv::split 主要用于将一个多通道图像分解为其各个单独的通道。例如,对于一个 BGR 彩色图像:
- mvbegin[0] 或 mv[0] 将存储蓝色(B)通道;
- mvbegin[1] 或 mv[1] 将存储绿色(G)通道;
- mvbegin[2] 或 mv[2] 将存储红色(R)通道;
- 如果输入图像有更多通道(如 alpha 透明度通道),则剩余的输出矩阵将依次存储这些额外通道。
使用 cv::split 的常见场景包括:
- 分析图像中各个颜色通道的特性,如进行直方图计算、边缘检测、阈值处理等针对单通道的操作。
- 在图像处理算法中需要对各个颜色通道独立操作后再合并回原色彩空间,如色彩校正、图像增强等。
- 实现图像格式转换,如从 BGR 转换到 HSV 颜色空间,通常先使用 cv::split 分离 BGR 通道,然后对各通道进行特定计算以得到 HSV 通道,最后使用 cv::merge 将 HSV 通道合并成新的图像。
注意事项
- 数据类型匹配:正如之前引用的资料所强调的,目标图像(即输出的单通道图像)必须与源图像(即输入的多通道图像)在大小和数据类型上完全匹配。
- 显示单通道图像:分离出的单通道图像在直接显示时通常表现为灰度图像,因为它们仅包含一个颜色分量。若要以各自对应的颜色(如红色、绿色通道显示为红色、绿色)显示这些单通道图像,需要通过特定方式(如 OpenCV 的 cv::applyColorMap 函数)添加伪彩色,或者使用 cv::merge 合并回多通道格式后再显示。
综上所述,cv::split 是一个用于将多通道图像分解为单通道图像序列的强大工具,常用于各种图像处理和分析任务中需要对颜色通道进行独立操作的场景。
示例
#include <opencv2/opencv.hpp>
int main() {
// 读取多通道图像
cv::Mat image = cv::imread("image.jpg");
// 分割图像通道
std::vector<cv::Mat> channels;
cv::split(image, channels);
// 显示分割后的单通道图像
for (int i = 0; i < channels.size(); ++i) {
cv::imshow("Channel " + std::to_string(i), channels[i]);
}
cv::waitKey(0);
return 0;
}
merge
函数说明
void cv::merge(const Mat* mv, size_t count, OutputArray dst);
void cv::merge(InputArrayOfArrays mv, OutputArray dst);
- mv 或 InputArrayOfArrays: 输入参数,表示一组待合并的单通道 cv::Mat 图像。这组图像通常按照预期的合并顺序排列,例如对于 RGB 彩色图像,应按 B(蓝色)、G(绿色)、R(红色)的顺序提供三个单通道矩阵。也可以使用 std::vector 或其他 OpenCV 支持的容器类型来封装这些单通道矩阵。
- count: 输入参数,指定 mv 指针数组中单通道图像的数量。当使用 std::vector 或 InputArrayOfArrays 时,这个参数通常不需要显式指定,因为它可以从容器的大小自动推断出来。
- dst: 输出参数,表示合并后生成的多通道 cv::Mat 图像。这个图像将包含所有输入单通道图像的数据,按照提供的顺序组合成对应的通道。dst 的尺寸(高度、宽度)应与输入的单通道图像相同,而其通道数(depth)将等于 count。
功能与用法
cv::merge 主要用于将一组单通道图像合成一个多通道图像,如:
将分离的 R、G、B 单通道图像合并成一个 BGR 彩色图像。
合并处理过的 HSV 通道图像,以生成新的 HSV 彩色图像。
组合不同类型的单通道数据(如强度、深度、法线等)生成多通道图像,用于立体视觉、3D 渲染等应用。
在实际使用中,cv::merge 常见于以下场景:
- 通道合并:在对单通道图像进行独立处理后(如直方图均衡化、滤波、阈值处理等),使用 cv::merge 将它们重新组合成一个多通道图像。
- 色彩空间转换:在进行色彩空间转换时,先使用 cv::split 分离原图像的通道,对各通道进行特定计算(如 BGR 到 HSV 的转换),然后使用 cv::merge 合并新计算出的通道,形成目标色彩空间的图像。
- 多通道数据构造:在需要构建具有多个数据层的图像时(如深度图、光流场、掩模等),将这些单层数据合并成一个多通道图像,便于后续统一处理或存储。
注意事项
- 输入图像一致性:所有输入的单通道图像在尺寸(高度、宽度)和数据类型上必须完全一致,否则合并操作无法进行。
- 通道顺序:正确指定单通道图像的合并顺序至关重要,特别是对于彩色图像,必须遵循目标色彩空间的通道顺序(如 BGR、RGB、HSV 等)。
总之,cv::merge 函数是 OpenCV 中用于将单通道图像组合成多通道图像的核心工具,广泛应用于图像处理、计算机视觉和图形学领域中的色彩空间转换、多通道数据构造等任务。
示例
#include <opencv2/opencv.hpp>
int main() {
// 读取单通道图像
cv::Mat channel1 = cv::imread("channel1.jpg", cv::IMREAD_GRAYSCALE);
cv::Mat channel2 = cv::imread("channel2.jpg", cv::IMREAD_GRAYSCALE);
cv::Mat channel3 = cv::imread("channel3.jpg", cv::IMREAD_GRAYSCALE);
// 合并单通道图像
std::vector<cv::Mat> channels = {channel1, channel2, channel3};
cv::Mat merged_image;
cv::merge(channels, merged_image);
// 显示合并后的多通道图像
cv::imshow("Merged Image", merged_image);
cv::waitKey(0);
return 0;
}
convertTo
void cv::Mat::convertTo(OutputArray dst, int rtype, double alpha = 1, double beta = 0) const;
- this (隐含参数): 当前调用该方法的 cv::Mat 对象,表示要进行转换的源图像或矩阵。
- dst: 输出参数,表示转换后的新 cv::Mat 对象。dst 的尺寸应与源图像相同,但其数据类型(rtype)可以与源图像不同。
- rtype: 整型参数,指定目标图像的数据类型。它可以是 OpenCV 支持的任何数据类型代码,如 CV_8U 表示无符号 8 位整型、CV_32F 表示单精度浮点型等。注意,此参数仅影响数据类型,不改变图像的通道数。
- alpha: 可选的标度因子,默认值为 1。转换过程中,源图像的每个元素值将乘以 alpha。这对于调整图像的亮度、对比度或其他数值属性非常有用。
- beta: 可选的偏移量,默认值为 0。转换过程中,源图像的每个元素值在乘以 alpha 后再加 beta。这可用于实现全局增益或偏移,如在调整图像亮度时增加一个固定的值。
功能与用法
cv::convertTo 主要用于实现以下功能:
- 数据类型转换:将源图像从一种数据类型(如 CV_8U)转换为另一种数据类型(如 CV_32F),以便进行特定的数学运算、滤波操作或与其他数据结构兼容。
- 图像值调整:利用 alpha 和 beta 参数,可以在转换过程中同时调整图像的数值范围。例如,可以提高对比度(通过增大 alpha)或改变亮度(通过设置合适的 beta 值)。
- 数值归一化:对于需要特定数值范围(如 [0, 1] 或 [-1, 1])的算法或显示要求,可以通过设置适当的 alpha 和 beta 值将图像值归一化到所需范围内。
注意事项
- 内存管理:在调用 cv::convertTo 之前,需要确保 dst 已经正确分配了内存。如果未预先分配,函数会自动创建与源图像尺寸相同但类型为 rtype 的新矩阵。如果已经预分配了内存,则应确保其尺寸、类型与预期转换结果匹配。
- 精度损失与溢出:数据类型转换可能导致精度损失(如从浮点型转为整型)或溢出(如小数据类型容纳不下经过 alpha 和 beta 调整后的值)。在进行转换时,应充分考虑源数据的动态范围和目标数据类型的限制,以避免不必要的信息丢失或错误。
- 不改变图像内容:cv::convertTo 不改变源图像的内容,而是将转换结果保存在 dst 中。这意味着源图像和转换后的图像可以同时存在并用于不同的目的。
- 不改变通道数:cv::convertTo 仅转换数据类型,而不改变图像的通道数。若需要改变图像的通道数(如从灰度图转为彩色图或反之),应使用其他函数,如 cv::cvtColor。
综上所述,cv::convertTo 函数在 OpenCV 中扮演着数据类型转换和数值调整的关键角色,适用于多种图像处理和计算机视觉任务,如数据预处理、特征提取、图像显示等。通过灵活运用 alpha 和 beta 参数,用户可以方便地对图像进行数值上的增强或规范化。
applyColorMap
人类的感知并不是为了观察灰度图像中的细微变化而建立的。人眼对观察颜色之间的变化更敏感,所以你经常需要对灰度图像重新着色,以获得有关它们的线索。OpenCV现在提供了各种颜色映射,以增强计算机视觉应用程序中的可视化效果。
applyColorMap() 是 OpenCV 库中用于将灰度图像或单通道图像映射到具有特定颜色模式的彩色图像的函数
函数说明
void applyColorMap(InputArray src, OutputArray dst, int colormap, bool applyAlpha = false);
- 输入图像 (InputArray src):
- 提供一个单通道(通常是灰度图)的 cv::Mat 或类似类型作为输入。该图像的数据类型通常为 CV_8U,表示无符号 8 位整数,范围为 [0, 255]。
- 输出图像 (OutputArray dst):
- 目标彩色映射图像,同样为 cv::Mat 类型。函数会自动根据所选的颜色映射类型和输入图像大小分配内存。输出图像通常具有三通道(BGR 或 RGB),数据类型为 CV_8U。
- 颜色映射类型 (int colormap):
- 指定要应用的颜色映射。这应为 OpenCV 中预定义的颜色映射常量之一,如:
- 是否应用 Alpha 通道 (bool applyAlpha):
- 可选参数,默认为 false。如果设为 true,函数将在输出图像中添加一个透明度(Alpha)通道,使得映射后的图像具有透明效果。注意,OpenCV 的大部分接口默认处理 BGR 顺序的三通道图像,因此带有 Alpha 通道的图像将是 BGRA 格式。
ColormapTypes
示例
Mat img_in = imread(argv[1]);
if(img_in.empty())
{
return -1;
}
Mat img_color;
applyColorMap(img_in, img_color, COLORMAP_JET);
效果展示
- 分割合并
- 彩色图构建