View Full Version : Histogram: YCM
Mounir
19th April 2012, 15:46
Is it possible to have an histogram with YCM values (yellow , cyan magenta) aka secondary colors. RGB+ CYM would be great imo for fine tuning colors.
post your input
um3k
20th April 2012, 00:33
Seeing as CMY values are pretty much directly derived from RGB values, I fail to see how this will contribute any useful information.
Mounir
20th April 2012, 02:28
if it's doable i'd need such histogram asap
it will be helpful to fix the intensity,sat etc of these secondary colors or more generally fine tune an image, that's the bet im making.
hanfrunz
20th April 2012, 08:47
One way would be to calculate a new clip and transform the R'G'B' values to C'M'Y' and map them to the R'G'B' channels so you can just use the normal histogram. Maybe i find the time to do figure out how to do it today :-)
EDIT:
just use invert() to get C'M'Y' values.
lansing
20th April 2012, 14:50
maybe this is what you looking for?
http://forum.doom9.org/showthread.php?t=133191
no histogram but it has a cmyk curve to play around with.
I myself found the CMYK Film Color in here (http://www.infognition.com/VirtualDubFilters/color_correction.html) more suitable, because i like pulling slider than dragging curve.
http://img585.imageshack.us/img585/8282/colorcorrected.jpg
I like how it remove the yellow cast without introducing blue cast like other rbg color correctors I'd tried.
Mounir
20th April 2012, 16:30
I like this cmyk filter lansing (negative masking is well thought), thanks a lot
This + colormill you get something in the end (result: here (http://imageupload.org/en/file/219350/cmykfilm-cmill-msucolor.jpg.html)) now i need an histogram for better analysis
-Vit-
20th April 2012, 19:52
Script for RGB and CMY levels histograms (because there isn't an RGB histogram either, unless I missed it...).
Edit: Also added an RGB parade as it was fairly similar.
Just write:
HistogramRGBLevels()
or
HistogramCMYLevels()
or
HistogramRGBParade()
Uses the standard avisynth histograms so the TV range is a left-over from that - you can switch it off if you want for the levels functions:
HistogramRGBLevels(false)
You can change the width of the RGB parade scope, default is 0.25:
HistogramRGBParade(0.2)
# Histograms in RGB & CMY
#
# HistogramRGBParade presents a fairly standard RGB parade color scope.
# Uses the "Classic" avisynth histogram for each RGB component, but applied to columns rather than rows
# - The "width" setting controls the size of the histogram display. Default is 0.25 (height is always 256 pixels)
# Examples:
# HistogramRGBParade()
# HistogramRGBParade(width=0.15) # display histogram a bit smaller (from default 0.25)
#
# HistogramRGBLevels / HistogramCMYLevels are like the "Levels" avisynth histogram but for RGB and CMY instead of YUV
# - Set range=false to hide the 16-235 range (a left-over from the Y histogram used to build these)
# - "factor" has same usage as Avisynth Histogram function
# Examples:
# HistogramRGBLevels()
# HistogramCMYLevels()
# HistogramRGBLevels(range=false) # don't show tv-range from luma graph
#---
function HistogramRGBLevels( clip input, bool "range", float "factor" )
{
return HistogramRGBLevelsType( input, input.ConvertToRGB(), $800000, $008000, $000080, range, factor )
}
function HistogramCMYLevels( clip input, bool "range", float "factor" )
{
return HistogramRGBLevelsType( input, input.ConvertToRGB().Invert(), $008080, $800080, $808000, range, factor )
}
function HistogramRGBParade( clip input, float "width" )
{
return HistogramRGBParadeType( input, input.ConvertToRGB(), $800000, $008000, $000080, width )
}
#---
# Generic levels form, not very useful as a standalone function
function HistogramRGBLevelsType( clip input, clip rgb, int color1, int color2, int color3, bool "range", float "factor" )
{
range = default(range,true)
ChannelHeight = 64
Gap = 8 # divisible by 4
r = rgb.ShowRed ("YV12").HistogramChannel("Levels", color1, "add", ChannelHeight, range, factor)
g = rgb.ShowGreen("YV12").HistogramChannel("Levels", color2, "add", ChannelHeight, range, factor)
b = rgb.ShowBlue ("YV12").HistogramChannel("Levels", color3, "add", ChannelHeight, range, factor)
gap = BlankClip(r, height=Gap)
hist = StackVertical(r,gap,g,gap,b).ConvertToMatch(input)
return input.Height() > hist.Height() ? \
StackHorizontal(input, hist.AddBorders(0,0,0,input.Height() - hist.Height())) : \
StackHorizontal(input.AddBorders(0,0,0,hist.Height() - input.Height()), hist)
}
# Generic parade form, not very useful as a standalone function
function HistogramRGBParadeType( clip input, clip rgb, int color1, int color2, int color3, float "width" )
{
width = default(width,0.25)
Gap = 8 # divisible by 4
rgb = rgb.PointResize( m4(rgb.Width()*width), m4(rgb.Height()) ).TurnRight()
r = rgb.ShowRed ("YV12").HistogramChannel("Classic", color1, "chroma", 0, true)
g = rgb.ShowGreen("YV12").HistogramChannel("Classic", color2, "chroma", 0, true)
b = rgb.ShowBlue ("YV12").HistogramChannel("Classic", color3, "chroma", 0, true)
gap = BlankClip(r, height=Gap)
hist = StackVertical(r,gap,g,gap,b).TurnLeft().ConvertToMatch(input)
return input.Height() > hist.Height() ? \
StackHorizontal(input, hist.AddBorders(0,0,0,input.Height() - hist.Height())) : \
StackHorizontal(input.AddBorders(0,0,0,hist.Height() - input.Height()), hist)
}
# Used by functions above, not a standalone function
function HistogramChannel( clip input, string type, int color, string colorMode, int height, bool range, float "factor" )
{
input.Histogram(type, factor).Crop(input.Width(),0,0,height).Greyscale()
range ? last : Levels(128,1.0,255,0,255,false)
return Overlay(BlankClip(color=color), mode=colorMode)
}
# Returns "input" converted to same colorspace as "ref"
function ConvertToMatch( clip input, clip ref )
{
return ref.IsYV12() ? input.IsYV12() ? input : input.ConvertToYV12() : \
ref.IsRGB32() ? input.IsRGB32() ? input : input.ConvertToRGB32() : \
ref.IsRGB24() ? input.IsRGB24() ? input : input.ConvertToRGB24() : \
ref.IsYUY2() ? input.IsYUY2() ? input : input.ConvertToYUY2() : \
ref.IsYV16() ? input.IsYV16() ? input : input.ConvertToYV16() : \
ref.IsYV24() ? input.IsYV24() ? input : input.ConvertToYV24() : \
ref.IsY8() ? input.IsY8() ? input : input.ConvertToY8() : \
ref.IsYV411() ? input.IsYV411() ? input : input.ConvertToYV411() : \
input
}
# Convert value to multiple of 4 which is >= 16
function m4( float x ) { return (x < 16 ? 16 : int(round(x / 4.0) * 4)) }
Mounir
20th April 2012, 21:28
you're the man i'll make good usage of it ;)
-Vit-
21st April 2012, 00:29
I added an RGB parade scope since it was fairly similar scripting to the RGB levels histogram. See the post above for details. I think I've got it right, I never use such a thing... ;)
fvisagie
30th June 2015, 17:27
Script for RGB and CMY levels histograms (because there isn't an RGB histogram either, unless I missed it...).
Edit: Also added an RGB parade as it was fairly similar.
Also very useful for checking clipping of individual colour channels whilst working in YUV, thanks :).
Updated to minimise/prevent inadvertent histogram scaling with YUV inputs:
# http://forum.doom9.org/showpost.php?p=1570968&postcount=7
# http://avisynth.nl/index.php/Histograms_in_RGB_%26_CMY
#
#
# Histograms in RGB & CMY
# Updated to minimise/prevent inadvertent histogram scaling with YUV inputs
#
# HistogramRGBParade presents a fairly standard RGB parade color scope.
# Uses the "Classic" avisynth histogram for each RGB component, but applied to columns rather than rows
# - The "width" setting controls the size of the histogram display. Default is 0.25 (height is always 256 pixels)
# - The "coeffs" setting specifies colourspace conversion matrix coefficients - "601" or "709" for Rec.601 and Rec.709 resp. Default is "601".
# Examples:
# HistogramRGBParade()
# HistogramRGBParade(width=0.15) # display histogram a bit smaller (from default 0.25)
# HistogramRGBParade(coeffs="709") # for Rec.709/HD content
#
# HistogramRGBLevels / HistogramCMYLevels are like the "Levels" avisynth histogram but for RGB and CMY instead of YUV
# - Set range=false to hide the 16-235 range (a left-over from the Y histogram used to build these)
# - "factor" has same usage as Avisynth Histogram function
# - The "coeffs" setting specifies colourspace conversion matrix coefficients - "601" or "709" for Rec.601 and Rec.709 resp. Default is "601".
# Examples:
# HistogramRGBLevels()
# HistogramCMYLevels()
# HistogramRGBLevels(range=false) # don't show tv-range from luma graph
# HistogramRGBParade(coeffs="709") # for Rec.709/HD content
#---
function HistogramRGBLevels( clip input, bool "range", float "factor", string "coeffs" )
{
coeffs = default(coeffs,"601")
return HistogramRGBLevelsType( input, input.ConvertToRGB(matrix="PC." + coeffs), $800000, $008000, $000080, range, factor, coeffs )
}
function HistogramCMYLevels( clip input, bool "range", float "factor", string "coeffs" )
{
coeffs = default(coeffs,"601")
return HistogramRGBLevelsType( input, input.ConvertToRGB(matrix="PC." + coeffs).Invert(), $008080, $800080, $808000, range, factor, coeffs )
}
function HistogramRGBParade( clip input, float "width", string "coeffs" )
{
coeffs = default(coeffs,"601")
return HistogramRGBParadeType( input, input.ConvertToRGB(matrix="PC." + coeffs), $800000, $008000, $000080, width, coeffs )
}
#---
# Generic levels form, not very useful as a standalone function
function HistogramRGBLevelsType( clip input, clip rgb, int color1, int color2, int color3, bool "range", float "factor", string "coeffs" )
{
range = default(range,true)
ChannelHeight = 64
Gap = 8 # divisible by 4
r = rgb.ShowRed ("YV12").HistogramChannel("Levels", color1, "add", ChannelHeight, range, factor)
g = rgb.ShowGreen("YV12").HistogramChannel("Levels", color2, "add", ChannelHeight, range, factor)
b = rgb.ShowBlue ("YV12").HistogramChannel("Levels", color3, "add", ChannelHeight, range, factor)
gap = BlankClip(r, height=Gap)
hist = StackVertical(r,gap,g,gap,b).ConvertToMatch(input, coeffs)
return input.Height() > hist.Height() ? \
StackHorizontal(input, hist.AddBorders(0,0,0,input.Height() - hist.Height())) : \
StackHorizontal(input.AddBorders(0,0,0,hist.Height() - input.Height()), hist)
}
# Generic parade form, not very useful as a standalone function
function HistogramRGBParadeType( clip input, clip rgb, int color1, int color2, int color3, float "width", string "coeffs" )
{
width = default(width,0.25)
Gap = 8 # divisible by 4
rgb = rgb.PointResize( m4(rgb.Width()*width), m4(rgb.Height()) ).TurnRight()
r = rgb.ShowRed ("YV12").HistogramChannel("Classic", color1, "chroma", 0, true)
g = rgb.ShowGreen("YV12").HistogramChannel("Classic", color2, "chroma", 0, true)
b = rgb.ShowBlue ("YV12").HistogramChannel("Classic", color3, "chroma", 0, true)
gap = BlankClip(r, height=Gap)
hist = StackVertical(r,gap,g,gap,b).TurnLeft().ConvertToMatch(input, coeffs)
return input.Height() > hist.Height() ? \
StackHorizontal(input, hist.AddBorders(0,0,0,input.Height() - hist.Height())) : \
StackHorizontal(input.AddBorders(0,0,0,hist.Height() - input.Height()), hist)
}
# Used by functions above, not a standalone function
function HistogramChannel( clip input, string type, int color, string colorMode, int height, bool range, float "factor" )
{
input.Histogram(type, factor).Crop(input.Width(),0,0,height).Greyscale()
range ? last : Levels(128,1.0,255,0,255,false)
return Overlay(BlankClip(color=color), mode=colorMode, pc_range=true)
}
# Returns "input" converted to same colorspace as "ref"
function ConvertToMatch( clip input, clip ref, string coeffs )
{
matrix = "PC." + coeffs
return ref.IsYV12() ? input.IsYV12() ? input : input.ConvertToYV12(matrix=matrix) : \
ref.IsRGB32() ? input.IsRGB32() ? input : input.ConvertToRGB32(matrix=matrix) : \
ref.IsRGB24() ? input.IsRGB24() ? input : input.ConvertToRGB24(matrix=matrix) : \
ref.IsYUY2() ? input.IsYUY2() ? input : input.ConvertToYUY2(matrix=matrix) : \
ref.IsYV16() ? input.IsYV16() ? input : input.ConvertToYV16(matrix=matrix) : \
ref.IsYV24() ? input.IsYV24() ? input : input.ConvertToYV24(matrix=matrix) : \
ref.IsY8() ? input.IsY8() ? input : input.ConvertToY8(matrix=matrix) : \
ref.IsYV411() ? input.IsYV411() ? input : input.ConvertToYV411(matrix=matrix) : \
input
}
# Convert value to multiple of 4 which is >= 16
function m4( float x ) { return (x < 16 ? 16 : int(round(x / 4.0) * 4)) }
Some test code:
rgb = StackVertical(\
BlankClip(length=1, width=320, height=160, pixel_type="RGB32", color=$101010), \
BlankClip(length=1, width=320, height=160, pixel_type="RGB32", color=$ebebeb) \
)
yuv = StackVertical(\
BlankClip(length=1, width=320, height=160, pixel_type="YV12", color_yuv=$108080), \
BlankClip(length=1, width=320, height=160, pixel_type="YV12", color_yuv=$eb8080) \
)
Import("Histograms_in_RGB_&_CMY.avsi")
before = StackHorizontal(HistogramRGBLevels(rgb).Subtitle("RGB32"), HistogramRGBLevels(yuv).ConvertToRGB32(matrix="PC.601").Subtitle("YV12")).Subtitle("Before", align=1)
Import("Histograms_in_RGB_&_CMY_mod.avsi")
after = StackHorizontal(HistogramRGBLevels(rgb).Subtitle("RGB32"), HistogramRGBLevels(yuv).ConvertToRGB32(matrix="PC.601").Subtitle("YV12")).Subtitle("After", align=1)
StackVertical(before, after)
Output (should display once attachment has been approved):
http://forum.doom9.org/attachment.php?attachmentid=14857&stc=1&d=1435681239
fvisagie
3rd July 2015, 17:27
Updated to minimise/prevent inadvertent histogram scaling with YUV inputs
Updated to account for ConvertToXXX() matrix parameter use differing between YUV <-> RGB and YUV <-> YUV conversions:
# http://forum.doom9.org/showpost.php?p=1728405&postcount=11
# http://avisynth.nl/index.php/Histograms_in_RGB_%26_CMY
#
#
# Histograms in RGB & CMY
# Updated to minimise/prevent inadvertent histogram scaling with YUV inputs
# Updated to account for ConvertToXXX() matrix parameter use differing between YUV <-> RGB and YUV <-> YUV conversions
#
# HistogramRGBParade presents a fairly standard RGB parade color scope.
# Uses the "Classic" avisynth histogram for each RGB component, but applied to columns rather than rows
# - The "width" setting controls the size of the histogram display. Default is 0.25 (height is always 256 pixels)
# - The "coeffs" setting specifies colourspace conversion matrix coefficients - "601" or "709" for Rec.601 and Rec.709 resp. Default is "601".
# Examples:
# HistogramRGBParade()
# HistogramRGBParade(width=0.15) # display histogram a bit smaller (from default 0.25)
# HistogramRGBParade(coeffs="709") # for Rec.709/HD content
#
# HistogramRGBLevels / HistogramCMYLevels are like the "Levels" avisynth histogram but for RGB and CMY instead of YUV
# - Set range=false to hide the 16-235 range (a left-over from the Y histogram used to build these)
# - "factor" has same usage as Avisynth Histogram function
# - The "coeffs" setting specifies colourspace conversion matrix coefficients - "601" or "709" for Rec.601 and Rec.709 resp. Default is "601".
# Examples:
# HistogramRGBLevels()
# HistogramCMYLevels()
# HistogramRGBLevels(range=false) # don't show tv-range from luma graph
# HistogramRGBParade(coeffs="709") # for Rec.709/HD content
#---
function HistogramRGBLevels( clip input, bool "range", float "factor", string "coeffs" )
{
coeffs = default(coeffs,"601")
return HistogramRGBLevelsType( input, input.ConvertToRGB(matrix="PC." + coeffs), $800000, $008000, $000080, range, factor, coeffs )
}
function HistogramCMYLevels( clip input, bool "range", float "factor", string "coeffs" )
{
coeffs = default(coeffs,"601")
return HistogramRGBLevelsType( input, input.ConvertToRGB(matrix="PC." + coeffs).Invert(), $008080, $800080, $808000, range, factor, coeffs )
}
function HistogramRGBParade( clip input, float "width", string "coeffs" )
{
coeffs = default(coeffs,"601")
return HistogramRGBParadeType( input, input.ConvertToRGB(matrix="PC." + coeffs), $800000, $008000, $000080, width, coeffs )
}
#---
# Generic levels form, not very useful as a standalone function
function HistogramRGBLevelsType( clip input, clip rgb, int color1, int color2, int color3, bool "range", float "factor", string "coeffs" )
{
range = default(range,true)
ChannelHeight = 64
Gap = 8 # divisible by 4
r = rgb.ShowRed ("YV12").HistogramChannel("Levels", color1, "add", ChannelHeight, range, factor)
g = rgb.ShowGreen("YV12").HistogramChannel("Levels", color2, "add", ChannelHeight, range, factor)
b = rgb.ShowBlue ("YV12").HistogramChannel("Levels", color3, "add", ChannelHeight, range, factor)
gap = BlankClip(r, height=Gap)
hist = StackVertical(r,gap,g,gap,b).ConvertToMatch(input, coeffs)
return input.Height() > hist.Height() ? \
StackHorizontal(input, hist.AddBorders(0,0,0,input.Height() - hist.Height())) : \
StackHorizontal(input.AddBorders(0,0,0,hist.Height() - input.Height()), hist)
}
# Generic parade form, not very useful as a standalone function
function HistogramRGBParadeType( clip input, clip rgb, int color1, int color2, int color3, float "width", string "coeffs" )
{
width = default(width,0.25)
Gap = 8 # divisible by 4
rgb = rgb.PointResize( m4(rgb.Width()*width), m4(rgb.Height()) ).TurnRight()
r = rgb.ShowRed ("YV12").HistogramChannel("Classic", color1, "chroma", 0, true)
g = rgb.ShowGreen("YV12").HistogramChannel("Classic", color2, "chroma", 0, true)
b = rgb.ShowBlue ("YV12").HistogramChannel("Classic", color3, "chroma", 0, true)
gap = BlankClip(r, height=Gap)
hist = StackVertical(r,gap,g,gap,b).TurnLeft().ConvertToMatch(input, coeffs)
return input.Height() > hist.Height() ? \
StackHorizontal(input, hist.AddBorders(0,0,0,input.Height() - hist.Height())) : \
StackHorizontal(input.AddBorders(0,0,0,hist.Height() - input.Height()), hist)
}
# Used by functions above, not a standalone function
function HistogramChannel( clip input, string type, int color, string colorMode, int height, bool range, float "factor" )
{
input.Histogram(type, factor).Crop(input.Width(),0,0,height).Greyscale()
range ? last : Levels(128,1.0,255,0,255,false)
return Overlay(BlankClip(color=color), mode=colorMode, pc_range=true)
}
# Returns "input" converted to same colorspace as "ref"
# Keep generalised implementation, although inputs from HistogramRGBxxxxxxType() are always YV12
function ConvertToMatch( clip input, clip ref, string coeffs )
{
matrix = "PC." + coeffs
return ref.IsYV12() ? input.IsYV12() ? input : input.IsRGB() ? input.ConvertToYV12(matrix=matrix) : input.ConvertToYV12() : \
ref.IsRGB32() ? input.IsRGB32() ? input : input.IsYUV() ? input.ConvertToRGB32(matrix=matrix) : input.ConvertToRGB32() : \
ref.IsRGB24() ? input.IsRGB24() ? input : input.IsYUV() ? input.ConvertToRGB24(matrix=matrix) : input.ConvertToRGB24() : \
ref.IsYUY2() ? input.IsYUY2() ? input : input.IsRGB() ? input.ConvertToYUY2(matrix=matrix) : input.ConvertToYUY2() : \
ref.IsYV16() ? input.IsYV16() ? input : input.IsRGB() ? input.ConvertToYV16(matrix=matrix) : input.ConvertToYV16() : \
ref.IsYV24() ? input.IsYV24() ? input : input.IsRGB() ? input.ConvertToYV24(matrix=matrix) : input.ConvertToYV24() : \
ref.IsY8() ? input.IsY8() ? input : input.IsRGB() ? input.ConvertToY8(matrix=matrix) : input.ConvertToY8() : \
ref.IsYV411() ? input.IsYV411() ? input : input.IsRGB() ? input.ConvertToYV411(matrix=matrix) : input.ConvertToYV411() : \
input
}
# Convert value to multiple of 4 which is >= 16
function m4( float x ) { return (x < 16 ? 16 : int(round(x / 4.0) * 4)) }
Test code:
input = StackVertical(\
BlankClip(length=1, width=320, height=160, pixel_type="YV12", color_yuv=$108080), \
BlankClip(length=1, width=320, height=160, pixel_type="YV12", color_yuv=$eb8080) \
)
RGB32 = input.ConvertToRGB32(matrix="PC.601")
RGB24 = input.ConvertToRGB24(matrix="PC.601")
Y8 = input.ConvertToY8 ( )
YUY2 = input.ConvertToYUY2 ( )
YV12 = input
YV16 = input.ConvertToYV16 ( )
YV24 = input.ConvertToYV24 ( )
YV411 = input.ConvertToYV411( )
RGBLevels = StackVertical(\
RGB32.HistogramRGBLevels() .Subtitle("RGB32"), \
RGB24.HistogramRGBLevels().ConvertToRGB32(matrix="PC.601").Subtitle("RGB24"), \
Y8 .HistogramRGBLevels().ConvertToRGB32(matrix="PC.601").Subtitle("Y8") , \
YUY2 .HistogramRGBLevels().ConvertToRGB32(matrix="PC.601").Subtitle("YUY2") , \
YV12 .HistogramRGBLevels().ConvertToRGB32(matrix="PC.601").Subtitle("YV12") , \
YV16 .HistogramRGBLevels().ConvertToRGB32(matrix="PC.601").Subtitle("YV16") , \
YV24 .HistogramRGBLevels().ConvertToRGB32(matrix="PC.601").Subtitle("YV24") , \
YV411.HistogramRGBLevels().ConvertToRGB32(matrix="PC.601").Subtitle("YV411") \
).Subtitle("RGBLevels", align=1)
CMYLevels = StackVertical(\
RGB32.HistogramCMYLevels() .Subtitle("RGB32"), \
RGB24.HistogramCMYLevels().ConvertToRGB32(matrix="PC.601").Subtitle("RGB24"), \
Y8 .HistogramCMYLevels().ConvertToRGB32(matrix="PC.601").Subtitle("Y8") , \
YUY2 .HistogramCMYLevels().ConvertToRGB32(matrix="PC.601").Subtitle("YUY2") , \
YV12 .HistogramCMYLevels().ConvertToRGB32(matrix="PC.601").Subtitle("YV12") , \
YV16 .HistogramCMYLevels().ConvertToRGB32(matrix="PC.601").Subtitle("YV16") , \
YV24 .HistogramCMYLevels().ConvertToRGB32(matrix="PC.601").Subtitle("YV24") , \
YV411.HistogramCMYLevels().ConvertToRGB32(matrix="PC.601").Subtitle("YV411") \
).Subtitle("CMYLevels", align=1)
RGBParade = StackVertical(\
RGB32.HistogramRGBParade() .Subtitle("RGB32"), \
RGB24.HistogramRGBParade().ConvertToRGB32(matrix="PC.601").Subtitle("RGB24"), \
Y8 .HistogramRGBParade().ConvertToRGB32(matrix="PC.601").Subtitle("Y8") , \
YUY2 .HistogramRGBParade().ConvertToRGB32(matrix="PC.601").Subtitle("YUY2") , \
YV12 .HistogramRGBParade().ConvertToRGB32(matrix="PC.601").Subtitle("YV12") , \
YV16 .HistogramRGBParade().ConvertToRGB32(matrix="PC.601").Subtitle("YV16") , \
YV24 .HistogramRGBParade().ConvertToRGB32(matrix="PC.601").Subtitle("YV24") , \
YV411.HistogramRGBParade().ConvertToRGB32(matrix="PC.601").Subtitle("YV411") \
).Subtitle("RGBParade", align=1)
StackHorizontal(RGBLevels, CMYLevels, RGBParade)
Stereodude
29th July 2018, 22:49
There's a mistake in all those scripts. The histograms are actually 66 pixels tall so the bottom 2 pixels are being cut off. Corrected:
# http://forum.doom9.org/showpost.php?p=1728405&postcount=12
# http://avisynth.nl/index.php/Histograms_in_RGB_%26_CMY
#
#
# Histograms in RGB & CMY
# Updated to minimise/prevent inadvertent histogram scaling with YUV inputs
# Updated to account for ConvertToXXX() matrix parameter use differing between YUV <-> RGB and YUV <-> YUV conversions
#
# HistogramRGBParade presents a fairly standard RGB parade color scope.
# Uses the "Classic" avisynth histogram for each RGB component, but applied to columns rather than rows
# - The "width" setting controls the size of the histogram display. Default is 0.25 (height is always 256 pixels)
# - The "coeffs" setting specifies colourspace conversion matrix coefficients - "601" or "709" for Rec.601 and Rec.709 resp. Default is "601".
# Examples:
# HistogramRGBParade()
# HistogramRGBParade(width=0.15) # display histogram a bit smaller (from default 0.25)
# HistogramRGBParade(coeffs="709") # for Rec.709/HD content
#
# HistogramRGBLevels / HistogramCMYLevels are like the "Levels" avisynth histogram but for RGB and CMY instead of YUV
# - Set range=false to hide the 16-235 range (a left-over from the Y histogram used to build these)
# - "factor" has same usage as Avisynth Histogram function
# - The "coeffs" setting specifies colourspace conversion matrix coefficients - "601" or "709" for Rec.601 and Rec.709 resp. Default is "601".
# Examples:
# HistogramRGBLevels()
# HistogramCMYLevels()
# HistogramRGBLevels(range=false) # don't show tv-range from luma graph
# HistogramRGBParade(coeffs="709") # for Rec.709/HD content
#---
function HistogramRGBLevels( clip input, bool "range", float "factor", string "coeffs" )
{
coeffs = default(coeffs,"601")
return HistogramRGBLevelsType( input, input.ConvertToRGB(matrix="PC." + coeffs), $800000, $008000, $000080, range, factor, coeffs )
}
function HistogramCMYLevels( clip input, bool "range", float "factor", string "coeffs" )
{
coeffs = default(coeffs,"601")
return HistogramRGBLevelsType( input, input.ConvertToRGB(matrix="PC." + coeffs).Invert(), $008080, $800080, $808000, range, factor, coeffs )
}
function HistogramRGBParade( clip input, float "width", string "coeffs" )
{
coeffs = default(coeffs,"601")
return HistogramRGBParadeType( input, input.ConvertToRGB(matrix="PC." + coeffs), $800000, $008000, $000080, width, coeffs )
}
#---
# Generic levels form, not very useful as a standalone function
function HistogramRGBLevelsType( clip input, clip rgb, int color1, int color2, int color3, bool "range", float "factor", string "coeffs" )
{
range = default(range,true)
ChannelHeight = 66
Gap = 6 # (ChannelHeight + Gap) is divisible by 4
r = rgb.ShowRed ("YV12").HistogramChannel("Levels", color1, "add", ChannelHeight, range, factor)
g = rgb.ShowGreen("YV12").HistogramChannel("Levels", color2, "add", ChannelHeight, range, factor)
b = rgb.ShowBlue ("YV12").HistogramChannel("Levels", color3, "add", ChannelHeight, range, factor)
gap = BlankClip(r, height=Gap)
hist = StackVertical(r,gap,g,gap,b).ConvertToMatch(input, coeffs)
return input.Height() > hist.Height() ? \
StackHorizontal(input, hist.AddBorders(0,0,0,input.Height() - hist.Height())) : \
StackHorizontal(input.AddBorders(0,0,0,hist.Height() - input.Height()), hist)
}
# Generic parade form, not very useful as a standalone function
function HistogramRGBParadeType( clip input, clip rgb, int color1, int color2, int color3, float "width", string "coeffs" )
{
width = default(width,0.25)
Gap = 8 # divisible by 4
rgb = rgb.PointResize( m4(rgb.Width()*width), m4(rgb.Height()) ).TurnRight()
r = rgb.ShowRed ("YV12").HistogramChannel("Classic", color1, "chroma", 0, true)
g = rgb.ShowGreen("YV12").HistogramChannel("Classic", color2, "chroma", 0, true)
b = rgb.ShowBlue ("YV12").HistogramChannel("Classic", color3, "chroma", 0, true)
gap = BlankClip(r, height=Gap)
hist = StackVertical(r,gap,g,gap,b).TurnLeft().ConvertToMatch(input, coeffs)
return input.Height() > hist.Height() ? \
StackHorizontal(input, hist.AddBorders(0,0,0,input.Height() - hist.Height())) : \
StackHorizontal(input.AddBorders(0,0,0,hist.Height() - input.Height()), hist)
}
# Used by functions above, not a standalone function
function HistogramChannel( clip input, string type, int color, string colorMode, int height, bool range, float "factor" )
{
input.Histogram(type, factor).Crop(input.Width(),0,0,height).Greyscale()
range ? last : Levels(128,1.0,255,0,255,false)
return Overlay(BlankClip(color=color), mode=colorMode, pc_range=true)
}
# Returns "input" converted to same colorspace as "ref"
# Keep generalised implementation, although inputs from HistogramRGBxxxxxxType() are always YV12
function ConvertToMatch( clip input, clip ref, string coeffs )
{
matrix = "PC." + coeffs
return ref.IsYV12() ? input.IsYV12() ? input : input.IsRGB() ? input.ConvertToYV12(matrix=matrix) : input.ConvertToYV12() : \
ref.IsRGB32() ? input.IsRGB32() ? input : input.IsYUV() ? input.ConvertToRGB32(matrix=matrix) : input.ConvertToRGB32() : \
ref.IsRGB24() ? input.IsRGB24() ? input : input.IsYUV() ? input.ConvertToRGB24(matrix=matrix) : input.ConvertToRGB24() : \
ref.IsYUY2() ? input.IsYUY2() ? input : input.IsRGB() ? input.ConvertToYUY2(matrix=matrix) : input.ConvertToYUY2() : \
ref.IsYV16() ? input.IsYV16() ? input : input.IsRGB() ? input.ConvertToYV16(matrix=matrix) : input.ConvertToYV16() : \
ref.IsYV24() ? input.IsYV24() ? input : input.IsRGB() ? input.ConvertToYV24(matrix=matrix) : input.ConvertToYV24() : \
ref.IsY8() ? input.IsY8() ? input : input.IsRGB() ? input.ConvertToY8(matrix=matrix) : input.ConvertToY8() : \
ref.IsYV411() ? input.IsYV411() ? input : input.IsRGB() ? input.ConvertToYV411(matrix=matrix) : input.ConvertToYV411() : \
input
}
# Convert value to multiple of 4 which is >= 16
function m4( float x ) { return (x < 16 ? 16 : int(round(x / 4.0) * 4)) }
StainlessS
30th July 2018, 07:44
# Convert value to multiple of 4 which is >= 16
function m4( float x ) { return (x < 16 ? 16 : int(round(x / 4.0) * 4)) }
The above conversion to Int is superfluous, Round() already produces an Int. [EDIT: And Int * Int = Int]
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.