Opencv 是否有内置功能将3通道垫拆分为三个3通道垫而不是三个1通道垫?

Opencv 是否有内置功能将3通道垫拆分为三个3通道垫而不是三个1通道垫?,opencv,Opencv,据我所知,内置的split将一个3通道Mat拆分为三个1通道Mat。因此,这三个Mat只是灰度级,具有一些不同的强度 我的目的是获得三个3通道Mat,如下所示 void splitTo8UC3(const Mat& input, vector<Mat>& output) { Mat blue = input.clone(); Mat green = input.clone(); Mat red = input.clone(); cons

据我所知,内置的
split
将一个3通道
Mat
拆分为三个1通道
Mat
。因此,这三个
Mat
只是灰度级,具有一些不同的强度

我的目的是获得三个3通道
Mat
,如下所示

void splitTo8UC3(const Mat& input, vector<Mat>& output)
{
    Mat blue = input.clone();
    Mat green = input.clone();
    Mat red = input.clone();
    const uint N = input.rows * input.step;

    for (uint i = 0; i < N; i += 3)
    {
        // blue.data[i]
        green.data[i] = 0;
        red.data[i] = 0;


        blue.data[i + 1] = 0;
        //green.data[i+1]
        red.data[i + 1] = 0;


        blue.data[i + 2] = 0;
        green.data[i + 2] = 0;
        //red.data[i+2]
    }

    output.push_back(blue);
    output.push_back(green);
    output.push_back(red);
}
void splitTo8UC3(常数矩阵与输入、向量与输出)
{
Mat blue=input.clone();
Mat green=input.clone();
Mat red=input.clone();
consuint N=input.rows*input.step;
对于(uint i=0;i
它的工作,但不是重新发明的车轮,我正在寻找内置的,如果有的话

编辑
建议的解决方案必须比我的快。

编辑:我从丹的评论中采纳了他的改进建议


我想不出一个内置函数能做到这一点,我也找不到。但是在做一些研究时,我发现了这个函数,它可能会改进您的解决方案。至少,它避免了实现循环

以下是我对您的代码的修改:

void splitTo8UC3(常数cv::Mat&input,std::vector&output)
{
//分配产出
cv::Mat b(cv::Mat::Zero(input.size(),input.type());
cv::Mat g(cv::Mat::zeros(input.size(),input.type());
cv::Mat r(cv::Mat::Zero(input.size(),input.type());
//收集输出
cv::Mat out[]={b,g,r};
//建立索引对
int从_到[]={0,0,1,4,2,8};
cv::混合通道(输入,1,输出,3,从_到,3);
赋值(std::begin(out),std::end(out));
}
让我们用这个测试图像
colors.png

让我们有这个测试代码:

cv::Mat img=cv::imread(“images/colors.png”);
std::载体bgr;
拆分为8UC3(img、bgr);
cv::imwrite(“images/b.png”,bgr[0]);
简历:imwrite(“images/g.png”,bgr[1]);
简历:imwrite(“images/r.png”,bgr[2]);
然后,我们得到以下输出
b.png
g.png
,和
r.png
,希望它们是您的初始解决方案:


希望有帮助

emm使用默认分割到3个1通道mat,然后使用cvtcolor?@DrYuanShenghai您将获得三个
CV_U8C1
,因此灰度图像。使用
cvtColor
将导致“灰色”
CV_U8C3
,即每个通道中的颜色信息是相同的,这不是OP想要的-我可以告诉你。哦,我明白了。同一个分割3 1通道。然后使用Merge和新创建的2X cv::Mat以及所有0输入来形成新的3-channel@DrYuanShenghai我使用OP在对我的答案的评论中提供的代码测试了这种方法,并且使用
cv::merge
也比他最初的解决方案慢,这可能是因为
cv::merge
被称为
cv::mixChannels
的“部分情况”。到目前为止,直接操作单个像素似乎是最快的。@MoneyOrientedProgrammer也许,您应该添加约束,使其比您的问题解决方案更快。我的第一印象是,您(只是)想要一个更简单/更干净/更易于阅读的代码。:-@MoneyOrientedProgrammer哇-那么我不想知道他们在做什么。当然,那么,保留您的实现!只是一个参考(您可能不感兴趣):好主意。如果您避免在零上复制零,并去掉
k
,它将比OP的代码快(请参阅)。基准测试也有点不公平,因为OP的代码只添加到
输出
向量(因此在测试结束时它有30个条目,而不是3个),而您(IMHO correcly)分配3个频道的
垫子(如果有旧的,取消分配旧的)。修复这会让OP的代码更接近你的时间。现在就开始运行。@DanMašek:你真是天才!谢谢!@Dan多么尴尬-你完全正确!我编辑了我的答案,并加入了你的改进。