【问题标题】:OpenCV Mat per-element operation: vector-matrix multiplicationOpenCV Mat 每元素运算:向量矩阵乘法
【发布时间】:2013-03-29 15:48:25
【问题描述】:

I是一个mxn矩阵,I的每个元素都是一个1x3向量(I 实际上是一个 3 通道的 Mat 图像)。

M 是一个 3x3 矩阵。

J是一个与I维数相同的矩阵,计算如下:J的每个元素都是向量-矩阵乘积I 和 M 的对应(即具有相同的坐标)元素。

即如果 v1(r1,g1,b1) 是 I 的元素,而 v2(r2,g2,b2) 是 I 的对应元素strong>J,然后 v2 = v1 * M(这是向量矩阵乘积,而不是每元素乘积)。

问题:如何有效地计算 J(在速度方面)?

感谢您的帮助。

【问题讨论】:

    标签: opencv matrix matrix-multiplication mat


    【解决方案1】:

    据我所知,实现这种操作最有效的方法如下:

    1. 将I从mxnx3重塑为(m·n)x3,我们称之为I'
    2. 计算 J' = I' * M
    3. 将J'从(m·n)x3重塑为mxnx3,这就是我们想要的J

    这个想法是将每个像素级操作pi'·M堆叠成一个单独的操作P'·M,其中 P 是 3x(m·n) 矩阵,包含列中的每个像素(因此 P' 每行保存一个像素。这只是一个约定,真的)。

    这是一个用 c++ 编写的代码示例:

    //  read some image
    cv::Mat I = cv::imread("image.png");               //  rows x cols x 3
    
    //  some matrix M, that modifies each pixel
    cv::Mat M = (cv::Mat_<float>(3, 3) << 0,  0,  0, 
                                          0, .5,  0, 
                                          0,  0, .5);  //  3 x 3
    
    //  remember old dimension
    uint8_t prevChannels = I.channels;                 
    uint32_t prevRows = I.rows;                        
    
    //  reshape I
    uint32_t newRows = I.rows * I.cols;                
    I = I.reshape(1, newRows);                         //  (rows * cols) x 3
    
    //  compute J
    cv::Mat J = I * M;                                 //  (rows * cols) x 3
    
    //  reshape to original dimensions
    J = J.reshape(prevChannels, prevRows);             //  rows x cols x 3
    

    OpenCV 提供了O(1) 的整形操作。 因此性能完全取决于矩阵乘法,我希望它在计算机视觉库中尽可能高效。

    为了进一步提高性能,您可能想看看使用ocl 和gpu 模块的矩阵乘法。

    【讨论】:

      猜你喜欢
      • 2012-02-12
      • 1970-01-01
      • 1970-01-01
      • 2011-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-25
      相关资源
      最近更新 更多