FCC NTSC to RGB

1. Given the following to convert R, G and B to Y, I and Q (FCC version), how does one convert Y, I and Q back to RGB?

Code:
```EY′ = 0.30 ER′ + 0.59 EG′ + 0.11 EB′
EI′ = -0.27(EB′ - EY′) + 0.74(ER′ - EY′)
EQ′ = 0.41(EB′ - EY′) + 0.48(ER′ - EY′)```

http://www.gpo.gov/fdsys/pkg/CFR-2013-title47-vol4/pdf/CFR-2013-title47-vol4-sec73-682.pdf

https://en.wikipedia.org/wiki/YIQ#FCC_version_of_NTSC_standard
2. Assuming you use Avisynth, ColorMatrix, ConvertToRGB, ConvertToYv12 are the filters you probably want to look into.
3. Selur -

Thank you for your reply. I'm not using avisynth and am interested specifically in the FCC version of NTSC:

The FCC version of NTSC standard, which is currently on the books for over-the-air analog color TV broadcasting, uses a slightly different matrix
FCC is the U.S. regulatory body for radio communications.

JVRAINES -

Math is my weak spot but I will try to work out the equations.
4. It's always good to work on one's math! But you can find the formula in matrix form at https://en.wikipedia.org/wiki/YIQ#Formulas and some implementation code at http://dystopiancode.blogspot.com/2012/06/yiq-rgb-conversion-algorithms.html
5. These formulas are just not complete.

There is a conversion (RGB) to (YIQ) and (YIQ) to (RGB). Also there is a conversion E'(RGB) to E'(YIQ). But no E'(YIQ) to E'(RGB); he would have to calculate the inverse matrix on his own.
6. Code:
```R = y + 0.9563 * i + 0.6210 * q
G = y - 0.2721 * i - 0.6474 * q
B = y - 1.1070 * i + 1.7046 * q```
Where do the above coefficients come from?

there is a conversion E'(RGB) to E'(YIQ). But no E'(YIQ) to E'(RGB); he would have to calculate the inverse matrix on his own.
I don't know how to do that calculation.
7. (deleted)
8. Better coverage on Page 20 of this document, which discusses conversion of NTSC in particular.
9. Originally Posted by JVRaines
Better coverage on Page 20 of this document, which discusses conversion of NTSC in particular.
According to that document, the two ways of calculating I and Q (one being the FCC way) are equivalent, but it turns out they are not.
10. Here are the inverse-matrix values for FCC YIQ to RGB courtesy of this handy web site: https://matrix.reshish.com/inverCalculation.php

Code:
```R = Y + 0.9469 * I + 0.6236 * Q
G = Y - 0.2748 * I - 0.6357 * Q
B = Y - 1.1 * I + 1.7 * Q```
FCC formula for RGB to YIQ:
Code:
```Y = R * #Kr + G * #Kg + B * #Kb
I = -0.27 * (B-Y) + 0.74 * (R-Y)
Q = 0.41 * (B-Y) + 0.48 * (R-Y)```
11. Originally Posted by chris319
Originally Posted by JVRaines
Better coverage on Page 20 of this document, which discusses conversion of NTSC in particular.
According to that document, the two ways of calculating I and Q (one being the FCC way) are equivalent, but it turns out they are not.
Well then, you'd better inform Charles Poynton. As a noted colorspace designer who has been heavily involved in the specification of digital systems since the 1990s, he would appreciate knowing that he has posted misinformation on his site.
12. The pdf document is on Poynton's site but he didn't write it. One of the authors is from the BBC.
13. Regarding:

https://en.wikipedia.org/wiki/YIQ#Formulas
http://www.poynton.com/PDFs/coloureq.pdf

If you look at the equations for RGB to YIQ at those two sites you'll see that there are two sign differences in the lower right corner:

[Attachment 41646 - Click to enlarge]

So one of them is wrong. After expanding these equations from Poynton's site (I realize the Poynton is not the author, I'm using his name here because the file is at his site and it's easier than typing "Ford/Roberts"):

Code:
```i = -0.27 * (B - y) + 0.74 * (R - y)
q =  0.41 * (B - y) + 0.48 * (R - y)```
I've determined that it's Poynton's equations that are wrong (please check my math!):

