How to save a svm file in mexopencv - matlab

So, I am about to train a classifier and needed to save the result from the classifier, in mexopencv.
hello = cv.SVM;
hello.save('foo.xml')
My Matlab compiler crashes due to segmentation fault. As far as I know this is supposed to be the way in OpenCV. Is there any other way to save files trained via SVM in mexopencv ; or is this something to do with Matlab file writing option. Thanks.

This is in fact a bug in OpenCV itself, not mexopencv. You should report it...
Here is a minimal C++ program to reproduce the bug:
#include "opencv2/opencv.hpp"
#include "opencv2/ml/ml.hpp"
using namespace cv;
int main()
{
Ptr<SVM> svm = new SVM();
svm->save("svm.xml");
return 0;
}
Running this under a debugger, I located the offending code:
df_count = class_count > 1 ? class_count*(class_count-1)/2 : 1;
df = decision_func;
cvStartWriteStruct( fs, "decision_functions", CV_NODE_SEQ );
for( i = 0; i < df_count; i++ )
{
int sv_count = df[i].sv_count;
...
}
At this point, the SVM model is untrained, and df is an uninitialized pointer. class_count equals 0, but df_count gets set to 1, hence df[i] (with i=0) causes an access violation...
I think this could be fixed as:
df_count = class_count > 1 ? class_count*(class_count-1)/2 : 1;
if (class_count == 0) df_count = 0;
Changing df_count to 0 during debugging, the program runs correctly and I get the following XML file:
svm.xml
<?xml version="1.0"?>
<opencv_storage>
<my_svm type_id="opencv-ml-svm">
<svm_type>C_SVC</svm_type>
<kernel>
<type>RBF</type>
<gamma>1.</gamma>
</kernel>
<C>1.</C>
<term_criteria>
<epsilon>1.1920928955078125e-007</epsilon>
<iterations>1000</iterations>
</term_criteria>
<var_all>0</var_all>
<var_count>0</var_count>
<sv_total>0</sv_total>
<support_vectors></support_vectors>
<decision_functions></decision_functions>
</my_svm>
</opencv_storage>
For now you could avoid the bug by training the model first before saving it to file :)

You can try libsvm which has a Matlab interface. It comes two functions to read and write in svm (libsvmwrite and libsvmread).

Related

Wrong output value of Legacy Code Tool's Sfunction

I am getting wrong result of the example published in the Mathworks documentation in the link
I am expecting the output to be 2 times the sine wave of amplitude 1, but I am getting constant value of large magnitude in the order of 1e8.
I used the following commands:
def = legacy_code('initialize');
def.HeaderFiles = {'myfunc.h'};%,'mat.h'};
def.SourceFiles = {'myfunc.c'};
def.SFunctionName = 'sfun_myfunc';
def.OutputFcnSpec = 'double y1 = myfunc(double u1)';
def.Options.singleCPPMexFile = false;
legacy_code('sfcn_cmex_generate', def);
legacy_code('sfcn_tlc_generate', def);
legacy_code('compile', def);
legacy_code('slblock_generate', def);
What am I missing ?
I found the problem. In the header file, instead of using #ifndef I used erroneously #ifdef.

How can I fix my code to do line by line conditional statements in Matlab

I just started learning Matlab roughly an hour ago after being told I had to convert my rscript into Matlab. I wrote a conditional statement below and it does not work. The reason I believe is because it is not currently going line by line. data is a Matlab table. Here is my current code:
if data.Year == data.initYear
data.initY = -1
else
data.initY = 0
end
in R it was:
workable$saleYear <- ifelse(workable$year == workable$initYear, -1,0)
Any help would be appreciated
You want to do this in a vector. That way you don't need for loops or if statements.
data.initY = zeros(size(data.Year));
data.initY(data.Year == data.initYear) = -1;

Calling mxDestroyArray on mxArray objects returned from Matlab Compiler Runtime

