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);
СТАТУС: НЕ ИСПРАВЛЕНО