Code:
```	i = -0.27 * (B -  y                           ) + 0.74 * (R -  y                           )
= -0.27 * (B - (0.299*R + 0.587*G + 0.114*B)) + 0.74 * (R - (0.299*R + 0.587*G + 0.114*B))
= -0.27 * (B -  0.299*R - 0.587*G - 0.114*B ) + 0.74 * (R  - 0.299*R - 0.587*G - 0.114*B )
= -0.27 * (  -  0.299*R - 0.587*G + 0.886*B)  + 0.74 * (     0.701*R - 0.587*G - 0.114*B )
=               0.081*R + 0.158*G - 0.239*B   +              0.519*R - 0.434*G - 0.084*B
=               0.600*R - 0.276*G - 0.323*B

q =  0.41 * (B - y                            ) + 0.48 * (R - y                          )
=  0.41 * (B - (0.299*R + 0.587*G + 0.114*B)) + 0.48 * (R - (0.299*R + 0.587*G + 0.114*B))
=  0.41 * (B -  0.299*R - 0.587*G - 0.114*B)  + 0.48 * (R -  0.299*R - 0.587*G - 0.114*B )
=  0.41 * (  -  0.299*R - 0.587*G + 0.886*B)  + 0.48 * (     0.701*R - 0.587*G - 0.114*B )
=            -  0.123*R - 0.241*G + 0.363*B   +              0.336*R - 0.282*G - 0.055*B
=               0.213*R - 0.523*G + 0.308*B```
As you can see, the sign of the coefficients in the lower right corner match the Wikipedia equations.

When implementing both sets of equations in a program it's clear that Poynton's coefficients are wrong:

Code:
`RGB (0.5, 0.5, 0.5) --> YIQ (0.5, 0.322, -3.11)`
That's a medium grey RGB so the I and Q values should both be 0.0 (all greyscale RGB should give I = Q = 0. And the round trip back to RGB gives:

Code:
`YIQ (0.5, 0.322, -3.11) --> RGB (0.6156, 0.614, -0.385)`
Using the Wikipedia equations we get:

Code:
`RGB (0.5, 0.5, 0.5) --> YIQ (0.5, 0.001, -0.001)`
and for the round trip:

Code:
`YIQ (0.5, 0.001, -0.001) --> RGB (0.500, 0.501, 0.498)`
So the correct ANSI C code is:

Code:
```/***************************************************************************/

void YIQ2RGB(double Y, double I, double Q, double *R, double *G, double *B)
{
double r, g, b;

r = Y + 0.956*I + 0.621*Q;
g = Y - 0.272*I - 0.647*Q;
b = Y - 1.105*I + 1.702*Q;

*R = r;
*G = g;
*B = b;
}

/***************************************************************************/

void RGB2YIQ(double R, double G, double B, double *Y, double *I, double *Q)
{
double y, i, q;

y = 0.299*R + 0.587*G + 0.114*B;
i = 0.600*R - 0.276*G - 0.323*B;
q = 0.213*R - 0.523*G + 0.308*B;

*Y = y;
*I = i;
*Q = q;
}

/***************************************************************************/```
Keep in mind that valid RGB values range from 0.0 to 1.0, Y ranges from 0.0 to 1.0, I from -0.5957 to 0.5957, and Q from -0.5226 to 0.5226. You will have to adjust these equations if you want to use standard full range or limited range integer RGB and YIQ. And obviously, this code isn't meant for spead, but rather for clarity.
14. Nice detective work, jagabo.

As you probably know, I'm more interested in the FCC implementation which I have working quite nicely. It has little practical value in the modern era, but I hate to see knowledge of how we did things in the olden days be lost to the ages forever.
15. The full FCC conversions are given at the Wikipedia page you originally linked to. The only difference is the use of two digits of precision instead of three in the Y calculation. Ie, 0.30, 0.59 and 0.11 instead of 0.299, 0.587, and 0.114.
16. Recent addition in the Wikipedia article:

To convert from FCC YIQ to RGB:

ER' = EY' + 0.9469 * EI' + 0.6236 * EQ'

EG' = EY' - 0.2748 * EI' - 0.6357 * EQ'

EB' = EY' - 1.1 * EI' + 1.7 * EQ'
17. Originally Posted by LigH.de
Ah, I see.

Statistics