We've been interfacing with a library created from the Matlab Compiler. Our problem is related to an array returned from the library.
Once we're finished with the array, we'd like to free the memory, however, doing this causes occasional segmentation faults.
Here is the Matlab library (bugtest.m)::
function x = bugtest(y)
x = y.^2;
Here is the command we used to build it (creating libbugtest.so, and libbugtest.h)::
mcc -v -W lib:libbugtest -T link:lib bugtest.m
Here is our C test program (bug_destroyarray.c)::
#include <stdio.h>
#include <stdlib.h>
#include "mclmcrrt.h"
#include "libbugtest.h"
#define TESTS 15000
int main(int argc, char **argv)
{
const char *opts[] = {"-nojvm", "-singleCompThread"};
mclInitializeApplication(opts, 2);
libbugtestInitialize();
mxArray *output;
mxArray *input;
double *data;
bool result;
int count;
for (count = 0; count < TESTS; count++) {
input = mxCreateDoubleMatrix(4, 1, mxREAL);
data = mxGetPr(input); data[0] = 0.5; data[1] = 0.2; data[2] = 0.2; data[3] = 0.1;
output = NULL;
result = mlfBugtest(1, &output, input);
if (result) {
/* HERE IS THE PROBLEMATIC LINE */
/*mxDestroyArray(output);*/
}
mxDestroyArray(input);
}
libbugtestTerminate();
mclTerminateApplication();
}
Here is how we compile the C program (creating bug_destroyarray)::
mbuild -v bug_destroyarray.c libbugtest.so
We believe that mxDestroyArray(output) is problematic.
We run the following to test crashing:
On each of the 32 cluster nodes.
Run bug_destroyarray.
Monitor output for segmentation faults.
Roughly 10% of the time there is a crash. If this is independent across nodes
then you might suppose it is crashing roughly 0.3% of the time.
When we take out that problematic line we are unable to cause it to crash.
However memory usage gradually increases when this line is not included.
From the research we've done, it seems we are not supposed to destroy the array returned, if not, how do we stop from leaking memory?
Thanks.
Okay, I know this is a little old now, but in case it helps clarify things for anyone passing by ...
Amro provides the most pertinent information, but to expand upon it, IF you don't call the mxDestroyArray function as things stand, then you WILL leak memory, because you've set output to NULL and so the mlf function won't try to call mxDestroyArray. The corollary of this is that if you've called mxDestroyArray AND then try to call the mlf function AND output is NOT NULL, then the mlf function WILL try to call mxDestroyArray on output. The question then is to what does output point? It's a bit of a dark corner what happens to output after passing it to mxDestroyArray. I'd say it's an unwarranted assumption that it's set to NULL; it's certainly not documented that mxDestroyArray sets its argument to NULL. Therefore, I suspect what is happening is that in between your call to mxDestroyArray and the code re-executing the mlf function, something else has been allocated the memory pointed to by output and so your mlf function tries to free memory belonging to something else. Voila, seg fault. And of course this will only happen if that memory has been reallocated. Sometimes you'll get lucky, sometimes not.
The golden rule is if you're calling mxDestroyArray yourself for something that is going to be re-used, set the pointer to NULL immediately afterwards. You only really need to destroy stuff at the end of your function anyway, because you can safely re-use output variables in mlf calls.
Guy
A few notes:
I don't see singleCompThread in the list of allowed options for mclInitializeApplication.
The recommended way to compile your C program is to dynamically link against the compiled library:
mbuild -v -I. bug_destroyarray.c -L. -lbugtest
At the top of your C program, just include the generated header file, it will include other headers in turn. From looking at the generated header, it has:
#pragma implementation "mclmcrrt.h"
#include "mclmcrrt.h"
I dont know the exact meaning of this pragma line, but maybe it matters with GCC compilers..
The fact that both mlx/mlf generated functions return booleans is undocumented. But looking at the header files, both signatures do indeed return a bool:
extern bool mlxBugtest(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[]);
extern bool mlfBugtest(int nargout, mxArray** x, mxArray* y);
I tried your code and it works just fine with no segfaults. As I dont have access to a cluster of computers, my testing was only done on my local machine (WinXP with R2013a).
I had to remove both MCR initialization options for it to work (specifically the nojvm caused a runtime error). Below is the full code with slight modifications. It took around 10 seconds to run:
#include <stdio.h>
#include <stdlib.h>
#include "libbugtest.h"
#define TESTS 15000
int main()
{
mxArray *output, *input;
double *data;
int count;
bool result;
if( !mclInitializeApplication(NULL,0) ) {
fprintf(stderr, "Could not initialize the application.\n");
return EXIT_FAILURE;
}
if ( !libbugtestInitialize() ) {
fprintf(stderr, "Could not initialize the library.\n");
return EXIT_FAILURE;
}
for (count = 0; count < TESTS; count++) {
input = mxCreateDoubleMatrix(4, 1, mxREAL);
data = mxGetPr(input);
data[0] = 0.5; data[1] = 0.2; data[2] = 0.2; data[3] = 0.1;
output = NULL;
result = mlfBugtest(1, &output, input);
if (!result) {
fprintf(stderr, "call failed on count=%d\n", count);
return EXIT_FAILURE;
}
mxDestroyArray(output); output = NULL;
mxDestroyArray(input); input = NULL;
}
libbugtestTerminate();
mclTerminateApplication();
return EXIT_SUCCESS;
}
Also the compilation step is a bit different on Windows, since we statically link against the import lib (which inserts a stub to dynamically load the DLL on runtime):
mbuild -v -I. bug_destroyarray.c libbugtest.lib
Thanks for the detailed reply Amro.
We tried changing our compilation steps to the recommended ones, with no success.
The following fixed our seg-faulting problem:
Do not set output = NULL at each iteration, instead do it once outside of the loop.
Do not call mxDestroyArray(output) inside the loop, reference: here.
Our misunderstanding was that (it seems) you are supposed to reuse mxArray pointers which you pass to MATLAB functions. It makes things slightly cumbersome on our side as we need to be careful reusing this pointer.
However, memory is completely stable, and we've not had a crash since.

