OpenCV mat to NvJPEGEncoder jpg limited range

I have an OpenCV mat of type CV_8UC3 with BGR data in it. I’m trying to convert it to the right format to save a jpg with NvJPEGEncoder.

I’m following the basics from this post: NvJPEGEncoder - Converting from OpenCV Mat

  1. Convert to YUV with

cvtColor(bayerMat, YUVmat, cv::COLOR_BGR2YUV_I420);

  1. Copy into an NvBuffer of type

NvBuffer nvbuf(V4L2_PIX_FMT_YUV420M, image_width, image_height, 0);

  1. Then save with the jpeg encoder

std::unique_ptr jpgEnc(NvJPEGEncoder::createJPEGEncoder(“jpenenc”));
jpgEnc->encodeFromBuffer(nvbuf, JCS_YCbCr, &out_buf_ptr, out_buf_size, jpgQuality);

however this produces a jpg with limited range (blacks and saturation missing). Using OpenCV imwrite on the BRG mat does not have this issue.

NvJPEGEncoder produced image histogram:
NvJPEGEncoder histogram

OpenCV imwrite produced image histogram:
Edit: it appears I can only embed one image in a post

Is there a different OpenCV conversion code I need to be using to get the full range?

The closest discussion I can find to my issue is this thread: cvtColor for BGR to YUV 4:2:0 returns darker image · Issue #13066 · opencv/opencv · GitHub which seems to indicate that the OpenCV YUV420 conversion is what’s limiting the range.

Any thoughts on a work around for this?

OpenCV imwrite produced image histogram:
NvJPEGEncoder histogram

Please dump the YUV420 and check if it is limited range. Looks like it converts BGR to limited-range YUV420.

Sorry, I was pulled to another task at work.

First, it looks like I attached the wrong histogram from the OpenCV imwrite jpg. Here is the correct one.
OpenCV histogram

It does appear that the OpenCV YUV420 conversion is what’s limiting the range.

I don’t fully understand the YUV420 format, but from the raw dump after the conversion the Y portion has a range of 21-235

If the data is shifted after converting to YUV420, we would suggest encode BGR data through cv2::imwrite() directly to avoid the conversion.

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