2016-10-11 1 views
0

Моя цель - увеличить мой уже существующий конвейер обработки изображений (написанный в Halide) с функциями OpenCV, такими как NL, означает шумоподавление. Функции OpenCV не смогут использовать функции планирования Halide, поэтому я планирую реализовать каждый Halide Func перед каждой стадией OpenCV. Остается вопрос, как лучше всего преобразовать из изображения Halide (результат реализации Func) в Matrix OpenCV (как вход в функцию OpenCV) и от OpenCV Mat до Halide Image, когда это будет сделано. Мои изображения Halide имеют тип float и имеют 3 канала.Как преобразовать OpenCV Mat в Halide Image и обратно?

Одним из очевидных решений является запись функций, которые копируют данные из одного типа данных в другой, но это кажется мне расточительным. Не только потребуется потратить драгоценное время на копирование данных, но также будет уничтожать память, так как изображение будет храниться как два разных типа данных. Есть ли способ использовать указатели или буферы данных, чтобы просто перевернуть данные изображения в новый формат? Надеюсь, этот процесс будет обратимым, поэтому я могу перейти от Halide к OpenCV, а затем после того, как функция OpenCV вернется в Halide.

ответ

0

Да, вы можете избежать копирования данных. Я вижу два возможных подхода: либо распределять память самостоятельно, либо ссылаться на эту память как в экземпляре OpenCV Mat, так и в структуре Halide buffer_t; или пусть класс Mat Matrix OpenCV распределяет память и ссылается на эту память в структуре buffer_t.

Для первого подхода, вы можете использовать конструктор Mat, который принимает указатель на данные:

float* data = new float[3 * width * height]; 
cv::Mat image(height, width, CV_32FC3, data, AUTO_STEP); 

Для второго подхода, вы можете использовать обычный конструктор или Mat :: создать метод:

cv::Mat image(height, width, CV_32FC3); 

в любом случае, вы можете использовать что-то вроде следующего кода, чтобы обернуть память в галоидных структуре buffer_t:

buffer_t buffer; 
memset(&buffer, 0, sizeof(buffer)); 
buffer.host = image.data; 
buffer.elem_size = image.elemSize1(); 
buffer.extent[0] = image.cols; 
buffer.extent[1] = image.rows; 
buffer.extent[2] = image.channels(); 
buffer.stride[0] = image.step1(1); 
buffer.stride[1] = image.step1(0); 
buffer.stride[2] = 1; 

Теперь вы можете работать в одной памяти с функциями OpenCV и Halide.

+0

Большое спасибо за ваш ответ Эрик. Я установил свой код для работы точно так, как вы описали, и он работает для OpenCV, а также для Halide по большей части. Одна странная проблема заключается в том, что когда я делаю изображение из buffer_t: Image input (buffer); Результат выглядит неправильно. – Kantthpel

+0

К сожалению, мы не можем редактировать комментарии. Я хотел сказать, что когда я сохраняю изображение, созданное из буфера, выход кажется неправильным. Однако, когда они передаются через любой Func, данные, как представляется, хранятся правильно, так как сохранение вывода Func, который не выполняет вычисления, приводит к правильному выводу. Похоже, что действие передачи изображения через Func исправляет что-то неправильное в изображении, созданном из буфера – Kantthpel

+0

Альтернативное предложение о странном поведении может заключаться в том, что функция halide save_image не может правильно разобрать шаги, определенные в буфер. Моя причина думать, что это так: когда входные данные являются плоскими, изображение выглядит правильно как до, так и после прохождения через пустой Func. Однако, когда входные данные чередуются (по умолчанию для OpenCV), то только изображение, которое проходит через пустой Func, выглядит правильно. – Kantthpel