-
Notifications
You must be signed in to change notification settings - Fork 44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Problem with conversion of YIQ
(or problem with non-sRGB gamut)
#372
Comments
I don't think Again, this is because I think that Edit: primary_red( ::Type{Gamut_sRGB}) = xyY(0.64, 0.33, 1)
primary_green(::Type{Gamut_sRGB}) = xyY(0.30, 0.60, 1)
primary_blue( ::Type{Gamut_sRGB}) = xyY(0.15, 0.06, 1)
whitepoint(::Type{Gamut_sRGB}) = WP_D65
# original NTSC(1953) gamut
abstract type Gamut_NTSC <: AbstractRGBGamut end
primary_red( ::Type{Gamut_NTSC}) = xyY(0.67, 0.33, 1)
primary_green(::Type{Gamut_NTSC}) = xyY(0.21, 0.71, 1)
primary_blue( ::Type{Gamut_NTSC}) = xyY(0.14, 0.08, 1)
whitepoint(::Type{Gamut_NTSC}) = WP_C
# SMPTE-C gamut
abstract type Gamut_SMPTE_C <: AbstractRGBGamut end
primary_red( ::Type{Gamut_SMPTE_C}) = xyY(0.630, 0.340, 1)
primary_green(::Type{Gamut_SMPTE_C}) = xyY(0.310, 0.595, 1)
primary_blue( ::Type{Gamut_SMPTE_C}) = xyY(0.155, 0.070, 1)
whitepoint(::Type{Gamut_SMPTE_C}) = WP_D65
function mat_rgb_to_xyz(gamut::Type{<:AbstractRGBGamut},
wp::Union{XYZ, xyY}=whitepoint(gamut))
pr, pg, pb = primary_red(gamut), primary_green(gamut), primary_blue(gamut)
z(c::xyY) = 1 - c.x - c.y # Y == 1
m_prim = [ pr.x pg.x pb.x
pr.y pg.y pb.y
z(pr) z(pg) z(pb) ]
w = convert(XYZ, wp)
sr, sg, sb = inv(m_prim) * [w.x, w.y, w.z] # diag.
@inbounds [ m_prim[1,1]*sr m_prim[1,2]*sg m_prim[1,3]*sb
m_prim[2,1]*sr m_prim[2,2]*sg m_prim[2,3]*sb
m_prim[3,1]*sr m_prim[3,2]*sg m_prim[3,3]*sb ]
end
function mat_xyz_to_rgb(gamut::Type{<:AbstractRGBGamut},
wp::Union{XYZ, xyY}=whitepoint(gamut))
inv(mat_rgb_to_xyz(gamut, wp))
end
function convert_gamut(c::T,
src::Type{<:AbstractRGBGamut},
dest::Type{<:AbstractRGBGamut}) where {T <: AbstractRGB}
# awesome RGB -> XYZ -> RGB conversion
end |
YIQ
YIQ
(or problem with non-sRGB gamut)
cf. #8 |
I will change the gamut for However, the gamma and the narrow sense of the color gamut are independent concepts. There is already a lot of confusion. 😕 |
I decided not to change this unless anyone else wanted the fix in Colors.jl. |
FYI, the following is the conversion code from sRGB to "SMPTE 170M" YIQ. function mat_srgb_to_xyz()
m_prim = [640 300 150
330 600 60
30 100 790] ./ big"1000"
w = [big"0.95047", big"1.0", big"1.08883"]
sr, sg, sb = inv(m_prim) * w # diag.
to_xyz = [ m_prim[1,1]*sr m_prim[1,2]*sg m_prim[1,3]*sb
m_prim[2,1]*sr m_prim[2,2]*sg m_prim[2,3]*sb
m_prim[3,1]*sr m_prim[3,2]*sg m_prim[3,3]*sb ]
return to_xyz
end
function mat_xyz_to_smptergb()
m_prim = [630 310 155
340 595 70
30 95 775] ./ big"1000"
w = [big"0.95047", big"1.0", big"1.08883"]
sr, sg, sb = inv(m_prim) * w # diag.
to_xyz = [ m_prim[1,1]*sr m_prim[1,2]*sg m_prim[1,3]*sb
m_prim[2,1]*sr m_prim[2,2]*sg m_prim[2,3]*sb
m_prim[3,1]*sr m_prim[3,2]*sg m_prim[3,3]*sb ]
return inv(to_xyz)
end
const M_SRGB_TO_XYZ = mat_srgb_to_xyz()
const M_XYZ_TO_SMPTERGB = mat_xyz_to_smptergb()
const M_SRGB_TO_SMPTERGB = M_XYZ_TO_SMPTERGB * M_SRGB_TO_XYZ
srgb_to_lin(v) = v <= big"0.04045" ? v / big"12.92" : ((v + big"0.055") / big"1.055")^big"2.4"
smpte_to_lin(v) = v < big"0.0812" ? v / big"4.5" : ((v + big"0.099") / big"1.099")^(100/big"45") # similar to Rec.709
function srgb_to_yiq(rgb::RGB)
r0 = srgb_to_lin(rgb.r)
g0 = srgb_to_lin(rgb.g)
b0 = srgb_to_lin(rgb.b)
rgb1 = M_SRGB_TO_SMPTERGB * [r0, g0, b0]
r1 = rgb1[1]
g1 = rgb1[2]
b1 = rgb1[3]
y = (587 * g1 + 114 * b1 + 299 * r1) / big"1000"
kb = sqrt(big"209556997" / big"96146491") / big"3"
kr = sqrt(big"221990474" / big"288439473")
u = kb * (b1 - y)
v = kr * (r1 - y)
i = -u * sind(big"33") + v * cosd(big"33")
q = u * cosd(big"33") + v * sind(big"33")
YIQ{Float64}(y, i, q)
end |
I have a proposal to add abstract gamut types in
ColorTypes.jl
.(JuliaGraphics/ColorTypes.jl#140)I think it will help reduce the misunderstandings about the color gamut and the misfortunes from them.
However, it also clarifies the issues that have been obscured so far. One of them is a problem with conversion of
YIQ
._Originally posted by @kimikage in JuliaGraphics/ColorTypes.jl#140 (comment)
In fact, the current
RGB
is implicitly considered as "sRGB". On the other hand, the current conversion methods from/toYIQ
consider that theRGB
is defined under the "NTSC" gamut.Colors.jl/src/conversions.jl
Lines 712 to 723 in 1bc194e
The trouble is that the gamuts are often ignored when we use
YIQ
orYCbCr
. In fact, some image processing tools do such conversions which are inaccurate from a color management perspective. However, in the testing, the inaccuracy or inconsistency is a big problem.The text was updated successfully, but these errors were encountered: