gpt4 book ai didi

c++ - 从数组创建或 reshape OpenCV 3 channel 垫

转载 作者:太空狗 更新时间:2023-10-29 20:40:47 28 4
gpt4 key购买 nike

我想根据任意数据类型、行维度、列维度和 channel 维度的一维数据数组构建一个 3 channel 矩阵。在我的示例中,我有一个 1x12 double 组数据,我想将其转换为 2x2x3 OpenCv 矩阵。

double rawData[] = {1.0, 1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, 3.0};

我的目标是:

Channel 1:
[ 1, 1;
1, 1]
Channel 2:
[ 2, 2;
2, 2]
Channel 3:
[ 3, 3;
3, 3]

这是我试过的:

cv::Mat aMat = cv::Mat(2, 2, CV_64FC3, rawData)

但是 OpenCv 不同意它应该如何使用 rawData 缓冲区。当我按 channel 拆分矩阵并打印每个单独的 channel 时:

cv::Mat channels[3];
cv::split(aMat ,channels);

确实如此:

Channel 1:
[ 1, 1;
2, 3]

Channel 2:
[ 1, 2;
2, 3]

Channel 3:
[ 1, 2;
3, 3]

我也试过将数据加载到 1D Mat 中,然后使用 cv::Reshape 但结果是一样的。

如何让 channel 以我想要的方式显示?我真的必须手动分配每个索引还是有更优雅/优化的方法?

编辑:问题约束

不应重新排列 rawData 中数据的顺序,因为这会增加确定维度和数据类型的复杂性。如果可能,我更愿意使用 OpenCV 接口(interface)。

最佳答案

我的解决方案与 berak 的解决方案很接近,将数据拆分到单独的 channel 中。除了一个重要的(我认为)区别。我用已经编码的数据类型初始化一个单行矩阵,即:

cv::Mat aMat = cv::Mat(1, 12, CV_64F, data);

然后我使用 colRange 方法提取部分列:

std::vector<cv::Mat> channelVector(3);
channelVector[0] = aMat.colRange(0,4);
channelVector[1] = aMat.colRange(4,8);
channelVector[2] = aMat.colRange(8,12);

我这样做是为了避免指针运算。这里的优点是我可以让我的数据缓冲区为 void* 类型,而且我不必担心首先将指针转换为正确的类型以增加缓冲区指针。

然后我使用一些 reshape 操作进行迭代。

for(cv::Mat& channel : channelVector)
channel = channel.reshape(1,2);

最后合并。

cv::Mat combinedMatrix;
cv::merge(channelVector, combinedMatrix);

这应该是高效的,因为这些操作是 O(1) 的。我不确定合并,我认为这实际上复制了数据,但我无法验证......但我还是要 clone() 最终结果,所以这对我。

关于c++ - 从数组创建或 reshape OpenCV 3 channel 垫,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22695197/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com