0

I'm porting a ComputerVision project to OpenFrameworks right now and part of it is emulating some small parts of a library, for which I'm writing my own, much more lightweight helper class.

I have Vectors and Matrices for which I use the OpenCV classes cv::Vec and cv::Matx. They're simple containers with little functionality, but that's fine for the most part.

The function I try to mock is a slice function. Basically take a row of a Matrix and return a Vector, or take a subset of a vector and return that smaller vector. Right now I have something like this:

template<typename Precision, int Start, int Length, int X>
cv::Vec<Precision, Length> slice(cv::Vec<Precision, X> v)
{
    assert(Start >= 0);
    assert((Start+Length) <= X);

    cv::Vec<Precision, Length> temp;

    for (int i = 0; i < Length; i++)
        temp[i] = v[Start+i];

    return temp;
}

And I would use it like this:

cv::Vec<double, 3> newVector = ImpUtil::slice<double, 3, 3, VectorLength>(vector);

cv::Vec does not have a member telling your long it is, so I have to pass the length over anyway right now. This is one reason why I plan to write my own class for this at some point.

The problem is that I'm using a template function that uses a template class. The int X/VectorLength part of the whole function is purely for the class however, and I was wondering if I could drop it somehow (and yes, this would mean dropping the 'assert' for now). The function should work with vectors of any length and besides the assert (which I may get from the vector at some point) it has no use within the function.

Gregor A. Lamche
  • 402
  • 2
  • 5
  • 18
  • You're not using `cv::Vec` the way it's supposed to be used. Use `std::vector` instead, or `std::array` – Miki Apr 05 '17 at 11:24
  • I can't say I'm using `cv::Vec` correctly (`cv::` has several Vector classes), but `std::vector` is definitely a different thing. I need the mathematical construct with dot and cross product, not an array. – Gregor A. Lamche Apr 05 '17 at 11:29
  • So why not using a `cv::Mat` with a single row/column? It seems to me you're over-complicating things – Miki Apr 05 '17 at 11:32
  • Hah! I've been asking me the same thing. One reason is to have the Vector/Matrix difference in the typing, and not just in the name/use. The other is that I can access `cv::Vec` with the `[]` operator which both `cv::Matx` and `cv::Mat` are omitting ( `operator() (int i, int j)` of `cv::Matx` is like fingernails on blackboard to me, and `at()` of `cv::Mat` is also a tick less readable than `[]`). In the end it may just be personal preferences, I have to admit. – Gregor A. Lamche Apr 05 '17 at 11:42

1 Answers1

1

I am trying to guess what is the problem here.

I guess that the problem you are trying to solve is having to specify "obvious" template parameters explicitly:

cv::Vec<double, VectorLength> vector; // did I guess this declaration right?
...
cv::Vec<double, 3> newVector = ImpUtil::slice<double, 3, 3, VectorLength>(vector);

In this code, it's clear that vector is of length 3 and contains double, yet you have to specify it in angle brackets for slice.

If this is the problem you are trying to solve, just rearrange the template parameters, so the "obvious" ones are at the end. If you don't specify all of the template parameters, the compiler will deduce the missing ones at the end.

template<int Start, int Length, typename Precision, int X>
cv::Vec<Precision, Length> slice(cv::Vec<Precision, X> v);

...

cv::Vec<double, VectorLength> vector; // I guessed this declaration
...
cv::Vec<double, 3> newVector = ImpUtil::slice<3, 3>(vector);
Community
  • 1
  • 1
anatolyg
  • 26,506
  • 9
  • 60
  • 134
  • Yeah, that's how I meant it, but wouldn't that only work if X is known at compile time? In some cases I'm going through loops of dynamic length and X is not fix. – Gregor A. Lamche Apr 05 '17 at 11:16