How do I declare a vector in OpenCV? - c++

How do you write a vector in OpenCV? that contains 3 values like this v = [p1,p2,p3]? This is what I tried:
int dim [1] = {3};
Mat v(1,dim,CV_32F, Scalar(p1,p2,p3));
But when I do debug in Qt, I see in the local and expression window that the vector v indeed has 1 column and 3 rows but has also 2 dim. I was wondering if this is due to the Mat type in the declaration.
With which type could I replace it to get just a simple vector of 3 values?

Which type could I use to get just a simple vector of 3 values? I want to do some operation on this vector like use the norm and change it's elements.
You can use cv::Vec type.
Assuming you're working on double values (the same applies for other types) you can:
// Create a vector
Vec3d v;
// Assign values / Change elements
v[0] = 1.1;
v[1] = 2.2;
v[2] = 3.3;
// Or initialize in the constructor directly
Vec3d u(1.1, 2.2, 3.3);
// Read values
double d0 = v[0];
// Compute the norm, using cv::norm
double norm_L2 = norm(v, NORM_L2); // or norm(v);
double norm_L1 = norm(v, NORM_L1);
For:
double type use Vec3d
float type use Vec3f
int type use Vec3i
short type use Vec3s
ushort type use Vec3w
uchar type use Vec3b

Related

Dot product as multiplication in armadillo

I have a row vector and a column vector and I would like to take their dot product.
rowvec v = {1,2,3,4};
vec w = {5,6,7,8};
double a = dot(v,w) // works
double b = v*w // doesn't work
double c = (v*w)(0) // doesn't work
double d = static_cast<vec>(v*w)(0) //works
Is it possible to get something that looks like b? I would like it for readability.
You may also use
double b = as_scalar(v*w);
but that was not really what you wanted ...
Don't think there are any other alternatives available except using mat format for v,w and b. Then you will get a [1x1] matrix for v*w and a [4x4] matrix for w*v

How to cast CV_64F type Matrix to 1D Array with Double elements

I couldn't find an answer to this question but I believe it should be easily done.
Here I have following data structures;
Mat MyMatrix = Mat(3, 1, CV_64F, &targetArray) //Some 3x1 data in it
// Some process...
array <double ,3> MyArray
MyMatrix.convertTo(MyArray, double, 0 , DBL_MAX)
I want to convert MyMatrix (which I guarantee to be 3x1) to an 1D Array (Array elements should be double). How can I do that with C++ and opencv3.0.1?
You cannot convert a cv::Mat to a std::array. You can only copy the data into an array.
Given a
Mat m = Mat(3, 1, CV_64F);
// fill with some value
you can use memcpy:
array<double, 3> a;
memcpy(a.data(), m.ptr<double>(0), 3*sizeof(double));
or std::copy:
array<double, 3> b;
copy(m.begin<double>(), m.end<double>(), b.begin());
or, since it's only 3 elements, the array constructor:
array<double, 3> c = {m.at<double>(0), m.at<double>(1), m.at<double>(2)};
or, obviously, with a loop:
array<double, 3> d;
for (int i = 0; i < d.size(); ++i) { d[i] = m.at<double>(i); }
Conversion is instead possible with std::vector:
vector<double> e = m;
Note that, instead of a matrix with only 3 values, you can use Vec3d, or Matx31 or Matx13. Using Mat1d would however simplify the notation and make the code less verbose.

c++ armadillo cast/convert to integer type vector or matrix

How can I convert a double/float-typed vector or matrix to an word/uword-typed vector or matrix?
I need to create an indexing array indices.
vec t = linspace(0, 100);
double freq = 0.25;
indices = floor(t / freq);
I'm having trouble on the last line.
If you are just dealing with positive values, then the conv_to function of the armadillo package will do exactly the same as the method you are trying to use.
vec t = linspace(0, 100);
double freq = 0.25;
ivec indices = conv_to<ivec>::from(t / freq);
If you want the results to be the same as the use of the floor function for negative values of t, you could replace the last line with
ivec indices = conv_to<ivec>::from(floor(t / freq));
Your best bet would be to use an iterator to walk through your t vector, and then push back the results of floor( *it_to_t / freq ) onto your indices vector.

How to specify the result type of MatExpr?

I have this expression in my code:
*h = ((*R) / ((*G) + (*R)));
where R, G and B are Mat pointers of uchar since there is division I want to convert the answer into a Mat pointer of float
so i tried this
*h = Mat_<float>((*R) / ((*G) + (*R)));
but I get segmentation fault for it.
How should I do it?
You need to convert the matrix *R into floats. Use method Mat::convert_to. Assuming R8 is a matrix of uchar you can create float matrix as follows:
Mat R32; R8.convertTo(R32,CV_32F);
This is nicely explained in introduction to OpenCV.
Note 1: This expression *h = Mat_<float>((*R) / ((*G) + (*R))) performs division using uchars and later re-interpret the result as float, which is wrong. Mat_<float> is only to simplify element access for arrays that are already floats.
Note 2: You don't need to use pointers to Mat most of the time.

How do I create a 2D Array in D?

This should be simple enough, but it's not.
import std.container, std.stdio;
void main(){
alias Array!double _1D;
alias Array!_1D _2D;
_1D a = _1D();
_2D b = _2D();
a.insert(1.2);
a.insert(2.2);
a.insert(4.2);
b.insert(a);
writeln(b[0][]); // prints [1.2, 2.2, 4.2], then throws exception
_2D c = _2D();
c.insert(_1D());
c[0].insert(3.3);
c[0].insert(2.2);
c[0].insert(7.7);
writeln(c[0][]); // prints []
}
Another method I was clued into by this question to declare the size of a dynamic array in advance is as follows:
auto matrix = new double[][](3, 2); // elements can be appended/removed
Though there are a variety of different ways to do it depending on how arbitrarily you want to add elements. You'll of course want to pick whichever style works best for your program, but here are some possibilities:
double[][] matrix = [[1.1, 1.2], [2.3, 2.4], [3.5, 3.6]];
or
double[][] matrix;
matrix ~= [1.1, 1.2];
matrix ~= [2.3, 2.4];
matrix ~= [3.5];
matrix[2] ~= 3.6;
or
double[][] matrix = new double[][](1,0);
matrix[0].length = 2;
matrix[0][0] = 1.1;
matrix[0][1] = 1.2;
++matrix.length;
matrix[1] ~= 2.3;
matrix[1] ~= 2.4;
matrix ~= new double[](0);
matrix[$-1] ~= [3.5, 3.6];
and finally, if you know that the size of your array at compile time and it will not ever change, you can create a static array instead:
double[2][3] staticMatrix; // size cannot be changed
These all use the natural builtin array mechanism though. Is there a specific reason you need to use the Array container class?