OpenCV中类似matlab的重塑的性能问题



我正在将Matlab代码翻译成OpenCV。该代码涉及对大型矩阵的大量重塑。由于matlab重塑与OpenCV不同,因此您不能只使用OpenCV重塑。原因如下:假设我们有一个 2x4x3 矩阵,如下所示:

a(:,:,1) =
     1     3     5     7
     2     4     6     8
a(:,:,2) =
     9    11    13    15
    10    12    14    16
a(:,:,3) =
    17    19    21    23
    18    20    22    24

当我们执行reshape(a,4,3,2)时,结果是

ans(:,:,1) =
     1     5     9
     2     6    10
     3     7    11
     4     8    12
ans(:,:,2) =
    13    17    21
    14    18    22
    15    19    23
    16    20    24

但是如果我们在OpenCV中执行类似的重塑,我们会得到

ans(:,:,1) =
     1     17   11
     5     21   15
     2     18   12
     6     22   16
ans(:,:,2) =
    9     3     19
    13    7     23
    10    4     20
    14    8     24

这是由于在OpenCV和Matlab中遍历矩阵的不同方式。Matlab 首先遍历列,然后遍历行和最后一个深度。OpenCV 首先遍历深度,然后遍历行和最后一列。所以我写了一个函数来对3D矩阵进行类似Matlab的重塑。首先,我将输入矩阵重塑为行矩阵。对于上面提到的矩阵,结果矩阵将被[1 2 3 ... 24]然后我将行矩阵重塑为所需的通道。但正如你所看到的,这段代码涉及大量创建辅助矩阵以及复制和转置,这对性能不利。

Mat matlab_reshape(const Mat &m, int new_row, int new_col, int new_ch)
{
    int old_row, old_col, old_ch;
    old_row = m.size().height;
    old_col = m.size().width;
    old_ch = m.channels();
    Mat m1 ( 1, new_row*new_col*new_ch, m.depth() );
    vector <Mat> p(old_ch);
    split(m,p);
    for ( int i=0; i<p.size(); ++i ){
        Mat t ( p[i].size().height, p[i].size().width, m1.type() );
        t = p[i].t();
        Mat aux = m1.colRange(i*old_row*old_col,(i+1)*old_row*old_col).rowRange(0,1);
        t.reshape(0,1).copyTo(aux);
    }
    vector <Mat> r(new_ch);
    for ( int i=0; i<r.size(); ++i ){
        Mat aux = m1.colRange(i*new_row*new_col,(i+1)*new_row*new_col).rowRange(0,1);
        r[i] = aux.reshape(0, new_col);
        r[i] = r[i].t();
    }
    Mat result;
    merge(r, result);
    return result;
} 

下面是一个示例:

Mat_ <Vec3b> m(2,4);
m(0,0) = Vec3b(1,9,17);
m(0,1) = Vec3b(3,11,19);
m(0,2) = Vec3b(5.1,13,21);
m(0,3) = Vec3b(7,15,23);
m(1,0) = Vec3b(2,10,18);
m(1,1) = Vec3b(4,12,20);
m(1,2) = Vec3b(6,14,22);
m(1,3) = Vec3b(8,16,24);
cout << m << endl;
cout << m.reshape(2,4) << endl;
cout << matlab_reshape(m,4,3,2) << endl;

[24700 X 10 X 1]尺寸的整形矩阵与[130 X 190 X 10]尺寸的矩阵的性能比较

MY_CODE      MATLAB
0.006222     0.000039 
0.006528     0.000036
0.006716     0.000042
0.006733     0.000035
0.006508     0.000031

我很感激任何使我的代码更快的建议。

黑白 MATLAB 和 Opencv 重塑的区别在于,MATLAB 读取src_vals列并按列填充列,但在 OpenCV 中,它读取src_vals行并填充行。

cv::Mat reshape(cv::Mat src, int cn, int rows, int cols)
{
    const std::vector<int> newshape = {cols, rows};
    cv::Mat result = src.reshape(cn, newshape).t();//OpenCV function reshape.
    return result;
}

相关内容

  • 没有找到相关文章

最新更新