如何组合仅在声明的类型中有所不同的两个函数

时间:2014-02-26 22:36:04

标签: c++ matlab mex

我正在编写一个mex函数来从FLI相机中获取图像。图像可以具有不同的位深度(8位或16位),因此我必须编写两个仅在声明的类型上有所不同的函数。我的问题:我如何结合以下功能来消除尽可能多的代码重复?

mxArray* grabFrame16Bit(flidev_t device, long imageWidth, long imageHeight) {
    long imageSize = imageWidth*imageHeight;
    uint16_t *image = (uint16_t *) mxCalloc(imageSize, sizeof(uint16_t));
    int iRow, ind;
    for (iRow = 0; iRow < imageHeight; iRow++) {
        ind = iRow*imageWidth;
        fli::checkReturn(FLIGrabRow(device, image+ind, imageWidth),
                         "fliTestSnapMex:FLIGrabRow"); 
    }

    mxArray *outMat = mxCreateDoubleMatrix(imageWidth, imageHeight, mxREAL);
    double *imageOut = mxGetPr(outMat);
    int i;
    for (i = 0; i < imageSize; i++)
        imageOut[i] = (double) image[i];
    mxFree(image);
    image = NULL;
    return outMat;
}

mxArray* grabFrame8Bit(flidev_t device, long imageWidth, long imageHeight) {
    long imageSize = imageWidth*imageHeight;
    uint8_t *image = (uint8_t *) mxCalloc(imageSize, sizeof(uint8_t));
    int iRow, ind;
    for (iRow = 0; iRow < imageHeight; iRow++) {
        ind = iRow*imageWidth;
        fli::checkReturn(FLIGrabRow(device, image+ind, imageWidth),
                         "fliTestSnapMex:FLIGrabRow"); }

    mxArray *outMat = mxCreateDoubleMatrix(imageWidth, imageHeight, mxREAL);
    double *imageOut = mxGetPr(outMat);
    int i;
    for (i = 0; i < imageSize; i++)
        imageOut[i] = (double) image[i];
    mxFree(image);
    image = NULL;
    return outMat;
}

这里是我编写的一个自定义函数的声明,以及其他API函数,以防您不熟悉FLI API或MATLAB mex / mx API。

// allocates memory
void *mxCalloc(mwSize n, mwSize size);

// checks for an error
void fli::checkReturn(long returnCode, char * errorId); 

// grabs a row of the image
long FLIGrabRow(flidev_t device, void * buffer, size_t width); 

// creates a double matrix
mxArray *mxCreateDoubleMatrix(mwSize m, mwSize n, mxComplexity complexFlag); 

// gives a pointer to the data in the matrix
double *mxGetPr(const mxArray *pm); 

2 个答案:

答案 0 :(得分:2)

欢迎来到模板世界!

一种天真的方法是只替换所有类型的匹配项并将其替换为模板类型参数。

template <class T>
mxArray* grabFrame(flidev_t device, long imageWidth, long imageHeight) {
    long imageSize = imageWidth*imageHeight;
    T *image = (T*) mxCalloc(imageSize, sizeof(T));
    int iRow, ind;
    for (iRow = 0; iRow < imageHeight; iRow++) {
        ind = iRow*imageWidth;
        fli::checkReturn(FLIGrabRow(device, image+ind, imageWidth),
                         "fliTestSnapMex:FLIGrabRow"); 
    }

    mxArray *outMat = mxCreateDoubleMatrix(imageWidth, imageHeight, mxREAL);
    double *imageOut = mxGetPr(outMat[0]);
    int i;
    for (i = 0; i < imageSize; i++)
        imageOut[i] = (double) image[i];
    mxFree(image);
    image = NULL;
    return outMat;
}

由于模板参数的类型不能从函数参数中推导出来,因此必须在每次调用时明确指定它:

mxArray* array = grabFrame<uint8_t>(device, width, height);

编辑:你的代码没有return语句,所以我允许自己添加它。

答案 1 :(得分:1)

template<typename PixelType>
mxArray* grabFrame(flidev_t device, long imageWidth, long imageHeight) {
    long imageSize = imageWidth*imageHeight;
    PixelType *image = (PixelType *) mxCalloc(imageSize, sizeof(PixelType));
    int iRow, ind;
    for (iRow = 0; iRow < imageHeight; iRow++) {
        ind = iRow*imageWidth;
        fli::checkReturn(FLIGrabRow(device, image+ind, imageWidth),
                     "fliTestSnapMex:FLIGrabRow"); 
    }

    mxArray *outMat = mxCreateDoubleMatrix(imageWidth, imageHeight, mxREAL);
    double *imageOut = mxGetPr(outMat[0]);
    int i;
    for (i = 0; i < imageSize; i++)
        imageOut[i] = (double) image[i];
    mxFree(image);
    image = NULL;
}

电话

 grabFrame<uint8_t>(....)

 grabFrame<uint16_t>(...)