![](/img/trans.png)
[英]Call a C++ function from Python and convert a OpenCV Mat to a Numpy array
[英]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.