C ++: получить изображение BGR (cv :: Mat) из памяти графического процессора (cudaMemcpy2D) - PullRequest
0 голосов
/ 28 января 2020

Я работаю над обработкой изображений и разработал оболочки для камер с OpenCV для RGB и моно chrome камеры. Теперь мне нужно использовать существующий алгоритм, который работает с CUDA для обработки этих двух потоков изображений с камеры. Для этого я должен скопировать изображения Mat на свое устройство (алгоритм не принимает gpumat). Я использую cv::Mat::ptr для доступа к данным изображений. Когда я использую cudaMemcpy2D, чтобы вернуть изображение на хост, я получаю темное изображение (только нули) для изображения RGB. Даже когда я использую cudaMemcpy2D, чтобы просто загрузить его на устройство и вернуть его на следующем шаге с cudaMemcpy2D, он не будет работать (я имею в виду, что я не делаю никакой обработки изображения между ними). Это работает нормально для моно изображения, хотя:

width = 1920; (image dimensions are the same for mono and BGR)
height = 1080;
Mat mat_mono(height, width, CV_8UC1);
Mat mat_mono_disp(height, width, CV_8UC1);
size_t pitch_mono;
uint8_t* image_mono_gpu,
size_t matrixLenMono = width;

cudaMallocPitch(&image_mono_gpu, &pitch_mono, width, height);

mat_mono = MonoCamera.CaptureMat(1); // wrapper for the mono camera that grabs the image

// copy to device
cudaMemcpy2D(image_mono_gpu, pitch_mono, mat_mono.ptr(), width, matrixLenMono, height, cudaMemcpyHostToDevice);

// copy back to host
cudaMemcpy2D(mat_mono_disp.ptr(), matrixLenMono, image_mono_gpu, pitch_mono, matrixLenMono, height, cudaMemcpyDeviceToHost);

namedWindow("Display window", WINDOW_AUTOSIZE);
imshow("Display window", mat_mono_disp);

Это код для изображения RGB (или, скорее, BGR), где я получаю только темное изображение после получения изображения с устройства:

Mat mat_BGR(height, width, CV_8UC3);
Mat mat_BGR_disp(height, width, CV_8UC3);
size_t pitch_BGR;
uint8_t* image_BGR_gpu,
size_t matrixLenBGR = width * 3;

cudaMallocPitch(&image_BGR_gpu, &pitch_BGR, matrixLenBGR, height);

mat_BGR = RGBCamera.CaptureMat(1); // wrapper for the RGB camera that grabs the image

// copy to device
cudaMemcpy2D(image_BGR_gpu, pitch_BGR, mat_BGR.ptr(), width, matrixLenBGR, height, cudaMemcpyHostToDevice);

// copy back to host
cudaMemcpy2D(mat_BGR_disp.ptr(), matrixLenBGR, image_BGR_gpu, pitch_BGR, matrixLenBGR, height, cudaMemcpyDeviceToHost);

namedWindow("Display window", WINDOW_AUTOSIZE);
imshow("Display window", mat_BGR_disp);

Означает ли это, что использование cv::Mat:ptr с монофоническим изображением работает, поскольку это особый случай? Я не знаю, что мне нужно учитывать при использовании изображения BGR.

1 Ответ

2 голосов
/ 04 февраля 2020

Как указано в предыдущем ответе , при выполнении копирования 2D-памяти OpenCV Mat в память устройства, выделенную с использованием cudaMallocPitch (или любой расширенной 2D-памяти ), мы должны используйте step член OpenCV Mat для определения выравнивания каждой строки.

В предоставленном коде правильным способом было бы использовать mat_BGR.step вместо width в 4-м аргументе cudaMemcpy2D.

cudaMemcpy2D(image_BGR_gpu, pitch_BGR, mat_BGR.ptr(), mat_BGR.step, matrixLenBGR, height, cudaMemcpyHostToDevice);
                                                              ^^^^
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...