Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Capturing and Editing Video > Avisynth Usage

Reply
 
Thread Tools Search this Thread Display Modes
Old 28th September 2014, 19:45   #1  |  Link
sven_x
Registered User
 
Join Date: Oct 2011
Location: Germany
Posts: 39
Cumulative histogram

Function to create a cumulative histogram across all frames of a clip

Similar to Virtualdubs "levels" plugin histogram, but with the following advantages:
* displays separate histograms for RGB and luma (or CMY and luma)
* adjustable speed up by choosing a factor n to process every nth frame only

(This first posting is a placeholder for the final script)
sven_x is offline   Reply With Quote
Old 28th September 2014, 20:12   #2  |  Link
sven_x
Registered User
 
Join Date: Oct 2011
Location: Germany
Posts: 39
This is the principle how it might work:

- calculate HistogramRGBLevels() (see here) for each nth frame of a clip
- summing up those histograms in a cumulative histogram using layers(CumulativeHistogram(last_frame),HistogramRGBLevels(current_frame),"mul")
- cropping last CumulativeHistogramm (cutting off the frame) or include a modified histogram function that shows histograms only (without frame)

Given the fact, that the used Histogram function (which can be a modified version of HistogramRGBLevels()) provides histogram graphs with black pixels on white background, a kind of cumulative histogramm can be obtained by muliplicating those histograms using layers. (With white on black, inverse multiplikation is needed instead.)
One will end up with one histogramm that contains all levels that were present across the whole clip.
The goal is to get histograms that show the modulation in each color channel of a recorded clip. This could help when restoring color of faded films (using CMY channels), where yellow and cyan are usally reduced to small levels.
When such a histogram is given, spreading of the levels can be performed more secure than it would be on the bases of one test scene only.

I just tried to put a script together, but I don't know how to use ScriptClip to get a cumulative clip (or an cumulative image, where the histogram information across the clip is gathered). Can anybody help, please?

Many thanks.

Last edited by sven_x; 29th September 2014 at 05:59.
sven_x is offline   Reply With Quote
Old 28th September 2014, 21:01   #3  |  Link
colours
Registered User
 
colours's Avatar
 
Join Date: Mar 2014
Posts: 312
This is a task that's much more easily done with an external script than trying to shoehorn Avisynth's scripting functionality to your requirements.

You can use Avisynth to do the histogram computation, dump the results to a file somehow (avs2pipemod or WriteFile or whatever is appropriate), then write a script to parse that file and add the histograms.

Alternatively, use Avisynth solely as a frame server and do the histogram computation in a separate program. (This is, incidentally, something I've done before, though I no longer have the source code or the binary.)

Edit: Just because you can do something in the Avisynth scripting language, for some very liberal definition of "can" (since clearly StainlessS's example is mostly not even the Avisynth scripting language), doesn't mean that you should. I have never been a fan of runtime scripting abuse because Avisynth is supposed to be a frame server, not anything more. Unfortunately the Avisynth Usage subforum seems to be about runtime hacks relatively often.

People like to throw around Avisynth's extensible runtime scripting functionality to demonstrate Avisynth's superiority over some alternatives, but what you really are doing is using the wrong tool for the task. This is in contrast to VapourSynth, which is also only a frame server, but is usually run in Python which is a general-purpose programming language. And I hope this doesn't sound too patronising, but of course you do general things in a general-purpose programming language; it doesn't make sense any other way. </blog>
__________________
Say no to AviSynth 2.5.8 and DirectShowSource!

Last edited by colours; 29th September 2014 at 01:24.
colours is offline   Reply With Quote
Old 28th September 2014, 22:53   #4  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 5,994
Here an RT_Stats script to get RGB Channel:Level Average over a number of sample frames, took about 10 mins on my less than powerful m/c
to sample 100 frames (* chans * 256), about 77000 calls to RT_RgbChanInRange().
Note, RT_RGBChanStats can simultaneously get stats for all 3 RGB channels, something for you to try. Also, RT_Ystats can get Y stats.

Here Script:
Code:
Avisource("D:\avs\JurassicPark.avi").ConvertToRGB32()

ARR         = "Hist.ARR"
RESULT      = "Result.Txt"
Samples     = 100
Channels    = 3

RT_FileDelete(RESULT)
RT_ArrayAlloc(ARR,2,Dim1=Channels,Dim2=256)         # 2 Dimensions, Type 2 = Float

GScript("""
    for(Samp = 0, Samples - 1) {
        n = Int(Samp * ((FrameCount - 1.0) / (Samples - 1.0)) + 0.5)
        RT_DebugF("%d) Processing Frame %d",Samp,n)
        for(chan=0,Channels-1) {
            for(i=0,255) {
                Tot = RT_ArrayGet(ARR,chan,i)
                d= RT_RgbChanInRange(Last,n=n,chan=chan,lo=i,hi=i)      # Population channel chan at level i, out range 0.0 -> 1.0
                Tot = Tot + d                                           # running total
                RT_ArraySet(ARR,Tot,chan,i)                             # Update total
            }
        }
    }
    for(chan=0,Channels-1) {
        for(i=0,255) {
            Tot = RT_ArrayGet(ARR,chan,i)                               # Get Total
            Tot = (Tot / Samples) * 255.0                               # Average, Range 0.0 -> 255.0
            RT_ArraySet(ARR,Tot,chan,i)                                 # Update
        }
    }
    for(i=0,255) {
        chan0 = RT_ArrayGet(ARR,0,i)
        chan1 = RT_ArrayGet(ARR,1,i)
        chan2 = RT_ArrayGet(ARR,2,i)
        S=RT_String("%3d] %6.2f %6.2f %6.2f",i,chan0,chan1,chan2)
        RT_DebugF("%s",S)
        RT_WriteFile(RESULT,"%s",S,Append=True)
    }
""")
MessageClip("All Done")
EDITED: Added RT_FileDelete(), delete existing file

I've just used a single accumulator array, not one for each sample frame, which you could do if required, just make the sample frame Dim1 and shift
chan and level index over one place in dimensions.

Colors suggests parsing of output text file, have implemented output txt file, but could instead just parse the resultant Array file,
I've only implemented Average of each channel:Level, seemed easiest example.
Is not terribly sprightly, but may add some kind of histogram testing func and maybe some kind of histogram clip creator func in next month or so.

EDIT: Might want to chop off intro and end credits, I did not and as it samples 1st and last frames, is slanted towards black.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 28th September 2014 at 23:34.
StainlessS is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 21:33.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2018, vBulletin Solutions Inc.