Unexpected output from lex program

I have written a simple lex program to perform average of positive numbers , the program is compiling fine but i'm not able to get the expected output.I'm passing the input to the program from a file by giving filename as a commandline argument.The output of the lex program is blank showing no result , i'm a beginner in lex and any help would be appreciated . I have attached the code below. The code is written in redhat linux kernel version 2.4.
%{
#include <stdio.h>
#include <stdlib.h>
%}
%%
[0-9]+ return atoi(yytext);
%%
void main()
{
int val, total = 0, n = 0;
while ( (val = yylex()) > 0 ) {
total += val;
n++;
}
if (n > 0) printf(“ave = %d\n”, total/n);
}
The input file contains numbers 3,6 and 4 and the name of the file is passed as command line argument.
./a.out < input
Your program works for me. I'm a bit suspicious of yywrap missing, so you probably link with the -lfl (or something alike) option. This library contains a yywrap and a main. Even though I'm not able to reproduce what you see, I'm wary that maybe the main from libfl is used. I'm assuming you do get any newlines in the input file on the output. Different linkers have different ways of resolving multiple occurrences of the same symbol.
All in all I think you have to look for the problem in the way your program is built, because the specification seems ok. If you add int yywrap(void) { return 1; } after your main, then you can do without libfl, which is what I would advise any user of lex and gnu-flex.

How to compile Matlab class into C lib?

