OpenCV:如何有效地将 Mat2d 矩阵的每个元素乘以 Mat1d 矩阵

Posted

技术标签:

【中文标题】OpenCV:如何有效地将 Mat2d 矩阵的每个元素乘以 Mat1d 矩阵【英文标题】:OpenCV: How to Efficiently Multiply Each Element of a Mat2d matrix by a Mat1d matrix 【发布时间】:2017-04-05 18:37:23 【问题描述】:

我有一个 Mat2d 矩阵,其中每个元素都是一个二维向量。例如:

[[x0, y0], [x1, y1]
 [x2, y2], [x3, y3]]

我想将这些向量中的每一个乘以一个 Mat1d 相机矩阵:

[fx, 0,  cx, 
 0,  fy, cy, 
 0,  0,  1]

(每个向量代表一个顶点在网格中的位置,我想将其从相机空间转换为像素空间。)

在本例中,生成的矩阵将是:

[[x0 * fx + cx, y0 * fy + cy], [x1 * fx + cx, y1 * fy + cy]
 [x2 * fx + cx, y2 * fy + cy], [x3 * fx + cx, y3 * fy + cy]]

实现此目的最直接、最有效的方法是什么?


这是我目前的做法:

Mat2d points = getMesh();
Mat1d cameraMtrx = getCameraMtrx();

for(int col = 0; col < points.cols; col++)
    for(int row = 0; row < points.rows; row++)
        points.at<Vec2d>(row, col).val[0] = points.at<Vec2d>(row, col)[0] * cameraMtrx.at<double>(0, 0) + cameraMtrx.at<double>(0, 2);
        points.at<Vec2d>(row, col).val[1] = points.at<Vec2d>(row, col)[1] * cameraMtrx.at<double>(1, 1) + cameraMtrx.at<double>(1, 2);
    

【问题讨论】:

应该是最快的方法,你可以从垫子中提取(引入 cariables)fx fy cx 和 cy 并减少函数调用。你可以使用行指针来表示点,这比 .at 函数更有效 不,您正在迭代外部循环中的 cols 和内部循环中的行。反过来做会更有效率! (行大订单!!) 【参考方案1】:

OpenCV Documentation 已经详细介绍了有效迭代cv::Mat 的各种方法,在提出的方法中,最有效的方法是使用cv::LUT(),但从这个问题的上下文来看,我猜的范围是输入矩阵值不固定,因此无法创建查找表,这对于RGB 图像非常有用,因为我们事先知道最小值将是0,最大值将是@987654327 @,所以我们可以很容易地创建一个查找表,但是在这个问题中,我们需要将两个矩阵相乘,我假设它们不是图像,所以我们将使用The efficient way。

int cameraMatrix[] = 2, 0, 10, 0, 4, 20, 0, 0, 1;
cv::Mat mat(2, 2, CV_32FC2, cv::Scalar(100, 20));
cv::Size contSize = mat.size();

// Calculate the length of array if the input matrix was flatten, in case of continuous matrix only.
if (mat.isContinuous()) 
    contSize.width *= contSize.height;
    contSize.height = 1;


cv::Vec2f* ptr;
for (int i = 0; i < contSize.height; ++i)

    ptr = mat.ptr<cv::Vec2f>(i);
    for (int j = 0; j < contSize.width; ++j)
    
        ptr[j] = cv::Vec2f(ptr[j].val[0]*cameraMatrix[0] + cameraMatrix[2], ptr[j].val[1] * cameraMatrix[4] + cameraMatrix[5]);
    

【讨论】:

以上是关于OpenCV:如何有效地将 Mat2d 矩阵的每个元素乘以 Mat1d 矩阵的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 SSE 更有效地将 A*B^T 或 A^T*B^T(T 表示转置)矩阵相乘?

将矩阵中的列向量复制到opencv中另一个矩阵的每个列中

OpenCV 中的高效矩阵复制

如何在 OpenCV 中计算矩阵的直方图?

给定两个 2D numpy 数组 A 和 B,如何有效地将采用两个 1D 数组的函数应用于 A 和 B 行的每个组合?

如何使用opencv从矩阵向量构造图像