How to define arrays in C++/ Open CV as I do in matlab ?
for example:
x=a:b:c;
or
y=linspace(a,b,n);
Refer the previous answers for general answers to your question.
Specifically, to address the two examples that you mention, here is some equivalent c++ code using vectors for dynamically generating the arrays you mentioned (haven't tested):
#include <vector>
using std::vector;
vector<double> generateRange(double a, double b, double c) {
vector<double> array;
while(a <= c) {
array.push_back(a);
a += b; // could recode to better handle rounding errors
}
return array;
}
vector<double> linspace(double a, double b, int n) {
vector<double> array;
double step = (b-a) / (n-1);
while(a <= b) {
array.push_back(a);
a += step; // could recode to better handle rounding errors
}
return array;
}
OpenCV offers some functions that are similar to Matlab, but their number is very limited.
You can
cv::Mat a = cv::Mat::eye(5);
cv::Mat b = cv::Mat::zeros(5);
cv::Mat img = cv::imread("myGorgeousPic.jpg");
cv::imwrite(img, "aCopyOfMyGorgeousPic.jpg");
It also supports diag()
But for most of that tricky Matlab functionality like linspace
or magic
or whatever, there is no correspondent in OpenCV, mostly because OpenCV is not a mathematics package, but a computer vision one. If you need some specific function, you can clone it in your project (aka write it by yourself)
Unfortunately C++ has nothing inbuilt into it to allow this kind of matrix initialisation. It supports multidimensional arrays but you would need to initialise every element yourself. C++ is a lower level language than Matlab and it involves a lot more work to write the functionality to create and initialise a matrix type variable.
Having said that there are a number of libraries available for use with C++ that make numerical computation easier than if you were to attempt writing it all yourself. If you need to consider using libraries, have a look at this link that suggests a few suitable ones https://scicomp.stackexchange.com/questions/351/recommendations-for-a-usable-fast-c-matrix-library
This is a simple implementation if you use openCV.
Mat linspace(double &startP,double &Endp,int &interval)
{
double spacing = interval-1;
Mat y(spacing,1,CV_64FC1);
for (int i = 0; i < y.rows; ++i)
{
y.at<double>(i) = startP + i*(Endp - startP)/spacing;
}
return y;
}
double* linspace(int xi, int xf, unsigned int n){
double *vec ;
vec = new double[n];
float esp, falt=xf-xi;
esp=falt/(n-1);
vec[0]=xi;
for(int i=1; i<n; i++)
vec[i]=vec[i-1]+esp;
return vec;
here is my tested linspace very similar to all the others but handles all the cases:
vector<double> Utilities::Linspace(double a, double b, int n) {
vector<double> array;
double epsilon = 0.0001;
double step = (b-a) / (n-1);
if (a==b)
{
for (int i = 0; i < n; i++)
{
array.push_back(a);
}
}
else if (step >= 0)
{
while(a <= b + epsilon)
{
array.push_back(a);
a += step;
}
}
else
{
while(a + epsilon >= b )
{
array.push_back(a);
a += step;
}
}
return array;
}
I would like to add a slight modification to the code proposed by mattgately. I used it and there are some cases when step
is not correctly calculated due to division approximation
double step = (b-a) / (n-1);
I just added a small number to the while
condition:
while(a <= b+0.00001)
Like this it worked with me and the correct number of intervals was created.
Extension of @Gilad's answer above for cases when n=0
and n=1
because the latter gives rise to division by zero.
vector<double> linspace(double a, double b, int n) {
vector<double> array;
if ((n == 0) || (n == 1) || (a == b))
array.push_back(b);
else if (n > 1) {
double step = (b - a) / (n - 1);
int count = 0;
while(count < n) {
array.push_back(a + count*step);
++count;
}
}
return array;
}