How to copy cv::cuda::GpuMat to jetson-utils image

Now I am trying to convert GpuMat in OpenCV to the format in jetson-utils. The below is my code to do that:

cv::Mat in_img = cv::imread(img_path);
int in_width = in_img.cols;
int in_height = in_img.rows;
cv::cuda::GpuMat g_img;
g_img.upload(in_img);

uchar3* j_img{NULL};
uint8_t* out_img{NULL};
if(!cudaAllocMapped((void**)&j_img, in_width, in_height, IMAGE_BGR8))
    std::cerr << "ALLOC ERROR" << std::endl;
if(CUDA_FAILED(cudaMemcpy((void*)j_img, g_img.cudaPtr(), imageFormatSize(IMAGE_BGR8, in_width, in_height), cudaMemcpyDeviceToDevice)))
    std::cerr << "COPY ERROR" << std::endl;
saveImage("/app/out.png", j_img, in_width, in_height, 100);

This is my input image:


And this is output image:

In my opinion, it seems that data layout format was be set wrong.
Can anyone help me to fix it? Thanks in advance.

While I do a reversed process, it works right.

uchar3* in_img = NULL;
int in_width{0};
int in_height{0};
if(!loadImage(img_path.c_str(), &in_img, &in_width, &in_height))
  std::cerr << "LOAD ERROR" << std::endl;

cv::cuda::GpuMat g_out(in_height, in_width, CV_8UC3, (void*)in_img);
cv::cuda::cvtColor(g_out, g_out, cv::COLOR_BGR2RGB);
cv::Mat out_img;
g_out.download(out_img);
cv::imwrite("/app/out_cv.png", out_img);

The output image is as same as the input.

Hi,

Could you check below for an example of loading a GPU buffer to jetson-utils?

The allocated buffer size is expected to be width * sizeof(unsigned char) * channels.
Please double-check if the channel value matches the parameter you used first.

Thanks.

1 Like

I was successful to fix it. The problem is not in image layout format. But it is in memory allocation of GpuMat. There is gap between rows of GpuMat. To solve this issue, I must allocate a continuous memory before updating data into as following:

cv::Mat in_img = cv::imread(img_path);
int in_width = in_img.cols;
int in_height = in_img.rows;

uchar3* j_img{NULL};
if(!cudaAllocMapped((void**)&j_img, in_width, in_height, IMAGE_BGR8))
    std::cerr << "ALLOC ERROR" << std::endl;
cv::cuda::GpuMat g_img(in_height, in_width, CV_8UC3, (void*)j_img);
g_img.upload(in_img);

saveImage("/app/out.png", j_img, in_width, in_height, 100);

It’s done.