Hi there,
I’m trying to convert VPIImage from VPI_IMAGE_FORMAT_UYVY to VPI_IMAGE_FORMAT_BGRA8 using the following code(not a complete code):
VPIStream stream;
CHECK_VPI_STATUS(vpiStreamCreate(0, &stream));
int w, h;
// img_data is the source data from v4l2 captured, image format is V4L2_PIX_FMT_UYVY (UYVY 4:2:2)
// img_frame is the source cv::Mat stored img_data
// img is the source image with format VPI_IMAGE_FORMAT_UYVY
unsigned char *img_data;
img_frame = cv::Mat(img_size, CV_8UC2, img_data);
CHECK_STATUS(vpiImageCreateOpenCVMatWrapper(img_frame, VPI_IMAGE_FORMAT_UYVY, 0, &img));
CHECK_VPI_STATUS(vpiImageGetSize(img, &w, &h));
VPIImage output;
CHECK_VPI_STATUS(vpiImageCreate(w, h, VPI_IMAGE_FORMAT_BGRA8, 0, &output));
CHECK_VPI_STATUS(vpiSubmitConvertImageFormat(stream, VPI_BACKEND_VIC, img, output, 0));
CHECK_VPI_STATUS(vpiStreamSync(stream));
According to documentation: VPI - Vision Programming Interface: Convert Image Format(VPI - Vision Programming Interface: Convert Image Format), this conversion is supported in VIC backend given scale == 1 and offset == 0, which is my case. I’m getting the following error:
VPI_ERROR_INVALID_IMAGE_FORMAT: Input format’s color range must be same as output’s
UYVY and BGRA8 have different color ranges, but the operation is listed as supported. Am I missing something?
Some more details:
hardware: AGX Xavier
Jetpack 4.6
VPI library version 1.1.12
And then:
My purpose is to convert UYVY to BGR8, if I operate as follows:
UYVY → UYVY_ER (by VIC)
UYVY_ER → BGRA8 (by VIC)
BGRA8 → BGR8 (by CUDA)
// use follows to get the final BGR8 data img_rgb_frame_vpi, BGR8 here represents the BGR8 VPIImage
VPIImageData out_data;
cv::Mat img_rgb_frame_from_vpi;
CHECK_STATUS(vpiImageLock(BGR8, VPI_LOCK_READ, &out_data));
CHECK_STATUS(vpiImageDataExportOpenCVMat(out_data, img_rgb_frame_vpi));
CHECK_STATUS(vpiImageUnlock(BGR8));
It works, but another question appears:
when using opencv cvtColor to get BGR8 from the same source img data like this:
cv::cvtColor(img_frame, img_rgb_frame_from_cv, cv::COLOR_YUV2BGR_UYVY);
cv::imwrite(“UYVY_TO_BGR8_BY_VPI.png”, img_rgb_frame_from_vpi);
cv::imwrite(“UYVY_TO_BGR8_BY_CV.png”, img_rgb_frame_from_cv);
I think that the “UYVY_TO_BGR8_BY_VPI.png” and “UYVY_TO_BGR8_BY_CV.png” should be almost the same.
In fact, I find that the difference between “UYVY_TO_BGR8_BY_VPI.png” and “UYVY_TO_BGR8_BY_CV.png” is distinct.
eg: The difference looks like this:
“UYVY_TO_BGR8_BY_CV.png”:
[51 59 55]
[52 60 57]
[53 61 58]
“UYVY_TO_BGR8_BY_VPI.png”:
[49 60 53]
[50 61 54]
[51 62 55]
So, my first question is whether the vpi convert can get the same result as opencv cvtColor,
secondly, by converting UYVY to UYVY_ER, then UYVY_ER to BGRA8, finally BGRA8 to BGR8, whether this way would cause more conversion errors,
lastly, is there any way to convert UYVY(YUV422) to BGR8 format by vpi directly?