1. 程式人生 > >matlab+opencv混編處理高光譜資料

matlab+opencv混編處理高光譜資料

之前介紹瞭如何在c++裡呼叫matlab庫函式讀取.mat檔案,這裡介紹如何將完整的c++檔案模組化為matlab可以呼叫的函式。
這個的好處是可以利用matlab方便的資料讀寫功能以及後續的繪圖功能,同時主體部分呼叫opencv 高效的c++程式碼。
我用的是matlab2016+visual stdio 2010 + opencv 2.4.9。因為opencv 2.4.9之後的版本不支援visual stdio 2010,請下載vs2015。

1.把opencv庫增加到## 標題 ##環境變數

把opencv2.4.9解壓到F:\1(自己設定)資料夾,在環境變數里加入如下語句
F:\1\opencv\build\x64\vc10\bin;
其中vc10與vs2010相對應,其它版本請選擇相應版本。

2.mex - setup

在matlab裡輸入 mex - setup然後點選選擇mex -setup C++ 把vs2010設定為編譯器。
這裡寫圖片描述

3.編譯.mexw64檔案

.mexw64檔案就相當於matlab函式,輸入和輸出都是matlab資料型別,但是執行的程式碼是自己寫的c++程式碼,效率更高。

clear all;    
is_64bit = strcmp(computer,'MACI64') || strcmp(computer,'GLNXA64') || strcmp(computer,'PCWIN64');  
out_dir='./';  
IE:\Matopencv
\build\include -IE:\Matopencv\build\include\opencv -IE:\Matopencv\build\include\opencv2'; CPPFLAGS = ' -O -DNDEBUG -I.\ -IF:\1\opencv\build\include -IF:\1\opencv\build\include\opencv -IF:\1\opencv\build\include\opencv2'; % your OpenCV "include" path LDFLAGS = ' -LF:\1\opencv\build\x64\vc10\lib'; LIBS = ' -lopencv_core249 -lopencv_highgui249 -lopencv_video249 -lopencv_imgproc249'; if is_64bit CPPFLAGS = [
CPPFLAGS ' -largeArrayDims']; end compile_files = { 'hyper_lsc_demo.cpp' }; for k = 1 : length(compile_files) str = compile_files{k}; fprintf('compilation of: %s\n', str); str = [str ' -outdir ' out_dir CPPFLAGS LDFLAGS LIBS]; args = regexp(str, '\s+', 'split'); mex(args{:}); end fprintf('Congratulations, compilation successful!!!\n');

4.介面函式

#include "mex.h"
#include "cv.h"
#include <opencv2/opencv.hpp>
#include <iostream>
#include <fstream>
#include <vector>
#include "lsc.h"
using namespace cv;
using namespace std;

void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
{
    const size_t *size;
    size = mxGetDimensions(prhs[0]);
    int m_height = *size;
    int m_width = *(size+1);
    int m_channels = *(size+2);
    int numberOfElements = mxGetNumberOfElements(prhs[0]);
    int m_imgSize = m_height*m_width;
    mexPrintf( " %d %d %d /n",m_height,m_width,m_channels);
    double *pMatl = (double *) mxGetPr(prhs[0]);

    Mat Im(m_imgSize, m_channels, CV_64F);
    for( int x = 0; x < m_width; x++ )
    {
        for( int y = 0; y < m_height; y++ )
        {
            int i = y*m_width+x;
            double *p = Im.ptr<double>(i);
            for( int j = 0; j < m_channels; j++ )
            {
                p[j] = pMatl[ j*m_imgSize+m_height*x+y ];
            }
        }
    }





    mexPrintf( " asdasd /n");
    size_t dims[3]={m_height,m_width,m_channels};
    plhs[0] = mxCreateNumericArray(3,dims,mxDOUBLE_CLASS,mxREAL);
    mexPrintf( " asdasd1 /n");
    double *pOutMatl = mxGetPr(plhs[0]);
    for( int x = 0; x < m_width; x++ )
    {
        for( int y = 0; y < m_height; y++ )
        {
            int i = y*m_width+x;
            double *p = Im.ptr<double>(i);
            for( int j = 0; j < m_channels; j++ )
            {
                pOutMatl[ j*m_imgSize+m_height*x+y ] = p[j];
            }
        }
    }
    mexPrintf( " asdasd2 /n");


}