РЕДАКТИРОВАТЬ: Я включил предложенные Дэном улучшения из его комментария.
Я не могу думать о встроенной функции, которая точно делает это, и я также не мог ее найти. Но, проводя некоторые исследования, я наткнулся на функцию mixChannels
, которая может улучшить ваше решение. По крайней мере, он избегает реализации цикла.
Вот мои модификации вашего кода:
void splitTo8UC3(const cv::Mat& input, std::vector<cv::Mat>& output)
{
// Allocate outputs
cv::Mat b(cv::Mat::zeros(input.size(), input.type()));
cv::Mat g(cv::Mat::zeros(input.size(), input.type()));
cv::Mat r(cv::Mat::zeros(input.size(), input.type()));
// Collect outputs
cv::Mat out[] = { b, g, r };
// Set up index pairs
int from_to[] = { 0,0, 1,4, 2,8 };
cv::mixChannels(&input, 1, out, 3, from_to, 3);
output.assign(std::begin(out), std::end(out));
}
Давайте получим это тестовое изображение colors.png
:
![image](https://i.stack.imgur.com/XTRLT.png)
And, let's have this test code:
cv::Mat img = cv::imread("images/colors.png");
std::vector<cv::Mat> bgr;
splitTo8UC3(img, bgr);
cv::imwrite("images/b.png", bgr[0]);
cv::imwrite("images/g.png", bgr[1]);
cv::imwrite("images/r.png", bgr[2]);
Затем мы получим следующие выходные данные b.png
, g.png
и r.png
, которые, как мы надеемся, являются теми же, что и для вашего исходного решения:
Надеюсь, это поможет!