c++ - 从 MATLAB 调用 c 函数?

标签 c++ c matlab image-processing mex

我想从 matlab 调用一个 c 函数,为此我尝试使用 MEX 编写一个包装函数。在编译时我得到 error C2109: 下标需要数组或指针类型 和错误 C2440:“函数”:无法从“double *”转换为“double” 任何人都可以帮助我在哪里做错了吗?

#include "mex.h"
#include "matrix.h"
#include "CVIPtoolkit.h"
#include "CVIPtools.h"
#include "CVIPmatrix.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>


void midd(double outdata, int type, int  height, int width){
     Image *outputImage;
     byte **output;
     int r,c;

     mexPrintf("type %d\n", type);
     mexPrintf("height %d\n", height);
     mexPrintf("width %d\n", width);

     outputImage=new_Image (PGM, GRAY_SCALE, 0, height,  width, CVIP_BYTE, REAL );
     outputImage = h_image(type, height,width);

     output = getData_Image(outputImage, 0);
     for(r=0; r < height; r++) {
            for(c=0; c < width; c++)
            {
                mexPrintf("type %d\n", type);
                mexPrintf("height %d\n", height);
                mexPrintf("width %d\n", width);

                outdata[r+height*c+height*width] =output[r][c];     /* passing data back to MATLAB variable from CVIPtools variable */
             }
         }     
 }


void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    double *outdata;
    int type, height, width;

   // double *indata = (double *)mxGetData(prhs[0]);

   type = mxGetScalar(prhs[0]);
   height = mxGetScalar(prhs[1]);
   width = mxGetScalar(prhs[2]);

   mexPrintf("type %d\n", type);
   mexPrintf("height %d\n", height);
   mexPrintf("width %d\n", width);

   plhs[0] = mxCreateDoubleMatrix(height,width,mxREAL);

   outdata = mxGetData(plhs[0]);
   midd(outdata, type, height, width);

}

我尝试调用的 c 函数如下:

#include "CVIPtoolkit.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>


Image *
h_image(int type, unsigned int height, unsigned int width){

    /* type = 1, Constant
     * type = 2, Fixed mask
     * type = 3, Gaussian
     */

    unsigned int r, c, hf_w = width/2, hf_h = height/2;
    Image *outimage;
    float **outdata, sum = 0.0, sigma, tmp1, tmp2, tmp;

    if (height < 3 || width < 3) {
        fprintf(stderr, "Masksize too small, at least 3x3\n");
        return (Image *)NULL;
    }

    outimage = new_Image(PGM, GRAY_SCALE, 1, height, width, CVIP_FLOAT, REAL);
    outdata = (float **)getData_Image(outimage, 0);

    switch (type) {
        case 1:
            for (r = 0; r < height; r++) 
                for (c = 0; c < width; c++) {
                    outdata[r][c] = 1.0;
                    sum += outdata[r][c];
                }
            break;
        case 2:
            for (r = 0; r < height; r++) 
                for (c = 0; c < width; c++) {
                    outdata[r][c] = 1.0;
                    sum += outdata[r][c];
                }
            outdata[height/2][width/2] = height * width;
            sum = sum - 1.0 + outdata[height/2][width/2];
            break;
        case 3:
            c = (width + height) /4;
            r = (width + height) /2;
            sigma = sqrt(c*c / (2 * log(2) + (r - 3) * log(3)));
            sigma = 1.0 / 2.0 /sigma/sigma;
            tmp = width * height;
            for (r = 0; r < height; r++) 
                for (c = 0; c < width; c++) {
                    tmp1 = (r-hf_h)*(r-hf_h); tmp2 = (c-hf_w)*(c-hf_w);
                    outdata[r][c] = tmp*exp(- (tmp1 + tmp2) * sigma);
                    sum += outdata[r][c];
                }
            break;
        default:
            fprintf(stderr, "Incorrect mask type number: %d\n", type);
            return (Image *)NULL;
    }

    return outimage;
}

最佳答案

在你的 main 函数中,outdata 是一个指向 double 的指针,但是你的函数 midd 接受了一个实际的 double 本身。这就是为什么您会收到该类型错误的原因。

只需更改您的函数声明,以便第一个输入接受指向 double 的指针:

void midd(double *outdata, int type, int  height, int width)
         //      ^^^^^^^^

小注

我质疑您将图像数据复制回 MEX 阵列:

outdata[r+height*c+height*width] =output[r][c];

您不需要 height*width 作为偏移量。 r + height*c 足以按列优先顺序访问单 channel 二维矩阵。如果你有一个多 channel 图像,你只需要偏移 height*width。该偏移量允许您访问其他 channel 中的图像数据...并且由于您只有单 channel 数据(看起来如此...),因此不需要此偏移量。

因此,您只需要做:

outdata[r + height*c] = output[r][c];

如果您不这样做,我怀疑您最终会遇到段错误,因为您最终会访问您不允许访问的内存部分。


此外,一旦您完全测试了您的代码,就摆脱 mexPrintf 语句。它会不必要地用打印消息淹没您的命令提示符,因为您将它放在嵌套的 for 循环中。我怀疑您这样做是为了调试,这完全没问题,但我建议您将 MEX 函数附加到实际的调试器并正确调试您的代码,而不是打印语句。

请参阅我关于如何在此处进行设置的帖子:Preventing a MEX file from crashing in MATLAB

关于c++ - 从 MATLAB 调用 c 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33470469/

相关文章:

c++ - 为什么shrink_to_fit(如果请求得到满足)会导致重新分配?

c++ - printf ("... %c ...",'\0' ) 和家人——会发生什么?

c - 在内存中(在后台)创建结构体时的操作顺序是什么?

c - 关于使用 C 程序将 csv 文件转换为特定格式

matlab - 如何向量化二次型 (x' * A * x) 的求值?

c++ - 为什么我的cin循环永远不会结束?

c - makefile - 如何从变量中排除文件扩展名后缀

c - 如何在c/matlab中显示8位256x256数组?

python - Matlab中的长度函数到python

c++ - "undefined behaviour"是否扩展到编译时?