繁体   English   中英

NumPy 在矩阵上的重复命令:如何在 OpenCV 中使用 cv::Mat 执行此操作?

[英]NumPy's repeat command on a matrix: how to do this in OpenCV with cv::Mat?

我对 OpenCV 比较陌生,需要将一些 Python 代码转换为 OpenCV (C++)。 给定某个矩阵,我需要创建一个具有特定模式的更大矩阵。 假设原始矩阵是一个随机整数矩阵:

>>> import numpy as np
>>> a = np.random.randint(0, 10, (3,3))
>>> a
array([[2, 7, 0],
       [3, 7, 5],
       [7, 2, 0]])

然后Python代码使用repeat命令构造一个更大的矩阵,方式如下:

>>> a.repeat(3, 0).repeat(3,1)
array([[2, 2, 2, 7, 7, 7, 0, 0, 0],
       [2, 2, 2, 7, 7, 7, 0, 0, 0],
       [2, 2, 2, 7, 7, 7, 0, 0, 0],
       [3, 3, 3, 7, 7, 7, 5, 5, 5],
       [3, 3, 3, 7, 7, 7, 5, 5, 5],
       [3, 3, 3, 7, 7, 7, 5, 5, 5],
       [7, 7, 7, 2, 2, 2, 0, 0, 0],
       [7, 7, 7, 2, 2, 2, 0, 0, 0],
       [7, 7, 7, 2, 2, 2, 0, 0, 0]])

在我的 C++ 代码中,我正在考虑使用 OpenCV 的Mat class 来存储矩阵,因为我需要做一些操作,比如转置、元素乘法、矩阵向量乘法等......

我知道如何创建较小的矩阵,例如如下所示:

double data[3][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };
cv::Mat m = cv::Mat(3, 3, CV_64FC1, &data);

但是我还没有想出一种方法来从这个较小的矩阵中构造出更大的矩阵。 对于 OpenCV 的Mat class,我找不到等效的 NumPy repeat命令。 怎么可能做到这一点?

cv::repeat 函数正是你所需要的

从 OpenCV 文档中,它表明使用 Mat 类应该可以重复,

任何返回矩阵或标量的矩阵或矩阵和标量函数,例如范数、均值、总和、countNonZero、迹线、行列式、重复等。

如果做不到这一点,对在C不同numpy的风格数组++的讨论在这里,虽然大多数似乎并没有提供所有相同的功能。 numpy 的实际源代码也将在 c 中,因此您可以提取功能或使用它进行重复。 但是,编写自己的重复函数可能会更简单......

与此同时,我想出了这个解决方案:

#include <iostream>
#include <opencv2/core/core.hpp>

int main() {

    double data[3][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };

    cv::Mat m = cv::Mat(3, 3, CV_64F, data);
    std::cout << "m = "<< std::endl << " "  << m << std::endl << std::endl;

    cv::Mat m_expanded = cv::Mat::zeros(9, 9, CV_64F);
    for (int row = 0; row < m.rows; row++)
    {
        for (int col = 0; col < m.cols; col++)
        {
            m_expanded(cv::Range(row*3,(row+1)*3), cv::Range(col*3,(col+1)*3)) = m.at<double>(row, col);
        }
    }
    std::cout << "m_expanded = "<< std::endl << " "  << m_expanded << std::endl << std::endl;

    return 1;
}

但有些事情告诉我有一种更优雅的方式来做到这一点。 我仍然很高兴听到优雅的方式。

命令cv::resize给你想要的结果。 只要确保使用正确的插值方法( INTER_NEAREST )。 这样,OpenCV 只会重复矩阵中的像素。

例子:

cv::Mat mat(10, 10, CV_32F);
cv::Mat scaledMat(100, 100, CV_32F);
cv::resize(mat, scaledMat, cv::Size(100, 100), 0, 0, cv::InterpolationFlags::INTER_NEAREST);

暂无
暂无

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

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