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多么尴尬-你完全正确!我编辑了我的答案,并加入了你的改进。