VideoHelp Forum

Our website is made possible by displaying online advertisements to our visitors. Consider supporting us by disable your adblocker or try DVDFab and copy, convert or make Blu-rays and DVDs! :)
+ Reply to Thread
Page 1 of 4
1 2 3 ... LastLast
Results 1 to 30 of 114
Thread
  1. I'm having trouble converting bt.709 YUV (or YCrCb) to RGB. I have two equations.

    This one gives accurate colors but leaves tiny artifacts on edges:

    Code:
    rf.f = (255/219)*y + (255/112)*v*(1-#Kr) - (255*16/219 + 255*128/112*(1-#Kr)) 
     gf.f = (255/219)*y - (255/112)*u*(1-Kb)*Kb/Kg - (255/112)*v*(1-Kr)*Kr/Kg - (255*16/219 - 255/112*128*(1-Kb)*Kb/Kg - 255/112*128*(1-Kr)*Kr/Kg) 
     bf.f = (255/219)*y + (255/112)*u*(1-Kb) - (255*16/219 + 255*128/112*(1-Kb))
    This one has no artifacts but the colors are inaccurate:
    Code:
    ;rf.f = y + 2*(v-128)*(1-0.2126) 
    ;gf.f = y - 2*(u-128)*(1-Kb)*Kb/Kg - 2*(v-128)*(1-Kr)*Kr/Kg 
    ;bf.f = y + 2*(u-128)*(1-Kb)
    Both come from here:

    http://avisynth.nl/index.php/Color_conversions

    Working with Y,U,V and R,G,B in the 0 - 255 range. The video comes from a camcorder which outputs video in the 0 - 255 range.

    Thoughts?

    The colors are accurate and there are no artifacts when played back through VLC and SMPlayer
    Quote Quote  
  2. Can you describe the "tiny artifacts on edges ?" , or post screenshot or sample ?

    Can you reproduce the same edge artifact with the same equation (or actually, the implementation of the equation) in avisynth ?

    If no, then there might be a problem with your implementation of the equation, or something else in the process (e.g. maybe source loading issue or other factor)

    If yes, then look at the VLC or SMplayer code to see what they are using
    Quote Quote  
  3. Hopefully you can see the file Artifact.jpg which I have attempted to upload.

    Look at the blue box. Note the magenta-colored fringes on the edges.
    Image Attached Thumbnails Click image for larger version

Name:	Artifact.JPG
Views:	31
Size:	69.7 KB
ID:	46998  

    Quote Quote  
  4. This lovely board software has shrunken the image so it might be hard to see. Below is a link to a full-size screen capture. See the magenta fringes at the edges of the blue patch.

    http://www.chrisnology.info/photos/Artifact.JPG

    It is possible to eliminate these fringes but then the colors become inaccurate, viz.:

    Code:
    rf.f = y + 2*(v-128)*(1-0.2126) 
    gf.f = y - 2*(u-128)*(1-Kb)*Kb/Kg - 2*(v-128)*(1-Kr)*Kr/Kg 
    bf.f = y + 2*(u-128)*(1-Kb)
    The variables rf, gf and bf are floats; y, u and v are fetched from a buffer as unsigned 8-bit variables:

    Code:
    y.a = PeekA(*pntr)
    u.a = frame((yCoord / 2) * (#W / 2) + (x / 2) + numpixels)
    v.a = frame((yCoord / 2) * (#W / 2) + (x / 2) + numpixels + (numpixels / 4))
    Then we limit the values to 255:

    Code:
    If rf > 255:rf = 255:EndIf :rd.a = rf
    If gf > 255:gf = 255:EndIf :gd.a = gf
    If bf > 255:bf = 255:EndIf :bd.a = bf
    there might be a problem with your implementation of the equation
    That's what I'm thinking. As I say, I can make those fringes disappear at the cost of inaccurate colors.

    The code that gives me more accurate colors gives me
    14-180-14
    for green. The original bmp color is 16-180-16. I can live with that because there is rounding error, but we have these fringes.

    The code that gives inaccurate colors gives:
    26-171-26 for green.
    I can't live with that.
    Last edited by chris319; 22nd Oct 2018 at 05:36.
    Quote Quote  
  5. To add to the confusion, I see the fringes only in the red channel. The green and blue channels have no such fringes.

    Here is the offending code for the red channel:

    Code:
    rf = (255/219)*y + (255/112)*v*(1-#Kr) - (255*16/219 + 255*128/112*(1-#Kr))
    Last edited by chris319; 22nd Oct 2018 at 06:00.
    Quote Quote  
  6. Follow standard as provided (page 4):

    Click image for larger version

Name:	R-REC-BT.709-6-201506-I!!PDF-E.pdf
Views:	67
Size:	629.2 KB
ID:	46999
    Quote Quote  
  7. Pandy: there is nothing on page 4 of the standard that would solve this dilemma.
    Quote Quote  
  8. An optimizing compiler may be treating calculations like (255/219) as integers, converting to (1) -- this is language and/or compiler dependent. Change all of them to floating point, eg. (255.0/219.0) to be sure. I suspect this isn't your problem because it would result in pretty large errors everywhere.

    Also, you are using the limited range (Y=16-235, UV=16-240) conversion, not full range. The commented out equation you're not using is full range.

    I would also check for underflow (<0) as well as overflow (>255).
    Last edited by jagabo; 22nd Oct 2018 at 10:22.
    Quote Quote  
  9. Member
    Join Date
    Aug 2010
    Location
    San Francisco, California
    Search PM
    Originally Posted by chris319 View Post
    To add to the confusion, I see the fringes only in the red channel. The green and blue channels have no such fringes.

    Here is the offending code for the red channel:

    Code:
    rf = (255/219)*y + (255/112)*v*(1-#Kr) - (255*16/219 + 255*128/112*(1-#Kr))
    Pardon my ignorance, but what does the # prefix indicate? This token is not found in the green and blue equations.
    Quote Quote  
  10. What a dumb guy I am!

    Sometimes the simplest solution is the one most easily overlooked.

    Code:
    If rf < 0:rf = 0:EndIf
    If gf < 0:gf = 0:EndIf
    If bf < 0:bf = 0:EndIf
    If r, g or b is allowed to go negative you're going to have problems!

    Problem solved. I am happy to have accurate colors now, and no fringing.

    Thank you to everyone who helped.

    Regarding #Kr, in PureBasic the # means Kr has been defined as a constant.
    Quote Quote  
  11. Originally Posted by chris319 View Post
    Pandy: there is nothing on page 4 of the standard that would solve this dilemma.
    I clearly see proper equations - chapter 3 "Signal format" , page 4 (physical 6).

    Those equations are OFFICIAL - there is no rounding in formal standard which assume truncating - this is one of common issues within video software - ROUNDING instead TRUNCATING - developers rarely following standards (as they are frequently unaware of standard existence - they mostly copying and pasting faulty code).



    btw your problem is obviously NOT related to equations (unless you not using arithmetic with SATURATION) but to rescaling - don't use resizer which produce under and overshoots https://en.wikipedia.org/wiki/Overshoot_%28signal%29 . Usually pulses and steps are shaped with Gaussian, raised cosine or Hann, Blackman window function

    This PDF may be nice to read...
    Click image for larger version

Name:	7BM18_0E.pdf
Views:	53
Size:	243.8 KB
ID:	47013
    Last edited by pandy; 23rd Oct 2018 at 04:23.
    Quote Quote  
  12. Originally Posted by pandy View Post
    Those equations are OFFICIAL - there is no rounding in formal standard
    It says:

    The operator INT returns the value of 0 for fractional parts in the range of 0 to 0.4999... and +1 for fractional parts
    in the range of 0.5 to 0.9999..., i.e. it rounds up fractions above 0.5.
    Quote Quote  
  13. Originally Posted by jagabo View Post
    Originally Posted by pandy View Post
    Those equations are OFFICIAL - there is no rounding in formal standard
    It says:

    The operator INT returns the value of 0 for fractional parts in the range of 0 to 0.4999... and +1 for fractional parts
    in the range of 0.5 to 0.9999..., i.e. it rounds up fractions above 0.5.
    To be more precise - 8 bit from 10 and higher bits are truncated without rounding - so you can calculate for 10 bit (black level 64 and White level 940) and divide by 4 AND truncate/loose fractional part... trust me - this is how Hardware implementation looks - most of (if not all) open source encoders accept only 8 bit not 8.2 (10 bit) sample format.
    Quote Quote  
  14. Member
    Join Date
    Aug 2010
    Location
    San Francisco, California
    Search PM
    Trust you? You lamented programmers not following the standard, and then you misrepresented it. No wonder there is such enduring confusion in implementations.
    Quote Quote  
  15. Page 4 of the standard has item numbers in the leftmost column. For clarity, please refer to those.

    If you're referring to Item 3.4, you need E'R, E'G and E'B to calculate D'R, D'G and D'B. How am I going to calculate R, G and B given only Y, Cr and Cb?

    Here is the code I am using now. Where do you see rounding or anything that is suboptimal? Better yet, why don't you rewrite my code if you think it can be written better. rf, gf, bf, #Kr, #Kg and #Kb are floats. y, u and V are 8-bit bytes output by the camcorder. I don't know why you're bringing 10-bits into the discussion because they don't come into play.

    Code:
    ;http://avisynth.nl/index.php/Color_conversions
    rf.f = (255/219)*y + (255/112)*v*(1-#Kr) - (255*16/219 + 255*128/112*(1-#Kr)) 
    gf.f = (255/219)*y - (255/112)*u*(1-#Kb)*#Kb/#Kg - (255/112)*v*(1-#Kr)*#Kr/#Kg - (255*16/219 - 255/112*128*(1-#Kb)*#Kb/#Kg - 255/112*128*(1-#Kr)*#Kr/#Kg)
    bf.f = (255/219)*y + (255/112)*u*(1-#Kb) - (255*16/219 + 255*128/112*(1-#Kb))
    
    If rf > 255: rf = 255:EndIf
    If gf > 255: gf = 255:EndIf
    If bf > 255: bf = 255:EndIf
    
    If rf < 0:rf = 0:EndIf
    If gf < 0:gf = 0:EndIf
    If bf < 0:bf = 0:EndIf
    The above code is giving me accurate colors without artifacts. What do I need to do differently?
    Quote Quote  
  16. Do I have these matrices right?

    See here:

    https://en.wikipedia.org/wiki/YUV#HDTV_with_BT.709

    I know very little about matrix notation so here goes:

    R = 1 * Y' +1.28033 * v

    G = 1 * Y' + -0.21482 * u + -0.38059 * v

    B = 1 * Y' + 2.12798 + 0 * v

    Where all except u and v are in the range 0 - 1.

    At this point I'm just experimenting. I could make these INT's if need be.
    Last edited by chris319; 29th Oct 2018 at 23:19.
    Quote Quote  
  17. Your conversion from matrix to algebraic notation is correct.
    Quote Quote  
  18. Actually I believe there was an error in the calculation of B. I omitted the multiplication by u.

    Code:
    R = 1 * Y' +1.28033 * v
    
    G = 1 * Y' + -0.21482 * u + -0.38059 * v
    
    B = 1 * Y' + 2.12798 * u + 0 * v
    In any event I'm getting the wrong colors.
    Last edited by chris319; 30th Oct 2018 at 15:10.
    Quote Quote  
  19. Originally Posted by JVRaines View Post
    Trust you? You lamented programmers not following the standard, and then you misrepresented it. No wonder there is such enduring confusion in implementations.
    lol - seem you trying to pin me but you have no clue how broadcast hardware works... for format 8.2 (so called 10 bit) fractional part is truncated, no rounding is performed - accordingly to you 50% grey will have 126 value but in real life it will have 125 - guess why...

    Don't trust me i don't care - perform quick test: 50% grey (value 502 on 8.2), use SDI with 8 bit analyser - accordingly to equations 8 bit will be 126 value but on analyser you will see 125 - why? Are you able to explain this?

    Originally Posted by chris319 View Post
    Page 4 of the standard has item numbers in the leftmost column. For clarity, please refer to those.

    If you're referring to Item 3.4, you need E'R, E'G and E'B to calculate D'R, D'G and D'B. How am I going to calculate R, G and B given only Y, Cr and Cb?
    E'R, E'G and E'B are denominated ("analog") values from 0 to 1 - 50% red will be 0.5 etc - your glitch is related to lack of saturation arithmetic - you need to clamp your values between 0 and 1 (digital 1 and 254 or 0 and 255 etc).

    Which is performed by this code (assumption is that you performing calculation with more than 8 bits - don't know what is default for your compiler - signed long?):

    Code:
    If rf > 255: rf = 255:EndIf
    If gf > 255: gf = 255:EndIf
    If bf > 255: bf = 255:EndIf
    
    If rf < 0:rf = 0:EndIf
    If gf < 0:gf = 0:EndIf
    If bf < 0:bf = 0:EndIf
    That's why you have proper values (without this you will have negative video signal).
    For example you may have pure chrominance signal without luminance (example of such signal is CCIR330 - if you try to convert CCIR330 to RGB without saturation arithmetic then for example Green will be significantly bellow zero (in real life you can't have negative Green light source).

    I introduced 10 bit during discussion (or rather 8.2) as this is default digital video signal representation for professional signal sources and as i explained earlier: 8 bit in broadcast is produced by truncating (removing) from 8.2 its fractional part without additional error processing. Standard provide proper error processing and error is within +- 1/2 LSB but real life may be different than expected. Simply i saw your problem from different point than others in topic.

    YCbCr to RGB equation is provided on page 3 (physical 5) in:
    Image
    [Attachment 47062 - Click to enlarge]


    General rule provide here: http://discoverybiz.net/enu0/faq/faq_YUV_YCbCr_YPbPr.html
    Last edited by pandy; 30th Oct 2018 at 18:12.
    Quote Quote  
  20. So it's the hardware engineers that can't follow the spec.
    Quote Quote  
  21. Originally Posted by jagabo View Post
    So it's the hardware engineers that can't follow the spec.
    Nope - conversion from 8.2 to 8.0 is not specified and usually you have no resources to perform such processing. This is not about following spec's. There is many ways to deal with such things - for example introduce dither but this is completely different topic.
    Btw - this is visible only when 10 bit source meet 8 bit receiver - usually broadcasters using 10 bit equipment (like video encoders) and customers don't care.

    OP issue is lack of proper arithmetic - clamping will solve issue. Such problem is described by R&S paper.
    Quote Quote  
  22. you need to clip your values between 0 and 1.
    We covered that a week ago, Pandy. All is well now.

    Today we're focused on this code from Wikipedia which is giving wrong colors:

    Code:
    R = 1 * Y' +1.28033 * v
    
    G = 1 * Y' + -0.21482 * u + -0.38059 * v
    
    B = 1 * Y' + 2.12798 * u + 0 * v
    Quote Quote  
  23. Originally Posted by chris319 View Post
    you need to clip your values between 0 and 1.
    We covered that a week ago, Pandy. All is well now.

    Today we're focused on this code from Wikipedia which is giving wrong colors:

    Code:
    R = 1 * Y' +1.28033 * v
    
    G = 1 * Y' + -0.21482 * u + -0.38059 * v
    
    B = 1 * Y' + 2.12798 * u + 0 * v
    You asked i replied even if this is week after (sorry but currently it is a bit hectic time for me and can't be on VH so frequently as before).

    quantization range? coefficients from ITU standards are for 16,235 (64,940) - this one perhaps is for 0,255?
    Are you able to use colour picker and read vales for RGB decoded correctly and not correctly (accordingly to you)?

    Wiki doesn't provide source for those coefficients (this was my remark about developers) - some people simply don't care...
    Quote Quote  
  24. Are you able to use colour picker and read values for RGB decoded correctly and not correctly
    Yes. I don't guess at the values.

    The coefficients are for BT.709. Follow the link. It explicitly says BT.709:

    https://en.wikipedia.org/wiki/YUV#HDTV_with_BT.709

    coefficients from ITU standards are for 16,235 (64,940) - this one perhaps is for 0,255
    There is one set of BT.709 coefficients for either 16-235 or 0-255.
    Last edited by chris319; 30th Oct 2018 at 20:56.
    Quote Quote  
  25. Originally Posted by chris319 View Post
    Yes. I don't guess at the values.
    Are you able to provide those values?

    Originally Posted by chris319 View Post

    The coefficients are for BT.709. Follow the link. It explicitly says BT.709:

    https://en.wikipedia.org/wiki/YUV#HDTV_with_BT.709
    I prefer to follow more reputable sources than Wikipedia - that's why I've provided you standards. Perhaps my comment on developers was harsh but this is outcome of my experience - if some developer feel offended - apologies.

    Originally Posted by chris319 View Post
    coefficients from ITU standards are for 16,235 (64,940) - this one perhaps is for 0,255
    There is one set of BT.709 coefficients for either 16-235 or 0-255.
    Performed quick test (color bar 100/75, Open Offce Calc) with your (wiki) coefficients and those coefficients are incorrect, they don't provide reversible RGB<>YCbCr for ITU 709 (limited quantization range)...

    Attaching two files, xilinx app with detailed information about RGB <> YCbCr conversion (seems HW guys knows how to do things) and my test for conversion from RGB to YCbCr to RGB with your (wiki) incorrect coefficients.
    Seem main coefficients for 709 are different for limited (16,235) Kr=0.2126, Kb=0.0722 and full (0,255) quantization range Kr=0.1819, Kb=0.0618.
    Click image for larger version

Name:	xapp931.pdf
Views:	36
Size:	364.8 KB
ID:	47067
    Click image for larger version

Name:	bt709.pdf
Views:	35
Size:	32.1 KB
ID:	47066
    Quote Quote  
  26. Are you able to provide those values?
    I can summarize by saying they are generally +/- 1 or 2 of the actual value. The error is due to rounding. Bear in mind that there is rounding error in the encoding and again in the decoding.

    Performed quick test (color bar 100/75, Open Offce Calc) with your (wiki) coefficients and those coefficients are incorrect, they don't provide reversible RGB<>YCbCr for ITU 709 (limited quantization range)...
    We've already established that. I think it best to disregard that code.

    Could you please post some compilable code encompassing this theory in the form I am already using? Here again is the code I am using now and the source of it (avisynth). If this code is not optimal then I'm sure the avisynth folks would like to know about it.

    Code:
    ;http://avisynth.nl/index.php/Color_conversions
    rf.f = (255/219)*y + (255/112)*v*(1-#Kr) - (255*16/219 + 255*128/112*(1-#Kr)) 
    gf.f = (255/219)*y - (255/112)*u*(1-#Kb)*#Kb/#Kg - (255/112)*v*(1-#Kr)*#Kr/#Kg - (255*16/219 - 255/112*128*(1-#Kb)*#Kb/#Kg - 255/112*128*(1-#Kr)*#Kr/#Kg)
    bf.f = (255/219)*y + (255/112)*u*(1-#Kb) - (255*16/219 + 255*128/112*(1-#Kb))
    
    If rf > 255: rf = 255:EndIf
    If gf > 255: gf = 255:EndIf
    If bf > 255: bf = 255:EndIf
    
    If rf < 0:rf = 0:EndIf
    If gf < 0:gf = 0:EndIf
    If bf < 0:bf = 0:EndIf
    In PureBasic the ".f" declares a variable as a float. The "#" signifies a constant.

    Let us assume a data range of 0 - 255 (not confined to 16 - 235).
    Quote Quote  
  27. Originally Posted by chris319 View Post
    Are you able to provide those values?
    I can summarize by saying they are generally +/- 1 or 2 of the actual value. The error is due to rounding. Bear in mind that there is rounding error in the encoding and again in the decoding.
    Ok, so seem errors are related to encoding/decoding and you understand their nature thus not a problem.

    Originally Posted by chris319 View Post
    We've already established that. I think it best to disregard that code.
    Perfect then - seem here is no issue, wikipedia has some equations but those equations are incorrect (unknown purpose).
    That's why i provided you ITU as reference not wikipedia (don't get me wrong - i like wikipedia however articles related to colour space and colour space conversions are not best ones).

    Originally Posted by chris319 View Post
    Could you please post some compilable code encompassing this theory in the form I am already using? Here again is the code I am using now and the source of it (avisynth). If this code is not optimal then I'm sure the avisynth folks would like to know about it.

    Code:
    ;http://avisynth.nl/index.php/Color_conversions
    rf.f = (255/219)*y + (255/112)*v*(1-#Kr) - (255*16/219 + 255*128/112*(1-#Kr)) 
    gf.f = (255/219)*y - (255/112)*u*(1-#Kb)*#Kb/#Kg - (255/112)*v*(1-#Kr)*#Kr/#Kg - (255*16/219 - 255/112*128*(1-#Kb)*#Kb/#Kg - 255/112*128*(1-#Kr)*#Kr/#Kg)
    bf.f = (255/219)*y + (255/112)*u*(1-#Kb) - (255*16/219 + 255*128/112*(1-#Kb))
    
    If rf > 255: rf = 255:EndIf
    If gf > 255: gf = 255:EndIf
    If bf > 255: bf = 255:EndIf
    
    If rf < 0:rf = 0:EndIf
    If gf < 0:gf = 0:EndIf
    If bf < 0:bf = 0:EndIf
    In PureBasic the ".f" declares a variable as a float. The "#" signifies a constant.

    Let us assume a data range of 0 - 255 (not confined to 16 - 235).
    I never said it is not optimal - i suggested to follow standard not relay on code that may have issues as frequently such equations are blindly (wiki code example - this can be OK but for special case not for regular use) copied.
    I didn't check this code as one of things that hit me first was wrong signal naming convention - YUV is present ONLY in Composite video signal encoders/decoders - see no justification to use YUV as synonym for YCbCr or YPbPr except software PAL encoders/decoders which is not your case.
    This code should work under some limitations - it expect Limited Quantization Range YCbCr (Y 16..235 ; Cb, Cr 16..240) and produce Full Quantization Range RGB output (0..255). It may be suboptimal when speed is your goal but i assume with modern CPU's capabilities this is not big issue.
    Perhaps it is better (as code seem to use floats and provide sufficient precision) to remove scaling coefficients (255/219, 255/112) and rescale RGB components explicitly later but this is cosmetics (may improve code readability and increase flexibility- code should be able to deal with Full Quantization Range YCbCr data - be aware that in video world Full Scale YCbCr is usually 1..254 not 0..255 thus scaling coefficient like 255/254 may be required anyway if your intention is to get Full Scale RGB).
    Quote Quote  
  28. Ok, so seem errors are related to encoding/decoding and you understand their nature thus not a problem.
    Due to rounding, not encoding/decoding.

    This code should work under some limitations - it expect Limited Quantization Range YCbCr (Y 16..235 ; Cb, Cr 16..240)
    Ah, this could be causing me problems as I am working with video from a camcorder which puts out > 235 and < 16.

    How would you rewrite this code to handle 0 - 255? My math is not the greatest so I could use some help. The camcorder does put out 0 and 255 as it is intended for consumers, not for broadcast.

    Code:
    rf = Int((255/219)*yf + (255/112)*Crf*(1-#Kr) - (255*16/219 + 255*128/112*(1-#Kr))+0.5)
    
    gf = Int((255/219)*yf - (255/112)*Cbf*(1-#Kb)*#Kb/#Kg - (255/112)*Crf*(1-#Kr)*#Kr/#Kg - (255*16/219 - 255/112*128*(1-#Kb)*#Kb/#Kg - 255/112*128*(1-#Kr)*#Kr/#Kg)+0.5)
    
    bf = Int((255/219)*yf + (255/112)*Cbf*(1-#Kb) - (255*16/219 + 255*128/112*(1-#Kb))+0.5)
    Last edited by chris319; 3rd Nov 2018 at 00:53.
    Quote Quote  
  29. Originally Posted by chris319 View Post
    Due to rounding, not encoding/decoding.
    Don't get me wrong but colour space conversion is form of encoding and rounding itself is a form of error encoding - agree - semantics is important but encoder/decoder is black box with appropriate abstraction layer from your issue perspective...

    Originally Posted by chris319 View Post
    Ah, this could be causing me problems as I am working with video from a camcorder which puts out > 235 and < 16.
    Yes and this is clearly specified on provided by you Avisynth wiki

    Originally Posted by chris319 View Post
    How would you rewrite this code to handle 0 - 255? My math is not the greatest so I could use some help. The camcorder does put out 0 and 255 as it is intended for consumers, not for broadcast.
    Such code is provided on same Avisynth page - yuv [0,255] <-> rgb [0,255] (0 <= [r,g,b] <= 255, 0 <= y <= 255, 0 <= [u,v] <= 255)

    Code:
    r = y + 2*(v-128)*(1-Kr) 
    
    g = y - 2*(u-128)*(1-Kb)*Kb/Kg - 2*(v-128)*(1-Kr)*Kr/Kg 
    
    b = y + 2*(u-128)*(1-Kb)
    You can rescale RGB later if your YCbCr data are range limited.
    You can also pre-process YCbCr and apply clamp before (limit Y between 16 and 235; Cb, Cr between 16, 240).
    Quote Quote  
  30. Code:
    r = y + 2*(v-128)*(1-Kr) 
    
    g = y - 2*(u-128)*(1-Kb)*Kb/Kg - 2*(v-128)*(1-Kr)*Kr/Kg 
    
    b = y + 2*(u-128)*(1-Kb)
    As noted previously in this thread, this code gives inaccurate colors.

    I have reworked my test pattern to include patches of #FFFFFF and #000000. This code gives accurate colors over the range #000000 through #FFFFFF, so I think we're good.

    https://youtu.be/69FU5Sjw0oc

    Code:
    rf = (255/219)*y + (255/112)*v*(1-#Kr) - (255*16/219 + 255*128/112*(1-#Kr)) 
    gf = (255/219)*y - (255/112)*u*(1-#Kb)*#Kb/#Kg - (255/112)*v*(1-#Kr)*#Kr/#Kg - (255*16/219 - 255/112*128*(1-#Kb)*#Kb/#Kg - 255/112*128*(1-#Kr)*#Kr/#Kg)
    bf = (255/219)*y + (255/112)*u*(1-#Kb) - (255*16/219 + 255*128/112*(1-#Kb))
    
    If rf > 255: rf = 255:EndIf
    If gf > 255: gf = 255:EndIf
    If bf > 255: bf = 255:EndIf
    
    If rf < 0:rf = 0:EndIf
    If gf < 0:gf = 0:EndIf
    If bf < 0:bf = 0:EndIf
    I can change the variable names from u, v to Cb, Cr.
    Quote Quote  



Similar Threads