OpenCV итерация по столбцам

Я пытаюсь выполнить итерацию по столбцам матрицы (например, ее кучу векторов столбцов, которые объединены в матрицу, и я хотел бы использовать каждый вектор столбца отдельно). Это довольно легко сделать с помощью цикла for:

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

Но я бы хотел сделать это с помощью итераторов, если это возможно, чтобы я мог использовать std:: accumulate или std:: transform, чтобы упростить мой код.

поэтому я в основном ищу что-то вроде

for each Mat c in mat.columns

Mat имеет функцию begin<> и end<>, но насколько я знаю, ее можно использовать только для перебора отдельных элементов.

Как это можно сделать?

Чтобы быть ясным, я бы хотел написать

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; });

Для простого примера.

Обновление:

Итак, поскольку на это не было ответа, если у кого-то есть домашнее решение для предоставления итераторов, как это, я бы посмотрел, иначе я мог бы изучить его сам, если у меня будет шанс

Ответ 1

Ну, прошло уже около двух лет с тех пор, как я опубликовал этот вопрос, но я, наконец, добрался до такой библиотеки. Вы можете найти его здесь.

https://gitlab.com/Queuecumber/opencvit

Он распространяется как простая в использовании библиотека сопутствующих программ для opencv по лицензии MIT. Примеры приведены в readme и должны быть очень интуитивными для людей, которые знают свой STL. Сейчас он предоставляет column_iterator и row_iterator, но есть еще много возможностей. Если у кого-то есть предложения или обнаружены ошибки, оставьте вопрос на репо.

Ответ 2

Может быть, перегрузка функции накопления может помочь. Вместо (возможная реализация стандарта)

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

Вы можете написать свой собственный, накапливать.

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;
}

Использовать его для ваших изображений. Вы должны использовать steplength (Math:: step1(), я думаю) для incr. Это должно работать, но я не тестировал его. Пожалуйста, дайте отзыв, если он сработает для вас.

Ответ 3

Проблема заключается в том, что изображения cv:: Mat могут иметь смещение (size (row)!= step()). Возможно, вы хотите создать datastructure с массивом указателей на начало каждой строки (например, созданной Mat:: ptr), тогда вы можете сделать что-то вроде этого:

std::vector<uchar*> matRows( mat.rows );
// init matRows via mat.ptr
//....

for (auto i : matRows)
    std::transform( i.begin(), i.begin() + mat.cols, i.begin(), my_trafo);

СТАТУС: НЕ ИСПРАВЛЕНО