繁体   English   中英

将numpy slice转换为Opencv C ++ Mat

[英]Convert numpy slice to Opencv c++ Mat

我在python中有一个形状为(1、17、17、5、5)的数组。 我需要获得此数组的子数组:

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

现在,我需要使用Opencv Mat在C ++中编写相同的代码。 我如何获得这个子阵列? 有没有一种简单的方法可以像使用Numpy一样切割Mat?

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

在特殊情况下,由于OpenCV对计算机视觉的专业化程度,OpenCV甚至不支持3维以上的矩阵。 如果您绝对需要为此使用opencv矩阵,请创建一个大小为sum(array.shape)的一维opencv矩阵,并将所有数据按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个元素偏移量的第4个索引,仅此而已。 为了提取该信息,我们首先计算要提取的元素数量,然后将它们输入另一个矩阵。

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);

它不会改变数组的尺寸,但是可以确保我只查看我感兴趣的数据。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM