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. |
11th September 2018, 13:32 | #1 | Link |
Registered User
Join Date: Mar 2017
Location: Germany
Posts: 234
|
U-V-Swap issue
Hi,
I got copies from older tape recordings (1'') of a series. About ten to 30 times in more than one episode a problem with the colours occurs: Obviously U and V are swapped. I first thought I could build a detector for this, seemed not too hard because the right black margin expands a few pixels each time the swapping occurs. So far so good, BUT: The channels are not swapped in the whole frame. Only rectangular parts of the picture, the rest keeps correct. Has anyone an idea how to build a mask that is transparent only where UV swapping occurs and opaque on the rest of the picture? Thanks for any idea. Last edited by Frank62; 11th September 2018 at 13:37. |
11th September 2018, 13:51 | #2 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
I'm sure that somebody would like to take a gander at your peculiar clip [if only for the 'wierd clip collection'], maybe post a sample,
no idea how to do as you require, sorry.
__________________
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 ??? |
11th September 2018, 14:19 | #4 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Is the block 'mirrored' on one of the preceding/postceding frames ? (are you getting chroma from the wrong frame, is it at scene change).
Post a bit of the clip if you can (not just an image). EDIT: Also try another source filter, and try load into eg VDub2, same ?
__________________
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 ??? |
11th September 2018, 14:35 | #5 | Link |
Registered User
Join Date: Mar 2017
Location: Germany
Posts: 234
|
No scenechange. The chroma is really the swapped chroma from the exact frame. Funny is that the left border of the swapping is fluent, no exact border. If I only could detect the area, I had the rest of the solution in mind already.
This is already from the restored clip, will post a original short clip later. Yes, I also thought of decoding problems, but from 26 episodes the most do not have this error. Anyway I tried to open the mxf (containing mpeg2) after lwlibavvideosource also by first demuxing with ffmpeg and then indexing with the most reliable DGIndex, as I did earlier, before LSMASH times. Same problem. |
11th September 2018, 16:10 | #6 | Link |
Registered User
Join Date: Mar 2017
Location: Germany
Posts: 234
|
A short sample:
https://we.tl/t-zBuudR6KqL |
11th September 2018, 20:05 | #7 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Strange.
As well as black rhs border swelling on problem, also significant reduction in chroma saturation for both U and V channels when problem occurs. (Histogram(mode="levels") When color comes back, seems to jump up from the bottom, (squares your mention), like I/Q (color burst or whatever it is in TV signal), aint quite in sync, maybe some TV engineer could give better insight. EDIT: Code:
AVISource("D:\UVSwap.mp4.AVI") ORG=LAst A=Trim(0,20) B=Trim(21,33) C=Trim(34,0) B=B.SwapUV.Subtitle("***",Align=5) Fx=A++B++C ORG=ORG.Histogram(Mode="Levels") Fx=FX.Histogram(Mode="Levels") StackVertical(ORG,Fx) EDIT: Added separate histograms to each clip in code block. EDIT: "Aint quite in sync", I'm sure that you've seen tumbling picture on old analogue TV, disappears off top of screen only to reappear up from the bottom, is kinda like that, TV / capture card could not lock to the signal. [EDIT: Lost both horizontal and vertical sync, but just for chroma]
__________________
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; 13th September 2018 at 16:11. |
11th September 2018, 21:26 | #8 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
This does detect, to some extent.
Code:
AVISource("D:\UVSwap.mp4.AVI").ConvertToYV24 ### Prep Crop_L=10 CROP_T=36 CROP_R=-20 CROP_B=-4 x0=701 x1=702 x2=703 x3=704 MID = Crop(Crop_L,CROP_T,CROP_R,CROP_B) # Crop off all border crap YC = MID.ConvertToY8 # available if needed UC = MID.UToY8 VC = MID.VToY8 ### Config ### GAP=0 Y0_TH=24.0 # AveLuma of RHS vertical column of pixels @ x0, ie border. [Border creeps in on damage] U_TH =17.0 # 17.0, Percent population in range 128-GAP -> 128+GAP [On damage, gets less saturated, more chroma at 128, less outside of 128] V_TH =23.5 # 23.5, Percent population in range 128-GAP -> 128+GAP [Ditto] ClipClopName= "ClipClopCmd.txt" FrameSelName= "FrameSelFrames.txt" RangeName = "Ranges.txt" WRITE_ENDS=True # If RangeName != "" then Also write RangeName+"_PRE.TXT" and RangeName+"_POST.TXT" frame before 1st & frame after last BAD frames. # Can use FrameSel to 'pull out' bad frame plus up to 5 frames either side of bad frame (total 11 frames incl bad frame). SHOW = True # True Show Metrics FLAGS= True # True Show Frame Number and Flags (Also Shown if SHOW=False) ########################### PREV_BINGO=False PREV_START=-1 PREV_FRAME=-1 ClipClopName=(ClipClopName!="") ? RT_GetFullPathName(ClipClopName): "" FrameSelName=(FrameSelName!="") ? RT_GetFullPathName(FrameSelName): "" RangeName= (RangeName!="") ? RT_GetFullPathName(RangeName) : "" DORANGES=RangeName!="" Pre_Name=(DORANGES)?RangeName+"_PRE.TXT":"" Post_Name=(DORANGES)?RangeName+"_POST.TXT":"" (ClipClopName!="") ? RT_FileDelete(ClipClopName) : NOP (FrameSelName!="") ? RT_FileDelete(FrameSelName) : NOP (RangeName!="") ? RT_FileDelete(RangeName) : NOP (Pre_Name!="") ? RT_FileDelete(Pre_Name) : NOP (Post_Name!="") ? RT_FileDelete(Post_Name) : NOP HILITE=RT_Ord("!") # RT_Subtitle Hilite control code NORM =RT_Ord("-") # RT_Subtitle Normal white text control code LOLITE=RT_Ord("L") # RT_Subtitle LoLite/DIM control code SSS=""" n=current_frame y0=RT_AverageLuma(x=x0,y=CROP_T,h=CROP_B,w=1) y1=RT_AverageLuma(x=x1,y=CROP_T,h=CROP_B,w=1) y2=RT_AverageLuma(x=x2,y=CROP_T,h=CROP_B,w=1) y3=RT_AverageLuma(x=x3,y=CROP_T,h=CROP_B,w=1) # Y=YC.RT_AverageLuma U=UC.RT_YInRange(lo=128-GAP,hi=128+GAP) * 100.0 # % V=VC.RT_YInRange(lo=128-GAP,hi=128+GAP) * 100.0 # % T1 = (Y0<Y0_TH) T2 = (U>U_TH) T3 = (V>V_TH) BINGO=(T1 && T2 && T3) T1_C=(T1)?HILITE:NORM T2_C=(T2)?HILITE:NORM T3_C=(T3)?HILITE:NORM # Hilite control codes for Metrics F1_C=(T1)?NORM:LOLITE F2_C=(T2)?NORM:LOLITE F3_C=(T3)?NORM:LOLITE F_BINGO=(BINGO)?HILITE:LOLITE # Ctrl codes for FLAGS (FLAGS)?RT_Subtitle("%d] \a%cB\a%cU\a%cV \a%c*",n,F1_C,F2_C,F3_C,F_BINGO):NOP (SHOW)?RT_Subtitle("Y at RHS: \a%cx0=%.2f\a- x1=%.2f x2=%.2f x3=%.2f",T1_C,y0,y1,y2,y3,align=5,Y=5*20):NOP (SHOW)?RT_Subtitle("YAve=%.2f : \a%cU=%.2f%%\a- : \a%cV=%.2f%%\a-",Y,T2_C,U,T3_C,V,align=5,Y=8*20):NOP (SHOW&&BINGO)?SUBTITLE("!!!BINGO!!!",Align=5,size=48):NOP (BINGO&&ClipClopName!="") ? RT_WriteFile(ClipClopName,"1 %d",n,Append=True) : NOP # Use ClipClop to replace frame with same from clip Index 1. (BINGO&&FrameSelName!="") ? RT_WriteFile(FrameSelName,"%d",n,Append=True) : NOP # Use FrameSel Frame number only file. if(DORANGES) { If(PREV_FRAME!=n-1) { DORANGES = False } # User jumped about so all bets are OFF Else { if(BINGO) { if(!PREV_BINGO) { # New Start PREV_START=n } } Else { if(PREV_BINGO) { # New End RT_WriteFile(RangeName,"%d,%d",PREV_START,n-1,Append=True) # Write Range if(WRITE_ENDS) { RT_WriteFile(Pre_Name,"%d",PREV_START-1,Append=True) # Write pre BAD frame RT_WriteFile(Post_Name,"%d",n,Append=True) # Write post BAD frame } PREV_START=-1 } } PREV_BINGO=BINGO } PREV_FRAME=n } Return last """ Return Scriptclip(SSS)
__________________
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; 12th September 2018 at 15:32. |
12th September 2018, 11:28 | #9 | Link |
Registered User
Join Date: Mar 2017
Location: Germany
Posts: 234
|
Wow! That looks interesting! I also detected meanwhile beginning, ends and single frame swaps, but this seems a way to detect everything between also without need for programming some logic outside Avisynth.
Thanks a lot! No time to test this the whole day but I will report how it works earliest tomorrow evening. |
12th September 2018, 13:57 | #10 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Have updated above script, writes Pre bad range and post bad range frames (ie frame before bad range and also frame after).
Can use FrameSel to pull out eg pre-bad + some extra frames, and simple fix might be to repair using frame before pre-bad, same type thing for frame after bad range. From FrameSel Code:
FrameSel(Clip, int F1, ... , int Fn, string 'scmd',string 'cmd', bool 'show', bool 'ver',bool "reject",bool "ordered", \ bool "debug", int "Extract"=1) Code:
Extract Int, Default 1, MUST be ODD, 1 to 11. Error if not default 1 AND neither Ordered nor Reject == True. Let us call the UNIQUE resultant frames after Ordered and/or Reject Processing 'Target' frames. The number of frames pulled out on either side of Target frame is Extract / 2 (integer divide), so when Extract=3, it will extract 1 frame before target, the Target frame, and 1 frame after target, for each and every Target frame. This arg allows you to select eg 3 frames for each Target frame, the previous frame, Target frame and next frame. May be of use to extract bad frames together with eg 1 frame either side for saving as bitmaps and editing in some kind of RotoScope editor to repair bad frames using image from adjacent frames. The edited frames could then be re-loaded, middle one selected via SelectEvery(3,1), and then put back into original source clip via FrameRep(). Another simple use could be when you have a clip where each frame before a scene change is bad, with Ordered=True and Extract=3, you pull out 3 frames, a SelectEvery(3,0) would select the frames previous to the bad frames and then use Framerep() to replace the bad frames with those previous to them. A SelectEvery(3,2) would select the frames after Target frames. The total number of frames pulled out of the source clip will be (Extract * number of Target frames). Reject is less likely to be of use with Extract, unless frame select commands specify good frames rather than bad, where Reject in FrameRep should also be true (same as in FrameSel, as always). See FrameRep() for example uses of Extract. Code:
C=Colorbars().Trim(0,-50).ShowFrameNumber() # 50 frames (0 -> 49) BADFRAMES = "10;20;30;40" # 4 bad frames in source clip EXTRACT=FrameSel(C,scmd=BADFRAMES,ordered=True,extract=3) # Extract Previous, Target and Next frames for each Target frame REPAIR=EXTRACT.SelectEvery(3,0) # Select each frame previous to Target bad frames, 1st of each triplet #REPAIR=REPAIR.Invert() # So we can easily see repaired frames Return FrameRep(C,REPAIR,scmd=BADFRAMES) # Fix bad frames with REPAIR clip using exact same BADFRAMES spec.
__________________
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 ??? |
12th September 2018, 15:51 | #11 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Added Flags shown top LHS,
Here last bad frame of range, and the following half bad frame where only two of detector metrics satified. (Border metric fails detect but chroma metric still detecting) [In such case might just be able to use chroma from following frame]. Might be best to do a prescan, to establish scene cuts, and process each separately after establishing some average chroma metric for the scene (how do we do that, considering some of scene may be bad ???). Script updated. Code:
A=trim(33,-1) B=trim(34,-1) StackVertical(A,B) Spline36Resize(640,960) Frame after half bad frame, ie 2 frames after last bad detect. Code:
X=trim(35,-1) return X.Spline36Resize(640,480)
__________________
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; 12th September 2018 at 15:58. |
12th September 2018, 17:42 | #12 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Modified to detect both bad range and last bad + 1 half bad frame, writing clipclop file to fix both
(assumes that detector works for complete clip, maybe does, maybe does not, Who can tell the secret of the Black Magic Box. Is the box of chocolates alive, or is the box of chocolates dead, you can only know when you open the box ). Code:
#_FIX_UVSWAP_MOD.avs AVISource("D:\UVSwap.mp4.AVI").ConvertToYV24 ### Prep Crop_L=10 CROP_T=36 CROP_R=-20 CROP_B=-4 x0=701 x1=702 x2=703 x3=704 MID = Crop(Crop_L,CROP_T,CROP_R,CROP_B) # Crop off all border crap YC = MID.ConvertToY8 # available if needed UC = MID.UToY8 VC = MID.VToY8 ### Config ### GAP=0 Y0_TH=24.0 # AveLuma of RHS vertical column of pixels @ x0, ie border. [Border creeps in on damage] U_TH =17.0 # 17.0, Percent population in range 128-GAP -> 128+GAP [On damage, gets less saturated, more chroma at 128, less outside of 128] V_TH =23.5 # 23.5, Percent population in range 128-GAP -> 128+GAP [Ditto] ClipClopName= "ClipClopCmd.txt" SHOW = True # True Show Metrics FLAGS= True # True Show Frame Number and Flags (Also Shown if SHOW=False) ########################### PREV_BINGO=False PREV_START=-1 PREV_FRAME=-1 ClipClopName=(ClipClopName!="") ? RT_GetFullPathName(ClipClopName): "" DORANGES=ClipClopName!="" (ClipClopName!="") ? RT_FileDelete(ClipClopName) : NOP HILITE=RT_Ord("!") # RT_Subtitle Hilite control code NORM =RT_Ord("-") # RT_Subtitle Normal white text control code LOLITE=RT_Ord("L") # RT_Subtitle LoLite/DIM control code SSS=""" n=current_frame y0=RT_AverageLuma(x=x0,y=CROP_T,h=CROP_B,w=1) y1=RT_AverageLuma(x=x1,y=CROP_T,h=CROP_B,w=1) y2=RT_AverageLuma(x=x2,y=CROP_T,h=CROP_B,w=1) y3=RT_AverageLuma(x=x3,y=CROP_T,h=CROP_B,w=1) # Y=YC.RT_AverageLuma U=UC.RT_YInRange(lo=128-GAP,hi=128+GAP) * 100.0 # % V=VC.RT_YInRange(lo=128-GAP,hi=128+GAP) * 100.0 # % T1 = (Y0<Y0_TH) T2 = (U>U_TH) T3 = (V>V_TH) BINGO=(T1 && T2 && T3) T1_C=(T1)?HILITE:NORM T2_C=(T2)?HILITE:NORM T3_C=(T3)?HILITE:NORM # Hilite control codes for Metrics F1_C=(T1)?NORM:LOLITE F2_C=(T2)?NORM:LOLITE F3_C=(T3)?NORM:LOLITE F_BINGO=(BINGO)?HILITE:LOLITE # Ctrl codes for FLAGS (FLAGS)?RT_Subtitle("%d] \a%cB\a%cU\a%cV \a%c*",n,F1_C,F2_C,F3_C,F_BINGO):NOP (SHOW)?RT_Subtitle("Y at RHS: \a%cx0=%.2f\a- x1=%.2f x2=%.2f x3=%.2f",T1_C,y0,y1,y2,y3,align=5,Y=5*20):NOP (SHOW)?RT_Subtitle("YAve=%.2f : \a%cU=%.2f%%\a- : \a%cV=%.2f%%\a-",Y,T2_C,U,T3_C,V,align=5,Y=8*20):NOP (SHOW&&BINGO)?SUBTITLE("!!!BINGO!!!",Align=5,size=48):NOP if(DORANGES) { If(PREV_FRAME!=n-1) { DORANGES = False } # User jumped about so all bets are OFF Else { if(BINGO) { if(!PREV_BINGO) { # New Start PREV_START=n } } Else { if(PREV_BINGO) { # New End RT_WriteFile(ClipClopName,"1 %d,%d",PREV_START,n-1,Append=True) # Write ClipClop Range to replace with clip index 1 if(T2 && T3) { # Border Detect Fail RT_WriteFile(ClipClopName,"2 %d",n,Append=True) # replace End Bad + 1 frame with clip index 2 frame } PREV_START=-1 } } PREV_BINGO=BINGO } PREV_FRAME=n } Return last """ Scriptclip(SSS) Code:
# _FIX_UVSwap_MOD_ClipClop.avs AVISource("D:\UVSwap.mp4.AVI") ClipClopName= "D:\ClipClopCmd.txt" ORG=Last CONT_U = 0 # ColorYUV U Sat adjust for bad range (0=no adjust) CONT_V = 0 # ColorYUV V Sat adjust for bad range (0=no adjust) Nxt=SelectEvery(1,1) # Shift next frame to current CN_Chroma = ORG.MergeChroma(Nxt) # Copy Next Chroma into current, Fix End Bad + 1 half bad frame V1 = SwapUV().ColorYUV(cont_u=CONT_U,cont_v=CONT_V) V2 = CN_Chroma NickNames =""" # Psuedonyms for clips (clip index number) SwapUV = 1 # Fixed Bad range clip (SwapUV with optional Chroma Sat adjustment) CN_Chroma = 2 # Fixed half bad end bad + 1 frame (Copy Chroma from next) """ SHOW=True ClipClop(ORG,V1,V2,Cmd=ClipClopName,nickname=NickNames,show=SHOW) StackVertical(Last,ORG) Last bad range + 1 frame (half bad frame, copy chroma from next frame) fixed (src on bottom) EDIT: ClipClopCmd.txt to fix range Plus End Bad + 1 (Half bad) frame Code:
1 21,33 2 34
__________________
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; 12th September 2018 at 18:23. |
12th September 2018, 21:23 | #13 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
I might not be able to do anything else before about Saturday, here a tool to perhaps enable you to continue with detector,
eg detect scenes, get some kind of average metrics for Chroma, and mod chroma detect thresholds for current scene. Just wrote the DBase_DetectScenes thing for this pupose. EDIT: Below DB_FindTrim() mentions clips, rather than scenes, function was written for different purpose. Library funcs Code:
# ############ # DB_FindTrim.avs [Replaced with RT_DBaseFindSeq() plugin function in RT_Stats v2.0] # DB_FindTrim Returns clip (or record number) containing movie frame Frame. # Search DBase for the record (clip) that contains the arg Frame, using Binary Search. # S_Field is the DB field that contains the first frame of the record clip. # E_Field is the DB field that contains the Last frame of the record clip. # Return of -1 = NOT FOUND. # ############ Function DB_FindTrim(String DB,Int S_Field,Int E_Field,Int Frame) { IsAvsPlus=(FindStr(UCase(versionString),"AVISYNTH+")!=0) HasGScript=RT_FunctionExist("GScript") Assert(IsAvsPlus || HasGScript,RT_String("DB_FindTrim: Need either GScript or AVS+")) result = -1 # Init NOT FOUND low = 0 high = RT_DBaseRecords(DB) - 1 GS=""" while(low <= high) { mid = (low + high) / 2 if(RT_DBaseGetField(DB,mid,E_Field) < Frame) { low = mid + 1 } Else If (RT_DBaseGetField(DB,mid,S_Field) > Frame) { high = mid - 1 } Else { low = high + 1 # Force exit Result = mid } } """ HasGScript ? GScript(GS) : Eval(GS) # Use GSCript if installed (loaded plugs override builtin) return result } Function DBase_DetectScenes(clip c,String DB,Int "SOS_Field",Int "EOS_Field",Int "OffSet",Int "thSCD1",Int "thSCD2") { /* Requires RT_Stats, MVTools2, MaskTools2. (and either Avs+ or GSCript) Given a pre-allocated DBase (can have 0 records), with at least two int fields for SOS and EOS (Start and End Of Scene), will APPEND records with SOS and EOS frame numbers inserted into SOS_Field and EOS_Field fields, remaining fields of record will be initialized to nul, ie int=0, Float=0.0, Bool=False, Bin=0,String="". Will Scan clip using MvTools2 MSCDetection, and when established SOS and EOS, will write new record filling in SOS_Field field with (StartOfSceneFrame + Offset) and EOS_Field field with (EndOfSceneFrame + Offset). SOS_Field, Default 0. EOS_Field, Default SOS_Field+1. Offset, Default 0. thSCD1, Default 400, See MvTools thSCD2, Default 130, See MvTools Returns Number of Records (ie Scenes found in clip) added to DBase. */ c myName="DBase_DetectScenes: " IsAvsPlus=(FindStr(UCase(versionString),"AVISYNTH+")!=0) HasGScript=RT_FunctionExist("GScript") HasMvTools=RT_FunctionExist("MSuper") HasMaskTools=RT_FunctionExist("MT_Lutxy") Assert(IsAvsPlus || HasGScript,RT_String("DB_FindTrim: Need either GScript or AVS+")) Assert(HasMVTools,RT_String("%sNeed MvTools2:-http://forum.doom9.org/showthread.php?t=131033",myName)) Assert(HasMaskTools,RT_String("%sNeed MaskTools",myName)) SOS_Field=Default(SOS_Field,0) EOS_Field=Default(EOS_Field,SOS_Field+1) OffSet=Default(OffSet,0) thSCD1=Default(thSCD1,400) thSCD2=Default(thSCD2,130) FC=FrameCount Records=RT_DBaseRecords(DB) Fields=RT_DBaseFields(DB) Rec=Records Assert(SOS_Field>=0 && SOS_Field<fields,RT_String("%sSOS_Field(%d) Does Not exist in DBase(0->%d)",myName,SOS_Field,Fields-1)) Assert(EOS_Field>=0 && EOS_Field<fields,RT_String("%sEOS_Field(%d) Does Not exist in DBase(0->%d)",myName,EOS_Field,Fields-1)) Assert(EOS_Field != SOS_Field,RT_String("%sEOS_Field(%d) Cannot be same as SOS_Field",myName,EOS_Field)) Sup = c.MSuper(pel=1,sharp=0,rfilter=2,hpad=16, vpad=16) BvEos= Sup.MAnalyse(isb=True, delta=1,blksize=16) FvSos= Sup.MAnalyse(isb=False, delta=1,blksize=16) Eos = c.MSCDetection(BvEos,thSCD1=thSCD1,thSCD2=thSCD2) Sos = c.MSCDetection(FvSos,thSCD1=thSCD1,thSCD2=thSCD2) SC_Clip = MT_Lutxy(Eos,Sos,yexpr="y 0 == x 0 == 0 1 ? x 0 == 2 3 ? ?",u=-128,v=-128) LastWrE=-1 GS=""" For(n=0,FC-1) { eosos = SC_Clip.RT_AverageLuma(n,w=1,h=1).Int # All Luma pixel = 0 =Norm, 1=EOS, 2=SOS, 3=EOS & SOS eosos = (n==FC-1) ? RT_BitSet(eosos,0) : eosos # Force EOS at Last frame, fix some bugged if(eosos>=2 && LastWrE<n-1 && n!=0) { # Is flagged SOS, so force any earlier non written range Rec=RT_DBaseExtend(DB,1) # Add 1 Record, nullified fields, Rec = current number of records RT_DBaseSetField(DB,Rec-1,SOS_Field,LastWrE+1+OFfset) LastWrE=n-1 RT_DBaseSetField(DB,Rec-1,EOS_Field,LastWrE+OFfset) } if(eosos==1 || eosos==3) { # Flagged EOS, Write to current Rec=RT_DBaseExtend(DB,1) # Add 1 Record, nullified fields, Rec = current number of records RT_DBaseSetField(DB,Rec-1,SOS_Field,LastWrE+1+OFfset) LastWrE=n RT_DBaseSetField(DB,Rec-1,EOS_Field,LastWrE+OFfset) } } """ HasGScript ? GScript(GS) : Eval(GS) # Use GSCript if installed (loaded plugs override builtin) Return Rec-Records } Create DBase with scene change range data (can add some fields for other stuff, eg stored chroma thresh to use in each detector stage (generated by some kind of chroma average script). DBase Generator (after generated, can fill in your additional empty fields via some eg chroma thresh based on average) Code:
# Create DBase AVISource("D:\Parade.AVI") DB="D:\Parade.DB" RT_DBaseAlloc(DB,0,"ii") # Alloc minimum of two int fields, 0=SOS, 1=EOS. (add others if required) Records = DBase_DetectScenes(DB) # Use Defaults for fields, Offset, and thSCD1 and thSCD2 Return MessageClip("DBase_DetectScenes: Records="+String(records)) Code:
# Show Scenes AVISource("D:\Parade.AVI") DB="D:\Parade.DB" SSS=""" n=current_frame Record=DB_FindTrim(DB,0,1,n) # Record or scene number (relative 0) # -1 NOT FOUND SceneStart = (Record>=0) ? RT_DBaseGetField(DB,Record,0) : -1 # Get scene start from field 0 (SOS) SceneEnd = (Record>=0) ? RT_DBaseGetField(DB,Record,1) : -1 # Get scene end from field 1 (EOS) RT_Subtitle("%d] #%d Start=%d End=%d",n,Record,SceneStart,SceneEnd) """ Scriptclip(SSS) return Last a Start Of Scene, above detector should be devoid of such behaviour. NOTE, Some scenes may be single frame, especially at blended transition. [ie both SOS and EOS] EDIT: You can use Offset, to concatenate multiple clip scene change data into a single DBase for spliced final clip.
__________________
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; 12th September 2018 at 22:01. |
13th September 2018, 01:11 | #14 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Additional Demo.
All done in one script, init DBase with scene change data, scan each scene getting min and max aveluma of scene, update DBase with min/max stuff then play clip showing result scene numbers, and scene min/max aveluma for each frame in scene. Code:
###### # Demo, Add something to DBase for each scene/record, in this case just min and max average luma as 2 Floats @ Field 2=min, 3=max ###### AVISource("D:\Parade.AVI") DB="D:\Parade.DB" ###### # 1st Create DBase with 2 additional fields ###### RT_DBaseAlloc(DB,0,"iiff") # Alloc two int fields for SOS & EOS, also add Field 2 Float for MinAveLuma, and Field 3 for MaxAveLuma Records = DBase_DetectScenes(DB) # Use Defaults for fields, Offset, and thSCD1 and thSCD2 RT_DebugF("DEMO: Detected %d Scenes, added to DBase",Records) # See output in DebugView (Google) #return MessageClip("DONE") ###### ### 2nd, Scan scenes in clip, establish Min/max luma for each scene, and update DBase ### Using AVS+ here, mod if using GSCript ###### Records=RT_DBaseRecords(DB) For(scene=0,Records-1) { SFrm = RT_DBaseGetField(DB,scene,0) # Get scene start from field 0 (SOS) EFrm = RT_DBaseGetField(DB,scene,1) # Get scene end from field 1 (EOS) MinLum=256.0 MaxLum=-1.0 # Prep for scene for(frm=SFrm,EFrm) { # Scan all Frames in Scene AveLum=RT_AverageLuma(n=frm) # could specify eg area to measure eg x=32,y=32,w=-32,h=-32 # as for crop(32,32,-32,-32) MinLum=Min(MinLum,AveLum) MaxLum=Max(MaxLum,AveLum) } RT_DbaseSetField(DB,scene,2,MinLum) # Set Minimum encountered luma in this scene to 3rd field, field 2 RT_DbaseSetField(DB,scene,3,MaxLum) # Set Maximum encountered luma in this scene to 4th field, field 3 RT_DebugF("DEMO: Scene#%d[%d,%d] MinLuma=%.3f MaxLuma=%.3f",scene,SFrm,EFrm,MinLum,MaxLum) # See output in DebugView (Google) } #return MessageClip("DONE") ###### # 3rd, NOW PLAY Clip ###### SSS=""" n=current_frame Record=DB_FindTrim(DB,0,1,n) # Record or scene number (relative 0) # -1 NOT FOUND if(Record>=0) { Records = RT_DBaseREcords(DB) # Show number of records ie scenes SceneStart = RT_DBaseGetField(DB,Record,0) # Get scene start from field 0 (SOS) SceneEnd = RT_DBaseGetField(DB,Record,1) # Get scene end from field 1 (EOS) MinLum = RT_DBaseGetField(DB,Record,2) # Get MinLuma for entire scene (same for each frame in scene) MaxLum = RT_DBaseGetField(DB,Record,3) # Get MaxLuma for entire scene (same for each frame in scene) SceneFMax = SceneEnd-SceneStart # For show scene relative frame number n/nmax, 0 rel RT_Subtitle("%d/%d] #%d/%d:%d/%d[%d,%d,Len=%d]\nMinLuma=%.3f\nMaxLuma=%.3f", \ n,FrameCount-1,Record,Records-1,n-scenestart,SceneFMax,SceneStart,SceneEnd,SceneFMax+1,MinLum,MaxLum) } Else { Subtitle("ERROR: RECORD NOT FOUND !",align=5,size=48)} """ Scriptclip(SSS) Can view some stuff via DebugView while Scanning (Google) EDIT: You also need prev posted library funcs. EDIT: In above ScriptClip Play section, could if required only update scene constant stuff from DBase, when a new scene is encountered, eg MinLuma is set for entire scene, and would only need be gotten once per scene, but is no real problem to get it every time, when it would be a good idea, would be when getting some string from DBase, where strings take up quite a bit of memory as new string required for every iteration, (waste of mem). However, if updating only on new record/scene, then would require a Global variable to remember the previous record/scene, and also the previous string.
__________________
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; 13th September 2018 at 16:57. |
13th September 2018, 18:39 | #15 | Link |
Registered User
Join Date: Mar 2017
Location: Germany
Posts: 234
|
You're great, a big thank you again!
I tried this with the whole episode: Unfortunately: -At some swapped ranges U and V population/saturation get a lot higher compared to the frames before and after, on other ranges it is as you assumed, they get smaller. At those ranges I observed, the differences between pop before/after and pop inside are quite significant - but this gives me again only the direct possibility to detect the beginnings and ends of the ranges - if you don't have another idea for this. And it's not safe, because with some ranges significantly higher, some ranges significantly lower, I bet that there are some where there will be no difference... -The other method with testing the right margin works most times well, but fails if the near content is also very dark - and I already found some scenes where exactly this happens... -My first method with this: Code:
v=avisource("26.avi") vminus1=trim(v,1,0) global sep=";" x=WriteFileIf(v,"F:\Scripts\26UV.log","(UDifferenceFromPrevious(v)-UDifferenceFromPrevious(vminus1)>1.7) && (YDifferenceFromPrevious(v)-YDifferenceFromPrevious(vminus1)<10)","current_frame-1") So I fear I will save the beginnings and ends with my/your mixed detector (works for this purpose quite at 100%) and write something meta that will output a final repair-script. To work myself into all that great stuff with database and all I haven't got the time, which I regret - all episodes have to be done next week. Again for your big efforts! Great people in this forum! Last edited by Frank62; 13th September 2018 at 18:50. |
14th September 2018, 09:48 | #16 | Link | |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Quote:
If you can up a longer (~500MB max, no audio), I'll try D/L today. I was thinking of compare with next frame, and also compare with eg SwapUV for detector. [I'm also still sticking with DBase, too much potential for error crossing scene boundaries]. EDIT: Also note that UDifferenceFromPrevious(vminus1) same as UDifferenceToNext(v), no need for additional next vminus clip.
__________________
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; 14th September 2018 at 10:16. |
|
14th September 2018, 11:46 | #17 | Link | |||
Registered User
Join Date: Mar 2017
Location: Germany
Posts: 234
|
Quote:
First hit is either single or beginning. If between this and next hit more than let's say 30 frames (maximum length I saw was 20 frames) then it was a single swap, if not, then next one is end. a. s. o. Only if two single swaps are nearer than 30 frames I will become problems. But can fix this by hand, maybe once an episode, if it ever happens. I can't do this in avisynth, but extern no problem, I am doing similar things all the time, so one or two hours of work should do. Quote:
Quote:
|
|||
14th September 2018, 17:13 | #18 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
When I get home, I shall try complete my version detector as in your 2nd last quote, seemed to be working before I had to leave.
Maybe yours works fine, but gonna try my altrnative, just the same. be good.
__________________
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 ??? |
14th September 2018, 19:58 | #20 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Yeh, I know, just found it an interesting prob.
In the words of some UK TV program (that I cant quite remember the name of, EDIT: MasterMind with Magnus Magnusson), 'I've started, so I'll finish', if your detector works, then great, if not then there might be a viable alternative, I'll post mine anyways, whether you successfully complete or not. But not right now, think I shall succumb to this booze induced coma that I'm about to fall into .
__________________
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; 15th September 2018 at 00:37. |
Thread Tools | Search this Thread |
Display Modes | |
|
|