From NvBuffer to cvMat BGRA

Hi, Nvidia,
I try to decode the jpeg data with fd and convert to cvMat BGA, but the final cvMat could not save and display with
cv::imwrite and cv::imshow, i dont know the root cause, pls help!
thanks!

the code as below:

void decode_image_nvidia_from_fd(NvJPEGDecoder *jpeg_decoder,unsigned char *in_buf, unsigned long in_buf_size, cv::Mat &img)
{
int fd = 0;
uint32_t width, height, pixfmt;

// Decode image
int ret = jpeg_decoder->decodeToFd(fd, in_buf, in_buf_size, pixfmt, width, height);//output is 
                                                                                           //fd,pixfmt,width,height and pixfmt is YUV422M
                                                                                                                                                    
if (ret < 0)
{
    LOG(ERROR) << "decode to Fd fail!";
}

LOG(INFO) << "fd = " << fd << ",pixfmt = " << pixfmt;

ret = decode_image_with_fd(fd,height,width,img);
if (ret < 0)
{
    LOG(ERROR) << "Could not decode image with fd!";
}

}
static int
decode_image_with_fd(const int input_fd, uint32_t const height,uint32_t const width, cv::Mat &img)
{
int ret = 0;

NvBufferCreateParams output_params;
NvBufferTransformParams transform_params;

output_params.width = width;
output_params.height = height;
output_params.layout = NvBufferLayout_Pitch;
output_params.payloadType = NvBufferPayload_SurfArray;
output_params.nvbuf_tag =  NvBufferTag_NONE;
output_params.colorFormat = NvBufferColorFormat_ABGR32;

// output_params.memsize = 4 * width * height;

int output_fd = 0;
//ret = NvBufferCreateEx(&output_fd, &output_params);

// typedef struct _NvBufferChromaSubSamplingParams
// {
// uint8_t chromaLocHoriz;
// uint8_t chromaLocVert;
// }NvBufferChromaSubsamplingParams;
NvBufferChromaSubsamplingParams SubsamplingParams;
SubsamplingParams.chromaLocHoriz = 0;
SubsamplingParams.chromaLocVert = 0;

ret = NvBufferCreateWithChromaLoc(&output_fd, &output_params,&SubsamplingParams);

if (ret)
{
    LOG(ERROR) << "Error in creating the output buffer!";
}

memset(&transform_params, 0, sizeof(transform_params));
transform_params.transform_flag = NVBUFFER_TRANSFORM_FILTER ;
transform_params.transform_flip = NvBufferTransform_None;
transform_params.transform_filter = NvBufferTransform_Filter_Smart;

transform_params.src_rect.top = 0;
transform_params.src_rect.left = 0;
transform_params.src_rect.width = width;
transform_params.src_rect.height = height;

transform_params.dst_rect.top = 0;
transform_params.dst_rect.left = 0;
transform_params.dst_rect.width = width;
transform_params.dst_rect.height = height;

ret = NvBufferTransform(input_fd, output_fd, &transform_params);
if (ret)
{
    LOG(ERROR) << "Error in transforming NvBuffer!";
}

cv::Mat bgraMat(height, width, CV_8UC4);
if (NvBuffer2Raw(output_fd, 0, width, height, bgraMat.data))
{
	LOG(ERROR) << "NvBuffer2Raw failed!";
}

img.create(height, width, CV_8UC3);

cv::cvtColor(bgraMat,img,cv::COLOR_RGBA2BGR);

// cv::imshow("imag",img);
// cv::waitKey(1);

NvBufferDestroy(output_fd);

return 0;


}

May I know which Jetson platform and which JetPack version you’re using?

Hi, kayccc,

i type the command “jtop”

it shows
“NVIDIA Jetson AGX Xavier[16GB] - Jetpack unknow[L4T 32.5.2]”

Hi,
Please refer to this patch:
NVBuffer (FD) to opencv Mat - #6 by DaneLLL

You would need to convert RGBA to BGR and then call cv::imwrite or cv::imshow

Hi,

actually i already convert RGBA to BGR by cv::cvtColor before imwrite…, you can refer to the code i list

img.create(height, width, CV_8UC3);
cv::cvtColor(bgraMat,img,cv::COLOR_RGBA2BGR);

// cv::imshow(“imag”,img);
// cv::waitKey(1);

NvBufferDestroy(output_fd);

Hi,
You may try NvBufferMemMap() as demonstrated in the patch. See if this approach works.

Hi DaneLLL,

follow your suggestion, i i try the below code , but still fail…

static int decode_image_with_fd(const int input_fd, uint32_t const height,uint32_t const width, cv::Mat &img)
{
int ret = 0;

NvBufferCreateParams output_params;
NvBufferTransformParams transform_params;

output_params.width = width;
output_params.height = height;
output_params.layout = NvBufferLayout_Pitch;
output_params.payloadType = NvBufferPayload_SurfArray;
output_params.nvbuf_tag =  NvBufferTag_NONE;
output_params.colorFormat = NvBufferColorFormat_ABGR32;

// output_params.memsize = 4 * width * height;

int output_fd = 0;
ret = NvBufferCreateEx(&output_fd, &output_params);
if (ret)
{
    LOG(ERROR) << "Error in creating the output buffer!";
}

memset(&transform_params, 0, sizeof(transform_params));
transform_params.transform_flag = NVBUFFER_TRANSFORM_FILTER ;
transform_params.transform_flip = NvBufferTransform_None;
transform_params.transform_filter = NvBufferTransform_Filter_Smart;

// transform_params.src_rect.top = 0;
// transform_params.src_rect.left = 0;
// transform_params.src_rect.width = width;
// transform_params.src_rect.height = height;

// transform_params.dst_rect.top = 0;
// transform_params.dst_rect.left = 0;
// transform_params.dst_rect.width = width;
// transform_params.dst_rect.height = height;

ret = NvBufferTransform(input_fd, output_fd, &transform_params);
if (ret)
{
    LOG(ERROR) << "Error in transforming NvBuffer!";
}

void *pdata = NULL;

NvBufferMemMap(output_fd, 0, NvBufferMem_Read, &pdata);
NvBufferMemSyncForCpu(output_fd, 0, &pdata);

cv::Mat imgbuf = cv::Mat(height, width, CV_8UC4, pdata);

cvtColor(imgbuf, img, cv::COLOR_RGBA2BGR);

cv::imwrite("1.jpg",img);

NvBufferMemUnMap(output_fd, 0, &pdata);

//NvBufferDestroy(output_fd);

return 0;

}

Hi,
The code looks fine and not sure why it doesn’t work. You may try to call dump_dmabuf() and check the dumped RGBA data via YUV viewer. To check if the data is valid. And they’re later releases like r32.7.2, r32.7.3. You may consider upgrade to later release.

ok, DaneLLL, thanks for your reply, i try to dump and further analysis

thanks !

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.