首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >同时对图像进行重新排序和旋转的高效方法

同时对图像进行重新排序和旋转的高效方法
EN

Stack Overflow用户
提问于 2015-08-18 05:02:56
回答 1查看 311关注 0票数 3

为了快速加载jpeg,我为turbojpeg实现了一个.mex-wrapper,以便高效地将(大的)jpeg读取到MATLAB中。对于4000x3000px的图像,实际解码只需要大约120ms(而不是5ms)。但是,像素排序是RGBRGBRGB...,而MATLAB需要一个W x H x 3矩阵,它在内存中是一个W*H*3数组,其中第一个WH项对应于红色,第二个WH项对应于绿色,最后一个WH项对应于蓝色。此外,图像围绕轴从左上角到右下角进行镜像。

重排循环的简单实现如下:

代码语言:javascript
复制
// buffer contains mirrored and scrambled output of turbojpe
// outImg contains image matrix for use in MATLAB
// imgSize is an array containing {H,W,3}
for(int j=0; j<imgSize[1]; j++) {
    for(int i=0; i<imgSize[0]; i++) {
        curIdx = j*imgSize[0] + i;
        curBufIdx = (i*imgSize[1] + j)*3;
        outImg[curIdx] = buffer[curBufIdx++];
        outImg[curIdx + imgSize[0]*imgSize[1] ] = buffer[curBufIdx++];
        outImg[curIdx + 2*imgSize[0]*imgSize[1] ] = buffer[curBufIdx];    
    }
}

它可以工作,但它需要大约120ms (不是20ms),大约与实际解码的时间一样长。关于如何让这段代码更有效率有什么建议吗?

由于一个bug,我更新了处理时间。

EN

回答 1

Stack Overflow用户

发布于 2015-08-18 06:55:50

编辑: turbojpeg 99%的C库将存储图像的行长,这意味着如果你从得到一个3xWH(一个二维数组),你可以把它当做一个3xWxH(上面预期的输入)。在这个表示中,像素读过然后向下读。你需要把它们读下来,然后在MATLAB中读懂。您还需要转换像素顺序(RGBRGBRGB...)到平面顺序(RRRR....GGGGG....BBBBB...)。解决方案是permute(reshape(I,3,W,H),[3 2 1])

在这种情况下,MATLAB的permute命令可能会比你在短时间内手工编写的任何东西都要快(至少比显示的循环快50% )。我通常会避开使用mexCallMATLAB的解决方案,但我认为这可能是一个例外。但是,输入的是mxArray,这可能不方便。无论如何,这里是如何做一个permute(I,[3 2 1])

代码语言:javascript
复制
#include "mex.h"

int computePixelCtoPlanarMATLAB(mxArray*& imgPermuted, const mxArray* img)
{
    mxArray *permuteRHSArgs[2];
    // img must be row-major (across first), pixel order (RGBRGBRGB...)
    permuteRHSArgs[0] = const_cast<mxArray*>(img);
    permuteRHSArgs[1] = mxCreateDoubleMatrix(1,3,mxREAL);

    // output is col-major, planar order (rows x cols x 3)
    double *p = mxGetPr(permuteRHSArgs[1]);
    p[0] = 3;
    p[1] = 2;
    p[2] = 1;

    return mexCallMATLAB(1, &imgPermuted, 2, permuteRHSArgs, "permute");
}

void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) {
    // do some argument checking first (not shown)
    // ...

    computePixelCtoPlanarMATLAB(plhs[0], prhs[0]);
}

或者在MATLAB中自己给permute(I,[3 2 1])打电话。

第一个从3xWH到3xWxH的reshape怎么样?只需告诉代码它实际上是3xWxH!reshape 不移动数据缓冲区--它只是告诉MATLAB将给定的数据缓冲区视为特定的大小。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32059654

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档