Доступ к массиву OpenCV Mat, какой путь самый быстрый и почему?
Меня интересует способ доступа к данным в Mat в OpenCV. Как вы знаете, мы можем получить доступ к данным разными способами. Я хочу сохранить изображение (ширина х высота х 1 глубина) в Mat и циклический доступ к каждому пикселю в изображении. Лучше всего использовать ptr<>(irow), чтобы получить пиксель строки, а затем получить доступ к каждому столбцу в строке? или лучше использовать <>(irow,jcol)? или с помощью прямого расчета индекса с помощью index = irow*Width + jrow является лучшим? Кто-нибудь знает причину.
заранее спасибо
4 ответа
Вы можете найти информацию здесь в документации: основной контейнер изображений и как сканировать изображения.
Я советую вам практиковаться с at
( здесь), если у вас нет опыта работы с OpenCV или с языками Си. Но самый быстрый способ ptr
как ответит Nolwenn, потому что вы избегаете проверки типов.
at<T>
выполняет проверку диапазона при каждом вызове, делая его медленнее, чем ptr<T>
, но безопаснее.
Итак, если вы уверены, что ваши расчеты дальности верны и вы хотите максимально возможную скорость, используйте ptr<T>
,
Согласно официальной документации, они предполагают, что наиболее эффективный способ - сначала получить указатель на строку, а затем просто использовать простой оператор C []. Это также сохраняет умножение для каждой итерации.
// compute sum of positive matrix elements
// (assuming that M isa double-precision matrix)
double sum=0;
for(int i = 0; i < M.rows; i++)
{
const double* Mi = M.ptr<double>(i);
for(int j = 0; j < M.cols; j++)
sum += std::max(Mi[j], 0.);
}
Я понимаю, что это старый вопрос, но я думаю, что текущие ответы как-то вводят в заблуждение.
Вызов обоих at<T>(...)
а также ptr<T>(...)
проверим границы в режиме отладки. Если _DEBUG
макрос не определен, они будут в основном вычислять y * width + x
и дать вам указатель на данные или сами данные. Итак, используя at<T>(...)
в режиме выпуска эквивалентно вычислению указателя самостоятельно, но безопаснее, потому что вычисление указателя не просто y * width + x
если матрица является просто подвидом другой матрицы. В режиме отладки вы получаете проверки безопасности.
Я думаю, что лучший способ - обрабатывать изображение построчно, получая указатель строки, используя ptr<T>(y)
а затем с помощью p[x]
, Преимущество этого заключается в том, что вам не нужно считать с различными макетами данных и все еще простым указателем для внутреннего цикла.
Вы можете использовать простые указатели полностью, что будет наиболее эффективно, потому что вы избегаете одного умножения на строку, но тогда вам нужно использовать step1(i)
продвигать указатель. Я думаю, что с помощью ptr<T>(y)
хороший компромисс