Log in

View Full Version : ShowHistograms ~ overlay multiple video scopes, audio waveform


raffriff42
12th July 2013, 20:02
This script rearranges the output from Histogram (http://avisynth.nl/index.php/Histogram) (Classic waveform monitor, Levels Y-U-V monitor, Color and Color2 vector scopes) and adds the Waveform (http://forum.doom9.org/showthread.php?t=165703) audio overlay. You can have all four video 'scopes' overlaid on your video with adjustable opacity, or you can show them outside your video, as shown in the examples. Source must be YUV, and should be at least 480p.

ShowHistograms()
Default output: 2 overlays + audio waveform (click to enlarge)
https://www.dropbox.com/s/sen1w6x3oymvri4/ShowHistograms_test%2020%20%28default%29-384x.jpg?raw=1 (https://www.dropbox.com/s/u94wq8ypwb52o6i/ShowHistograms_test%2020%20%28default%29.jpg?dl=0)

ShowHistograms(
\ classic_align=9, levels_align=6, color2_align=3,
\ border_right=true, bypass=false)
Classic+Levels+Color2 off right side: (note Classic is rotated to emulate a standard waveform monitor)
https://www.dropbox.com/s/8ly00hrdif2vn9r/ShowHistograms_test%2014%20%28classic%2C%20levels%2C%20color2%20%2BR%29-384x.jpg?raw=1 (https://www.dropbox.com/s/vokl9cdrikuouff/ShowHistograms_test%2014%20%28classic%2C%20levels%2C%20color2%20%2BR%29.jpg?dl=0)

ShowHistograms(
\ classic_align=7, levels_align=9, color_align=1, color2_align=3,
\ border_left=true, border_right=true, bypass=false)
All 4 scopes off left and right:
https://www.dropbox.com/s/7kbteo2e477p3gm/ShowHistograms_test%2012%20%28all-scopes%2BLR%29-384x.jpg?raw=1 (https://www.dropbox.com/s/e8wewrz6zfgntoo/ShowHistograms_test%2012%20%28all-scopes%2BLR%29.jpg?dl=0)

EDIT additional preset functions (common settings with fewer options and new features like) moved here (https://www.dropbox.com/s/m9rvmklnxtnhoxv/uuhistograms-132-2.avsi.txt?dl=0) as the code became too large for a single post.

# http://forum.doom9.org/showthread.php?p=1636573

LoadPlugin(pathBase + "fastturn\fturn_26.dll")
LoadPlugin(pathBase + "MaskTools2\mt_masktools-26.dll")
LoadPlugin(pathBase + "Waveform\waveform.dll") ## only required if waveform=true

###########################################################
### TABLE OF CONTENTS ###

####### Show multiple Histogram function overlays
#@function ShowHistograms(clip C,
##\ int classic_align=0, int levels_align=7, int color_align=0, int color2_align=9,
##\ bool border_left=false, bool border_top=false, bool border_right=false, bool border_bottom=false,
##\ bool waveform=false, bool classic_rotate=true, float opacity=0.85, bool bypass=false)

####### Show classic Histogram as overlay
#@ function ShowClassic(clip C, int align, float opacity)

####### Show classic Histogram + Color2 scope as overlay
#@function ShowClassic(clip C, int align=7, float opacity=0.85)

### Show Levels histogram as overlay
#@function ShowLevels(clip C, int align=7, float opacity=0.85)

####### Show Levels histogram + Color2 scope as overlay
#@function ShowLevels2(clip C, int level_align=7, int color2_align=9, float opacity=0.85)

####### Show 2/3 sized video + classic Histogram + Levels histogram + Color2 scope outside
#@function ShowHist3shrink(clip C, bool shrink=true, bool align_right=true, bool bypass=false)

####### Show video + classic Histogram + Levels histogram + Color2 scope outside
#@function ShowHist3border(clip C, bool add_border=true, bool align_right=true, bool bypass=false)

####### Show vertically sqeezed video + classic Histogram + Levels histogram + Color2 scope on top
#@function ShowHist3topshrink(clip C, bool bypass=false)

####### Show audio waveform as overlay
#@function ShowWaveform(clip C, float opacity=0.85)

####### make side-by-side split clip (for comparison or preview)
#@function ShowHistogramsTwoAcrossCropped(
##\ clip A, clip B,
##\ int classic_align=0, int levels_align=7,
##\ int color_align=0, int color2_align=9,
##\ int border=8, float pan=0.0, bool bypass=false)

###########################################################


##################################
### Show multiple Histogram function overlays
#
# @ C - clip to test (YUV format)
#
# @ XX_align - insert position, using "numeric keypad" notation (cf. Avisynth:Subtitle)
# *---------*
# | 7 8 9 | (1-2-3-4 and 6-7-8-9 sets overlay alignment as shown)
# | 4 :) 6 | (first if > 999, returns XX as standalone)
# | 1 2 3 | (any other number hides that overlay) (default=0)
# *---------*
# @ border_XX - if true, add a 256-pixel wide border (not part of histogram measurement)
# @ waveform - if true, show audio Waveform() display (default=false)
# @ classic_rotate - if true, rotate classic histogram 90° left (default=true)
# @ opacity - master overlay opacity (default=1.0, range=0..1)

# @ levels_height - squeeze or stretch vertically (default=1.0, range=0.1 to 2.0)
# @ bypass - if true, disable all changes except added borders
#
# raffriff42
# http://forum.doom9.org/showthread.php?p=1636573
#
# version 1.0 12-Jul-2013
#
# version 1.1 13-Jul-2013 - audio waveform on by default;
# keep borders in bypass mode;
# process half-sized clip for speed;
# add 75% reference dots to Color scope;
# adjust scope brightness etc
#
# version 1.2 18-Jul-2013 - flip vscopes per
# http://forum.doom9.org/showthread.php?p=1577459
#
# version 1.3 27-Jul-2013 - less aggressive resizing;
# FTurn http://forum.doom9.org/showthread.php?t=168315
#
# version 1.3.1 28-Aug-13 - waveform default=false
# version 1.3.2 17-Aug-14 - levels_height
#
function ShowHistograms(clip C,
\ int "classic_align", int "levels_align", int "color_align", int "color2_align",
\ bool "border_left", bool "border_top", bool "border_right", bool "border_bottom",
\ bool "waveform", bool "classic_rotate", float "opacity", float "levels_height",
\ bool "bypass")
{
Assert((C.IsYV12 || C.IsYUY2), "ShowHistograms: source must be YUV format")

border_left = Default(border_left, false)
border_top = Default(border_top, false)
border_right = Default(border_right, false)
border_bottom = Default(border_bottom, false)
has_border = (border_left || border_top || border_right || border_bottom)

align1 = Default(classic_align, 0)
align2 = Default(levels_align,
\ border_right ? 9 :
\ border_bottom ? 1 :
\ (align1==0) ? 7 : 0)

align3 = Default(color_align, 0)
align4 = Default(color2_align,
\ (border_right || border_bottom) ? 3 :
\ border_left ? 1 :
\ (align3==0) ? 9 : 0)

waveform = Default(waveform, false)
rotate1 = Default(classic_rotate, true)

opacity = Float(Default(opacity, has_border ? 1.0 : 0.85))
opacity = (opacity < 0.3) ? 0.3 : opacity
opacity = (opacity > 1.0) ? 1.0 : opacity
opacity2 = 1.0 - 2.0 * (1.0 - opacity) ## levels
opacity2 = (opacity2 < 0.3) ? 0.3 : opacity2
opacity3 = (opacity2 > 0.6) ? 0.6 : opacity2 ## waveform
bypass = Default(bypass, false)
levels_height = Min(Max(0.1, Default(levels_height, 1.0)), 2.0)

## clip CS: small version, to speed processing
CS = (C.Width <= 1280 && C.Height <= 720) ? C : C.BilinearResize(1280, 720)
#CS = (C.Width <= 640 && C.Height <= 360) ? C : C.BilinearResize(640, 360)

H1 = (rotate1) ? CS.FTurnRight : CS ## FTurn ##
H1 = H1.Histogram(mode="classic")
H1 = H1.Crop(H1.Width-256, 0, 256, H1.Height)
H1 = (rotate1) ? H1.FTurnLeft : H1 ## FTurn ##
H1 = H1.BicubicResize(256, 256).mt_lut("x 2 * 16 + ").Tweak(sat=0.2)

H2 = CS.Histogram("levels", 95.0).Tweak(sat=0.50)
H2 = H2.Crop(H2.Width-256, 0, 256, 240)
H2 = (Abs(1.0-levels_height)<0.01) ? H2
\ : H2.BicubicResize(H2.Width, 2*Round(0.5*levels_height*H2.Height))

CR = CS._uu_add_ref_colors()
H3 = CR.Histogram(mode="color")
H3 = H3.Crop(H3.Width-256, 0, 256, 256).mt_lut(yexpr="x 12 - 16 * ").Tweak(sat=0.15)
H3 = H3.FlipVertical()
#H3 = H3.hist_color_labels2(color2=true, x=0, y=0)

H4 = CS.Histogram(mode="color2")
H4 = H4.Crop(H4.Width-256, 0, 256, 256).Tweak(sat=0.50)
H4 = (align4 < 999) ? H4.BicubicResize(240, 240) : H4
H4 = (align4 < 999) ? H4.AddBorders(8, 8, 8, 8) : H4
H4 = H4.FlipVertical()
#H4 = H4.hist_color_labels2(color2=true, x=0, y=0)

## clip B: bypass path
B = C

C = (waveform) ?
\ C.Overlay(C.Waveform(height=C.AudioChannels * 0.1),
\ opacity=opacity3)
\ : C

C = (border_left) ? C.AddBorders(256, 0, 0, 0) : C
C = (border_top) ? C.AddBorders(0, 256, 0, 0) : C
C = (border_right) ? C.AddBorders(0, 0, 256, 0) : C
C = (border_bottom) ? C.AddBorders(0, 0, 0, 256) : C

## keep borders in bypass mode
B = (border_left) ? B.AddBorders(256, 0, 0, 0) : B
B = (border_top) ? B.AddBorders(0, 256, 0, 0) : B
B = (border_right) ? B.AddBorders(0, 0, 256, 0) : B
B = (border_bottom) ? B.AddBorders(0, 0, 0, 256) : B

omode3 = (border_left && (align3==1 || align3==4 || align3==7) ||
\ border_top && (align3==7 || align3==8 || align3==9) ||
\ border_right && (align3==3 || align3==6 || align3==9) ||
\ border_bottom && (align3==1 || align3==2 || align3==3)) ?
\ "blend" : "add"

omode4 = (border_left && (align4==1 || align4==4 || align4==7) ||
\ border_top && (align4==7 || align4==8 || align4==9) ||
\ border_right && (align4==3 || align4==6 || align4==9) ||
\ border_bottom && (align4==1 || align4==2 || align4==3)) ?
\ "blend" : "blend"

##bottom left
C = (align1 == 1) ? C.Overlay(H1, 0, C.Height-H1.Height, opacity=opacity)
\ : (align2 == 1) ? C.Overlay(H2, 0, C.Height-H2.Height, opacity=opacity2)
\ : (align3 == 1) ? C.Overlay(H3, 0, C.Height-H3.Height, opacity=opacity, mode=omode3)
\ : (align4 == 1) ? C.Overlay(H4, 0, C.Height-H4.Height, opacity=opacity, mode=omode4)
\ : C

##bottom center
C = (align1 == 2) ? C.Overlay(H1,
\ Round(0.5*C.Width)-Round(0.5*H1.Width), C.Height-H1.Height, opacity=opacity)
\ : (align2 == 2) ? C.Overlay(H2,
\ Round(0.5*C.Width)-Round(0.5*H2.Width), C.Height-H2.Height, opacity=opacity2)
\ : (align3 == 2) ? C.Overlay(H3,
\ Round(0.5*C.Width)-Round(0.5*H3.Width), C.Height-H3.Height, opacity=opacity,
\ mode=omode3)
\ : (align4 == 2) ? C.Overlay(H4,
\ Round(0.5*C.Width)-Round(0.5*H4.Width), C.Height-H4.Height, opacity=opacity,
\ mode=omode4)
\ : C

##bottom right
C = (align1 == 3) ? C.Overlay(H1,
\ C.Width-H1.Width, C.Height-H1.Height, opacity=opacity)
\ : (align2 == 3) ? C.Overlay(H2,
\ C.Width-H2.Width, C.Height-H2.Height, opacity=opacity2)
\ : (align3 == 3) ? C.Overlay(H3,
\ C.Width-H3.Width, C.Height-H3.Height, opacity=opacity, mode=omode3)
\ : (align4 == 3) ? C.Overlay(H4,
\ C.Width-H4.Width, C.Height-H4.Height, opacity=opacity, mode=omode4)
\ : C

##center left
C = (align1 == 4) ? C.Overlay(H1,
\ 0, Round(0.5*C.Height)-Round(0.5*H1.Height), opacity=opacity)
\ : (align2 == 4) ? C.Overlay(H2,
\ 0, Round(0.5*C.Height)-Round(0.5*H2.Height), opacity=opacity2)
\ : (align3 == 4) ? C.Overlay(H3,
\ 0, Round(0.5*C.Height)-Round(0.5*H3.Height), opacity=opacity, mode=omode3)
\ : (align4 == 4) ? C.Overlay(H4,
\ 0, Round(0.5*C.Height)-Round(0.5*H4.Height), opacity=opacity, mode=omode4)
\ : C

##center right
C = (align1 == 6) ? C.Overlay(H1,
\ C.Width-H1.Width, Round(0.5*C.Height)-Round(0.5*H1.Height), opacity=opacity)
\ : (align2 == 6) ? C.Overlay(H2,
\ C.Width-H2.Width, Round(0.5*C.Height)-Round(0.5*H2.Height), opacity=opacity2)
\ : (align3 == 6) ? C.Overlay(H3,
\ C.Width-H3.Width, Round(0.5*C.Height)-Round(0.5*H3.Height), opacity=opacity,
\ mode=omode3)
\ : (align4 == 6) ? C.Overlay(H4,
\ C.Width-H4.Width, Round(0.5*C.Height)-Round(0.5*H4.Height), opacity=opacity,
\ mode=omode4)
\ : C

##top left
C = (align1 == 7) ? C.Overlay(H1, opacity=opacity)
\ : (align2 == 7) ? C.Overlay(H2, opacity=opacity2)
\ : (align3 == 7) ? C.Overlay(H3, opacity=opacity, mode=omode3)
\ : (align4 == 7) ? C.Overlay(H4, opacity=opacity, mode=omode4)
\ : C

##top center
C = (align1 == 8) ? C.Overlay(H1,
\ Round(0.5*C.Width)-Round(0.5*H1.Width), 0, opacity=opacity)
\ : (align2 == 8) ? C.Overlay(H2,
\ Round(0.5*C.Width)-Round(0.5*H2.Width), 0, opacity=opacity2)
\ : (align3 == 8) ? C.Overlay(H3,
\ Round(0.5*C.Width)-Round(0.5*H3.Width), 0, opacity=opacity, mode=omode3)
\ : (align4 == 8) ? C.Overlay(H4,
\ Round(0.5*C.Width)-Round(0.5*H4.Width), 0, opacity=opacity, mode=omode4)
\ : C

##top right
C = (align1 == 9) ? C.Overlay(H1, C.Width-H1.Width, 0, opacity=opacity)
\ : (align2 == 9) ? C.Overlay(H2, C.Width-H2.Width, 0, opacity=opacity2)
\ : (align3 == 9) ? C.Overlay(H3, C.Width-H3.Width, 0, opacity=opacity, mode=omode3)
\ : (align4 == 9) ? C.Overlay(H4, C.Width-H4.Width, 0, opacity=opacity, mode=omode4)
\ : C

C = (align1 > 999) ? H1
\ : (align2 > 999) ? H2
\ : (align3 > 999) ? H3
\ : (align4 > 999) ? H4
\ : C

return (bypass) ? B : C
}


##################################
## add reference color markers for vector scope use ONLY
#
function _uu_add_ref_colors(clip C)
{
## (75% color bars)
h = 4
B=StackVertical(
\ BlankClip(C, height=h, color=$bf0000),
\ BlankClip(C, height=h, color=$bfbf00),
\ BlankClip(C, height=h, color=$00bfbf),
\ BlankClip(C, height=h, color=$0000bf),
\ BlankClip(C, height=h, color=$00bf00),
\ BlankClip(C, height=h, color=$bf00bf))

return StackVertical(C, B)
}

MediumRare
5th January 2015, 12:12
Thank you for this script! (I just ran across it and had to try it out.)

However there seems to be a missing helper function (_uu_add_ref_colors). I commented it out because I didn't use the "color" option and things worked fine.

Could you please add or eliminate it? The only hit from Google was this thread, so it doesn't seem to be part of another plugin.

Thank you.

G

raffriff42
11th January 2015, 22:46
Oops, sorry about that! Here is the missing function (also added to the OP): ##################################
## add reference color markers for vector scope use ONLY
#
function _uu_add_ref_colors(clip C)
{
## (75% color bars)
h = 4
B=StackVertical(
\ BlankClip(C, height=h, color=$bf0000),
\ BlankClip(C, height=h, color=$bfbf00),
\ BlankClip(C, height=h, color=$00bfbf),
\ BlankClip(C, height=h, color=$0000bf),
\ BlankClip(C, height=h, color=$00bf00),
\ BlankClip(C, height=h, color=$bf00bf))

return StackVertical(C, B)
}

MediumRare
11th January 2015, 23:19
Thank you!

G

(grrr - have to jump through hoops i.e. random questions with unclear answers to reply here :confused: )