Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenCV iterate over columns

I am trying to iterate over the columns of a matrix (e.g. its a bunch of column vectors that are concatenated into a matrix and I'd like to operate on each column vector separately). It is pretty easy to do this using a for loop:

for(int n = 0; n < mat.cols; n++)
{
    cv::Mat c = mat.col(n);
    // do stuff to c
}

But I'd like to do it using iterators if possible so that I can using std::accumulate or std::transform to simplify my code.

so Im basically looking for something like

for each Mat c in mat.columns

Mat has begin<> and end<> function but as far as I know it can only be used to iterate over single elements.

Can this be done somehow?

Just to be clear I'd like to write

cv::Mat input;

cv::Mat output = std::accumulate(input.begincols(), input.endcols(), cv::Mat::zeros(n,k,CV_64F),
[](const cv::Mat &acum, const cv::Mat &column) { return acum + column * 5; });

For a simple example.

Update:

So since this hasn't been answered, if anyone has a home grown solution to provide iterators like this I'd take a look otherwise I might look into it myself if I get the chance

like image 273
Max Ehrlich Avatar asked Mar 12 '14 20:03

Max Ehrlich


1 Answers

Maybe overloading the accumulate function can help. Instead of (possible implementation of the standard)

template<class InputIt, class T>
T std::accumulate(InputIt first, InputIt last, T init)
{
   for (; first != last; ++first) {
        init = init + *first;
   }
   return init;
}

You can write your own, accumulate.

template<class InputIt, class T>
T std::accumulate(InputIt first, InputIt last, T init, std::size_t incr)
{
   for (; first != last; first += incr) {
        init = init + *first;
   }
   return init;
}

To use it for your images. You have to use the steplength (Math::step1() i guess ) for incr. This should work, but i haven't tested it. Please give feedback if it worked for you.

like image 52
user1235183 Avatar answered Sep 28 '22 00:09

user1235183