将numpy切片转换为OpenCV C 垫子

Convert numpy slice to Opencv c++ Mat

本文关键字:OpenCV 垫子 转换 numpy 切片      更新时间:2023-10-16

我的python阵列具有形状(1、17、17、5、5(。我需要获得此数组的子阵列:

subarray = array[0]
subarray = subarray[:,:,:,4]

现在,我需要使用OpenCV垫子在C 中编写相同的代码。我如何获得这个子阵列?是否有一种简单的方法可以切成与Numpy相同的垫子?

openCV矩阵遵循与numpy阵列完全不同的范式,因此您将无法利用广播和其他索引功能Numpy允许。

在特殊情况下,由于OpenCV对计算机视觉的专业化程度,OpenCV甚至不支持3个维度的矩阵。如果您绝对需要为此使用OpenCV矩阵,请创建一个大小 sum(array.shape)的1维操作矩阵,并按C顺序进行所有数据,然后您仍然可以将一般索引公式用于任意维度:

cv::Mat your_mat = /*what ever data for your flattened matrix assuming double,*/
vector<int> dimensions = {/*what ever your dimensions are, in this case 1, 17, 17, 5, 5*/};
vector<int> nd_index = {/*what ever indexes you are trying to access, assuming x, y, z, ... order, not C order*/};
int accumulated_frame_size = 1;
int linear_index = 0;
for(int dim_idx = 0; dim_idx < dimensions.size(); ++dim_idx){
    linear_index += nd_index[dim_idx] * accumulated_frame_size;
    accumulated_frame_size *= nd_index[dim_idx];
}
//the value for that index. 
std::cout << your_mat.at<double>(linear_idx) << "n";

当然,您可能想在此操作的大部分事情可能无法使用,除非它完全是明智的。

由于您想做一些特定的事情,我们可以做得更好。由于我们在C 中将其弄平,因此我们的数组中的第一个单元尺寸将不存在,因此无需通过[0]下注。如果我们考虑一下,subarray[:,:,:,4]实际上只是每5个元素偏移的第四个索引,仅此而已。为了提取这些信息,我们首先计算要提取多少这些元素,然后在另一个矩阵中输入它们。

int extract_count =  17 * 17 * 5; //all dimensions before indexed dimension.
int final_dim_size = 5;
int extract_index = 4;
cv::Mat extracted_mat(1,extract_count,CV_64F);
for(int i = 0; i< extract_count ; ++i){
    extracted_mat.at<double>(i) = your_mat.at<double>(i*final_dim_size + extract_index);
}

Numpy所做的是内部将您所做的所有索引转换为类似操作。

我最终使用cv :: range来获取我需要的子阵列

std::vector<cv::Range> ranges;
ranges.push_back(cv::Range(0, 1));
ranges.push_back(cv::Range::all());
ranges.push_back(cv::Range::all());
ranges.push_back(cv::Range::all());
ranges.push_back(cv::Range(4, 5));
cv::Mat subarray = array(ranges);

它不会更改数组的尺寸,但请确保我只是在寻找我感兴趣的数据。