基於Matlab Coder將matlab程式碼轉換成c程式碼
最近在做訊號處理相關的功能,首先在matlab上做模擬,之後使用c/c++實現,然後嘗試使用Matlab Coder做轉換功能。
參考:
基於MATLAB Coder將matlab程式碼轉換成C程式碼
官網視訊講解
matlab呼叫c/c++程式碼
特此感謝!
一、概念及開發流程
MATLAB Coder可以從MATLAB程式碼生成獨立的、可讀性強、可移植的C/C++程式碼。
通俗地說,就是將寫好的matlab功能模組程式碼轉換為c/c++程式碼,然後我們在此基礎上進行改進。
本文開發環境:Win10 64、VS2015、Matlab R2016A。
開發流程:使用MATLAB Coder產生C程式碼的3個步驟:
- 開發實現特定演算法功能的MATLAB程式碼及其測試檔案
- 檢查MATLAB程式碼的相容性,確保MATLAB程式碼中的語句都能被轉換成C程式碼(有些matlab程式碼語句並不能生成c/c++程式碼,例如matlab中的imread、imshow、plot等函式)
- 利用MATLAB Coder生成c/c++程式碼,並在VS2015中驗證。
二、實踐測試
參考的文章中給出了功能模組程式碼與測試程式碼分離的思想,因此本文借鑑這種思想,進行實踐測試。
當然功能模組a.m檔案可以作為b.m檔案的呼叫,在編譯時兩個都要選中進行編譯(可以理解為依賴),不過本文暫時不涉及該功能的實現。
2.1 Matlab功能模組程式碼及其測試程式碼
myfft.m
對輸入的資料去除直流分量並進行FFT。其中,%#codegen用來防止出現警告錯誤
%#codegen
function B = myfft(v1,N)
v1=v1 - mean(v1);
B = fft(v1,N);
test_main.m
產生資料集並測試
f=100; %訊號頻率Hz
Fs=1000; %取樣頻率
N=256; %取樣點數
t=(0:N-1)/Fs; %取樣時間s
S=1000*sin(2*pi*f*t)+20*randn(size(t)); %訊號取樣值
%B = meanVal(S,N)
B = myfft(S,N);
f =((-N/2):(N/2-1))*Fs/N;
plot(abs(B))
title('Amplitude Spectrum of S')
xlabel('f (Hz)')
ylabel('|P1(f)|')
matlab輸出:
f = (N-1)Fs/N = 261000/256=100Hz。
2.2 利用MATLAB Coder生成c/c++程式碼
-
在命令視窗,輸入
mex -setup
,選中一個存在的編譯器,筆者這裡自帶了一個c編譯器,讀者也可以切換為c++編譯器(輸入mex -setup C++
)。
-
在命令視窗輸入coder(圖形介面),回車,彈出MATLAB Coder Project對話方塊(或在matlab軟體的介面中點選
MatLab Coder
圖示)。
(1)在Select模組中選擇我們想要編譯的功能模組myfft.m
(2)點選Next
上圖紅色方框處也可以繼續新增功能模組的.m檔案。
(3)點選Next,進入Define Input Types介面。輸入test_main.m測試檔案,點選Autodefine Input Types按鈕,從而使得matlab能自動檢測出功能模組函式的介面變數的維度和型別。
(4)點選Next,點選check for issues按鈕。
(5)點選Next,點選Generate按鈕,生成了C/C++程式碼。
生成成功後如下圖,可以在lib檔案下檢視到該檔案。
2.3 VS2015驗證
利用VS2015在lib同級目錄下的資料夾libvs中建立工程myfftprj,將所有的.c .h匯入工程。
由於物理路徑的關係,修改當前工程標頭檔案路徑即可。
我們發現工程中輸入例項輸入為空,因此根據test_main.m檔案需要進行修改。
/*
* Arguments : double result[256]
* Return Type : void
*/
static void argInit_1x256_real_T(double result[256])
{
int idx1;
const double pi = 3.141592653589793;
const double Fs = 1000; //取樣頻率
/* Loop over the array to initialize each element. */
for (idx1 = 0; idx1 < 256; idx1++) {
/* Set the value of the array element.
Change this value to the value that the application requires. */
double t = idx1 / Fs;
result[idx1] = 100 * sin(2 * pi * 100 * t);;//argInit_real_T()
}
}
同時輸入引數N也要進行適當修正,新增<stdio.h>
和getchar()等輔助列印函式。
這裡需要注意的是,生成的c++程式碼輸出變數是根據實際輸出決定的一個結構體型別變數,我們要在理解該結構體的基礎上進行除錯及列印。
比如當輸出複數時,型別為emxArray_creal_T
,當輸出實數時,型別為emxArray_real_T
。
程式碼:
/* Include Files */
#include "../rt_nonfinite.h"
#include "../myfft.h"
#include "main.h"
#include "../myfft_terminate.h"
#include "../myfft_emxAPI.h"
#include "../myfft_initialize.h"
#include <stdio.h>
/* Function Definitions */
void printArr(emxArray_creal_T *arr, int size)
{
for (int i = 0; i < size; i++)
{
printf("%4d %8.4f %8.4f \n", i, (arr->data[i]).re, (arr->data[i]).im);
//printf("%4d %8.4f \n", i, arr->data[i]);
}
}
/* Function Declarations */
static void argInit_1x256_real_T(double result[256]);
static double argInit_real_T(void);
static void main_myfft(void);
/* Function Definitions */
/*
* Arguments : double result[256]
* Return Type : void
*/
static void argInit_1x256_real_T(double result[256])
{
int idx1;
const double pi = 3.141592653589793;
const double Fs = 1000; //取樣頻率
/* Loop over the array to initialize each element. */
for (idx1 = 0; idx1 < 256; idx1++) {
/* Set the value of the array element.
Change this value to the value that the application requires. */
double t = idx1 / Fs;
result[idx1] = 100 * sin(2 * pi * 100 * t);;//argInit_real_T()
}
}
/*
* Arguments : void
* Return Type : double
*/
static double argInit_real_T(void)
{
return 0.0;
}
/*
* Arguments : void
* Return Type : void
*/
static void main_myfft(void)
{
emxArray_creal_T *B;
double dv0[256];
emxInitArray_creal_T(&B, 2);
/* Initialize function 'myfft' input arguments. */
/* Initialize function input argument 'v1'. */
/* Call the entry-point 'myfft'. */
argInit_1x256_real_T(dv0);
myfft(dv0,256 , B); //argInit_real_T()
printArr(B, 256);
emxDestroyArray_creal_T(B);
}
/*
* Arguments : int argc
* const char * const argv[]
* Return Type : int
*/
int main(int argc, const char * const argv[])
{
(void)argc;
(void)argv;
/* Initialize the application.
You do not need to do this more than one time. */
myfft_initialize();
/* Invoke the entry-point functions.
You can call entry-point functions multiple times. */
main_myfft();
/* Terminate the application.
You do not need to do this more than one time. */
myfft_terminate();
getchar();
return 0;
}
輸出:
三、Matlab小技巧
- 不以科學計數法顯示(參考文章)
format short g
- c/c++生成.m檔案的demo (參考 matlab呼叫c/c++程式碼)
#include "mex.h"
//使用MEX必須包含的標頭檔案
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]){
mexPrintf("hello world\n");
}
mex hello.c
hello %指令碼執行
相關文章
- 使用MATLAB compiler將matlab程式轉成獨立應用程式exeMatlabCompile
- matlab程式碼轉exe可執行軟體Matlab
- 將 SQL轉換成 Laravel Query Builder 程式碼SQLLaravelUI
- python呼叫matlab程式,MATLAB 指令碼打包為 exe可執行程式PythonMatlab指令碼行程
- (Keras)基於深度學習SketchCode將線框原型圖轉換成HTML程式碼Keras深度學習原型HTML
- matlab版本轉換Matlab
- 如何在matlab程式碼中加一層分隔?Matlab
- MATLAB人工神經網路ANN程式碼Matlab神經網路
- 將ES6程式碼轉換為ES5程式碼
- 基於matlab的車牌識別(含子程式)Matlab
- 基於深度學習的車輛檢測系統(MATLAB程式碼,含GUI介面)深度學習MatlabGUI
- PSO-LSSVM演算法及其MATLAB程式碼演算法Matlab
- 使用 Babel 將基於 ES6 的 SAP UI5 的程式碼轉譯成傳統 JavaScript 程式碼BabelUIJavaScript
- 影像壓縮編碼碼matlab實現——變換編碼Matlab
- 基於YOLOv4的目標檢測系統(附MATLAB程式碼+GUI實現)YOLOMatlabGUI
- 評價模型TOPSIS與熵權法MATLAB程式碼模型熵Matlab
- 基於YOLOv5的目標檢測系統詳解(附MATLAB GUI版程式碼)YOLOMatlabGUI
- 玩轉matlab之一維 gauss 數值積分公式及matlab原始碼Matlab公式原始碼
- MATLAB生成.coe檔案和.mif檔案程式碼示例Matlab
- Matlab程式設計之——卷積神經網路CNN程式碼解析Matlab程式設計卷積神經網路CNN
- 矩陣LU分解---使用MATLAB和DEV-C++實現的程式碼過程矩陣MatlabdevC++
- 計算機視覺 | Matlab實現單目視覺里程計基於SURF特徵(程式碼類)計算機視覺Matlab特徵
- 基於MATLAB公式識別Matlab公式
- 量子圖形加密演算法的MATLAB程式碼實現加密演算法Matlab
- MATLAB實戰系列(十)-二維裝箱問題之BL法修正版(附MATLAB程式碼)Matlab
- 在matlab中如何將圖片(png和jpg)轉成mat格式Matlab
- 工程座標轉換方法C#程式碼實現C#
- embed-c:可將C程式碼直接嵌入到Rust程式碼中C程式Rust
- matlab練習程式(灰度拉伸)Matlab
- MATLAB神經網路工具箱(程式碼簡單實現)Matlab神經網路
- MATLAB 檢驗資料正態分佈及程式碼實現Matlab
- MATLAB程式設計與應用系列-關於MATLAB程式設計入門教程的總體編寫安排Matlab程式設計
- matlab 基礎Matlab
- COST231-WI模型通道模擬,原始碼模擬matlab程式設計原始碼模型原始碼Matlab程式設計
- 基於方塊編碼的影像壓縮matlab模擬,帶GUI介面MatlabGUI
- 基於AMC4030的二維滑軌的MATLAB程式設計控制Matlab程式設計
- 基於多重替換方式的iOS程式碼混淆方案iOS
- YUV影像質量的客觀評估SSIM matlab程式碼實現Matlab