将 numpy 切片转换为 Opencv c++ Mat

Posted

技术标签:

【中文标题】将 numpy 切片转换为 Opencv c++ Mat【英文标题】:Convert numpy slice to Opencv c++ Mat 【发布时间】:2019-07-31 16:50:11 【问题描述】:

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

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

现在我需要使用 Opencv Mat 在 C++ 中编写相同的代码。 我如何得到这个子数组?有没有一种像 Numpy 一样简单的方法来切片 Mat?

【问题讨论】:

【参考方案1】:

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

在特殊情况下,OpenCV 甚至不支持超过 3 维的矩阵,因为 OpenCV 对计算机视觉非常专业。如果您绝对需要为此使用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 所做的是在内部将您创建的所有索引转换为类似的操作。

【讨论】:

【参考方案2】:

我最终使用 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);

它不会改变数组的维度,但确保我只查看我感兴趣的数据。

【讨论】:

以上是关于将 numpy 切片转换为 Opencv c++ Mat的主要内容,如果未能解决你的问题,请参考以下文章

使用 Python 将 OpenCV BoundingRect 转换为 NumPy 数组

Python - 使用 OpenCV 将字节图像转换为 NumPy 数组

将 python、numpy 和 scipy 代码转换为 C++ 兼容代码?

基于变化角的Opencv C++裁剪图像

如何将围绕 C++ 函数的 R 包装器转换为 Python/Numpy

将CV2 numpy数组转换为QImage时如何配置颜色?