2

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

M是一个3x3矩阵。

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

即如果v1(r1,g1,b1)I的一个元素,而v2(r2,g2,b2)是其对应的J元素,那么v2 = v1 * M(这是一个向量矩阵乘积,而不是一个 per-元积)。

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

感谢您的帮助。

4

1 回答 1

4

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

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

想法是将每个逐像素操作p i ' · 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)的整形操作。因此性能完全取决于矩阵乘法,我希望它在计算机视觉库中尽可能高效。

To further enhance performance, you might want to take a look at matrix multiplication using the ocl and gpu modules.

于 2013-05-22T09:52:06.927 回答