giapvn
April 9, 2025, 9:18am
1
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.
giapvn
April 9, 2025, 10:18am
2
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?
LogError(LOG_IMAGE " * rgb8\n");
LogError(LOG_IMAGE " * rgba8\n");
LogError(LOG_IMAGE " * rgb32f\n");
LogError(LOG_IMAGE " * rgba32f\n");
LogError(LOG_IMAGE " * gray8\n");
LogError(LOG_IMAGE " * gray32\n");
return false;
}
// allocate memory for the uint8 image
const size_t channels = imageFormatChannels(format);
const size_t stride = width * sizeof(unsigned char) * channels;
const size_t size = stride * height;
unsigned char* img = (unsigned char*)ptr;
// if needed, convert from float to uint8
const imageBaseType baseType = imageFormatBaseType(format);
if( baseType == IMAGE_FLOAT )
{
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
giapvn
April 10, 2025, 8:00am
5
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.