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 13th August 2012, 05:24   #21  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Here An updated QueryBorderCrop(), unfortunately, the site screws up at a simple 16K script, so
I'm splitting it into several posts.

Here Some of the Text I will have to strip out of the AVS file.

Code:
Function QueryBorderCrop(clip c,int "Samples",Float "Thresh",bool "Laced",int "XMod",int "YMod",int "WMod",int "HMod", \
    bool "Relative", String "Prefix",int "RLBT",bool "DEBUG",float "Ignore",int "Matrix") {
# QueryBorderCrop v1.08, By StainlessS, Requires GScript & RT_Stats v1.01 Plugins.
# http://forum.doom9.org/showthread.php?p=1586858#post1586858 
#
# Prescan function to get coords for eg cropping black borders. Planar, YUY2, RGB.
# Simultaneously returns 4 sets of strings holding crop coords, here is one set: "QBCropX=8 QBCropY=8 QBCropW=640 QBCropH=480".
# String sets are Chr(10) separated, the 'exact found' coords set as above, not rounded at all and possibly  throwing an error if
# you try to crop, although could use in eg resize.
# Second set using eg "QBCropXL=8", which is CropLess("L" trailer), ie when rounding for Xmod,WMod etc may leave some black border.
# Third set using eg "QBCropXM=8", which is CropMore, ie when rounding for Xmod,WMod etc may crop some image.
# Forth set using eg "QBCropXP=8", which is CropPlus, moves border positions an extra 2 pixels inwards on each edge and then as CropMore.
# The non-exact coords try to center the coords when cropping for larger WMod/HMod's so as to evenly crop from eg both left and right instead of
# just one side. Also returned in the return string is the used Threshold, perhaps set by AutoThresh, as eg "QBCropThresh=32.0"
# You can use eg Eval(QueryBorderCrop()) to set values into QBCropX, QBCropY,QBCropW,QBCropH etc variables.
#
# Args:-
#
# Samples=24, Number of frames to sample from source clip c.
#
# Thresh= -32.0, Average luma value below or equal to which is considered possible black border, above considered possible image
#  (if 3 adjacent pixel rows/columns above Thresh, then taken as image).
#  A zero or negative value is 'AutoThresh', will prescan 'Samples' frames looking for minimum pixel luma value (but ignoring a percentage
#  of the darkest pixels, see Ignore) and set 'Thresh' to that value plus the negated AutoThresh value, ie defaults sets Thresh to minimum
#  found Y value + 32.0.
#  Auto cropping will likely fail on END CREDITS ONLY clips, where on black background, and will probably crop off the sides that are no
#  different in average luma to any letterbox borders, if you cannot see the borders, then neither can QueryBorderCrop(), even setting the
#  auto Thresh to eg -1.0 or 0.0 is quite likely to fail. (See RLBT edge bitflags).
#  v1.08, If 'samples' < 12 [samples would have been reduced if greater than framecount], and Thresh is not specified, then default
#     AutoThresh will be adjusted.
#        Thresh = -(((samples - 1) * (31.5/(12-1))) + 0.5)      # samples==1 comes out as -0.5 : samples==12 would come out at -32.0
#     So if eg single frame, would use an AutoThresh of -0.5
#     If RGB and user specified a PC matrix then AutoThresh would also be scaled up a little (by (255.0/(235-16)).
#     The adjustment to auto Thresh where samples < 12, is to reduce the possibility of overcropping on eg a dark single 'Samples' clip,
#     but could result in not cropping enough border, its a bit of a balancing act really.
#     As an observation, most clips have good border recogition within the 1st 2 sampled frames using the default -32 AutoThresh
#     although have noticed some dark clips that required ~8 samples (or more) for full recognition @ default Thresh = -32.
#     We use a default Samples=24, because we are intrinsically paranoid.
#     To speed up, you may want to leave Auto-Thresh alone and reduce samples, but there is danger that it will not detect all borders
#     (overcrop).
#     NOTE, The plugin AutoCrop() uses a Thresh of 40.0 and samples == 5 by default (No AutoThresh), but the logic is not too dissimilar. 
#   
# Laced=true, set true for Interlaced.  (Modifies defaults for YMod,HMod, explicit YMod/HMod will override).
#
# XMod, Default: Planar 2, YUY2=2, RGB=1
# YMod, Default: Planar=2, YUY2=1, RGB=1: BUT, Doubled if laced=true.
# WMod, Default: Planar=4, YUY2=2, RGB=1
# HMod, Default: Planar=2, YUY2=1, RGB=1: BUT, Doubled if laced=true.
#  The above XMod etc set rounding for the non-exact cropping coords.
#  The only real reason for default planar WMod=4 is VirtualDubMod dont like it less than that (Vdub latest, OK).
#
# Relative=false, False returns Width and Height, true returns Width/Height relative eg QBCropW=-6 QBCropH=-4.
#
# Prefix="QBCrop", string for returned variable names, only use valid variable name characters eg NO SPACES. Default returns eg "QBCropX".
#
# RLBT=15=All Borders, Bitflags of edges to crop, 15 ($0F) crops all four. Each letter in the name 'RLBT' represents an edge and bit position
#  starting with 'R' in bit 3 representing the value 8 (2^3=8). 'L' = bit 2=4 (2^2=4), 'B' = bit 1=2 (2^1=2), 'T' = bit 0=1 (2^0=1).
#  To calculate the RLBT bitflags, for 'R'(Right) add 8, for 'L'(Left) add 4, for 'B'(Bottom) add 2, and for 'T'(Top) add 1. 
#  Add all of the bit flags together 8+4+2+1 (=15) crops all four edges, 8+4 crops only Right & Left, and 2+1 crops only Bottom & Top.
#
# DEBUG=False=No Debug. Set True for debugging info, need DebugView: http://technet.microsoft.com/en-gb/sysinternals/bb545027
#
# Ignore=0.2, percentage of darkest pixels to ignore during Full image AutoThresh scan. 
#
# Matrix, For conversion of RGB to YUV-Y, 0 = Rec601, 1 = Rec709, 2 = PC601, 3 = PC709
#  Default for RGB is 2(PC601) if width <= 720 else 1(PC709) : YUV not used 
#  The defaults are for PC601 & PC709 range 0-255.
#  So as to not require different Thresh for RGB, if clip c is RGB and matrix is PC range, then Thresh will be scaled
#  to RGB full range ie Thresh = Thresh * (255.0/(235.0-16.0))
#
# If cropping too much border, then increase Samples or reduce Thresh 
# If not cropping enough border then border is being seen as image, increase Thresh.
The Bare Script Follows In next post
__________________
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; 4th September 2012 at 14:53.
StainlessS is offline   Reply With Quote
Old 13th August 2012, 05:26   #22  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
QueryBorderCrop(), See Also previous and following posts.

Code:
Function QueryBorderCrop(clip c,int "Samples",Float "Thresh",bool "Laced",int "XMod",int "YMod",int "WMod",int "HMod", \
    bool "Relative", String "Prefix",int "RLBT",bool "DEBUG",float "Ignore",int "Matrix") {
    VERS="QueryBorderCrop v1.08 - 29 Aug 2012"
    c
    GScript("""
        DEBUG=default(DEBUG,False)     
        Laced = Default(Laced,True)  
        XM=IsPlanar()?2:IsYUY2()?2:1        WM=IsPlanar()?4:IsYUY2()?2:1         YM=IsPlanar()?2:IsYUY2()?1:1   YM=(Laced)?2*YM:YM
        XMod  = int(Default(XMod,XM))       YMod  = int(Default(YMod,YM))        WMod  = int(Default(WMod,WM))  HMod  = int(Default(HMod,YM))
        Prefix= Default(Prefix,"QBCrop")    Relative= Default(Relative,false)    RLBT=int(Default(RLBT,15))     w=Width  h=Height Frames = Framecount()
        Ignore=Float(Default(Ignore,0.2))
        Samples = int(Default(Samples,24))  
        Samples = (Samples > Frames)? Frames : Samples
        Mat = (width <= 720) ? 2 : 3                                # Default to PC levels
        Matrix = Default(Matrix,Mat)
        Assert((Samples >= 1), "QueryBorderCrop: Requires Samples>=1")
        Assert(XMod>0 && YMod>0 && WMod>0 && HMod>0,"QueryBorderCrop: XMod,YMod,WMod,HMod Must be at least 1")
        Assert(WMod%XMod==0,"QueryBorderCrop: WMod must be a multiple of XMod")
        Assert(HMod%YMod==0,"QueryBorderCrop: HMod must be a multiple of YMod")
        Assert(RLBT>=1 && RLBT<=15,"QueryBorderCrop: RLBT 1->15 Only")
        flgs=RLBT flgR=(flgs>=8) flgs=flgs % 8 flgL=(flgs>=4) flgs=flgs % 4 flgB=(flgs>=2) flgs=flgs % 2 flgT=(flgs>=1)
        CX=0 CY=0 CW=0 CH=0 Rgt=w/2 Bot=h/2 Lft=Rgt-1 Top=Bot-1
        DBGS1="" DBGS2=""           
        if(!Defined(Thresh)) {
          if(samples < 12) {
              Thresh = -(((samples - 1) * (31.5/(12-1))) + 0.5)      # samples==12 would come out at -32
              DBGS1="QBC: Low Samples count, AutoThresh reduced from default -32 to "+String(Thresh)
              }
          else            {Thresh = -32.0}                                      
        }
        if(isRGB() && Matrix >= 2) {
            Thresh=Thresh *(255.0/(235.0-16.0))                             # Scale up a bit for PC levels
            DBGS2="QBC: RGB PC Levels Thresh Auto Scaled to "+String(Thresh)
        }
        if(DEBUG){RT_Debug("QBC:") RT_Debug("QBC:",VERS,"- By StainlessS") RT_Debug("QBC:")
            RT_Debug(DBGS1)
            RT_Debug(DBGS2)            
            RT_Debug("QBC:","Samples="+String(Samples),"Thresh="+String(Thresh,"%.2f"),"Laced="+String(Laced),"Matrix="+String(Matrix))
            RT_Debug("QBC:","XMod="+String(XMod),"YMod="+String(YMod),"WMod="+String(WMod),"HMod="+String(HMod))
            RT_Debug("QBC:","Relative="+String(Relative),"Prefix="+String(Prefix),"RLBT="+String(RLBT),"Ignore="+String(Ignore,"%.2f"))
            RT_Debug("QBC:")}
        if(Thresh < 0.0) { thmin = 255.0
            if(IsPlanar() && Width < 4096 && Height < 4096) { if(DEBUG){RT_Debug("QBC:","AutoThresh Using Avisynth Planar Luma Sampling")}
                for(Samp = 1,Samples) { current_frame = int(Samp * ((Frames - 1.0) / (Samples+1)) + 0.5)
                    th=YPlaneMin(threshold=Ignore) if (thmin>th){thmin=th}
                    if(DEBUG){
                        RT_Debug("QBC:","AutoThresh",String(Samp,"%-2.0f")+")","["+String(current_frame,"%-5.0f")+ "]","YPlaneMin="+String(thmin))}
                    if(thmin==0.0){Samp = Samples + 1} # No smaller possible, Break.
                }
            } else { if(DEBUG) {RT_Debug("QBC:","AutoThresh Using RT_Stats Luma Sampling")}
                for(Samp = 1,Samples) { Frm = int(Samp * ((Frames - 1.0) / (Samples+1)) + 0.5)
                    th=RT_YPlaneMin(Frm,threshold=Ignore,matrix=Matrix) if (thmin>th){thmin=th}
                    if(DEBUG){ RT_Debug("QBC:","AutoThresh",String(Samp,"%-2.0f")+")","["+String(frm,"%-5.0f")+"]","YPlaneMin="+String(thmin))}
                    if(thmin==0.0){Samp = Samples + 1} # No smaller possible, Break.
                }
            }
            Thresh = thmin + (-Thresh) if(DEBUG) {RT_Debug("QBC:","AutoThresh","Thresh="+String(Thresh,"%.2f")) RT_Debug("QBC:")}
        }
        GotF=-1 GotN=0                          # Track Number of frames where coords 1st found
        for(Samp = 1,Samples) {
            Frm = int(Samp * ((Frames - 1.0) / (Samples+1)) + 0.5)  # Sample frame
            th2=0.0 th1=0.0 th=0.0              # Init, Previous luma values (pass the parcel)
            # Only Y-Top Commented
            if(flgT && Top>=2) {                # Required and some more to do ?
                cnt=0                           # Init, got none yet 
                For(y=0,Top) {                  # Searching from outside inwards
                    th2=th1 th1=th th=RT_AverageLuma(Frm,y=y,h=1,x=CX,w=CW,matrix=Matrix) # Pass the parcel
                    if(th>Thresh) {             # Possible image
                        if(Cnt>=2) {            # Is Image, (found 3 adjacent scanlines all passing Thresh, No Incr this time)
                            CY=y-2              # The outer scanline that passed first (th2 was th at that time).
                            Top=(y<=2)?0:y-1    # If no top border at all, no more search: else, next time search max scanline y-1.
                            if(Frm<>GotF) {     
                                GotF=Frm        # Rememeber Last active Frame where image found
                                GotN=GotN+1     # Incr number of active frames
                            }
                            y=h                 # Force loop exit. (No more to do this frame, found 1st match scanning inwards)
                            if(DEBUG) {
                                RT_Debug("QBC:","Top",String(Samp)+")","["+String(Frm,"%-5.0f")+"]","AveY="+String(th2,"%3.2f"),"CY="+String(CY))
                            }
                        } else {
                            Cnt=Cnt+1           # Incr count, scanlines passed OK as possible image
                        }
                    } else {
                        Cnt=0                   # Failed, maybe border.
                    }
                }
            }
            if(flgB && Bot<=(h-1)-2){
                cnt=0 For(y=h-1,Bot,-1){th2=th1 th1=th th=RT_AverageLuma(Frm,y=y,h=1,x=CX,w=CW,matrix=Matrix)
                    if(th>Thresh){if(Cnt>=2){CH= -((h-1)-(y+2)) Bot=((h-1)-y<=2)?h-1: y+1 if(Frm<>GotF) {GotF=Frm GotN=GotN+1} y=-1
                    if(DEBUG){RT_Debug("QBC:","Bot",String(Samp)+")","["+String(Frm,"%-5.0f")+"]","AveY="+String(th2,"%3.2f"),"CH="+String(CH))}
                    } else {Cnt=Cnt+1}}else {Cnt=0}}}
            if(flgL && Lft>=2){
                cnt=0 For(x=0,Lft){th2=th1 th1=th th=RT_AverageLuma(Frm,x=x,w=1,y=CY,h=CH,matrix=Matrix)
                    if(th>Thresh){if(Cnt>=2){CX=x-2 Lft=(x<=2)?0:x-1 if(Frm<>GotF) {GotF=Frm GotN=GotN+1} x=w
                    if(DEBUG){RT_Debug("QBC:","Lft",String(Samp)+")","["+String(Frm,"%-5.0f")+"]","AveY="+String(th2,"%3.2f"),"CX="+String(CX))}
                    } else {Cnt=Cnt+1}} else {Cnt=0}}}
            if(flgR && Rgt<=(w-1)-2){
                cnt=0 For(x=w-1,Rgt,-1){th2=th1 th1=th th=RT_AverageLuma(Frm,x=x,w=1,y=CY,h=CH,matrix=Matrix)
                    if(th>Thresh){if(Cnt>=2){CW= -((w-1)-(x+2)) Rgt=((w-1)-x<=2)?w-1:x+1 if(Frm<>GotF) {GotF=Frm GotN=GotN+1} x=-1
                    if(DEBUG){RT_Debug("QBC:","Rgt",String(Samp)+")","["+String(Frm,"%-5.0f")+"]","AveY="+String(th2,"%3.2f"),"CW="+String(CW))}
                    } else {Cnt=Cnt+1}}else {Cnt=0}}}
            if((!flgT||Top==0) && (!flgL||Lft==0) && (!flgB||Bot==h-1) && (!flgR||Rgt==w-1))
                {Samp = Samples + 1} # No further cropping possible, Break.
        }
        if(DEBUG){ RT_Debug("QBC:","Active Frames (where image coords first found) = "+String(GotN))
                RT_Debug("QBC:","Sampled Borders:","X="+String(CX),"Y="+String(CY), \
                        "W="+String(CW)+"("+String(w-CX+CW)+")","H="+String(CH)+"("+String(h-CY+CH)+")")
                RT_Debug("QBC:")
        }
        
        # Crop Exact                        # Make Exact found Coords: Default, QBCropX, QBCropY, QBCropW, QBCropH
        CX0 = CX                            # Just make dupes
        CY0 = CY
        CW0 = w - CX + CW                   # Dont change CW and CH as needed for CropMore/CropLess/CropPlus
        CH0 = h - CY + CH
        if(DEBUG){RT_Debug("QBC:","CropExact:","X ="+String(CX0,"%2.0f"),"Y ="+String(CY0,"%2.0f"), \
                "W ="+String(CW0,"%3.0f")+"("+String(CX0+CW0-w)+")","H ="+String(CH0,"%3.0f")+"("+String(CY0+CH0-h)+")")}

        # CropLess X,W                      # Make CropLess Coords: Default, QBCropXL, QBCropYL, QBCropWL, QBCropHL
        CX1     = int(CX / XMod)
        CW1_Lim = int(w / XMod) - CX1
        CW1     = int((w - (CX1*XMod) + CW + WMod - 1) / XMod)
        CW1     = (CW1 > CW1_Lim) ? CW1_Lim : CW1
        CW1_D   = int(WMod/XMod)
        CW1_M   = int((CW1 % CW1_D) / 2)
        CW1_Off = (CX1 < CW1_M) ? CX1 : CW1_M
        CX1 = CX1 - CW1_Off
        CW1 = CW1 + CW1_Off        
        CX1 = CX1 * XMod
        CW1 = int(CW1 / CW1_D) * CW1_D * XMod               
        # CropLess Y,H
        CY1     = int(CY / YMod)
        CH1_Lim = int(h / YMod) - CY1
        CH1     = int((h - (CY1*YMod) + CH + HMod - 1) / YMod)
        CH1     = (CH1 > CH1_Lim) ? CH1_Lim : CH1
        CH1_D   = int(HMod/YMod)
        CH1_M   = int((CH1 % CH1_D) / 2)
        CH1_Off = (CY1 < CH1_M) ? CY1 : CH1_M
        CY1 = CY1 - CH1_Off
        CH1 = CH1 + CH1_Off
        CY1 = CY1 * YMod
        CH1 = int(CH1 / CH1_D) * CH1_D * YMod
        if(DEBUG) {
            if(CW1_Off<>0) {RT_Debug("QBC:","CropLess: "," XL Centered - "+String(CW1_Off))}
            if(CH1_Off<>0) {RT_Debug("QBC:","CropLess: "," YL Centered - "+String(CH1_Off))}
            RT_Debug("QBC:","CropLess: "," XL="+String(CX1,"%2.0f"),"YL="+String(CY1,"%2.0f"), \
                    "WL="+String(CW1,"%3.0f")+"("+String(CX1+CW1-w)+")","HL="+String(CH1,"%3.0f")+"("+String(CY1+CH1-h)+")")
        }    
        # CropMore X,W                                      # Make CropMore Coords: Default, QBCropXM, QBCropYM, QBCropWM, QBCropHM
        CX2     = int((CX+XMod-1)/XMod)*XMod                # Round up CX2
        CW2_Tmp = int(((w - CX2 + CW)/XMod))*XMod           # wid Mod XMod
        CW2     = int(CW2_Tmp/WMod)*WMod                    # wid Mod WMod
        CW2_Dif = int((CW2_Tmp - CW2) / XMod)               # Diff due to WMod in XMod steps
        CW2_Off = (int(CW2_Dif/2)) * XMod                   # Half difference to try and center
        CX2     = CX2 + CW2_Off                             # Center, try to share out cropping due to big WMod
        # CropMore Y,H
        CY2     = int((CY+YMod-1)/YMod)*YMod                # Round up CY2
        CH2_Tmp = int(((h - CY2 + CH)/YMod))*YMod           # height Mod YMod
        CH2     = int(CH2_Tmp/HMod)*HMod                    # height Mod HMod
        CH2_Dif = int((CH2_Tmp - CH2) / YMod)               # Diff due to HMod in YMod steps
        CH2_Off = (int(CH2_Dif/2)) * YMod                   # Half difference to try and center
        CY2     = CY2 + CH2_Off                             # Center, try to share out cropping due to big HMod
        if(DEBUG) {
            if(CW2_Off<>0) {RT_Debug("QBC:","CropMore: "," XM Centered + "+String(CW2_Off))}
            if(CH2_Off<>0) {RT_Debug("QBC:","CropMore: "," YM Centered + "+String(CH2_Off))}            
            RT_Debug("QBC:","CropMore: "," XM="+String(CX2,"%2.0f"),"YM="+String(CY2,"%2.0f"), \
                    "WM="+String(CW2,"%3.0f")+"("+String(CX2+CW2-w)+")","HM="+String(CH2,"%3.0f")+"("+String(CY2+CH2-h)+")")
        }
        # CropPlus X,W                                      # Make CropPlus Coords: Default, QBCropXP, QBCropYP, QBCropWP, QBCropHP
        CXP     = CX+2                                      # CropPlus Over Cropping, dont touch orig vars
        CYP     = CY+2                                      # Cropping extra 2 pixels from each edge
        CWP     = CW-2                                      # After that, as CropMore
        CHP     = CH-2        
        CX3     = int((CXP+XMod-1)/XMod)*XMod               # Round up CX3
        CW3_Tmp = int(((w - CX3 + CWP)/XMod))*XMod          # wid Mod XMod
        CW3     = int(CW3_Tmp/WMod)*WMod                    # wid Mod WMod
        CW3_Dif = int((CW3_Tmp - CW3) / XMod)               # Diff due to WMod in XMod steps
        CW3_Off = (int(CW3_Dif/2)) * XMod                   # Half difference to try and center
        CX3     = CX3 + CW3_Off                             # Center, try to share out cropping due to big WMod
        # CropPlus Y,H
        CY3     = int((CYP+YMod-1)/YMod)*YMod               # Round up CY3
        CH3_Tmp = int(((h - CY3 + CHP)/YMod))*YMod          # height Mod YMod
        CH3     = int(CH3_Tmp/HMod)*HMod                    # height Mod HMod
        CH3_Dif = int((CH3_Tmp - CH3) / YMod)               # Diff due to HMod in YMod steps
        CH3_Off = (int(CH3_Dif/2)) * YMod                   # Half difference to try and center
        CY3     = CY3 + CH3_Off                             # Center, try to share out cropping due to big HMod
        if(DEBUG) {
            if(CW3_Off<>0) {RT_Debug("QBC:","CropPlus: "," XP Centered + "+String(CW3_Off))}
            if(CH3_Off<>0) {RT_Debug("QBC:","CropPlus: "," YP Centered + "+String(CH3_Off))}            
            RT_Debug("QBC:","CropPlus: "," XP="+String(CX3,"%2.0f"),"YP="+String(CY3,"%2.0f"), \
                    "WP="+String(CW3,"%3.0f")+"("+String(CX3+CW3-w)+")","HP="+String(CH3,"%3.0f")+"("+String(CY3+CH3-h)+")")
        }

        if(Relative) {  CW0 = CX0 + CW0 - w     CH0 = CY0 + CH0 - h         CW1 = CX1 + CW1 - w     CH1 = CY1 + CH1 - h     
                        CW2 = CX2 + CW2 - w     CH2 = CY2 + CH2 - h         CW3 = CX3 + CW3 - w     CH3 = CY3 + CH3 - h}            
        RS0=Prefix+"X=" +String(CX0)+" "+Prefix+"Y=" +String(CY0)+" "+Prefix+"W=" +String(CW0)+" "+Prefix+"H=" +String(CH0)
        RS1=Prefix+"XL="+String(CX1)+" "+Prefix+"YL="+String(CY1)+" "+Prefix+"WL="+String(CW1)+" "+Prefix+"HL="+String(CH1)
        RS2=Prefix+"XM="+String(CX2)+" "+Prefix+"YM="+String(CY2)+" "+Prefix+"WM="+String(CW2)+" "+Prefix+"HM="+String(CH2)       
        RS3=Prefix+"XP="+String(CX3)+" "+Prefix+"YP="+String(CY3)+" "+Prefix+"WP="+String(CW3)+" "+Prefix+"HP="+String(CH3)       
        RST=Prefix+"Thresh="+String(Thresh)   # Return used Thresh, might be useful to avoid 2nd prescan for AutoThresh.
        if(DEBUG){RT_Debug("QBC:") RT_Debug("QBC:","Return:",RS0) RT_Debug("QBC:","Return:",RS1) RT_Debug("QBC:","Return:",RS2)
            RT_Debug("QBC:","Return:",RS3) RT_Debug("QBC:","Return:",RST)}
    """)
    Return RS0+Chr(10)+RS1+Chr(10)+RS2+Chr(10)+RS3+Chr(10)+RST+Chr(10)
}
__________________
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; 29th August 2012 at 10:39.
StainlessS is offline   Reply With Quote
Old 13th August 2012, 05:30   #23  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
QueryLumaMinMax(), And a couple of other script functions. See Previous and following posts.


Code:
Function QueryLumaMinMax(clip c,int "Samples",float "Ignore",String "Prefix",bool "DEBUG",int "X",int "Y",int "W",int "H",int "Matrix") {
# QueryLumaMinMax v1.01, By StainlessS, Requires GScript & RT_Stats v1.01 Plugins.
# Prescan function to get Luma Min,Max. Planar, YUY2, RGB.
# Returns luma min/max as string Default eg "QLMMMin=25 QLMMMax=244", use eg "Eval(QueryLumaMinMax())" to set variables for
# use in Avisynth.
# http://forum.doom9.org/showthread.php?p=1586859#post1586859
#
# Samples=24=frames to sample.
#
# Ignore=0.2=Percentage of extreme pixels to ignore.
#
# Prefix="QLMM"=Prefix for return values.
#
# X=Y=W=H=0=Full screen, as crop.
#
# DEBUG=false= dont show. True=debug info. Need DebugView: http://technet.microsoft.com/en-gb/sysinternals/bb545027
#
# Matrix, For conversion of RGB to YUV-Y, 0 = Rec601, 1 = Rec709, 2 = PC601, 3 = PC709
#   Default for RGB is 2(PC601) if width <= 720 else 3(PC709) : YUV not used
#   For RGB, it probably does not make sense to use anything other than PC levels, unless studio RGB.
# 
#     Usage:
#
#     # Auto levels using Levels() filter.
#     AUTOLEVEL_STRENGTH = 0.5    # 0.0 -> 1.0
#     Eval(QueryLumaMinMax())     # using default values, sets QLMMMin and QLMMMax.
#           if(IsRGB()) {               # Requires GScript
#               CSMin = 0
#               CSMax = 255
#           } else {        
#               CSMin = 16
#               CSMax = 235
#           }
#           ALMin = Int(CSMin - ((CSMin - QLMMMin) * AUTOLEVEL_STRENGTH) + 0.5) # Round Up
#           ALMax = Int(CSMax - ((CSMax - QLMMMax) * AUTOLEVEL_STRENGTH))       # Round down
#           Levels(ALMin,1.0,ALMax,CSMin,CSMax,Coring=False) # DO NOT use Coring 
#
    VERS="QueryLumaMinMax v1.01 - 29 Aug 2012"
    c
    Samples = Default(Samples,24) Ignore=Float(Default(Ignore,0.2)) Prefix = Default(Prefix,"QLMM") DEBUG=default(DEBUG,False)
    X=int(Default(X,0)) Y=int(Default(Y,0)) W=int(Default(W,0)) H=int(Default(H,0)) 
    W = (W<=0) ? Width  - X + W : W         H = (H<=0) ? Height - Y + H : H
    Mat = (width <= 720) ? 2 : 3            # Default, PC601 or PC709 for RGB
    Matrix = Default(Matrix,Mat)
    GScript("""
        Assert((Samples >= 1), "QueryLumaMinMax: Requires Samples>=1")
        Frames=FrameCount mn=255.0 mx=0.0       Samples = (Samples > Frames)? Frames : Samples
        if(DEBUG){RT_Debug("QLMM:") RT_Debug("QLMM:",VERS,"- By StainlessS") RT_Debug("QLMM:")
            RT_Debug("QLMM:","Samples="+String(Samples),"Ignore="+String(Ignore,"%.2f"),"Prefix="+String(Prefix))
            RT_Debug("QLMM:","X="+String(X),"Y="+String(Y),"W="+String(W),"H="+String(H),"Matrix="+String(Matrix))  
            RT_Debug("QLMM:")}
        if(IsPlanar==True && X==0 && Y==0 && W==Width && H==Height && Width < 4096 && Height < 4096) {
            if(DEBUG){RT_Debug("QLMM:","Using Avisynth Planar Full Frame Luma Sampling")}
            for(Samp = 1,Samples) {
                current_frame = int(Samp * ((Frames - 1.0) / (Samples+1)) + 0.5)          
                Mn_Tmp = YPlaneMin(threshold=ignore)      Mx_Tmp = YPlaneMax(threshold=ignore)      
                if(DEBUG){RT_Debug("QLMM:","LumaRange:",String(Samp,"%-2.0f")+")","["+String(current_frame,"%-5.0f")+"]", \
                    "LumaMin = "+String(Mn_Tmp),"LumaMax = "+String(Mx_Tmp))}
                mn=(Mn_Tmp<mn)?Mn_Tmp:mn    mx=(Mx_Tmp>mx)?Mx_Tmp:mx}
        } else {if(DEBUG){RT_Debug("QLMM:","Using RT_Stats Luma Sampling")}
            for(Samp = 1,Samples) {
                n = int(Samp * ((Frames - 1.0) / (Samples+1)) + 0.5)          
                Mn_Tmp = RT_YPlaneMin(n,x=X,y=Y,w=W,h=H,threshold=ignore,matrix=Matrix) 
                Mx_Tmp = RT_YPlaneMax(n,x=X,y=Y,w=W,h=H,threshold=ignore,matrix=Matrix)
                if(DEBUG){RT_Debug("QLMM:","LumaRange:",String(Samp,"%-2.0f")+")","["+String(n,"%-5.0f")+"]", \
                    "LumaMin = "+String(Mn_Tmp),"LumaMax = "+String(Mx_Tmp))}
                mn=(Mn_Tmp<mn)?Mn_Tmp:mn    mx=(Mx_Tmp>mx)?Mx_Tmp:mx}       
        }
        RS=Prefix+"Min="+String(Mn) + " " + Prefix+"Max=" + String(mx)                  
        if(DEBUG){RT_Debug("QLMM:") RT_Debug("QLMM:","Return:",RS)}
    """)
    Return RS
}
#--------------

# Get File extension from filename, use to eg select Source filter for audio file.
Function GetFileExtension(String fn) {len   = FindStr(RevStr(fn),".") - 1 Return Len>=1 ? RightStr(fn,Len) : ""}

Function GetCropDAR(clip c,float DAR,float "X",float "Y",float "W",float "H") {
# Call prior to Crop/Resize with (possibly fractional) cropping to calc resultant DAR, X,Y,W,H are cropping coords
#   DAR = FAR * SAR   :::   FAR = DAR / SAR   :::   SAR = DAR / FAR
#
    X=Float(Default(X,0.0)) Y=Float(Default(Y,0.0)) W=Float(Default(W,0.0)) H=Float(Default(H,0.0))
    W=W<=0.0?c.width+W-X:W  H=H<=0.0?c.height+H-Y:H
    # Irrespective of what various resizers in various Avisynth versions silently correct, we dont allow eg -ve X
    Assert(X>=0.0&&X  < c.width, "GetCropDAR: Invalid X("+String(X)+")")
    Assert(Y>=0.0&&Y  < c.height,"GetCropDAR: Invalid Y("+String(Y)+")")
    Assert(W> 0.0&&X+W<=c.width, "GetCropDAR: Invalid W("+String(W)+")")
    Assert(H> 0.0&&Y+H<=c.height,"GetCropDAR: Invalid H("+String(H)+")")
    Return c.GetSAR(DAR) * W / H 
}

#--------------

# From MeGUI Wiki:
Function GetDAR(clip c, float SAR) { return Float(c.width) * SAR / Float(c.height)}     # Gets the DAR from the SAR
Function GetSAR(clip c, float DAR) { return DAR * Float(c.height) / Float(c.width) }    # Gets the SAR from the DAR
Function SignalDAR(float DAR){global MeGUI_darx=Round(1000*DAR) global MeGUI_dary=1000} # Signal DAR for MEGUI (Name change from SetDar)
__________________
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; 29th August 2012 at 10:41.
StainlessS is offline   Reply With Quote
Old 13th August 2012, 05:32   #24  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
A Little Demo script for QueryBorderCrop() and QueryLumaMinMax (), See previous few posts.

Code:
Import ("D:\avs\QueryBorderCrop.avs")
Import ("D:\avs\QueryLumaMinMax.avs")
GSCript("""
####################################
DAR     =   16.0/9.0                         # Input Full Frame Display Aspect Ratio
SIZE_X  =   640                             # Output X dim
SIZE_Y  =   480                             # Output Y dim
DEBUG   =   True                            # Debug ON
TFF     =   True
AUTOLEVEL_STRENGTH = 0.5					# Strength of auto leveling, 0.0 -> 1.0
####################################
VideoFileName 	=LCase("D:\TEST_VOBS\1.d2v")
AudioFileName 	=LCase("D:\TEST_VOBS\1 T80 3_2ch 448Kbps DELAY 0ms.ac3")
AudioDelay      =Value(LCase("0.000"))

###############
MPEG2Source(VideoFileName,cpu2="xxxxxx")
AudioExt=GetFileExtension(AudioFileName)

Audio=      (AudioExt=="ac3") ? NICAC3Source(AudioFileName,channels=2,DRC=0)
        \ : (AudioExt=="mpa"||AudioExt=="mp1"||AudioExt=="mp2"||AudioExt=="mp3") ? NicMPG123Source(AudioFileName,Normalize=False)
        \ : (AudioExt=="wav") ? RaWavSource(AudioFileName)
        \ : 0       
 (!isInt(Audio))?AudioDub(Audio).DelayAudio(AudioDelay).Trim(0,0):NOP

(AudioRate() <> 44100 && AudioRate() <> 48000)?ResampleAudio(44100):NOP

(TFF)?AssumeTFF():AssumeBFF

Eval(QueryBorderCrop(laced=false,Debug=DEBUG))                      # Get Return string and initialize QBCropX type variables in Avisynth
PreCrop=Crop(QBCropXP,QBCropYP,QBCropWP,QBCropHP)       # Get OverCropped coord clip using CropPlus Coords ('P' trailer character)

# Get Auto Levels Min/Max from OVERCROPPED Clip (Ignore black borders)
Eval(QueryLumaMinMax(PreCrop,Debug=DEBUG))

if(IsYUV()) {
	CSMin = 16
	CSMax = 235
} else {		
	CSMin = 0
	CSMax = 255
}
ALMin = Int(CSMin - ((CSMin - QLMMMin) * AUTOLEVEL_STRENGTH) + 0.5)	# Round Up
ALMax = Int(CSMax - ((CSMax - QLMMMax) * AUTOLEVEL_STRENGTH))       # Round down
Levels(ALMin,1.0,ALMax,CSMin,CSMax,Coring=False) # AutoLevel, DONT USE Coring 


if(DEBUG) {
    RT_Debug("AutoLevel: Levels("+String(ALMin)+",1.0,"+String(ALMax)+","+String(CSMin)+","+String(CSMax)+")")
}
if(QBCropXM<>0||QBCropYM<>0||QBCropWM<>SIZE_X||QBCropHM<>SIZE_Y) {
    DAR=GetCropDAR(DAR,QBCropXM,QBCropYM,QBCropWM,QBCropHM)      # Calc New DAR after Resize with CropMore ('M' Trailer Char)
    Spline36Resize(SIZE_X,SIZE_Y,QBCropXM,QBCropYM,QBCropWM,QBCropHM)   
}

if(DEBUG){RT_Debug("SIGNALDAR:","MeGUI DAR="+String(DAR))}
SignalDAR(DAR)                                                  # Tell MeGUI the new Resized/Cropped Display Aspect Ratio
return last
""")
And the RT_Stats, RT_Debug Output

Code:
00000005  10:53:34  RT_Debug: QBC:  
00000006  10:53:34  RT_Debug: QBC: QueryBorderCrop v1.08 - 29 Aug 2012 - By StainlessS  
00000007  10:53:34  RT_Debug: QBC:  
00000008  10:53:34  RT_Debug: QBC: Samples=24 Thresh=-32.00 Laced=false Matrix=2  
00000009  10:53:34  RT_Debug: QBC: XMod=2 YMod=2 WMod=4 HMod=2  
00000010  10:53:34  RT_Debug: QBC: Relative=false Prefix=QBCrop RLBT=15 Ignore=0.20 
00000011  10:53:34  RT_Debug: QBC:  
00000012  10:53:34  RT_Debug: QBC: AutoThresh Using Avisynth Planar Luma Sampling 
00000013  10:53:34  RT_Debug: QBC: AutoThresh 1 ) [715  ] YPlaneMin=16  
00000014  10:53:35  RT_Debug: QBC: AutoThresh 2 ) [1430 ] YPlaneMin=16  
00000015  10:53:35  RT_Debug: QBC: AutoThresh 3 ) [2145 ] YPlaneMin=16  
00000016  10:53:35  RT_Debug: QBC: AutoThresh 4 ) [2860 ] YPlaneMin=16  
00000017  10:53:35  RT_Debug: QBC: AutoThresh 5 ) [3575 ] YPlaneMin=16  
00000018  10:53:36  RT_Debug: QBC: AutoThresh 6 ) [4290 ] YPlaneMin=16  
00000019  10:53:36  RT_Debug: QBC: AutoThresh 7 ) [5004 ] YPlaneMin=16  
00000020  10:53:36  RT_Debug: QBC: AutoThresh 8 ) [5719 ] YPlaneMin=16  
00000021  10:53:36  RT_Debug: QBC: AutoThresh 9 ) [6434 ] YPlaneMin=16  
00000022  10:53:36  RT_Debug: QBC: AutoThresh 10) [7149 ] YPlaneMin=16  
00000023  10:53:37  RT_Debug: QBC: AutoThresh 11) [7864 ] YPlaneMin=16  
00000024  10:53:37  RT_Debug: QBC: AutoThresh 12) [8579 ] YPlaneMin=16  
00000025  10:53:37  RT_Debug: QBC: AutoThresh 13) [9294 ] YPlaneMin=16  
00000026  10:53:37  RT_Debug: QBC: AutoThresh 14) [10009] YPlaneMin=16  
00000027  10:53:37  RT_Debug: QBC: AutoThresh 15) [10724] YPlaneMin=16  
00000028  10:53:38  RT_Debug: QBC: AutoThresh 16) [11439] YPlaneMin=16  
00000029  10:53:38  RT_Debug: QBC: AutoThresh 17) [12154] YPlaneMin=16  
00000030  10:53:38  RT_Debug: QBC: AutoThresh 18) [12869] YPlaneMin=16  
00000031  10:53:38  RT_Debug: QBC: AutoThresh 19) [13583] YPlaneMin=16  
00000032  10:53:39  RT_Debug: QBC: AutoThresh 20) [14298] YPlaneMin=16  
00000033  10:53:39  RT_Debug: QBC: AutoThresh 21) [15013] YPlaneMin=16  
00000034  10:53:39  RT_Debug: QBC: AutoThresh 22) [15728] YPlaneMin=16  
00000035  10:53:39  RT_Debug: QBC: AutoThresh 23) [16443] YPlaneMin=16  
00000036  10:53:40  RT_Debug: QBC: AutoThresh 24) [17158] YPlaneMin=16  
00000037  10:53:40  RT_Debug: QBC: AutoThresh Thresh=48.00  
00000038  10:53:40  RT_Debug: QBC:  
00000039  10:53:44  RT_Debug: QBC: Top 2) [1430 ] AveY=65.15 CY=75  
00000040  10:53:44  RT_Debug: QBC: Bot 2) [1430 ] AveY=61.18 CH=-76 
00000041  10:53:44  RT_Debug: QBC: Lft 2) [1430 ] AveY=48.26 CX=46  
00000042  10:53:44  RT_Debug: QBC: Rgt 2) [1430 ] AveY=48.14 CW=-77 
00000043  10:53:45  RT_Debug: QBC: Lft 3) [2145 ] AveY=120.76 CX=0  
00000044  10:53:45  RT_Debug: QBC: Rgt 3) [2145 ] AveY=106.21 CW=0  
00000045  10:53:58  RT_Debug: QBC: Active Frames (where image coords first found) = 2 
00000046  10:53:58  RT_Debug: QBC: Sampled Borders: X=0 Y=75 W=0(720) H=-76(425)  
00000047  10:53:58  RT_Debug: QBC:  
00000048  10:53:58  RT_Debug: QBC: CropExact: X = 0 Y =75 W =720(0) H =425(-76) 
00000049  10:53:58  RT_Debug: QBC: CropLess:  XL= 0 YL=74 WL=720(0) HL=426(-76) 
00000050  10:53:58  RT_Debug: QBC: CropMore:  XM= 0 YM=76 WM=720(0) HM=424(-76) 
00000051  10:53:58  RT_Debug: QBC: CropPlus:  XP= 2 YP=78 WP=716(-2) HP=420(-78)  
00000052  10:53:58  RT_Debug: QBC:  
00000053  10:53:58  RT_Debug: QBC: Return: QBCropX=0 QBCropY=75 QBCropW=720 QBCropH=425 
00000054  10:53:58  RT_Debug: QBC: Return: QBCropXL=0 QBCropYL=74 QBCropWL=720 QBCropHL=426 
00000055  10:53:58  RT_Debug: QBC: Return: QBCropXM=0 QBCropYM=76 QBCropWM=720 QBCropHM=424 
00000056  10:53:58  RT_Debug: QBC: Return: QBCropXP=2 QBCropYP=78 QBCropWP=716 QBCropHP=420 
00000057  10:53:58  RT_Debug: QBC: Return: QBCropThresh=48.000000 
00000058  10:53:58  RT_Debug: QLMM: 
00000059  10:53:58  RT_Debug: QLMM: QueryLumaMinMax v1.01 - 29 Aug 2012 - By StainlessS 
00000060  10:53:58  RT_Debug: QLMM: 
00000061  10:53:58  RT_Debug: QLMM: Samples=24 Ignore=0.20 Prefix=QLMM  
00000062  10:53:58  RT_Debug: QLMM: X=0 Y=0 W=716 H=420 Matrix=2  
00000063  10:53:58  RT_Debug: QLMM: 
00000064  10:53:58  RT_Debug: QLMM: Using Avisynth Planar Full Frame Luma Sampling  
00000065  10:53:58  RT_Debug: QLMM: LumaRange: 1 ) [715  ] LumaMin = 16 LumaMax = 23  
00000066  10:53:58  RT_Debug: QLMM: LumaRange: 2 ) [1430 ] LumaMin = 18 LumaMax = 163 
00000067  10:53:58  RT_Debug: QLMM: LumaRange: 3 ) [2145 ] LumaMin = 83 LumaMax = 199 
00000068  10:53:58  RT_Debug: QLMM: LumaRange: 4 ) [2860 ] LumaMin = 21 LumaMax = 103 
00000069  10:53:58  RT_Debug: QLMM: LumaRange: 5 ) [3575 ] LumaMin = 25 LumaMax = 159 
00000070  10:53:58  RT_Debug: QLMM: LumaRange: 6 ) [4290 ] LumaMin = 17 LumaMax = 164 
00000071  10:53:58  RT_Debug: QLMM: LumaRange: 7 ) [5004 ] LumaMin = 19 LumaMax = 170 
00000072  10:53:58  RT_Debug: QLMM: LumaRange: 8 ) [5719 ] LumaMin = 17 LumaMax = 145 
00000073  10:53:58  RT_Debug: QLMM: LumaRange: 9 ) [6434 ] LumaMin = 17 LumaMax = 159 
00000074  10:53:58  RT_Debug: QLMM: LumaRange: 10) [7149 ] LumaMin = 16 LumaMax = 176 
00000075  10:53:58  RT_Debug: QLMM: LumaRange: 11) [7864 ] LumaMin = 16 LumaMax = 191 
00000076  10:53:58  RT_Debug: QLMM: LumaRange: 12) [8579 ] LumaMin = 17 LumaMax = 196 
00000077  10:53:58  RT_Debug: QLMM: LumaRange: 13) [9294 ] LumaMin = 20 LumaMax = 195 
00000078  10:53:58  RT_Debug: QLMM: LumaRange: 14) [10009] LumaMin = 18 LumaMax = 197 
00000079  10:53:58  RT_Debug: QLMM: LumaRange: 15) [10724] LumaMin = 18 LumaMax = 155 
00000080  10:53:58  RT_Debug: QLMM: LumaRange: 16) [11439] LumaMin = 16 LumaMax = 143 
00000081  10:53:58  RT_Debug: QLMM: LumaRange: 17) [12154] LumaMin = 16 LumaMax = 153 
00000082  10:53:58  RT_Debug: QLMM: LumaRange: 18) [12869] LumaMin = 20 LumaMax = 191 
00000083  10:53:58  RT_Debug: QLMM: LumaRange: 19) [13583] LumaMin = 24 LumaMax = 127 
00000084  10:53:58  RT_Debug: QLMM: LumaRange: 20) [14298] LumaMin = 27 LumaMax = 204 
00000085  10:53:58  RT_Debug: QLMM: LumaRange: 21) [15013] LumaMin = 21 LumaMax = 191 
00000086  10:53:58  RT_Debug: QLMM: LumaRange: 22) [15728] LumaMin = 20 LumaMax = 184 
00000087  10:53:58  RT_Debug: QLMM: LumaRange: 23) [16443] LumaMin = 18 LumaMax = 200 
00000088  10:53:58  RT_Debug: QLMM: LumaRange: 24) [17158] LumaMin = 29 LumaMax = 191 
00000089  10:53:58  RT_Debug: QLMM: 
00000090  10:53:58  RT_Debug: QLMM: Return: QLMMMin=16 QLMMMax=204  
00000091  10:53:58  RT_Debug: AutoLevel: Levels(16,1.0,219,16,235)  
00000092  10:53:58  RT_Debug: SIGNALDAR: MeGUI DAR=2.415094
__________________
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; 29th August 2012 at 10:57.
StainlessS is offline   Reply With Quote
Old 23rd August 2012, 01:33   #25  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
New version RT_Stats() v1.02, see first post.
__________________
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 ???
StainlessS is offline   Reply With Quote
Old 29th August 2012, 10:59   #26  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
New version RT_Stats() v1.03, see first post.

