Selur's Little Message Board

Full Version: Request: RGB Histograms for AviSynth
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Here's a script for one (doesn't require any dlls):

http://avisynth.nl/index.php/Histograms_in_RGB_%26_CMY
http://forum.doom9.org/showthread.php?p=...ost1847665

Could go on "Misc" tab.

Includes a RGB scope (like what Resolve has), and RGB/CMY levels.

Can specify width of graphs. Can turn TV range off and on.

I tried it on custom tab and it works (saved script as histograms.avs):

Code:
Import("C:\Program Files\Hybrid\32bit\avisynthPlugins\histograms.avs")
HistogramRGBParade(width=0.10)

I think it's more useful than the default histogram! Wink

Edit - If implemented, be sure to use the last revision by Stereodude:

Code:
# 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)) }
Quote:I think it's more useful than the default histogram!
Don't really agree, but I rarely use Avisynth to begin with nowdays and I see no harm in adding to the histogram selection.
- coeffs is atomatically set depending on the current color matrix
(don't see any reason to add 'factor' or 'range' or 'width')
Okay, seems to only work with 8bit, as it
Code:
LWLibavVideoSource("G:\TESTCL~1\files\10BITT~1.MKV",cache=false,format="YUV420P16", prefer_hw=0,repeat=true)
# current resolution: 640x352
# filtering
HistogramRGBParade()
errors with 'ShowRed source bit deoth must be 8 for YV12'
(same when using HistogramRGBLevels and HistogramCMYLevels so I'll restrict it to 8bit)
-> send you link to a dev version for testing

Cu Selur
Hey cool, thanks a lot for this! Big Grin

I got an error when running it however:

Code:
Avisynth preview error: -> Script error: the named argument "coeffs" to HistogramRGBParade had the wrong type (C:\Users\Admin\AppData\Local\Temp\tempPreviewAvisynthFile18_02_48_621_tmp.avs, line 20)

I don't believe it can use the coeffs parameter.

It can use "range" and "factor" (but not "width") for HistogramRGBLevels and HistogramCMYLevels, and only "width" for HistogramRGBParade.

I found that the AviSynth previewer tends to crash with HD video (i.e., 1920x1080) with HistogramRGBParade. I found that when I reduced the width using the "width" parameter, the crashing stopped (I used width=.10). So it *might* be a good idea to include width! :\

I personally don't see a need for "factor".

"range" can be "Hide Range Overlay" check box, "width" can be number box, appearing to the right of "Show Histogram" drop down. (There's room! Wink)

Range should be greyed out unless "RGBLevels" or "CMYLevels" is selected. (Default is true or checked.)

Width should be greyed out unless "RGBParade" is selected. (Default is .25)


At the very least I think "width" should be included, as I found it was needed to prevent crashing on some videos in the previewer.
coeffs -> forgot the quotes will fix later
About the width crash: Did you use Avisynth 32bit or 64bit? (I used 64bit and 4k video without a problem; also tried 32bit Avisynth with 4k video without a problem; had to change the color matrix to avoid the coeffs problem) 32bit seems to be running out of ram when scrolling inside the preview with Parade and 4k
-> will look at it this evening

Cu Selur
Okay, a few things about those histograms:
a. they are slow
b. they require tons of memory

Loading a 4k source and doing a side-by-side with the original + filtered (no filters used) and RGBPrade eats u to 6.5 GB of RAM here ~ 3.7GB for HD sources.
-> So if you want to use these on HD content use 64bit Avisynth.

Cu Selur
Send you a link to a dev version which always sets the coeffs-value.
Don't plan to add 'width', 'factor' or 'range' as parameters.

Cu Selur
Thank you!!! Wink