CImg
CImg copied to clipboard
Problems working with NV12 formated image buffer
Hello developers!
I have an issue regarding the image processing with CImg library (congrats on making such a masterpiece).
I have an shared image so I initialize the CImg class with pointer to a buffer. All works good as long as we come to colors.
When initializing an image, I have trouble finding the right depth and spectrum (if I assume correctly that this is a problem).
So my buffer is of type NV12. With this code:
`CImg
const unsigned char red[] = { 76, 84, 255 };
picture.draw_circle(50,50,20,red,1);`
I only manage to get black circle (instead of red one). I assume that's because it only changes the Y byte of the buffer. I also tried changing depth and spectrum values but unsuccessfully. Can anyone help?
Best regards, L
CImg picture(image->y,image->ywide,image->yhigh,1,1,true);
Why not specifying 3 for the spectrum argument of the constructor if you want a color image ?
Thanks for your reply!
Yes I also tried this but I get strange shape https://prnt.sc/ttnr66 . I think this is the problem of itteration through chroma buffer.
It seems that NV12 buffers have sub-sampled chromas, so taking the raw NV12 buffer by itself cannot be done directly I suppose. You should at least double-up the chroma resolution before being able to construct a color CImg image from it.
I am going to try to reshape the chroma buffer to its two times length. Can you tell me, what YUV format does library expect to process? Probably it does not support chroma buffer of this kind where Cr and Cb are interleaved. Gonna report when I reach any success. Thanks
Turns out i cannot extend my buffer since I only get access to image buffer by a pointer and i can only modify bytes within frame range. Is there any other option to solve this problem or is this library just not capable of working with colorspace of this kind? Thanks for the help! L
It's always possible to use CImg to read your 3 components independently (using 3 constructors like the one you used), then reconstruct the color image, something like
CImg<unsigned char> Y(ptr_luma,W,H,1,1,false); // Read luminance part
CImg<unsigned char> CbCr(ptr_chroma,W/2,H/2,1,2,false); // Read chroma part (half resolution)
CbCr.resize(W,H,1,2,1); // Resize chroma at full res.
CImg<unsigned char> res = (Y,CbCr).get_append('c').YCbCrtoRGB(); // Recompose 3-channel image and convert to RGB.
I've not tested it BTW all depend on how your NV12 buffer is encoded precisely. I've never worked with such buffers, so I can't say if that can be as easy as that, but it should be not too far. CImg is actually focused on image processing, not on converting data between all possible image formats.
If I'm right, this code only works if image is not shared, but mine is. In fact, I cannot display anything if I initialize CImg paramter "is_shared" as false, it needs to be true because the image is actually shared. The point is that each frame I process stops at my function, I can process it and "send" it forward. So if I modify the length of the buffer in any way, there will be error.
Any suggestions or maybe other library proposals?
Since the library is opensource, is there a way to change/set some kind of a step for iteration thorugh a buffer from 1 to 2 because the U and V are interleaved? Regards,L