Доступ к массиву OpenCV Mat, какой способ самый быстрый и почему?

Мне интересно, как получить доступ к данным в Mat в OpenCV. Как вы знаете, мы можем получить доступ к данным разными способами. Я хочу сохранить изображение (ширина x высота x 1 глубина) в Mat и зациклить доступ к каждому пикселю изображения. Лучше всего использовать ptr‹>(irow) для получения пикселя строки, а затем получить доступ к каждому столбцу в строке? или лучше использовать at‹>(irow,jcol)? или лучше всего использовать прямой расчет индекса с помощью index = irow*Width + jrow? Кто-нибудь знает причину.

заранее спасибо


person Community    schedule 11.01.2013    source источник


Ответы (4)


Вы можете найти информацию здесь в документации: основной контейнер изображения и как сканировать изображения.

Я советую вам попрактиковаться с at (здесь), если вы не знакомы с OpenCV или с типами языка C, черт возьми. Но самый быстрый способ - ptr как ответ Nolwenn, потому что вы избегаете проверки типа.

person nkint    schedule 11.01.2013

Я понимаю, что это старый вопрос, но я думаю, что текущие ответы как-то вводят в заблуждение.

Вызов как at<T>(...), так и ptr<T>(...) проверит границы в режиме отладки. Если макрос _DEBUG не определен, они в основном вычислят y * width + x и дадут вам либо указатель на данные, либо сами данные. Таким образом, использование at<T>(...) в режиме деблокирования эквивалентно самостоятельному вычислению указателя, но безопаснее, поскольку вычисление указателя — это не просто y * width + x, если матрица является просто подвидом другой матрицы. В режиме отладки вы получаете проверки безопасности.

Я думаю, что лучший способ - обрабатывать изображение построчно, получая указатель строки с помощью ptr<T>(y), а затем с помощью p[x]. Преимущество этого заключается в том, что вам не нужно учитывать различные макеты данных и по-прежнему простой указатель для внутреннего цикла.

Вы можете постоянно использовать простые указатели, что было бы наиболее эффективно, поскольку вы избегаете одного умножения на строку, но тогда вам нужно использовать step1(i) для продвижения указателя. Я думаю, что использование ptr<T>(y) — хороший компромисс.

person Lukáš Lalinský    schedule 12.12.2014

at<T> выполняет проверку диапазона при каждом вызове, что делает его медленнее, чем ptr<T>, но безопаснее.

Итак, если вы уверены, что ваши расчеты дальности верны, и вам нужна максимально возможная скорость, используйте ptr<T>.

person user703016    schedule 11.01.2013

Согласно официальной документации, они предполагают, что наиболее эффективный способ — сначала получить указатель на строку, а затем просто использовать простой оператор 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.);
}
person beahacker    schedule 07.05.2015