Преобразование зацикливания матрицы OpenCV в JavaCV

Не так давно я получил книгу «Изучение OpenCV» О'Рейли, и с тех пор я был занят преобразованием всего кода, который я там вижу, из OpenCV в JavaCV, за которым обычно следуют небольшие изменения. Все это время я стараюсь максимально придерживаться чистого кода OpenCV (C) и избегать Java. Например, я реализовал все элементы интерфейса непосредственно через пакет highgui OpenCV в JavaCV, а не через Java Swing. Делая это, я надеюсь изучить библиотеку OpenCV и немного C в относительно короткие сроки, а также создать библиотеку полезных функций, которые я смогу легко преобразовать в C, если позже решу перейти на чистый OpenCV.

Во всяком случае, я немного знаю C и иногда сталкиваюсь с проблемами при работе с указателями. В книге рекомендуется следующий код в качестве оптимального способа перебора 3-канальной матрицы:

float sum( const CvMat* mat ) {
    float s = 0.0f;
    for(int row=0; row<mat->rows; row++ ) {
        const float* ptr = (const float*)(mat->data.ptr + row * mat->step);
        for( col=0; col<mat->cols; col++ ) {
            s += *ptr++;
        }
    }
    return( s );
}

Вот включенное объяснение этого кода:

При вычислении указателя на матрицу помните, что данные элемента матрицы являются объединением. Следовательно, при отмене ссылки на этот указатель вы должны указать правильный элемент объединения, чтобы получить правильный тип указателя. Затем, чтобы отключить этот указатель, вы должны использовать шаговый элемент матрицы. Как отмечалось ранее, элемент шага находится в байтах. Чтобы быть в безопасности, лучше всего сделать арифметику указателя в байтах и> затем привести к соответствующему типу, в этом случае float. Хотя структура CVMat имеет> концепцию высоты и ширины для совместимости со старой структурой IplImage, вместо этого мы используем более современные строки и столбцы. Наконец, обратите внимание, что мы пересчитываем ptr для> каждой строки, а не просто начинаем с начала и затем увеличиваем этот указатель при каждом чтении. Это может показаться чрезмерным, но поскольку указатель данных CvMat может просто указывать на ROI в большем массиве, нет гарантии, что данные будут> смежными между строками.

Однако у меня возникли проблемы с преобразованием его в JavaCV. Поле ptr (указатель) кажется плавающим, что меня смущает. Я предполагаю, что это на самом деле не «указатель», а значение, к которому добавляется значение каждого пикселя? Или это на самом деле указатель, в котором значение s находит общую сумму для всех столбцов в данной строке?

В любом случае, я был бы признателен, если бы кто-нибудь опубликовал для меня код JavaCV для эквивалентного цикла. Я знаю, что есть другие способы доступа к каждому пикселю в CvMat, но AFAIK они все менее эффективны или неточны.

Ответы на вопрос(2)

Ваш ответ на вопрос