OpenCV 中 cv::split() 的最基础用法
一、cv::split() 是干什么的?
一句话:把一张多通道图像,拆成好几个单通道图像。
比如:
- 3通道彩色图(RGB/BGR) → 拆成 R、G、B 三张灰度图
- 4通道带透明度 → 拆成 R、G、B、A
二、最基本用法(标准格式)
cpp
// 把 image 拆分成多个单通道图像,放进 channels 里
void cv::split(
const cv::Mat& image, // 输入:多通道图像(比如3通道彩色图)
std::vector<cv::Mat>& channels // 输出:每个单通道图像(vector装)
);
三、超级简单例子(一看就会)
例子1:把彩色图拆成 R、G、B
cpp
// 1. 读取一张彩色图片
cv::Mat image = cv::imread("test.jpg"); // 3通道 BGR
// 2. 创建一个vector,用来装拆出来的3个通道
vector<cv::Mat> channels;
// 3. 拆分!
cv::split(image, channels);
// 现在:
// channels[0] = B 通道(灰度图)
// channels[1] = G 通道(灰度图)
// channels[2] = R 通道(灰度图)
结果:
一张彩色图 → 变成 三张灰度图。
四、另一种写法(数组写法)
你代码里用的就是这种:
cpp
cv::Mat channels[3];
cv::split(image, channels);
效果完全一样,只是用数组存。
五、最重要的知识点(你必须懂)
split 做了什么?
输入图像(3通道)的内存排布:
B G B G B G B G ...
split 之后:
channels[0] = B B B B B B
channels[1] = G G G G G G
channels[2] = R R R R R R
一句话:
split 把交织在一起的通道,分开成连续的单通道。
六、你现在再看你原来的代码
cpp
// 1. 先给 ms 里每个 mat 绑定好 Tensor 的内存地址(只是指路)
ms[i] = cv::Mat(height, width, CV_32F, cpu<float>(n, i));
// 2. 然后 split 把图像拆开放进这些地址里!
cv::split(image, &ms[0]);
现在是不是彻底懂了?
- 先准备好 3 个空的单通道 Mat(指向Tensor)
- split 把彩色图拆开,直接写入这 3 个 Mat
- 因为 Mat 指向 Tensor,所以数据直接进 Tensor!