Azzera filtri
Azzera filtri

How to read a 'CompactSVMModel' saved in a .mat file from a C++/Qt program

28 visualizzazioni (ultimi 30 giorni)
I tried to save a machine learning model into a .mat file, and then read it from a Qt/C++ application. Following the documentation, I managed to read files containing basic types like double or int. As my model is of type 'classreg.learning.classif.CompactClassificationSVM', I wonder if it is still possible to read it.
As and example, i saved this iosnosphere model on matlab
load ionosphere
SVMModel = fitcsvm(X,Y,'Standardize',true,'ClassNames',{'b','g'})
CompactSVMModel = compact(SVMModel)
save("CompactSVMModel.mat", "CompactSVMModel")
I imported the relevant library in the CMakeLists.txt
find_package(Matlab "x.xx" EXACT COMPONENTS "MX_LIBRARY" "MAT_LIBRARY" "DATAARRAY_LIBRARY" )
target_link_libraries(target PRIVATE Matlab::mat )
I used the "mat.h" library to open and read the data.
#include "mat.h"
int main () {
std::string stdFilename = "/filepath/CompactSVMModel.mat";
const char *variableName = "CompactSVMModel";
// Open the MAT-File
MATFile *matFile = matOpen(stdFilename.c_str(), "r");
if (!matFile) {
qDebug() << "Error opening MAT file: " << stdFilename;
}
// Read the variable from the MAT-File
mxArray *dataArray = matGetVariable(matFile, variableName);
if (!dataArray) {
qDebug() << "Error reading variable: " << variableName << " from MAT file: " << stdFilename;
}
...
// read a save the diffrent fields into containers
return 0;
}
At the first if statement, matFile is NULL.

Risposta accettata

Arnav
Arnav il 26 Lug 2024 alle 9:17
Hi,
I tried executing your code with the particulars provided in the CMakeLists.txt with MATLAB R2022b libraries.
This is my CMakeLists.txt:
cmake_minimum_required(VERSION 3.10)
project(ML_Answers)
find_package(Matlab "9.13.0.2553342"EXACT COMPONENTS MX_LIBRARY MAT_LIBRARY DATAARRAY_LIBRARY)
include_directories(${Matlab_INCLUDE_DIRS})
add_executable(ML_Answers main.cpp)
target_link_libraries(ML_Answers PRIVATE Matlab::mat)
I built and ran the project using the following commands:
$ cmake -G "MinGW Makefiles" -DCMAKE_CXX_COMPILER=C:\ProgramData\MATLAB\SupportPackages\R2022b\3P.instrset\mingw_w64.instrset\bin\g++.exe .
$ mingw32-make.exe
$./ML_Answers.exe
This executes as expected. I encountered the issue you mentioned when I built the project in a different build subdirectory (instead of the project root directory) and tried executing the executable from inside the build subdirectory. This was due to the relative path of the CompactSVMModel.mat file not being correct. You might try rechecking to see if you made a similar error.
For the task of reading a class instance from CompactSVMModel.mat file using a standalone C++ program, a workaround would be to save the different properties as different variables in the CompactSVMModel.mat file as follows:
% Extract the SupportVectors property
SupportVectors = CompactSVMModel.SupportVectors;
save('CompactSVMModel.mat', 'SupportVectors', 'CompactSVMModel');
Following this, the SupportedVectors variable can be read using C++ program in the following way (I substituted qDebug() for std::cerr and std::cout):
#include "mat.h"
#include <string>
#include <iostream>
int main() {
std::string stdFilename = "./CompactSVMModel.mat";
const char* variableName = "SupportVectors"; // Change to read the SupportVectors property
// Open the MAT-File
MATFile *matFile = matOpen(stdFilename.c_str(), "r");
if (!matFile) {
std::cerr << "Error opening MAT file: " << stdFilename << std::endl;
return 1; // Exit with error code
}
// Read the variable from the MAT-File
mxArray *dataArray = matGetVariable(matFile, variableName);
if (!dataArray) {
std::cerr << "Error reading variable: " << variableName << " from MAT file: " << stdFilename << std::endl;
matClose(matFile);
return 1; // Exit with error code
}
// Print the dimensions of the SupportVectors matrix
mwSize numRows = mxGetM(dataArray);
mwSize numCols = mxGetN(dataArray);
std::cout << "SupportVectors dimensions: " << numRows << " x " << numCols << std::endl;
// Clean up and close the MAT-File
mxDestroyArray(dataArray);
matClose(matFile);
std::cout << "SupportVectors have been successfully read from the MAT file." << std::endl;
return 0;
}
Output for the C++ Program:
SupportVectors dimensions: 89 x 2
SupportVectors have been successfully read from the MAT file.
You can learn more about how to read variables here:
Alternatively, you can build your project using MEX and use C++ MEX API. You can read more about the C++ MEX API here:
  1 Commento
MahnnUser
MahnnUser il 31 Lug 2024 alle 13:53
Hi @Arnav,
Thank you for your response. In the end, I used a different approach. My goal was to translate my MATLAB program into a C++ program using MATLAB Coder. Since the MATLAB program used a model, I needed to import it. However, I found that the model could be integrated into the C++ library generated by MATLAB Coder. https://fr.mathworks.com/help/stats/loadlearnerforcoder.html

Accedi per commentare.

Più risposte (0)

Categorie

Scopri di più su Write C Functions Callable from MATLAB (MEX Files) in Help Center e File Exchange

Prodotti


Release

R2022b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by