You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C++(OpenCV)中堆叠2D Mat生成可遍历的3D数组?

Replicating and Stacking 2D cv::Mat into a 3D Structure in OpenCV (C++)

Great question! Coming from NumPy's handy vstack/stack functions, it’s totally reasonable to want a similar workflow in OpenCV for C++. Luckily, OpenCV’s cv::Mat natively supports multi-dimensional arrays, so we can achieve exactly what you need—stacking a 2D grayscale image into a 3D matrix with N copies, and easily traversing each element to modify values.

Let’s walk through two straightforward approaches:

1. Quick & Clean: Use cv::repeat + cv::reshape

This method is perfect if you just need to duplicate your image N times and reshape the result into a 3D array in one go. It’s concise and requires minimal code.

Example Code

#include <opencv2/opencv.hpp>
#include <iostream>

int main() {
    // Load your grayscale image
    cv::Mat im = cv::imread("image.png", 0);
    if (im.empty()) {
        std::cerr << "Failed to load image!" << std::endl;
        return -1;
    }

    const int N = 5; // Number of layers you want to stack

    // Step 1: Repeat the image N times vertically (result is H*N x W, single channel)
    cv::Mat repeated = cv::repeat(im, N, 1);

    // Step 2: Reshape into a 3D Mat with dimensions (N, image_height, image_width)
    // reshape params: 1st = number of channels (keep 1), 2nd = new 3D size vector
    cv::Mat stacked_3d = repeated.reshape(1, cv::Size({N, im.rows, im.cols}));

    // Now you have your 3D matrix ready for use!
    return 0;
}

2. Manual Control: Create 3D Mat & Fill Layers

If you need more flexibility (e.g., modifying layers as you stack them), manually creating the 3D matrix and copying each layer gives you full control over the process.

Example Code

#include <opencv2/opencv.hpp>
#include <iostream>

int main() {
    cv::Mat im = cv::imread("image.png", 0);
    if (im.empty()) {
        std::cerr << "Failed to load image!" << std::endl;
        return -1;
    }

    const int N = 5;
    // Define 3D dimensions: (number of layers, image height, image width)
    int dims[] = {N, im.rows, im.cols};

    // Create an empty 3D Mat with the same data type as your input image
    cv::Mat stacked_3d(3, dims, im.type());

    // Copy the original image into each layer
    for (int layer_idx = 0; layer_idx < N; ++layer_idx) {
        // Extract the current layer as a sub-matrix
        cv::Mat layer = stacked_3d(cv::Range(layer_idx, layer_idx + 1), 
                                   cv::Range::all(), 
                                   cv::Range::all());
        // Reshape the layer to match the original image's 2D size, then copy
        im.copyTo(layer.reshape(1, im.rows));
    }

    return 0;
}

Traversing the 3D Mat

Once you have your 3D matrix, accessing and modifying elements is straightforward using cv::Mat::at<>(). For a grayscale image (uchar type), you can iterate through all layers, rows, and columns like this:

// Iterate through every element in the 3D matrix
for (int i = 0; i < stacked_3d.size[0]; ++i) { // i = layer index
    for (int y = 0; y < stacked_3d.size[1]; ++y) { // y = row
        for (int x = 0; x < stacked_3d.size[2]; ++x) { // x = column
            // Add 1 to each element (example operation)
            stacked_3d.at<uchar>(i, y, x) += 1;
        }
    }
}

Quick Notes

  • If you prefer a multi-channel 2D Mat instead of a strict 3D array (e.g., treating layers as channels), you could use cv::merge with a vector of repeated images—but this is a different structure than a true 3D matrix.
  • For better performance with large images, consider using pointer-based access instead of at<>(), but at<>() is perfectly fine for most use cases and much more readable.

内容的提问来源于stack exchange,提问作者daniglezad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:45:06