Matlab C/C++混合编程实例学习
2015-03-15 16:25
501 查看
在某些情况下,我们需要使用Matlab C/C++混合编程的方法,或达到提高Matlab运行效率,或解决内存不足等问题。推荐阅读Matlab C/C++, Fortran, and Python API Reference,在阅读这篇手册的时候,我们可以重点关注如下一些api:
mexFunction,void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
mxGetData
mxGetPr
mxGetScalar
mxGetNumberOfDimensions
mxGetDimensions
mxGetNumberOfElements
mxCalloc
mxFree
mxCreateNumericMatrix
mxSetData
mxSetPr
mxSetDimensions
mxClassID
mxGetClassID
mexAtExit
mexPrintf
mexErrMsgIdAndTxt
掌握好这几个典型的api,基本上就可以开始享受matlab混合编程的乐趣了。不同于冗长的API讲解,ispforfun在这里提供一个干活,供大家理解这些api。
代码功能描述:对输入像素进行Gamma矫正。数学原理:
代码如下:
调用方法一:
调用方法二:
无论采用哪种调用方法,用
mexFunction,void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
mxGetData
mxGetPr
mxGetScalar
mxGetNumberOfDimensions
mxGetDimensions
mxGetNumberOfElements
mxCalloc
mxFree
mxCreateNumericMatrix
mxSetData
mxSetPr
mxSetDimensions
mxClassID
mxGetClassID
mexAtExit
mexPrintf
mexErrMsgIdAndTxt
掌握好这几个典型的api,基本上就可以开始享受matlab混合编程的乐趣了。不同于冗长的API讲解,ispforfun在这里提供一个干活,供大家理解这些api。
代码功能描述:对输入像素进行Gamma矫正。数学原理:
代码如下:
/* * isp_gamma_correction.c *----------------------------- * Created by ispforfun * * The calling syntax is: * out_img = isp_gamma_correction(in_img, gamma_param, in_img_bps, out_img_bps) * * Revision: 1.0 */ #include <stdlib.h> #include <stdio.h> #include <string.h> #include <math.h> #include "matrix.h" #include "mex.h" #define GAMMA_LUT_SIZE 512 static void initial_Gamma_LUT(unsigned short * lut_array, int out_img_bps, double gamma_param) { int i; int out_img_max_level = (1 << out_img_bps) - 1; double output; for (i = 0; i < GAMMA_LUT_SIZE; i++){ output = pow(((double)i)/GAMMA_LUT_SIZE, gamma_param); lut_array[i] = (unsigned short)(output * out_img_max_level); } } /* mexFunction is the gateway routine for the MEX-file. */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { mxClassID in_param_category; unsigned short *pInputImg; unsigned char *pOutputImgUint8; unsigned short *pOutputImgUint16; unsigned short in_pix, out_pix; int in_pix_integer_part, in_pix_frac_part; unsigned short lut_0, lut_1; mwSize input_img_dims; const mwSize *input_img_dims_array; unsigned short *LutArray; int in_img_bps, out_img_bps; double gamma_param; int i, num_pix_elements, in_pix_shift_cnt; if (nrhs != 4){ mexErrMsgIdAndTxt("Matlab:isp_gamma_correction:the input parameters are not correct", "out_img = isp_gamma_correction(in_img, gamma_param, in_img_bps, out_img_bps)"); return; } in_param_category = mxGetClassID(prhs[0]); if (in_param_category != mxUINT16_CLASS){ mexErrMsgIdAndTxt("Matlab:isp_gamma_correction:the input image's data type should be uint16", "uin16 input image required."); } else { pInputImg = (unsigned short *)mxGetData(prhs[0]); //mexPrintf("Image width = %d\n", mxGetN(prhs[0])); //mexPrintf("Image height = %d\n", mxGetM(prhs[0])); //mexPrintf("Image size = %d\n", mxGetNumberOfElements(prhs[0])); gamma_param = mxGetScalar(prhs[1]); in_img_bps = (int)mxGetScalar(prhs[2]); out_img_bps = (int)mxGetScalar(prhs[3]); // ... input_img_dims = mxGetNumberOfDimensions(prhs[0]); mexPrintf("Image has %d dimensions\n", input_img_dims); input_img_dims_array = mxGetDimensions(prhs[0]); for (i = 0; i < input_img_dims; i++){ mexPrintf("Image's dim[%d] = %d\n", i, input_img_dims_array[i]); } num_pix_elements = (int)mxGetNumberOfElements(prhs[0]); mexPrintf("Image's size = %d\n", num_pix_elements); if (out_img_bps == 8){ pOutputImgUint8 = (unsigned char *)mxCalloc(num_pix_elements, sizeof(unsigned char)); } else { pOutputImgUint16 = (unsigned short *)mxCalloc(num_pix_elements, sizeof(unsigned short)); } LutArray = (unsigned short *)mxCalloc(GAMMA_LUT_SIZE, sizeof(unsigned short)); initial_Gamma_LUT(LutArray, out_img_bps, gamma_param); in_pix_shift_cnt = in_img_bps - 9; if (in_pix_shift_cnt >= 0){ for (i = 0; i < num_pix_elements; i++){ in_pix = pInputImg[i]; // debug pixel is (242, 1028) //if ( i == (241*input_img_dims_array[0] + 1027) ){ // mexPrintf("Debug: in pixel = %d\n", in_pix); //} in_pix_integer_part = in_pix >> in_pix_shift_cnt; in_pix_frac_part = in_pix - (in_pix_integer_part << in_pix_shift_cnt); lut_0 = LutArray[in_pix_integer_part]; if (in_pix_integer_part >= (GAMMA_LUT_SIZE - 1)){ lut_1 = (1 << out_img_bps) - 1; } else { lut_1 = LutArray[in_pix_integer_part + 1]; } out_pix = (lut_0 * ((int)((1 << in_pix_shift_cnt) - in_pix_frac_part)) + lut_1 * in_pix_frac_part) >> in_pix_shift_cnt; //if ( i == (241*input_img_dims_array[0] + 1027) ){ // mexPrintf("Debug: out pixel = %d\n", out_pix); //} if (out_img_bps == 8) { if (out_pix > 255){ out_pix = 255; } pOutputImgUint8[i] = (unsigned char)out_pix; } else { pOutputImgUint16[i] = (unsigned short)out_pix; } } } else { } mxFree(LutArray); if (out_img_bps == 8){ plhs[0] = mxCreateNumericMatrix(0, 0, mxUINT8_CLASS, mxREAL); mxSetData(plhs[0], (void *)pOutputImgUint8); } else { plhs[0] = mxCreateNumericMatrix(0, 0, mxUINT16_CLASS, mxREAL); mxSetData(plhs[0], (void *)pOutputImgUint16); } mxSetDimensions(plhs[0], input_img_dims_array, input_img_dims); } }
调用方法一:
demo_img = isp_gamma_correction(demo_img, 0.45, 14, 8);
调用方法二:
demo_img_R = isp_gamma_correction(demo_img(:,:,1), 0.45, 14, 8); demo_img_G = isp_gamma_correction(demo_img(:,:,2), 0.45, 14, 8); demo_img_B = isp_gamma_correction(demo_img(:,:,3), 0.45, 14, 8); demo_img = cat(3, demo_img_R, demo_img_G, demo_img_B);
无论采用哪种调用方法,用
figure; imshow(demo_img);都可以显示出Gamma校正以后的图像。
相关文章推荐
- C++&MATLAB混合编程之mwArray使用实例
- C++与Matlab混合编程
- 【混合编程实例】C/C++调用FORTRAN编写的DLL
- 基础知识(二)matlab与c++混合编程之经验笔记
- 64位系统vs2010平台下实现C++与matlab R2014混合编程方法示例
- matlab c++ 混合编程初始设置
- matlab和c++混合编程---Mex结构和mexFunction参数传递
- VC与Matlab混合编程之调用动态链接库dll(C++)——<二>
- matlab c++ 混合编程初始设置
- C++学习之编程实例
- [改写] matlab转C/C++ 的混合编程 (beta版)
- 【Matlab学习笔记】【编程实例】二(将两幅灰度图片调整成相同的尺寸,然后左右拼接到一起)
- Matlab混合编程之C++SL(C++篇)
- 混合编程---c++调用matlab生成的dll----findCircles的应用
- C#与MATLAB混合编程实例
- 【Matlab学习笔记】【编程实例】一(将两幅图像调整为相同的尺寸大小)
- Matlab混合编程实例集
- Matlab与C++的混合编程
- Visual Studio 2008学习过程(之二)与MATLAB混合编程
- c++与matla混合编程之一---调用matlab工具箱内的函数