我有一个2D矩阵,我希望以下面的方式有效地将其值垂直复制到一维数组。
Matrice(3x3)
[1 2 3;
4 5 6;
7 8 9]
myarray:
{1,4,7,2,5,8,3,6,9}
对于1000x750x3图像,蛮力需要0.25秒。我不想使用向量,因为我将myarray
给另一个函数(我没有写这个函数)作为输入。那么,我可以使用c ++或opencv函数吗?请注意,我正在使用opencv库。
将矩阵复制到数组也没关系,我可以先对Mat进行转置,然后将其复制到数组中。
答案 0 :(得分:2)
cv::Mat transposed = myMat.t();
uchar* X = transposed.reshape(1,1).ptr<uchar>(0);
或
int* X = transposed.reshape(1,1).ptr<int>(0);
取决于您的矩阵类型。它可能会复制数据。
答案 1 :(得分:1)
您可以进行优化以使其更加缓存友好,即您可以按块进行复制,跟踪myArray中数据应该到达的位置。关键是,您使用暴力方法很可能会使每个对矩阵的访问都脱离缓存,从而产生巨大的性能影响。因此,考虑缓存行大小最好复制垂直/水平。
请参阅bbelow的想法(我没有对它进行测试,因此它很可能存在错误,但它应该明确这个想法)。
size_t cachelinesize = 128/sizeof(pixel); // assumed cachelinesize of 128 bytes
struct pixel
{
char r;
char g;
char b;
};
array<array<pixel, 1000>, 750> matrice;
vector<pixel> vec(1000*750);
for (size_t row = 0; row<matrice.size; ++row)
{
for (size_t col = 0; col<matrice[0].size; col+=cachelinesize)
{
for (size_t i = 0; i<cachelinesize; ++i)
{
vec[row*(col+i)]=matrice[row][col+i]; // check here, if right copy order. I didn't test it.
}
}
}
答案 2 :(得分:0)
如果在垂直分配/查询之前使用矩阵,则可以在点击列的每个元素时缓存必要的列。
//Multiplies and caches
doCalcButCacheVerticalsByTheWay(myMatrix,calcType,myMatrix2,cachedColumns);
instead of
doCalc(myMatrix,calcType,myMatrix2); //Multiplies
then use it like this:
...
tmpVariable=cachedColumns[i];
...
例如,upper函数将矩阵与另一个矩阵相乘,然后当到达必要的列时,会发生缓存到临时数组中,以便稍后以连续的顺序访问它的元素。
答案 3 :(得分:0)
我认为Mat :: reshape就是你想要的。它不会复制数据。