簡體   English   中英

在opencv(C++)中從caffe中讀取多維數組

[英]Read multi-dimensional array from caffe in opencv (C++)

我在caffe中有一個生成多維數組的模型。 這個數組的大小是[1x10x8x8]所以在 python 中我對這個大小沒有問題,因為 python 自動管理這個數組,我知道元素的順序。 但是當我用 c++ 切換到opencv ,整個數組是一個向量,我不知道如何重新生成像 python 數組這樣的東西,我使用cv::NAryMatIterator來訪問多維數組,如下所示

const cv::Mat* arrays[]={&prob,0};  //my multi-dimensional array is prob
cv::Mat my_planes[1];
cv::NAryMatIterator it(arrays,my_planes);
cv::Mat Multi_Array ;                               //temporary Mat 
for (int p = 0; p < it.nplanes; ++p,++it) {
    Multi_Array = it.planes[0];
}

這樣做之后,我看到Multi_Array大小為[640x1] ,這似乎等於 python 生成的8x8x10 有沒有辦法一個接一個地訪問8x8飛機?

編輯:我的多維數組大小是[1x10x8x8]

要像訪問形狀為[640][1]的 2D 數組一樣訪問 3D 數組,您可以編寫 3 個循環來使用[x,y,z]格式迭代元素例如:

int data[640][1] = { 0 };
int width = 8, height = 8, depth = 10;

for (int x = 0; x < width; x++)
    for (int y = 0; y < height; y++)
        for (int z = 0; z < depth; z++)
        {
            int idx = x * height * depth + y * depth + z;
            data[idx][0] = idx;
        }

這會用 0 到 639 之間的數字填充數組。

如果您希望將 2D 數組作為 1D 訪問,請查看此答案

如果您的模型數據以行優先形式排序,您可以讓 OpenCV 將數據解釋為所需大小的Mat 然后,可以使用multidim_mat.row( row_number )訪問Mat平面。

為了從數據創建一個Mat

int data[640] = { 0 };
const int size[] = { 8, 8, 10 };

cv::Mat multidim_mat(3, size, CV_32S, data);

std::cout << multidim_mat.dims << std::endl;
for (int i = 0; i < multidim_mat.dims; i++) {
    std::cout << "Dimension " << i << " is of size " << multidim_mat.size[i] << std::endl;
}

CV_32S是通知 OpenCV 將數據解釋為有符號的 32 位整數。

參考資料: https : //docs.opencv.org/3.4.0/d3/d63/classcv_1_1Mat.html#a5fafc033e089143062fd31015b5d0f40、https : //docs.opencv.org/3.4.0/d3/d63/details_1_1Mat.html#a5fafc033e089143062fd31015b5d0f40

第一步,我們需要獲得一個指向 OpenCV Mat 對象的指針,您可以通過以下命令執行此操作。(我假設表示您的數據的數據主要是float並考慮概率 Mat 是我們從 caffe 中獲取此 Mat 的prob

float* p = (float*)(prob.data);

該指針將指向數據駐留在內存中的位置。 因此,例如,如果我們想訪問 (1,3,7,7) 位置中的元素,我們可以執行以下操作:

int S= sizeof(float);    
float val = p[(
    7*p.step[3]/S +    //forth dimension
    7*p.step[2]/S +    //third dimension
    3*p.step[1]/S      //second dimension
  )]           
 //first dimension is not needed, because it is decoded in address of p
 //and if you have any higher number than 1 in first dimension you need to add it to the above command

因此,為了遍歷概率矩陣,您可以像下面這樣:

auto S=sizeof(float);
for (int d2 = 0; d2 < 129; ++d2) {
    for (int d3 = 0; d3 < 129; ++d3) {
        for (int d4 = 0; d4 < 10; ++d4) {
            float val = p[(d2*prob.step[3]/S + d3*prob.step[2]/S + d4* prob.step[1]/S)];
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM