Hello, I am trying to update to NvBufSurf a module I did for Jetpack 4.6.X to be able to transform a cv::MAT image → jpeg. However, there is something wrong doing RGBA → NV12 → RGBA with NvBufsurfaceTransform as it changes the colors of the image.
NvBuffer
//MWE for NVIDIA Dev Forums
//Jetpack 4.6.3 with old NvBuffer
#include <opencv2/opencv.hpp>
#include <NvJpegEncoder.h>
#include <NvBuffer.h>
#include <nvbuf_utils.h>
#include <fstream>
using namespace std;
int main() {
cv::Mat frame=cv::imread("testcard.png");
int dmaFd;
NvBufferCreateParams params = {
.width = frame.size().width,
.height = frame.size().height,
.payloadType = NvBufferPayload_SurfArray,
.memsize = frame.cols * frame.rows,
.layout = NvBufferLayout_Pitch,
.colorFormat = NvBufferColorFormat_ARGB32,
.nvbuf_tag = NvBufferTag_JPEG
};
if (NvBufferCreateEx(&dmaFd, ¶ms)) {
std::cerr << "Create buffer failed\n";
return(-1);
}
int dmaFd1;
NvBufferCreateParams params1 = {
.width = frame.size().width,
.height = frame.size().height,
.payloadType = NvBufferPayload_SurfArray,
.memsize = frame.cols * frame.rows,
.layout = NvBufferLayout_Pitch,
.colorFormat = NvBufferColorFormat_NV12,
.nvbuf_tag = NvBufferTag_JPEG
};
if (NvBufferCreateEx(&dmaFd1, ¶ms1)) {
std::cerr << "Create buffer failed\n";
return(-1);
}
int dmaFd2;
NvBufferCreateParams params2 = {
.width = frame.size().width,
.height = frame.size().height,
.payloadType = NvBufferPayload_SurfArray,
.memsize = frame.cols * frame.rows,
.layout = NvBufferLayout_Pitch,
.colorFormat = NvBufferColorFormat_ARGB32,
.nvbuf_tag = NvBufferTag_JPEG
};
if (NvBufferCreateEx(&dmaFd2, ¶ms2)) {
std::cerr << "Create buffer failed\n";
return(-1);
}
NvBufferTransformParams trans_params = {0};
trans_params.transform_flag = NVBUFFER_TRANSFORM_FILTER;
trans_params.transform_filter = NvBufferTransform_Filter_Smart;
cv::Mat yuv;
cv::cvtColor(frame, yuv, cv::COLOR_BGR2BGRA);
if (Raw2NvBuffer(yuv.data, 0, frame.cols, frame.rows, dmaFd)) {
std::cerr << "Raw2NvBuffer failed\n";
return(-2);
}
if (0 != NvBufferTransform(dmaFd, dmaFd1, &trans_params)) {
std::cerr << "NvBufferTransform failed\n";
}
if (0 != NvBufferTransform(dmaFd1, dmaFd2, &trans_params)) {
std::cerr << "NvBufferTransform failed\n";
}
cv::Mat bgraMat2(frame.rows, frame.cols, CV_8UC4);
if (NvBuffer2Raw(dmaFd2, 0, yuv.cols, yuv.rows, bgraMat2.data)) {
std::cerr << "NvBuffer2Raw failed\n";
return(-3);
}
cv::Mat conv;
cv::cvtColor(bgraMat2, conv, cv::COLOR_BGRA2BGR);
cv::imshow("Original",frame);
cv::imshow("Transformed",conv);
cv::waitKey(0);
}
Output:
NvSurfTransform:
//MWE for NVIDIA Dev Forums
//Jetpack 5.X with NvBufSurface
#include <opencv2/opencv.hpp>
#include <NvJpegEncoder.h>
#include <NvBufSurface.h>
#include <nvbuf_utils.h>
#include <fstream>
using namespace std;
int main() {
cv::Mat frame=cv::imread("testcard.png");
int dmaFd_ARGB;
NvBufSurf::NvCommonAllocateParams input_params_ARGB;
input_params_ARGB.memType = NVBUF_MEM_SURFACE_ARRAY;
input_params_ARGB.width = frame.size().width;
input_params_ARGB.height = frame.size().height;
input_params_ARGB.layout = NVBUF_LAYOUT_PITCH;
input_params_ARGB.colorFormat = NVBUF_COLOR_FORMAT_ARGB;
input_params_ARGB.memtag = NvBufSurfaceTag_JPEG;
if (NvBufSurf::NvAllocate(&input_params_ARGB, 1, &dmaFd_ARGB)) {
std::cerr << "Create buffer failed\n";
return(-1);
}
int dmaFd_NV12;
NvBufSurf::NvCommonAllocateParams input_params_NV12;
input_params_NV12.memType = NVBUF_MEM_SURFACE_ARRAY;
input_params_NV12.width = frame.size().width;
input_params_NV12.height = frame.size().height;
input_params_NV12.layout = NVBUF_LAYOUT_PITCH;
input_params_NV12.colorFormat = NVBUF_COLOR_FORMAT_NV12;
input_params_NV12.memtag = NvBufSurfaceTag_JPEG;
if (NvBufSurf::NvAllocate(&input_params_NV12, 1, &dmaFd_NV12)) {
std::cerr << "Create buffer failed\n";
return(-1);
}
int dmaFd_ARGB2;
NvBufSurf::NvCommonAllocateParams input_params_ARGB2;
input_params_ARGB2.memType = NVBUF_MEM_SURFACE_ARRAY;
input_params_ARGB2.width = frame.size().width;
input_params_ARGB2.height = frame.size().height;
input_params_ARGB2.layout = NVBUF_LAYOUT_PITCH;
input_params_ARGB2.colorFormat = NVBUF_COLOR_FORMAT_ARGB;
input_params_ARGB2.memtag = NvBufSurfaceTag_JPEG;
if (NvBufSurf::NvAllocate(&input_params_ARGB2, 1, &dmaFd_ARGB2)) {
std::cerr << "Create buffer failed\n";
return(-1);
}
NvBufSurf::NvCommonTransformParams transform_params = {0};
transform_params.flag = NVBUFSURF_TRANSFORM_FILTER;
transform_params.filter = NvBufSurfTransformInter_Algo3;
cv::Mat yuv;
NvBufSurface *pSurf = NULL;
NvBufSurface *pSurf2 = NULL;
cv::cvtColor(frame, yuv, cv::COLOR_BGR2BGRA);
if (-1 == NvBufSurfaceFromFd(dmaFd_ARGB, (void**)(&pSurf))){
std::cerr << "Failed to get NvBufSurface from FD";
}
if (Raw2NvBufSurface(yuv.data, 0, 0, frame.cols, frame.rows, pSurf)) {
std::cerr << "Raw2NvBuffer failed\n";
}
if (0 != NvBufSurf::NvTransform(&transform_params, dmaFd_ARGB, dmaFd_NV12)) {
std::cerr << "Failed to transform 1\n";
}
if (0 != NvBufSurf::NvTransform(&transform_params, dmaFd_NV12, dmaFd_ARGB2)) {
std::cerr << "Failed to transform 2\n";
}
if (-1 == NvBufSurfaceFromFd(dmaFd_ARGB2, (void**)(&pSurf2))){
std::cerr << "Failed to get NvBufSurface from FD";
}
cv::Mat bgraMat2(frame.rows, frame.cols, CV_8UC4);
if (NvBufSurface2Raw(pSurf2, 0, 0, bgraMat2.cols, bgraMat2.rows, bgraMat2.data)) {
std::cerr << "NvBuffer2Raw failed\n";
return(-3);
}
cv::Mat conv;
cv::cvtColor(bgraMat2, conv, cv::COLOR_BGRA2BGR);
cv::imshow("Original",frame);
cv::imshow("Transformed",conv);
cv::waitKey(0);
}
Output:
i would appreciate if anyone could provide with any ideas about what could be the cause of this disparity of results.