VideoHelp Forum
+ Reply to Thread
Results 1 to 6 of 6
Thread
  1. Member
    Join Date
    Sep 2017
    Location
    Lincoln, UK
    Search Comp PM
    Hi
    I own a 3D printer which is inside a cabinet (Sound Proofing mainly) so I can't see what the printer is doing unless I'm sat there watching it. But prints can take days to coplete. So I and many other people use a video camera to watch the print instead.

    I expect your aware of photo recognition software and I was thinking if you recorded a print in full and stored that video on the computer, you could run the print again and let the computer watch that print and compare it with the video it has stored in its memory.

    So if anything should go wrong the computer would sound an alarm and stop the printer head if there was a deviation from the original video.

    In theory I think its a good idea as you could go off to bed or out and leave the printer to carry on working and not worry about it.

    We already have "End of Spool" monitors and over heat alerts which turn off the printer.

    I'd like to hear what other members think and any ideas they may come up with.

    Thanks a lot.

    Michael
    (Lindum)
    Quote Quote  
  2. "StainlessS" over at doom9.org wrote some amazing software that does excellent motion detection on video. He then wrote some different software that compares two video clips and takes action when it senses a difference. Between the two, you should be able to put together an AVISynth script that does exactly what you want.

    Here is a link to all the software he has made available. If you sort it so the most recent are on top, I think the two things you want are located near the top:

    https://www.mediafire.com/folder/hb26mthbjz7z6/StainlessS
    Quote Quote  
  3. Member
    Join Date
    Sep 2017
    Location
    Lincoln, UK
    Search Comp PM
    WOW thanks a lot john

    To be honest, I was sceptical weather I would get an answer to my question. I had the idea after putting a file inside a photo (Stenography). I've look on the site and going back there this evening (Saturday) to have a good rummage around.

    Thanks again.

    Michael.
    Quote Quote  
  4. Some of the StainlessS code you might want to look at:

    ClipClop
    "Clipclop is a simple plugin to replace ranges in a source clip with the same range, from a replacement clip."

    SpatialAlign v1.0 : Spatial Alignment of clips
    "Fix spatial alignment between two clips containing similar scenes" (probably not needed if your camera doesn't move at all between prints)

    MatchFrames/LocateFrames v1.06
    "Find And return frames in c clip that are best matched to frames in f clip."

    These are all concerned with finding and matching frames from two different video files. Some of them were originally created to help people who have two different sources of the same movie combine them together in order to get the best quality from each movie, or eliminate subtitles, etc.

    You should also download and look at the huge collection of plugins included with his great "RT_Stats" AVISynth package. Included in that collection are the plugins required to detect motion in security camera footage, something that is exactly what you asked for. I have used this on a 10-hour surveillance video I created, and it worked perfectly. Lots of really useful options, too.

    Here is the detection script that uses RT_Stats.

    Code:
    AVISource("CAP4.avi") #.Trim(32,-10000)
    
    ############################################
    # SecurityCamExtractMotion.AVS, v1.2, By StainlessS.
    # Requires RT_Stats v1.20, FrameSel v1.03, GScript, Grunt.
    #
    # MUST SCAN STRAIGHT THROUGH, NO JUMPING ABOUT IN ShowMetrics OR MakeFramesCmd.
    # Normally use MODE=0 (RT_LumaDifference) and MODE=1 for special use (RT_LumaSceneChange) which uses extra MODE 1 args.
    #
    # MakeFramesCmd() creates 3 .txt command files for KEEP frames (movement), DROP frames, and DUPE frames.
    # Using SelectFrames() you can select frames types of each of the 3 command files, or using the Reject mode of FrameSel, you can
    # instead return the frames NOT in the command file, so using the 3 created command files, you can select 6 variations of frames.
    ############################################
    X=0 Y=0 W=-0    H=-0    # Area Of Interest, avoid eg passing traffic or timecode.
    
    TH    =3.5              # Greater or equal KEEP (movement), below is DROP. Use ShowMetrics, need check against source.
    DTH   =0.001            # Below is DUPE
    BLK   =64               # Suggest 16 -> 64 (even only). Metrics will change with block size. For RT_LumaMovement().
                            # Localized movement. Lower more sensitive, higher less sensitive but faster.
                            # Could set BLK to eg 32768 and will be limited to frame size, ie similar to LumaDifference(), 
                            # faster, but less sensitive to local movement.
                            # for very small localized movement suggest BLK = 16, if still not enough then maybe try MODE=1
                            # and maybe eg Gain=1.2, or eg Rpow=1.2 or whatever. See RT_LumaSceneChange Graffer to see how it
                            # affects pixel differences.
    
    MODE  =0                # For RT_LumaMovement. 0=RT_LumaDifference, 1=RT_LumaSceneChange, Metrics will change with Mode.
    
    # MODE is RT_LumaMovement() mode. RT_LumaMovement carves frames into BLKxBLK blocks, gets a metric on each block and returns
    # the greatest block metric, more sensitive to local motion than getting a single metric on entire frame, but also slower.
    # MODE=1 builds a LUT for each BLKxBLK sized block, gets abs difference between pixels of adjacent frames, LUT massage of that
    # difference, and sums the output of that to get the average.
    #  Sort of like mt_lutxy("x y - abs").LUT().AverageLuma(), where below args are used to build the LUT.
    #
    # MODE=1, Args for RT_LumaMovement MODE 1 (ie RT_LumaSceneChange MODE)
    # Provided defaults are linear, same as MODE = 0 (MODE=0 is faster)
    BIAS =0.0               # -512.0 -> 512.0, Default 0.0
    GAIN =1.0               # -8.0 -> 8.0,     Default 0.0
    CONT =1.0               # -8.0 -> 8.0,     Default 1.0
    RPOW =1.0               # 0.1 -> 4.0,      Default 1.0
    SPOW =1.0               # 0.1 -> 4.0,      Default 1.0
    SPMID=0.5               # 0.01 -> 0.99,    Default 0.5
    PORD =False            # Default False
    ###
    SHOW    =True           # Show Info on frame when extracting frames
    SHOWTIME=False          # Show original Time on Frame
    ###
    dclip=Last              # Or some kind of denoise or whatever, used for detection.
    ##########################################
    # Choose 1 of below options:- (uncomment)
    ##########################################
    
     # Show metrics to get best Threshold 'th'.
    ShowMetrics(dclip,TH,DTH,X,Y,W,H,mode=MODE,blkw=BLK,blkh=BLK,bias=BIAS,gain=GAIN,cont=CONT,rpow=RPOW,spow=SPOW,spmid=SPMID,pord=PORD,fast=true,showTime=SHOWTIME)
    
     # Make Frames Cmd file for SelectFrames(), Must Play all way through.
    #MakeFramesCmd(dclip,TH,DTH,X,Y,W,H,mode=MODE,blkw=BLK,blkh=BLK,bias=BIAS,gain=GAIN,cont=CONT,rpow=RPOW,spow=SPOW,spmid=SPMID,pord=PORD)
    
     # Return KEEP Frames using EXISTING Keep.txt frames Command file (after MakeFramesCmd)
    #SelectFrames("Keep.txt",show=SHOW,showTime=SHOWTIME)
    
     # Return DROP Frames using EXISTING Drop.txt frames Command file (after MakeFramesCmd)
    #SelectFrames("Drop.txt",show=SHOW,showTime=SHOWTIME)
    
     # Return DUPE Frames using EXISTING Dupe.txt frames Command file (after MakeFramesCmd)
    #SelectFrames("Dupe.txt",show=SHOW,showTime=SHOWTIME)
    
     # Return NOT KEEP Frames using EXISTING "Keep.txt" frames Command file (after MakeFramesCmd), ie both DROP and DUPE frames
    #SelectFrames("Keep.txt",show=SHOW,showTime=SHOWTIME,Reject=True)
    
     # Return NOT DROP Frames using EXISTING "Drop.txt" frames Command file (after MakeFramesCmd), ie both DUPE and KEEP frames
    #SelectFrames("Dupe.txt",show=SHOW,showTime=SHOWTIME,Reject=True)
    
     # Return NOT DUPE Frames using EXISTING "Dupe.txt" frames Command file (after MakeFramesCmd), ie both DROP and KEEP frames
    #SelectFrames("Dupe.txt",show=SHOW,showTime=SHOWTIME,Reject=True)
    
     # Make Frames command files and then extract KEEP frames automatically in 1 pass.
    #AutoGetFrames(TH,DTh,X,Y,W,H,Mode,Blk,Blk,BIAS,GAIN,CONT,RPOW,SPOW,SPMID,PORD,dclip=dclip,show=SHOW,showTime=SHOWTIME)
    
    AssumeFPS(250.0)
    return Last
    ##########################################
    
    Function ShowMetrics(clip c,float th,Float "dth",int "x",int "y",int "w",int "h", int "Mode",int "BlkW",int "BlkH",
        \ Float "bias",Float "gain",Float "cont",Float "rpow",Float "spow",Float "SPMid",Bool "pord",
        \ bool "dim",bool "fast",bool "Showtime") {
        c
        dth=Float(Default(dth,0.001))   x=default(x,0) y=default(y,0)   w=default(w,0)  h=default(h,0)
        Mode=Default(Mode,0) BlkW=Default(BlkW,64)  BlkH=Default(BlkH,64)
        Dim=Default(dim,true) Fast=Default(Fast,False)  ShowTime=Default(ShowTime,False)
        Bias=Float(Default(Bias,0.0))       # Arg to RT_LumaSceneChange(), -512.0 -> 512.0, Default 0.0
        Gain=Float(Default(Gain,1.0))       # Arg to RT_LumaSceneChange(), -8.0 -> 8.0,     Default 1.0
        Cont=Float(Default(Cont,1.0))       # Arg to RT_LumaSceneChange(), -8.0 -> 8.0,     Default 1.0
        RPow=Float(Default(RPow,1.0))       # Arg to RT_LumaSceneChange(), 0.1 -> 4.0,      Default 1.0
        SPow=Float(Default(SPow,1.0))       # Arg to RT_LumaSceneChange(), 0.1 -> 4.0,      Default 1.0
        SPMid=Float(Default(SPMid,0.5))     # Arg to RT_LumaSceneChange(), 0.01 -> 0.99,    Default 0.5
        Pord=Default(Pord,false)            # Arg to RT_LumaSceneChange(),                  Default False
        x = (x / 4) * 4                         y = (y / 4) * 4
        w = (w<=0) ? width() - X + W  : w       h = (h<=0) ? height() - Y + H : h
        w = (w / 4) * 4                         h = (h / 4) * 4                         # Mod 4 both dimensions
        Cropped=Crop(x,y,w,h)
        (Dim && (w!=width || h!=height)) ? levels(0,1.0,255,0,128).Overlay(Cropped,x=X,y=Y,opacity=1.0) : Last
    #    (Exist("Keep.txt")) ? RT_FileDelete("Keep.txt") : NOP
    #    (Exist("Drop.txt")) ? RT_FileDelete("Drop.txt") : NOP
    #    (Exist("Dupe.txt")) ? RT_FileDelete("Dupe.txt") : NOP
        Fmt=(mode==0)
    		\ ? "%d ] %s{%c} Diff=%.3f MaxDrop=%.3f MinKeep=%.3f\n" +
    		\ "DUPE=%d(%03.2f%%) DROP=%d(%03.2f%%) KEEP=%d(%03.2f%%)\nTh=%.2f DTh=%.3f Mode=%d BlkW=%d BlkH=%d"
            \ : "%d ] %s{%c} Diff=%.3f MaxDrop=%.3f MinKeep=%.3f\n" +
    		\ "DUPE=%d(%03.2f%%) DROP=%d(%03.2f%%) KEEP=%d(%03.2f%%)\nTh=%.2f DTh=%.3f Mode=%d BlkW=%d BlkH=%d" +
            \ "\nBias=%6.2f : Gain=%6.2f : Cont =%6.2f\nRPow=%6.2f : SPow=%6.2f : SPMid=%6.2f : Pord=%s"
        Global SM_DUPE=0 Global SM_DROP=0 Global SM_KEEP=0 Global SM_LMAX=0.0 Global SM_LMIN=255.0 Global SM_PrevMat=0
        ScriptClip("""
            n=current_frame
            d=RT_LumaMovement(Last,Last,n2=n-1,x=x,y=y,w=w,h=h,mode=Mode,blkw=BlkW,blkh=BlkH,
    				\ bias=BIAS,gain=GAIN,cont=CONT,rpow=RPOW,spow=SPOW,spmid=SPMid,pord=PORD)
            mat=(d<dth)?0:(d<th)?1:2
            Global SM_DUPE=(mat==0) ? SM_DUPE +1 : SM_DUPE
            Global SM_DROP=(mat==1) ? SM_DROP +1 : SM_DROP
            Global SM_KEEP=(mat==2) ? SM_KEEP +1 : SM_KEEP
            Global SM_LMAX=(mat==1) ? (SM_PrevMat==2 ? d : (d>SM_LMAX) ? d : SM_LMAX) :  (mat==2) ? 0.0 	: SM_LMAX
            Global SM_LMIN=(mat==2) ? (SM_PrevMat==1 ? d : (d<SM_LMIN) ? d : SM_LMIN) :  (mat==1) ? 255 	: SM_LMIN
            Global SM_PrevMat=(mat != 0) ? mat : SM_PrevMat
            Z=RT_Ord("-12",mat+1)
            (mode==0) ?
                \ RT_SubTitle(Fmt,n,(mat==0)?"DUPE":(mat==2)?"KEEP":"DROP",z,d,SM_LMAX,SM_LMIN,
                \ SM_DUPE, SM_DUPE*100.0 / (n+1.0),
                \ SM_DROP, SM_DROP*100.0 / (n+1.0),
                \ SM_KEEP, SM_KEEP*100.0 / (n+1.0),
                \ th,dth,Mode,BlkW,BlkH)
                \ : RT_SubTitle(Fmt,n,(mat==0)?"DUPE":(mat==2)?"KEEP":"DROP",z,d,SM_LMAX,SM_LMIN,
                \ SM_DUPE, SM_DUPE*100.0 / (n+1.0),
                \ SM_DROP, SM_DROP*100.0 / (n+1.0),
                \ SM_KEEP, SM_KEEP*100.0 / (n+1.0),
                \ th,dth,Mode,BlkW,BlkH,
                \ Bias,Gain,Cont,RPow,SPow,SPMid,Pord)
    #        (mat==0) ? RT_TxtWriteFile(String(n),"Dupe.txt",append=true) : NOP
    #        (mat==1) ? RT_TxtWriteFile(String(n),"Drop.txt",append=true) : NOP
    #        (mat==2) ? RT_TxtWriteFile(String(n),"Keep.txt",append=true) : NOP
            return Last
        """,args="th,dth,x,y,w,h,Mode,BlkW,BlkH,bias,gain,cont,rpow,spow,spmid,pord,Fmt")           # Needs Grunt for args
        (ShowTime) ? ShowTime() : NOP
        return ((Fast)?AssumeFPS(250.0):Last)   .KillAudio()
    }
    
    Function MakeFramesCmd(clip c,float th,Float "dth",int "x",int "y",int "w",int "h",int "Mode",int "BlkW",int "BlkH",
        \ Float "bias",Float "gain",Float "cont",Float "rpow",Float "spow",Float "SPMid",Bool "pord",
        \ String "KeepFN",String "DropFN",String "DupeFN" ) {
        c
        dth=Float(Default(dth,0.001))       x=default(x,0) y=default(y,0)       w=default(w,0) h=default(h,0)
        KeepFN=Default(KeepFN,"Keep.Txt")   DropFN=Default(DropFN,"Drop.Txt")   DupeFN=Default(DupeFN,"Dupe.Txt")
        (KeepFN!="" && Exist(KeepFN)) ? RT_FileDelete(KeepFN) : NOP     # Delete existing
        (DropFN!="" && Exist(DropFN)) ? RT_FileDelete(DropFN) : NOP
        (DupeFN!="" && Exist(DupeFN)) ? RT_FileDelete(DupeFN) : NOP
        x = (x / 4) * 4                         y = (y / 4) * 4
        w = (w<=0) ? width() - X + W  : w       h = (h<=0) ? height() - Y + H : h
        w = (w / 4) * 4                         h = (h / 4) * 4                         # Mod 4 both dimensions
        ScriptClip("""
            n=current_frame
            d=RT_LumaMovement(Last,Last,n2=n-1,x=x,y=y,w=w,h=h,mode=Mode,blkw=BlkW,blkh=BlkH,
                    \ bias=BIAS,gain=GAIN,cont=CONT,rpow=RPOW,spow=SPOW,spmid=SPMid,pord=PORD)
            mat=(d<dth)?0:(d<th)?1:2
            (mat==0&&DupeFN!="")    ? RT_TxtWriteFile(String(n),DupeFN,append=true)     : NOP
            (mat==1&&DropFN!="")    ? RT_TxtWriteFile(String(n),DropFN,append=true)     : NOP
            (mat==2&&KeepFN!="")    ? RT_TxtWriteFile(String(n),KeepFN,append=true)     : NOP
            return Last
        """,args="th,dth,x,y,w,h,Mode,BlkW,BlkH,bias,gain,cont,rpow,spow,spmid,pord,KeepFN,DropFN,DupeFN")
        return AssumeFPS(250.0).KillAudio()
    }
    
    Function SelectFrames(clip c,String Fn,bool "Show",bool "Showtime",bool "Reject") {
        c   Show=Default(Show,False)    ShowTime=Default(ShowTime,False) Reject=Default(Reject,False)
        (ShowTime) ? ShowTime() : NOP   FrameSel(CMD=Fn,show=Show,reject=Reject)            # Returns NO audio
    }
    
    Function AutoGetFrames(clip c,float th,Float "dth",int "x",int "y",int "w",int "h",int "Mode",int "BlkW",int "BlkH",
        \ Float "bias",Float "gain",Float "cont",Float "rpow",Float "spow",Float "SPMid",Bool "pord",
        \ String "KeepFN",String "DropFN",String "DupeFN", clip "dclip",bool "Show",bool "Showtime") {
        Default(dclip,c)            # Use detection clip (denoised or whatever) for making frames command files.
        KeepFN=Default(KeepFN,"Keep.txt")
        # Make the command file for FrameSel()
        MakeFramesCmd(th,dth,x,y,w,h,Mode,BlkW,BlkH,bias,gain,cont,rpow,spow,SPMid,pord,KeepFN,DropFN,DupeFN)
        GSCript("""
            For(i=0,framecount-1) {
                RT_YankChain(n=i)                                   # Force Process, MakeFrames
            }
            c.SelectFrames(KeepFN,Show=Show,showtime=Showtime)      # Extract source frames and return to client
        """)
    }
    Quote Quote  
  5. Member
    Join Date
    Sep 2017
    Location
    Lincoln, UK
    Search Comp PM
    Right John

    To be honest, I haven't the faintest idea what I'm looking for in those thousands of lines of data code StainlessS has put together on the subject of DVD. I'm not going to waste your's and other members time asking strange questions when you could be helping other people. Not that I don't appreciate what you've done.

    What I'll do is hunt round the internet and look for some software that will do what I need.

    Thanks a lot.

    Michael.
    Quote Quote  
  6. Sigh ... you can lead a horse to water ...
    Quote Quote  



Similar Threads

Visit our sponsor! Try DVDFab and backup Blu-rays!