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
Post a Comment