I've developed a C++ program which calculates a set of coordinates (x, y) within a loop. Every iteration I want to send the coordinate to Matlab for further processing, at a speed of about 25 times per second. I have a Matlab function that then takes this coordinate and uses it in real time; however, I haven't found an effective way of sending variables quickly from C++ to Matlab.
I've tried using the Matlab engine here: Passing Variable from C++ to Matlab (Workspace), except I want this variable to be used in the existing Matlab session and not simply run Matlab commands through C++.
I've also tried writing the C++ coordinate to a binary file and then reading this file in Matlab - this method is very fast but I'm having problems with the timing between both languages. Setting the Matlab code to an infinite loop reading the binary file, whilst running the C++ program writing the coordinate to the file, means that Matlab reads in a very strange order (ie. Matlab reads 15, 200, 70, 12 when I write the i values to file). I suspect this is due to poor timing between each program trying to open and either read or write the file.
C++:
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/opencv.hpp"
#include <iostream>
#include <math.h>
#include <fstream>
#include <stdio.h>
#include <Windows.h>
using namespace cv;
using namespace std;
int main()
{
int a = 0
for (int i = 0; i < 100000; ++i)
{
a = i;
std::ofstream ofile("foobar.bin", std::ios::binary);
ofile.write((char*) &a, sizeof(int));
ofile.close();
}
return 0;
}
Matlab:
A = fopen('foobar.bin');
fread(A)
fclose(A);
Is there a way to quickly and accurately send data between C++ and Matlab by writing to binary OR some other method which I can implement?
Thank you very much!
I cannot provide code samples because it has been a few years since I did this, but I know that you can use a create a COM object and interface it with matlab. Here is the link describing how to interface a COM object with matlab. http://www.mathworks.com/help/matlab/using-com-objects-in-matlab.html
Related
I was prepossessing data in C++ using the Armadillo library. The program end product is a ucube, which is a cube filled with unsigned integers. After its run, I want to load the ucube to R to perform some final statistical tests. To do so, I made a C++ function that load the ucube returning an array.
But it does not work!
I got the following warning: "warning: Cube::load(): incorrect header in B.bin" and the program returns a 0x0x0 array.
Trying to find why, I made a toy C++ program, which works fine. It is able to load the cubes without any problem.
#include <iostream>
#include <armadillo>
using namespace arma;
void read_cubes(char const* A, char const* B){
cube C;
ucube D;
C.load(A, arma_binary);
D.load(B, arma_binary);
}
int main(int argc, char** argv){
cube A = randu<cube>(5,5,5);
ucube B = randi<ucube>(5,5,5, distr_param(1, 10));
A.save(argv[1], arma_binary);
B.save(argv[2], arma_binary);
read_cubes(argv[1], argv[2]);
}
But I do not know why, doing the same steps in R does not work. To illustrate, please run the toy program as ./a.out A.bin B.bin. It will yield the Cube<double> A.bin and the Cube<uword> B.bin, which I will mention later.
The problem
If I source the following C++ code with Rcpp::sourceCpp and I try to read the Cube<double> A.bin with read_cube("A.bin") it works, but if I do the same for the Cube<uword> B.bin with read_ucube("B.bin") it does not (I get the warning).
#include <RcppArmadillo.h>
#include <iostream>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
arma::cube read_cube(char const* x){
arma::cube A;
A.load(x, arma::arma_binary);
return A;
}
// [[Rcpp::export]]
arma::ucube read_ucube(char const* x){
arma::ucube B;
B.load(x, arma::arma_binary);
return B;
}
Of course I could cast the Cube<uword> to a Cube<double> before ending the C++ program, but I would like to know why this happen and if it is possible to load a Cube<uword> in RcppArmadillo. Because it should be possible, right?
Unfortunately R still only supports 32 bit integers, so RcppArmadillo forces Armadillo to use 32 bit integers. This is done by defining ARMA_32BIT_WORD before including the armadillo header. See RcppArmadillo's configuration here.
You can apply the same "trick" with your Armadillo programs like so:
#define ARMA_32BIT_WORD
#include <armadillo>
One of the effects is that ucube (Cube<uword>) will use 32 bit unsigned integers.
After doing the above trick, recompile your Armadillo programs and save the ucubes again. They can then be loaded in RcppArmadillo.
I am using this open source software for working with Sick Lidar Devices:
https://github.com/rhuitl/sicktoolbox/tree/master/trunk/c%2B%2B/drivers/lms5xx/sicklms5xx
and this documentation which provides information on the data:
https://www.sick.com/media/docs/7/27/927/Technical_information_Telegram_Listing_Ranging_sensors_LMS1xx_LMS5xx_TiM5xx_NAV310_LD_OEM15xx_LD_LRS36xx_en_IM0045927.PDF
I am trying to use the C++ implementation to parse already written files in the "CoLa B" format from SickLMS5xx, mentioned in said documentation. However, this toolbox appears to have been written to deal with the device directly, and not files that are outputted from it (like what I am working with).
It appears I can use the functions in the SickLMS5xxMessage (ParseMessage() etc.) to achieve what I want. I made a main method to interract with this class (and it's SickMessage() superclass) like so:
#include <iostream>
#include <fstream>
#include <boost/thread/thread.hpp>
#include "SickLMS5xxMessage.cc"
void run() {
SickLMS5xxMessage msg(uint8_t * const telegramFileBuffer[]);
std::ifstream telegramFile("MMS21_01");
if(telegramFile.is_open()) {
uint8_t telegramFileBuffer[msg.GetMessageLength()];
for(int i = 0; i < msg.GetMessageLength(); ++i) {
telegramFile >> telegramFileBuffer[i];
}
}
msg.Print();
}
int main (int argc, char** argv) {
run();
return (0);
}
But it doesn't appear to work properly, as it cannot recognise the GetMessageLength() and Print() functions from SickLMS5xxMessage, and gives me an unresolved method error?
Maybe it's an error with my C++ coding (because I come from a Java background and so C++ is still relatively new to me).
Any help will be appreciated though, thank you :)
I am relatively new to c++ coding and try to write a program to solve differential equations numerically. I use codeBlocks as the compiler for that and work under windows. The numeric solver already works well.
My program contains of some very long formulas which are created by mathematica and converted into cpp-language. Then the formulas are stored in a .txt-file.I can already read the formula as a string, but not use it to calculate things because the program has to interpret the formula as a double-type math and not as a string. The problem here is, that my formula does not contain only numbers, but letters as variables (their value is set in the program) and other mathematical symbols. That is why I think I cannot just use "atof" (http://www.cplusplus.com/reference/cstdlib/atof/?kw=atof) or other conversion functions. (If I am wrong at this point, I would be glad to learn how to use the function for this problem!)
Here is some example code from my little program:
//Program to solve ODEs
#include <iostream>
#include <math.h>
#include <cmath>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
#include <time.h> //to measure the time
#include <stdio.h>
#include <conio.h>
using namespace std;
int main(void)
{
double k1=0;
ifstream file("Formelvu1.txt");//file with the fromula
string line;
stringstream longform;
while(getline(file, line)){ //read the formula and store them
longform << line; //store the string in "longform"
cout << longform;
}
return 0;
for(double t=0; t<10; t++){
k1 = (longform) * t; //simple operation with the formula
}
return 0;
}
This code doesn't work, becuase longform is no double...
longform is a string with something like: ab+pow(t,3)-sin(tb)/x.
I already found several questions related to this topic, but none of them was easy enough for me to understand or the right thing I want to do:
How can I convert string to double in C++?
From what I understand is this guy trying the nearest from what I wish to do:
Evaluate math formula from String using ScriptEngine
But I don't understand the code completely.
If it is useful for my problem: What does this part do?
try{
return (Double)engine.eval(tmp);
}
catch(Exception fexp)
{
}
I also heard about parser which can interpret the xpressions line muparser:
http://muparser.beltoforion.de/mup_eval.html
But I don't know if this would be more than I need...
I appreciate every answer/response and help with this problem.
Thank you!
You have to study carefully what is included in the basic C/C++ language and standard library and what not.
However, if you get a C++ compatible expression from mathematica, then you can let the C++ compiler do its work as in
double myfunc(double a, double b, double c, double t, double x) {
return
#include "Formelvu1.txt"
;
}
my file structure for executing a .exe is something like this
c:\Documents and settings\Desktop\Release\abc.exe
i want to execute this from other c++ program in vb c++ after building, it generates an error that c:\Document is not external or internal command
few lines of code are as follows:
#include<stdlib.h>
#include<stdio.h>
int main( void ) {
int result;
result=system("c:\\Documents and settings\\Desktop\\Release\\abc.exe");
getchar();
return 0;
}
As I suspected when writing an earlier comment, the way to do it is to wrap the entire string in double-quotes. 'Escaping the spaces' sounds non-sensical to me. 25 seconds of googling and I don't see (nor have I heard of in over 20 years) an escape-sequence for a space character in C.
The solution is indeed to include quotes in the string - not to just wrap the string in a single pair of them, as you've done. The following will do the trick:
#include <stdlib.h>
#include <stdio.h>
int main()
{
int result;
result = system("\"c:\\Documents and settings\\Desktop\\Release\\abc.exe\"");
getchar();
return 0;
}
However, that said - you shouldn't really be using the system call for this job. Since you're on a windows machine, you should use the ShellExecute function instead. There are many reasons for this, which I wont go into here, you can look them up yourself. But suffice to say it's an infinitely better way to invoke another program.
More on ShellExecute: http://msdn.microsoft.com/en-us/library/windows/desktop/bb762153(v=vs.85).aspx
I've started to use OpenCV with Visual C++ 2010 Express, because it was supposed to be faster than MATLAB.
In order to do a fair comparison between both, I'm running a program where I convert a RGB image to its gray scale correspondent and I calculate the conversion image space operation elapsed time.
Using cvtColor command to do the task in C++ Release, it takes me around 5 ms, average. Doing the same operation in MATLAB, takes me more or less the same average time (the codes are bellow).
I already tested, and both programs are working fine.
Does anybody have any idea if I can improve the OpenCV speed?
C++ code.
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <opencv2/imgproc/imgproc.hpp>
#include <windows.h>
using namespace cv;
using namespace std;
double PCFreq = 0.0;
__int64 CounterStart = 0;
void StartCounter()
{
LARGE_INTEGER li;
if(!QueryPerformanceFrequency(&li))
cout << "QueryPerformanceFrequency failed!\n";
PCFreq = double(li.QuadPart)/1000.0;
QueryPerformanceCounter(&li);
CounterStart = li.QuadPart;
}
double GetCounter()
{
LARGE_INTEGER li;
QueryPerformanceCounter(&li);
return double(li.QuadPart-CounterStart)/PCFreq;
}
int main()
{
double time;
Mat im, result;
im = imread("C:/Imagens_CV/circles_rgb.jpg");
StartCounter();
cvtColor(im,result, CV_BGR2GRAY);
time = GetCounter();
cout <<"Process time: "<< time << endl;
}
MATLAB code
tic
img_gray = rgb2gray(img_rgb);
toc
Color conversion in OpenCV will make extensive use of Intel IPP if it is available at compile time. See modules\imgproc\src\color.cpp. More info from Intel. Note that this code has no OpenMP pragmas or TBB code, so that won't help here.
The exciting bit is that Intel has granted OpenCV the right to use a subset of IPP for free, incuding these functions. See the third item in the release summary for more info. But you need to use at least OpenCV 3.0 to get this free functionality; otherwise you need to compile with your own copy of IPP.
Clearly, cvtColor (far left) does not benefit much, but it gets a little boost. Other functions do much better.
If you follow the call to rgb2gray function in MATLAB (edit rgb2gray.m), you'll find that it eventually calls a private MEX-function imapplymatrixc.mexw64 implemented in C++.
In fact if you load this shared library into a tool like "Dependency Walker", you'll see it has a dependency on tbb.dll which indicates the function is multi-threaded using Intel TBB library.
While it doesn't seem to be the case for color conversion functions, the Image Processing Toolbox does use Intel IPP library for some of its image arithmetic functions (there is a setting you can control to enable/disable the use of "hardware optimization" ippl: iptsetpref('UseIPPL', true)).
In addition, there is a version of the function that runs on the GPU (CUDA) when using gpuArray input arrays (edit gpuArray>rgb2gray.m). This requires the Parallel Computing Toolbox.
So it is safe to say the function is well optimized!