opencv - YUV420 to RGB conversion -


i converted rgb matrix yuv matrix using formula:

y  =      (0.257 * r) + (0.504 * g) + (0.098 * b) + 16 cr = v =  (0.439 * r) - (0.368 * g) - (0.071 * b) + 128 cb = u = -(0.148 * r) - (0.291 * g) + (0.439 * b) + 128 

i did 4:2:0 chroma subsample on matrix. think did correctly, took 2x2 submatrices yuv matrix, ordered values least greatest, , took average between 2 values in middle.

i used formula, wikipedia, access y, u, , v planes:

size.total = size.width * size.height; y = yuv[position.y * size.width + position.x]; u = yuv[(position.y / 2) * (size.width / 2) + (position.x / 2) + size.total]; v = yuv[(position.y / 2) * (size.width / 2) + (position.x / 2) + size.total + (size.total / 4)]; 

i'm using opencv tried interpret best can:

y = src.data[(i*channels)+(j*step)]; u = src.data[(j%4)*step + ((i%2)*channels+1) + max]; v = src.data[(j%4)*step + ((i%2)*channels+2) + max + (max%4)]; 

src yuv subsampled matrix. did interpret formula correctly?

here how converted colours rgb:

bgr.data[(i*channels)+(j*step)] = (1.164 * (y - 16)) + (2.018 * (u - 128)); // b bgr.data[(i*channels+1)+(j*step)] = (1.164 * (y - 16)) - (0.813 * (v - 128)) - (0.391 * (u - 128)); // g bgr.data[(i*channels+2)+(j*step)] = (1.164 * (y - 16)) + (1.596 * (v - 128));   // r 

the problem image not return original colours.

here images reference: http://i.stack.imgur.com/vqkpt.jpg (subsampled) http://i.stack.imgur.com/oucc5.jpg (output)

i see should converting yuv444 rgb don't quite understand clip function in sample found on wiki.

c = y' − 16 d = u − 128 e = v − 128  r = clip(( 298 * c           + 409 * e + 128) >> 8) g = clip(( 298 * c - 100 * d - 208 * e + 128) >> 8) b = clip(( 298 * c + 516 * d           + 128) >> 8) 

does >> mean should shift bits?

i'd appreciate help/comments! thanks

update

tried doing yuv444 conversion made image appear in shades of green.

        y = src.data[(i*channels)+(j*step)];         u = src.data[(j%4)*step + ((i%2)*channels+1) + max];         v = src.data[(j%4)*step + ((i%2)*channels+2) + max + (max%4)];          c = y - 16;         d = u - 128;         e = v - 128;          bgr.data[(i*channels+2)+(j*step)] = clip((298*c + 409*e + 128)/256);         bgr.data[(i*channels+1)+(j*step)] = clip((298*c - 100*d - 208*e + 128)/256);         bgr.data[(i*channels)+(j*step)] = clip((298*c + 516*d + 128)/256); 

and clip function: int clip(double value) { return (value > 255) ? 255 : (value < 0) ? 0 : value; }

you won't same image since uv compress image.
don't if result wrong (ie error) or not perfect

r = clip(( 298 * c           + 409 * e + 128) >> 8) g = clip(( 298 * c - 100 * d - 208 * e + 128) >> 8) b = clip(( 298 * c + 516 * d           + 128) >> 8) 

the >> 8 bit shift, equivalent dividing 256. allow arithmatic in integer units rather floating point speed


Comments

Popular posts from this blog

c# - SharpSVN - How to get the previous revision? -

c++ - Is it possible to compile a VST on linux? -

url - Querystring manipulation of email Address in PHP -