Also updated QueryBorderCrop() and QueryLumaMinMax(), a few posts earlier (Also now contained in RT_Stats zip).
__________________
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 ???
StainlessS is offline   Reply With Quote
Old 3rd September 2012, 22:38   #27  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
New Version RT_Stats, See first post.
Added RT_Call() function, calls an executable.
__________________
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 ???
StainlessS is offline   Reply With Quote
Old 4th September 2012, 05:04   #28  |  Link
wiseant
Registered User
 
Join Date: May 2007
Posts: 146
@StainlessS

Nice!

Keep up the great work on this . . .
wiseant is offline   Reply With Quote
Old 13th September 2012, 09:52   #29  |  Link
wiseant
Registered User
 
Join Date: May 2007
Posts: 146
using RT_Call with MediaInfo and template

http://forum.doom9.org/showthread.ph...58#post1591158
wiseant is offline   Reply With Quote
Old 23rd September 2012, 19:23   #30  |  Link
martin53
Registered User
 
Join Date: Mar 2007
Posts: 407
StainlessS,
tried RT_call, because you gave it a 'hide' option . It performs different from 'Call', like I wrote in that thread. What I mean is shown in this example:
Code:
ColorBars()
ShowFrameNumber()
ConvertToRGB24()
ScriptClip("""
    c = last
    Trim(current_frame, -1)
    ImageWriter("C:\Temp\", 0, 0, type="tif")
    Call("C:\PortableApps\ImageMagick\Mogrify.exe -flip C:\Temp\000000.tif", "0")
    #RT_Call("C:\PortableApps\ImageMagick\Mogrify.exe -flip C:\Temp\000000.tif",true)
    StackHorizontal(last,ImageSource("C:\Temp\000000.tif")).Crop(c.width,0,0,0)
""")
(For the newbies who happen to read this thread: The StackHorizontal... trick forces the 'last' frame with the ImageWriter and Call commands to be requested first, and then the ImageSource clip - so ImageWriter and Call can prepare the file for ImageSource within the same run of the realtime environment)