The origin of this question is from here How to use "global static" variable in matlab function called in c.
I'm trying to encapsulate the "global variable" into an object. However I don't know how to export the matlab class to c++ using MATLAB Compiler (mcc)
To do this I just tried the standard command
Matlab Command
mcc -W cpplib:Vowel4 -T link:lib Vowel4.m
Matlab Script
classdef Vowel4
properties
x
y
end
methods
Vowel4
A
B
end
end
The generated lib is actually stand-alone functions rather than c++ class.
How can I compile classes in Matlab into c++ classes?
I've been searching for an answer but didn't find one.
Obviously the matlab command is not suitable for this scenario. However I cannot find any information on building Matlab classes into c++ classes.
========================== Edit ========================
The actual cpp code is as follows: #Alan
mclInitializeApplication(NULL, 0);
loadDataInitialize();
soundByCoefInitialize();
loadData();
mwArray F(4, 1, mxDOUBLE_CLASS);
float test[4];
for ( ;; ){
const Frame frame = controller.frame();
const FingerList fingers = frame.fingers();
if ( !fingers.empty() ){
for ( int i = 0; i < 4; i ++ ){
double v = fingers.count() > i ? (fingers[i].tipPosition().y / 50) - 2 : 0;
F(i+1,1) = v;
test[i] = v;
cout << v << ' ';
}
cout << endl;
soundByCoef(F);
}
}
Here the matlabA() corresponds to the loadData(), which loads the data, and soundByCoef(F) corresponds to the matlabB(), which do the job in the main loop.
As noted by Alan, I was only suggesting using handle class as a container for your global variables (with the benefit that such an object would be passed by reference). The created object is not intended to be directly manipulated by your C++ code (it will be stored in the generic mxArray/mwArray C/C++ struct).
As far as I know, you cannot directly compile classdef-style MATLAB classes into proper C++ classes when building shared libraries using the MATLAB Compiler. It only supports building regular functions. You could create functional interfaces to MATLAB class member methods, but that's a different story...
Perhaps a complete example would help illustrate the idea I had in mind. First lets define the code on the MATLAB side:
GlobalData.m
This is the handle class used to store the global vars.
classdef GlobalData < handle
%GLOBALDATA Handle class to encapsulate all global state data.
%
% Note that we are not taking advantage of any object-oriented programming
% concept in this code. This class acts only as a container for publicly
% accessible properties for the otherwise global variables.
%
% To manipulate these globals from C++, you should create the class API
% as normal MATLAB functions to be compiled and exposed as regular C
% functions by the shared library.
% For example: create(), get(), set(), ...
%
% The reason we use a handle-class instead of regular variables/structs
% is that handle-class objects get passed by reference.
%
properties
val
end
end
create_globals.m
A wrapper function that acts as a constructor to the above class
function globals = create_globals()
%CREATE_GLOBALS Instantiate and return global state
globals = GlobalData();
globals.val = 2;
end
fcn_add.m, fcn_times.m
MATLAB functions to be exposed as C++ functions
function out = fcn_add(globals, in)
% receives array, and return "input+val" (where val is global)
out = in + globals.val;
end
function out = fcn_times(globals, in)
% receives array, and return "input*val" (where val is global)
out = in .* globals.val;
end
With the above files stored in current directory, lets build the C++ shared library using the MATLAB Compiler:
>> mkdir out
>> mcc -W cpplib:libfoo -T link:lib -N -v -d ./out create_globals.m fcn_add.m fcn_times.m
You should expect the following generated files among others (I'm on a Windows machine):
./out/libfoo.h
./out/libfoo.dll
./out/libfoo.lib
Next, we could create a sample C++ program to test the library:
main.cpp
// Sample program that calls a C++ shared library created using
// the MATLAB Compiler.
#include <iostream>
using namespace std;
// include library header generated by MATLAB Compiler
#include "libfoo.h"
int run_main(int argc, char **argv)
{
// initialize MCR
if (!mclInitializeApplication(NULL,0)) {
cerr << "Failed to init MCR" << endl;
return -1;
}
// initialize our library
if( !libfooInitialize() ) {
cerr << "Failed to init library" << endl;
return -1;
}
try {
// create global variables
mwArray globals;
create_globals(1, globals);
// create input array
double data[] = {1,2,3,4,5,6,7,8,9};
mwArray in(3, 3, mxDOUBLE_CLASS, mxREAL);
in.SetData(data, 9);
// create output array, and call library functions
mwArray out;
fcn_add(1, out, globals, in);
cout << "Added matrix:\n" << out << endl;
fcn_times(1, out, globals, in);
cout << "Multiplied matrix:\n" << out << endl;
} catch (const mwException& e) {
cerr << e.what() << endl;
return -1;
} catch (...) {
cerr << "Unexpected error thrown" << endl;
return -1;
}
// destruct our library
libfooTerminate();
// shutdown MCR
mclTerminateApplication();
return 0;
}
int main()
{
mclmcrInitialize();
return mclRunMain((mclMainFcnType)run_main, 0, NULL);
}
Lets build the standalone program:
>> mbuild -I./out main.cpp ./out/libfoo.lib -outdir ./out
And finally run the executable:
>> cd out
>> !main
Added matrix:
3 6 9
4 7 10
5 8 11
Multiplied matrix:
2 8 14
4 10 16
6 12 18
HTH
Following on from the thread in the previous post, the suggestion wasn't to wrap your functions in a class, but rather to use a class to pass about the global variable which compiling leaves you unable to use.
classdef Foo < handle
properties
value
end
methods
function obj = Foo(value)
obj.value = value;
end
end
end
Note: the class Foo extends the handle class in order to make it pass by reference, rather than pass by value. See: the comparison between handle and value classes.
function foo = matlabA()
foo = new Foo(1);
end
function matlabB(foo)
foo.value
end
As far as I know, the matlab compiler doesn't compile the code as such, but rather packages it with a copy of the MATLAB Component Runtime and writes some wrapper functions to handle invoking said runtime on the code from c/c++.
I would recommend avoiding jumping back and forth between matlab and c/c++ too much; there is bound to be some overhead to converting the datatypes and invoking the MCR. All I really use it for is wrapping up a complex but self-contained matlab script (i.e.: doesn't need to interact with the c/c++ code mid way through said script) as a function, or packaging up code for deployment to environments which don't have a full copy of matlab.
As an interesting side note: if you are calling C++ from within Matlab, and that C++ code needs access to a global variable, things are much easier. You can simply do this by wrapping your C++ code into a mexFunction and compiling that. In the places you need to access a variable which is in the Matlab workspace, you can do so using the mexGetVariablePtr which will return a read-only pointer to the data. The variable you are accessing can be in either the global workspace, or that of the function which called your mexFunction.
With this approach I would suggest liberally comment the variable that you are getting in both the C++ and Matlab code, as the link between them may not be obvious from the Matlab side; you wouldn't want someone to come along later, edit the script and wonder why it had broken.
In this case it seems that the C++ side doesn't really need access to the data, so you could refactor it to have matlab do the calling by wrapping the "get current position of fingers" code into a mexFunction, then have matlab do the loop:
data = loadData();
while(~stop) {
position = getFingerPositionMex();
soundByCoef(position, data);
}
Assuming you don't modify the data within soundByCoef Matlab will use pass by reference, so there will be no copying of the large dataset.