電腦配置:html
操做系統:window 8.1ios
Matlab 2012a安裝路徑:D:\Program Files\MATLAB\R2012ac++
VS2010 :編程
OpenCV 2.4.3:D:\Program Files\opencvapi
補充說明:app
在配置前,先檢查一下系統變量:ide
1.若缺乏系統變量(該路徑必須添加!!!):函數
D:\Program Files\MATLAB\R2012a\runtime\win64工具
致使結果:程序沒法正常啓動0x000007b。請單擊「肯定」關閉應用程序測試
注意變量配置後記得重啓纔會生效,並且添加路徑要在英文符號下加入」 ; 」,末尾不須要加分號!!!!
2.其餘變量:可加可不加,經驗證不會影響結果!!!
(1)用戶變量:
D:\Program Files\MATLAB\R2012a\bin\win64
D:\Program Files\MATLAB\R2012a\runtime\win64
(2)系統變量:
D:\Program Files\MATLAB\R2012a\bin\win64
本文轉自博客:http://www.cnblogs.com/newpanderking/articles/4057977.html
一、背景
衆所周知,matlab在處理矩陣、數學計算、計算機仿真、圖像處理等方面有着 c c++無可比擬的優點,可是作成系統供使用時,又顯得過於粗糙,爲了使用起來高大上,計算起來有簡單,方便。無疑,c++ 與matlab混合編程將會使很是靠譜的選擇。
這裏暫且不論所謂的matlab效率低,c/c++效率高的問題,自我感受,以我目前編碼的功底,所編寫的代碼的效率遠遠不及matlab提供的代碼的效率。除非你是大牛,或者你是人云亦云,因此能用matlab混合c++編碼仍是很不錯的選擇,話很少說,咱們開始討論正題。
二、我使用的版本是matlab2012與vs2010混合編程的。
軟件的下載這裏就很少說了,我相信看這篇教程的你,這兩個軟件已經安裝的妥穩當當的了。
這裏我選用網上經常使用來作例子的matlab代碼作測試,spline.m,該文件位於
D:\Program Files\MATLAB\R2012a\toolbox\matlab\polyfun
固然該文件中依賴調用另外一個文件chckxy.m,該文件也在這條路徑下。找到後複製到matlab的工做目錄下。
這裏爲了方便提供兩個文件的代碼:
spline.m
1 function output = spline(x,y,xx) 2 %SPLINE Cubic spline data interpolation. 3 % PP = SPLINE(X,Y) provides the piecewise polynomial form of the 4 % cubic spline interpolant to the data values Y at the data sites X, 5 % for use with the evaluator PPVAL and the spline utility UNMKPP. 6 % X must be a vector. 7 % If Y is a vector, then Y(j) is taken as the value to be matched at X(j), 8 % hence Y must be of the same length as X -- see below for an exception 9 % to this. 10 % If Y is a matrix or ND array, then Y(:,...,:,j) is taken as the value to 11 % be matched at X(j), hence the last dimension of Y must equal length(X) -- 12 % see below for an exception to this. 13 % 14 % YY = SPLINE(X,Y,XX) is the same as YY = PPVAL(SPLINE(X,Y),XX), thus 15 % providing, in YY, the values of the interpolant at XX. For information 16 % regarding the size of YY see PPVAL. 17 % 18 % Ordinarily, the not-a-knot end conditions are used. However, if Y contains 19 % two more values than X has entries, then the first and last value in Y are 20 % used as the endslopes for the cubic spline. If Y is a vector, this 21 % means: 22 % f(X) = Y(2:end-1), Df(min(X))=Y(1), Df(max(X))=Y(end). 23 % If Y is a matrix or N-D array with SIZE(Y,N) equal to LENGTH(X)+2, then 24 % f(X(j)) matches the value Y(:,...,:,j+1) for j=1:LENGTH(X), then 25 % Df(min(X)) matches Y(:,:,...:,1) and Df(max(X)) matches Y(:,:,...:,end). 26 % 27 % Example: 28 % This generates a sine-like spline curve and samples it over a finer mesh: 29 % x = 0:10; y = sin(x); 30 % xx = 0:.25:10; 31 % yy = spline(x,y,xx); 32 % plot(x,y,'o',xx,yy) 33 % 34 % Example: 35 % This illustrates the use of clamped or complete spline interpolation where 36 % end slopes are prescribed. In this example, zero slopes at the ends of an 37 % interpolant to the values of a certain distribution are enforced: 38 % x = -4:4; y = [0 .15 1.12 2.36 2.36 1.46 .49 .06 0]; 39 % cs = spline(x,[0 y 0]); 40 % xx = linspace(-4,4,101); 41 % plot(x,y,'o',xx,ppval(cs,xx),'-'); 42 % 43 % Class support for inputs x, y, xx: 44 % float: double, single 45 % 46 % See also INTERP1, PCHIP, PPVAL, MKPP, UNMKPP. 47 48 % Carl de Boor 7-2-86 49 % Copyright 1984-2010 The MathWorks, Inc. 50 % $Revision: 5.18.4.6 $ $Date: 2010/09/02 13:36:29 $ 51 52 53 % Check that data are acceptable and, if not, try to adjust them appropriately 54 [x,y,sizey,endslopes] = mychckxy(x,y); 55 n = length(x); yd = prod(sizey); 56 57 % Generate the cubic spline interpolant in ppform 58 59 dd = ones(yd,1); dx = diff(x); divdif = diff(y,[],2)./dx(dd,:); 60 if n==2 61 if isempty(endslopes) % the interpolant is a straight line 62 pp=mkpp(x,[divdif y(:,1)],sizey); 63 else % the interpolant is the cubic Hermite polynomial 64 pp = pwch(x,y,endslopes,dx,divdif); pp.dim = sizey; 65 end 66 elseif n==3&&isempty(endslopes) % the interpolant is a parabola 67 y(:,2:3)=divdif; 68 y(:,3)=diff(divdif')'/(x(3)-x(1)); 69 y(:,2)=y(:,2)-y(:,3)*dx(1); 70 pp = mkpp(x([1,3]),y(:,[3 2 1]),sizey); 71 else % set up the sparse, tridiagonal, linear system b = ?*c for the slopes 72 b=zeros(yd,n); 73 b(:,2:n-1)=3*(dx(dd,2:n-1).*divdif(:,1:n-2)+dx(dd,1:n-2).*divdif(:,2:n-1)); 74 if isempty(endslopes) 75 x31=x(3)-x(1);xn=x(n)-x(n-2); 76 b(:,1)=((dx(1)+2*x31)*dx(2)*divdif(:,1)+dx(1)^2*divdif(:,2))/x31; 77 b(:,n)=... 78 (dx(n-1)^2*divdif(:,n-2)+(2*xn+dx(n-1))*dx(n-2)*divdif(:,n-1))/xn; 79 else 80 x31 = 0; xn = 0; b(:,[1 n]) = dx(dd,[2 n-2]).*endslopes; 81 end 82 dxt = dx(:); 83 c = spdiags([ [x31;dxt(1:n-2);0] ... 84 [dxt(2);2*(dxt(2:n-1)+dxt(1:n-2));dxt(n-2)] ... 85 [0;dxt(2:n-1);xn] ],[-1 0 1],n,n); 86 87 % sparse linear equation solution for the slopes 88 mmdflag = spparms('autommd'); 89 spparms('autommd',0); 90 s=b/c; 91 spparms('autommd',mmdflag); 92 93 % construct piecewise cubic Hermite interpolant 94 % to values and computed slopes 95 pp = pwch(x,y,s,dx,divdif); pp.dim = sizey; 96 97 end 98 99 if nargin==2, output = pp; else output = ppval(pp,xx); end
chckxy.m
1 function [x,y,sizey,endslopes] = mychckxy(x,y) 2 %CHCKXY check and adjust input for SPLINE and PCHIP 3 % [X,Y,SIZEY] = CHCKXY(X,Y) checks the data sites X and corresponding data 4 % values Y, making certain that there are exactly as many sites as values, 5 % that no two data sites are the same, removing any data points that involve 6 % NaNs, reordering the sites if necessary to ensure that X is a strictly 7 % increasing row vector and reordering the data values correspondingly, 8 % and reshaping Y if necessary to make sure that it is a matrix, with Y(:,j) 9 % the data value corresponding to the data site X(j), and with SIZEY the 10 % actual dimensions of the given values. 11 % This call to CHCKXY is suitable for PCHIP. 12 % 13 % [X,Y,SIZEY,ENDSLOPES] = CHCKXY(X,Y) also considers the possibility that 14 % there are two more data values than there are data sites. 15 % If there are, then the first and the last data value are removed from Y 16 % and returned separately as ENDSLOPES. Otherwise, an empty ENDSLOPES is 17 % returned. This call to CHCKXY is suitable for SPLINE. 18 % 19 % See also PCHIP, SPLINE. 20 21 % Copyright 1984-2011 The MathWorks, Inc. 22 23 % make sure X is a vector: 24 if length(find(size(x)>1))>1 25 error(message('MATLAB:chckxy:XNotVector')) 26 end 27 28 % ensure X is real 29 if any(~isreal(x)) 30 error(message('MATLAB:chckxy:XComplex')) 31 end 32 33 % deal with NaN's among the sites: 34 nanx = find(isnan(x)); 35 if ~isempty(nanx) 36 x(nanx) = []; 37 warning(message('MATLAB:chckxy:nan')) 38 end 39 40 n=length(x); 41 if n<2 42 error(message('MATLAB:chckxy:NotEnoughPts')) 43 end 44 45 % re-sort, if needed, to ensure strictly increasing site sequence: 46 x=x(:).'; 47 dx = diff(x); 48 49 if any(dx<0), [x,ind] = sort(x); dx = diff(x); else ind=1:n; end 50 51 if ~all(dx), error(message('MATLAB:chckxy:RepeatedSites')), end 52 53 % if Y is ND, reshape it to a matrix by combining all dimensions but the last: 54 sizey = size(y); 55 56 57 while length(sizey)>2&&sizey(end)==1, sizey(end) = []; end 58 59 60 yn = sizey(end); 61 sizey(end)=[]; 62 yd = prod(sizey); 63 64 if length(sizey)>1 65 y = reshape(y,yd,yn); 66 else 67 % if Y happens to be a column matrix, change it to the expected row matrix. 68 if yn==1 69 yn = yd; 70 y = reshape(y,1,yn); 71 yd = 1; 72 sizey = yd; 73 end 74 end 75 76 % determine whether not-a-knot or clamped end conditions are to be used: 77 nstart = n+length(nanx); 78 if yn==nstart 79 endslopes = []; 80 elseif nargout==4&&yn==nstart+2 81 endslopes = y(:,[1 n+2]); y(:,[1 n+2])=[]; 82 if any(isnan(endslopes)) 83 error(message('MATLAB:chckxy:EndslopeNaN')) 84 end 85 if any(isinf(endslopes)) 86 error(message('MATLAB:chckxy:EndslopeInf')) 87 end 88 else 89 error(message('MATLAB:chckxy:NumSitesMismatchValues',nstart, yn)) 90 end 91 92 % deal with NaN's among the values: 93 if ~isempty(nanx) 94 y(:,nanx) = []; 95 end 96 97 y=y(:,ind); 98 nany = find(sum(isnan(y),1)); 99 if ~isempty(nany) 100 y(:,nany) = []; x(nany) = []; 101 warning(message('MATLAB:chckxy:IgnoreNaN')) 102 n = length(x); 103 if n<2 104 error(message('MATLAB:chckxy:NotEnoughPts')) 105 end 106 end
function [x,y,sizey,endslopes] = mychckxy(x,y) %CHCKXY check and adjust input for SPLINE and PCHIP % [X,Y,SIZEY] = CHCKXY(X,Y) checks the data sites X and corresponding data % values Y, making certain that there are exactly as many sites as values, % that no two data sites are the same, removing any data points that involve % NaNs, reordering the sites if necessary to ensure that X is a strictly % increasing row vector and reordering the data values correspondingly, % and reshaping Y if necessary to make sure that it is a matrix, with Y(:,j) % the data value corresponding to the data site X(j), and with SIZEY the % actual dimensions of the given values. % This call to CHCKXY is suitable for PCHIP. % % [X,Y,SIZEY,ENDSLOPES] = CHCKXY(X,Y) also considers the possibility that % there are two more data values than there are data sites. % If there are, then the first and the last data value are removed from Y % and returned separately as ENDSLOPES. Otherwise, an empty ENDSLOPES is % returned. This call to CHCKXY is suitable for SPLINE. % % See also PCHIP, SPLINE. % Copyright 1984-2011 The MathWorks, Inc. % make sure X is a vector: if length(find(size(x)>1))>1 error(message('MATLAB:chckxy:XNotVector')) end % ensure X is real if any(~isreal(x)) error(message('MATLAB:chckxy:XComplex')) end % deal with NaN's among the sites: nanx = find(isnan(x)); if ~isempty(nanx) x(nanx) = []; warning(message('MATLAB:chckxy:nan')) end n=length(x); if n<2 error(message('MATLAB:chckxy:NotEnoughPts')) end % re-sort, if needed, to ensure strictly increasing site sequence: x=x(:).'; dx = diff(x); if any(dx<0), [x,ind] = sort(x); dx = diff(x); else ind=1:n; end if ~all(dx), error(message('MATLAB:chckxy:RepeatedSites')), end % if Y is ND, reshape it to a matrix by combining all dimensions but the last: sizey = size(y); while length(sizey)>2&&sizey(end)==1, sizey(end) = []; end yn = sizey(end); sizey(end)=[]; yd = prod(sizey); if length(sizey)>1 y = reshape(y,yd,yn); else % if Y happens to be a column matrix, change it to the expected row matrix. if yn==1 yn = yd; y = reshape(y,1,yn); yd = 1; sizey = yd; end end % determine whether not-a-knot or clamped end conditions are to be used: nstart = n+length(nanx); if yn==nstart endslopes = []; elseif nargout==4&&yn==nstart+2 endslopes = y(:,[1 n+2]); y(:,[1 n+2])=[]; if any(isnan(endslopes)) error(message('MATLAB:chckxy:EndslopeNaN')) end if any(isinf(endslopes)) error(message('MATLAB:chckxy:EndslopeInf')) end else error(message('MATLAB:chckxy:NumSitesMismatchValues',nstart, yn)) end % deal with NaN's among the values: if ~isempty(nanx) y(:,nanx) = []; end y=y(:,ind); nany = find(sum(isnan(y),1)); if ~isempty(nany) y(:,nany) = []; x(nany) = []; warning(message('MATLAB:chckxy:IgnoreNaN')) n = length(x); if n<2 error(message('MATLAB:chckxy:NotEnoughPts')) end end
ps:說明下,因爲這兩個文件都是matlab的工具文件,因此chckxy.m在調用時,改了名字叫作mychckxy.m,相應的文件名字也須要改。
作一個簡單的測試,作一個調用:
clc; clear all; close all; x = 0:10; y = sin(x); xx = 0:.25:10; yy = spline(x,y,xx) plot(x,y,'o',xx,yy);
運行結果:
到此爲止,都是準備工做作,下面開始介紹如何在vs中調用spline函數。
1)在matlab中輸入命令 mbuild -setup , 運行結果以下圖所示, 按照提示選擇編譯器 vs2010.
mbuild -setup
而後鍵入:mex -setup 命令,運行結果以下圖所示,按照提示選擇編譯器 vs2010
mex -setup
而後在matlab命令窗口輸入:
mcc -W cpplib:libspline -T link:lib spline.m
spline是名字,會根據.m文件的不一樣而不一樣!!!
或者輸入:mcc -B csharedlib:name name.m
能夠獲得以下圖這些文件:
依然,其中的"libspline.dll"、"libspline.h"和"libspline.lib"這三個文件是咱們所需的。
2)打開vs2010建一個控制檯應用程序,能夠選擇一個空的控制檯應用程序。
建立程序以後把第一步中獲得的三個文件copy到工程中。
因爲個人電腦是win 7 64bit(win8 64bit),matlab是64bit,因此應該選擇x64,而不是win32平臺。
a)修改平臺參數,爲x64
生成 ---> 配置管理器
b)配置包含目錄與庫目錄
項目 ----> 屬性 ----> vc++目錄
包含目錄:
D:\Program Files\MATLAB\R2012a\extern\include
庫目錄:
D:\Program Files\MATLAB\R2012a\extern\lib\win64\microsoft
C1)配置附加依賴項
右鍵MatlabTest解決方案->屬性->連接器->輸入
在「附加依賴項中」中添加相應的靜態連接庫文件。對於須要添加的靜態庫文件的數量和名稱,根據須要添加。
libmx.lib
libeng.lib
libmex.lib
libmat.lib
…………
根據須要後續補上。
c2)配置附加依賴項 , 這裏根據項目的不一樣,依賴的文件不一樣,這裏測試依賴的是"mclmcrrt.lib"和"libspline.lib"這兩個lib,第一是庫lib,第二個是咱們生成的lib.文件。所依賴的lib文件在庫目錄已經說明了,
路徑爲:D:\Program Files\MATLAB\R2012a\extern\lib\win64\microsoft下。
這裏有兩種解決方案,第一種在vs中配置。
第一種在vs中配置。建議採用第二種方法!!!!由於第一種不一樣連接庫配置的lib會不同
項目 ----> 屬性 ----> 鏈接器 ----> 輸入
第二種方法是,在文件中直接引入lib文件。
作完以上工做後,咱們新建一個主函數做爲入口函數,具體測試代碼以下:
#include "libspline.h" //增長頭文件 #include <cmath> #include <iostream> #include <iomanip> using namespace std; #pragma comment(lib,"mclmcrrt.lib") #pragma comment(lib,"libspline.lib") int main() { //初始化lib(必須) if (!libsplineInitialize()) return -1; int i, j; double x[1][11], y[1][11]; for(i=0; i<11; i++) { x[0][i] = i; y[0][i] = sin(x[0][i]); } double xx[1][41]; for(i=0; i<41; i++) xx[0][i] = i*0.25; double yy[1][41]; mwArray mwX(1,11,mxDOUBLE_CLASS); mwArray mwY(1,11,mxDOUBLE_CLASS); mwArray mwXX(1,41,mxDOUBLE_CLASS); mwArray mwYY(1,41,mxDOUBLE_CLASS); mwX.SetData(*x, 11); mwY.SetData(*y, 11); mwXX.SetData(*xx, 41); mwYY.SetData(*yy, 41); spline(1, mwYY, mwX, mwY, mwXX); //調用spline cout<<"yy = "<<endl; i = 0; for(j = 0; j < 41; j++) { //Get第一個參數表示用1個下標訪問元素,j+1是列號(MATLAB下標從1開始,而C++從0開始,故作+1操做) yy[0][j] = mwYY.Get(1,j+1); cout<<setprecision(4)<<right<<setw(10)<<yy[0][j]; i++; if(i%7 == 0) cout<<endl; //換行 } cout<<endl; //終止調用 libsplineTerminate(); return 0; }
運行結果如圖:
比較這個結果與最開始咱們測試matlab運行的結果,測試經過。matlab配置完成。
ps說明:配置過程當中遇到的問題:
配置時常常遇到 LINK2019的錯誤。這種錯誤就是典型的lib缺失導入的問題。
main.obj : error LNK2019: 沒法解析的外部符號 mclGetMatrix_proxy,該符號在函數 "public: __cdecl mwArray::mwArray(unsigned __int64,unsigned __int64,enum mxClassID,enum mxComplexity)" (??0mwArray@@QEAA@_K0W4mxClassID@@W4mxComplexity@@@Z) 中被引用 1>main.obj : error LNK2019: 沒法解析的外部符號 mclcppGetLastError_proxy,該符號在函數 "public: static void __cdecl mwException::raise_error(void)" (?raise_error@mwException@@SAXXZ) 中被引用 1>main.obj : error LNK2019: 沒法解析的外部符號 mclcppCreateError_proxy,該符號在函數 "public: __cdecl mwException::mwException(void)" (??0mwException@@QEAA@XZ) 中被引用 1>main.obj : error LNK2019: 沒法解析的外部符號 ref_count_obj_addref_proxy,該符號在函數 "public: __cdecl mwException::mwException(class mwException const &)" (??0mwException@@QEAA@AEBV0@@Z) 中被引用 1>main.obj : error LNK2019: 沒法解析的外部符號 ref_count_obj_release_proxy,該符號在函數 "public: virtual __cdecl mwException::~mwException(void)" (??1mwException@@UEAA@XZ) 中被引用 1>main.obj : error LNK2019: 沒法解析的外部符號 error_info_get_message_proxy,該符號在函數 "public: virtual char const * __cdecl mwException::what(void)const " (?what@mwException@@UEBAPEBDXZ) 中被引用 1>main.obj : error LNK2019: 沒法解析的外部符號 array_ref_getV_int_proxy,該符號在函數 "public: class mwArray __cdecl mwArray::GetPromoted(unsigned __int64,...)" (?GetPromoted@mwArray@@QEAA?AV1@_KZZ) 中被引用 1>main.obj : error LNK2019: 沒法解析的外部符號 array_ref_set_numeric_mxDouble_proxy,該符號在函數 "public: void __cdecl mwArray::SetData(double *,unsigned __int64)" (?SetData@mwArray@@QEAAXPEAN_K@Z) 中被引用 1>main.obj : error LNK2019: 沒法解析的外部符號 array_ref_get_numeric_mxDouble_proxy,該符號在函數 "public: __cdecl mwArray::operator double(void)const " (??BmwArray@@QEBANXZ) 中被引用
這裏是由於缺乏:mclmcrrt.lib
#pragma comment(lib,"mclmcrrt.lib")
便可解決。