You will see the flipped frame. Now move the comment marker to Call, and you see that the frame is no longer flipped!

In my humble words: It seems as if RT_Call, like Run, are executed when the realtime environment is compiled, rather than when a frame is requested. Call however is executed during frame #0 request, and because the clip is always trimmed to start with the current frame, every frame is frame #0 for Call.

Of course I would be happy if you decided to extend RT_Call to my need, because the 'hide' option is very nice indeed.

And btw., here I demonstrate how all Imagemagick filters in fact can even be used inside the runtime environment. In the thread where I first asked for an interface and then proposed a solution, I had not yet found the StackHorizontal... trick and hence needed a separate ScriptClip to read the file back.

Last edited by martin53; 23rd September 2012 at 20:20. Reason: link to other thread
martin53 is offline   Reply With Quote
Old 27th September 2012, 08:03   #31  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
@Martin53,

See CallCmd() v0.0 beta, source included here:-
http://forum.doom9.org/showthread.ph...32#post1593132

NOTE, your above example fails if 000000.tif does not already exist before script executed,
ImageSource() checks for it in its constructor (EDIT: before tif created) and fails if absent.

EDIT:
Also, mogrify.exe produces below text in console window, seems to be an incompatibility between ImageWriter
and mogrify.exe, presume in EXIF (or similar) data.

Code:
 
mogrify.exe: incorrect count for field "DateTime" (21, expecting 20); tag ignored. (C:\Temp\000000.tif).
__________________
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 2012 at 06:27. Reason: additional
StainlessS is offline   Reply With Quote
Old 29th September 2012, 13:05   #32  |  Link
martin53
Registered User
 
Join Date: Mar 2007
Posts: 407
@StainlessS,
sorry for the inconvenience. Yes, it seems that the file must be there in advance. I propose this approach (red line added).
Code:
ColorBars()
ShowFrameNumber()
ConvertToRGB24()
Exist("C:\Temp\000000.tif") ? last : ImageWriter("C:\Temp\", 0, 0, type="tif")
ScriptClip("""
    c = last
    Trim(current_frame, -1)
    ImageWriter("C:\Temp\", 0, 0, type="tif")
    Call("C:\PortableApps\ImageMagick\Mogrify.exe -flip C:\Temp\000000.tif", "0")
    #RT_Call("C:\PortableApps\ImageMagick\Mogrify.exe -flip C:\Temp\000000.tif",true)
    StackHorizontal(last,ImageSource("C:\Temp\000000.tif")).Crop(c.width,0,0,0)
""")
As for the mogrify error message, I do not experience this - or I am not aware of it. Does the example still work and the message can be ignored, or does the exampe fail? Maybe it's an ImageMagick version issue ...
Anyway, tif format is not mandatory. I just chose it because I expected that it fulfills the requirements (speed, compatibility, no quality loss due to compression)

Last edited by martin53; 29th September 2012 at 13:29.
martin53 is offline   Reply With Quote
Old 29th September 2012, 14:56   #33  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Nice Exist solution.

I recently downloaded ImageMagick (already got a copy but could not find it), perhaps you have newer version.

From Mogrify.exe

Version: @(#)ImageMagick 5.4.6 06/01/02 Q:8 http://www.imagemagick.org
Copyright: Copyright (C) 2002 ImageMagick Studio LLC

It was only a warning anyway, did not affect result.
__________________
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 ???
StainlessS is offline   Reply With Quote
Old 29th September 2012, 17:03   #34  |  Link
martin53
Registered User
 
Join Date: Mar 2007
Posts: 407
Mine says

Version: ImageMagick 6.7.8-3 2012-07-11 Q16 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2012 ImageMagick Studio LLC

Never gave version issues a thought - just downloaded and used.

I tested the command line Mogrify.exe -flip C:\Temp\000000.tif
- no warnings, works as expected.
martin53 is offline   Reply With Quote
Old 1st October 2012, 18:00   #35  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
@Martin53
The initial Mogrify.exe I was using from 2002 (v5.4.6) was from here:
http://www.dylanbeattie.net/magick/downloads.html

Works fine and only 2.3MB.

Portable one I just downloaded from ImageMagick.org (ImageMagick-6.7.9-9-Q16-windows.zip) 44MB
http://imagemagick.org/script/binary...es.php#windows

But this one displays mogrify'ed images as bright green with a little darker color around font edges when loaded into any
MS apps except MS Paint. Other paint type programs I tried all loaded them OK, so strangely its only
the more capable MS apps that screw up. Think I'll stick with the older smaller portable version.

EDIT: the newer one is listed as "16 bits-per-pixel", strange that MS Paint (XP32) has no problems and MS OFFICE 2003
picture manager fails. (I dont like office 2007+).
__________________
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; 1st October 2012 at 18:11.
StainlessS is offline   Reply With Quote
Old 1st October 2012, 19:45   #36  |  Link
martin53
Registered User
 
Join Date: Mar 2007
Posts: 407
Thanks for the testing, that might help users who want to use the interface and struggle with the incompatible capabilities.
martin53 is offline   Reply With Quote
Old 1st October 2012, 20:26   #37  |  Link
martin53
Registered User
 
Join Date: Mar 2007
Posts: 407
StainlessS,
I never said for RT_Stats. I do now!

I am just facing a problem: I use MVTools2's MMask(kind=5) to get a U/V frame of object motion.

MMask leaves U/V at the default 128 for blocks it can not assign a valid motion vector to.

Now I need the average motion of a part of the image.
Aside from needing crop and AverageChromaU, or UToY and RT_AverageLuma - so two steps either way (I am always in the RTE with my projects), the pixels with 128 spoil the result. I could use

if (RT_AverageLuma>128) {
#start a while () loop with RT_YPlaneMin() and ascending threshold to get the %age of pixels with 128, then recalculate the average ond the basis of that amount
} else {
#RT_YPlaneMax()...
}
but that would fail if some blocks move in one direction, and some in the other.

I could convert to RGBA, ResetMask(), ColorMask() to create a copy of these pixels in the mask clip.

That's all so complicated. Do you have a better idea? Maybe a new function I give two numbers and the function tells me how many % of the pixels are in that range? That would also allow cool histogram functions.
martin53 is offline   Reply With Quote
Old 1st October 2012, 22:58   #38  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Quote:
Originally Posted by martin53 View Post
Maybe a new function I give two numbers and the function tells me how many % of the pixels are in that range? That would also allow cool histogram functions.
OK, but it's your job to think up a name, my plugs nearly all start out having names like "Fred" or "Test", same for arg names.

I'll implement "Greater or equal to low" and "below high", if not as desired, say so. I'll look here again before I post link.

EDIT: Ps, hope you saw the edit in the developer Call() thread concerning Exist().
__________________
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; 1st October 2012 at 23:06.
StainlessS is offline   Reply With Quote
Old 2nd October 2012, 00:32   #39  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Here tis, given a moniker of YBetwixt(), (EDIT: "betwixt", usage archaic, "in the interval", ie "between")
EDIT: Link removed, See 1st post, renamed func to RT_YInRange().

Code:
As for RT_Stats funcs


YBetwixt(clip,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,bool "interlaced"=false,int "Matrix"=0,
        int "lo"=64,int "hi"=192)

Returns Float % population of pixels above or equal to "lo" and below "hi".

If hi <= lo then will return 0.0
EDIT: If OK, I may perhaps add to RT_Stats plug as RT_YBetwixt or another name if you have one.
EDIT: If I do add it to RT_Stats, may return value in range 0.0-255.0 comparable to other RT_Stats funcs,
can easily convert to percent by *100.0/255.0
__________________
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; 3rd October 2012 at 18:07.
StainlessS is offline   Reply With Quote
Old 2nd October 2012, 03:03   #40  |  Link
wiseant
Registered User
 
Join Date: May 2007
Posts: 146
@Stainless

Re RT_Stats

One thing I noticed is that RT_Stats won't work reading an imagelist if the imagefile name is e.g. %big_file06.jpg - the problem being the %
[probably some other funky characters as well]

Is there a way to overcome this without having to rename the files in question?

TIA
wiseant is offline   Reply With Quote
Reply

Tags
averageluma, correlation, lumadifference, runtime

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 22:22.


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