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. |
|
|
Thread Tools | Search this Thread | Display Modes |
3rd May 2021, 10:50 | #1 | Link |
Registered User
Join Date: Apr 2021
Posts: 128
|
[Solved] Colour mark detection for frames remouval in 8mm/S8 transfer
Hello dear users,
BACKGROUND I am achieving the construction of a film-transfer system for 8mm and Super8 films. It is based on the method of capturing the frames directly into the projector's gate with a running video camera (versus frame by frame capture). My first goal coming here was to enjoy the huge Fred's script and John's version generously shared here and perfected with the help of many users in this thread. As I needed to have a frame accurate capture (one video frame for one footage frame) to use these scripts, i built a system and posted my setup description and question there. But that became off topic. I began this thread. SETUP Detailed setup + pictures here As is not possible to synchronize the camera I am using with the projector, I had to find a way to peseudo-sync them. The idea I had was to place an LED on the side of the gate. The LED is turned on each time the projector is changing from one frame to the next one, then turned off when the frame is steady. The projector runs at 18 fps while the camera shoots at 50 fps. This way, the capture contains the information about which frames are usable and which are not. THE SITUATION Sample here, md5:0820A24F2D0AB47483FA5E3BF5DADB69 File is directly out of the camera, hence inverted. As you can see in the sample, I now have captured sequences containing one or more "bad frames" followed by one or more "good frames": Here is a screenshot to give you an idea: B = Bad frame (blue light presence) G = good frame (no blue light) Example starting from frame 314 included, to 335: G B GG B GG B G BB G BB G B GG B GG B We sometimes have GG, sometimes BB. But we always have at least one G between one or some B. I think we could say: "keep only one G between each B/each group of B", it should work, don't You think? Step by step, more or less human spoken, it would give: If B, throw away and flag "last was B" else if G, and flag is "last was B", keep and flag "last was G" else if G, and flag is "last was G", throw away and so on... THE QUESTION How do we ask this to Avisynth? I'll share my attempts into the next post. Last edited by chmars; 30th May 2021 at 10:53. Reason: explain inverted image, add pic Edit2: mark as solved |
3rd May 2021, 10:56 | #2 | Link |
Registered User
Join Date: Apr 2021
Posts: 128
|
Being very noob, I needed half of last night to find a start of partly working solution.
It may be very naive and inappropriate but here it is, at least to prove my effort :--) This code is removing all B frames except when two are directly in a row. Code:
LoadPlugin("C:\Program Files (x86)\AviSynth+\plugins/ffms2.dll") # Load the plugin able to read MXF files initial_video = FFmpegSource2("C:\some_path\my_sample.MXF", atrack=-2) # How to read and which is the file video = Crop(initial_video, 474, 190, -166, -170) # Crop my video frame ScriptClip(video, \ #Will be done on each frame of clip "video" "frame_chromaU = AverageChromaU(Crop(video,0, 0, -1000, 0))" + chr(13) + \ #Store the chroma U average of a cropped part of the immage in a variable "frame_chromaV = AverageChromaV(Crop(video,0, 0, -1000, 0))" + chr(13) + \ #Store the chroma V average of a cropped part of the immage in a variable "frame_luma = AverageLuma(Crop(video,0, 0, -1000, 0))" + chr(13) + \ #Store the luma average of a cropped part of the immage in a variable "black_ref_luma = AverageLuma(Crop(video,150, 560, -1000, 0))" + chr(13) + \#Same for black part as reference "round(frame_chromaU) > 520 && \ # If chroma U average is bigger than 520 AND round(frame_chromaV) < 503 && \ # if chroma V average is smaller than 503 AND round(frame_luma) > 200 && \ # if luma average is bigger than 200 AND round(black_ref_luma) < 200 \ # if the black part of the image is not lit by something else ? DeleteFrame(current_frame) : subtitle(string()) ") # then we can hope the led is ON and delete the frame. Else, do nothing And then? It'll result in a file with lots of duplicated frames. I could then use someting like a duplicated frame detector. But this is no good solution as it adds an interpretation of the images, introducing a cause of errors (Am I right on this point?). What would be needed is to store the B frame-number into a variable outside of the run-time environment to be able to keep only one of the next G frames. Or write a list into a text file? I'll make some tries but if you have suggestions, they are very welcome. |
3rd May 2021, 16:24 | #3 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,042
|
Script moved here from this post:- https://forum.doom9.org/showthread.p...99#post1941999
Blue_LED_Detect.avs [detector, frames.txt maker] Code:
# Blue_LED_Detect.avs /* Requires, AVS+, RT_Stats, MaskTools Detects Blue LED's, selects mid frame of those frames between blue LEDs, when SEL2ND==True and frame count between Blue LEDs are even, then selects the later middle frame rather than default earlier middle frame. Writes only single middle frame between BLUE frames. May need to adjust AREA Coords where BLUE expected */ FN = "MBGV0403.MXF" ############ VFLIP = True # Vertical Flip if upside down SETUP_BLUE = False # Setup BLUE Detect Vars MODE ONLY. DOES NOT Detect non BLUE nor write Frames BAFFLE = 4 # Blue Detect Vars (RT_YInRangeLocate, Probably should leave this one alone) THRESH = 10.0 # Ditto, Maybe bout 5.0 -> 20.0 LUMA_MIN = 60 # Ditto, blue luma min LUMA_MAX = 255 # Ditto (Leave alone) AREA_X = 240 # BLUE Coords test area AREA_Y = 300 # Ditto AREA_W = 530 # Ditto AREA_H = 572 # Ditto SEL2ND = False # When NonBlue count is EVEN, false selects earlier middle frame, True select later middle frame. SHOW = true # Metrics + BLUE MARKER [FALSE for final, quicker] ############ FN = FN.RT_GetFullPathName LWLibavVideoSource(FN) ############ ConvertBits(8).ConvertToYV12 # Just for Detect ORG = Last (VFLIP) ? FlipVertical : NOP # Un-comment BELOW to SHOW BLUE TEST AREA COORDS #return Overlay(Last.BlankClip(Length=1,Width=AREA_W,Height=AREA_H,color=$FFFF00),x=AREA_X,y=AREA_Y,Opacity=0.3) ########################## DB = ".\MyDBase.DB".RT_GetFullPathName FRAMES = ".\Frames.txt".RT_GetFullPathName TypeStr = "iiiiiiii" RT_FileDelete(FRAMES) RT_DBaseAlloc(DB,FrameCount,TypeStr) ############ DBase Field Index's STAT_FLD = 0 # 0=Unknown, 1=BLUE, 2=Non Blue Frame(Not chosen), 3=Non Blue chosen Frame. # Valid only When STAT==2 OR STAT==3 (NOT BLUE_LED Stat==1) FRM_S_FLD = 1 # Ditto, 1st frame of non BLUE FRM_M_FLD = 2 # Ditto Chosen Non Blue (writen to Frames file) FRM_E_FLD = 3 # Ditto Last frame of non BLUE BLUE_X_FLD = 4 # Blue Detect Coords, Valid ONLY when STAT==1 (BLUE_LED) BLUE_Y_FLD = 5 # Ditto BLUE_W_FLD = 6 # Ditto BLUE_H_FLD = 7 # Ditto # Setup Detect Vars Script SCRIPT_0 = """ n=current_frame if(RT_YInRangeLocate(Last,n=n,x=AREA_X,y=AREA_Y,w=AREA_W,h=AREA_H,Baffle=BAFFLE,Thresh=THRESH,Lo=LUMA_MIN,Hi=LUMA_MAX)) { Blue_x = YIRL_X /2 * 2 Blue_y = YIRL_Y / 2 * 2 Blue_w = (YIRL_W + 1) / 2 * 2 Blue_h = (YIRL_H + 1) / 2 * 2 Mrk = Last.BlankClip(Length=1,Width=Blue_w,Height=Blue_h,Color=$FFFF00) Msk = Hit_Marker(Blue_w,Blue_h,False) Overlay(Mrk,x=Blue_x,y=Blue_y,Mask=Msk,Mode="Blend") } Subtitle("Setup BLUE Detect Vars",Size=48) Return Last """ # Write FRAMES File Script SCRIPT_1=""" n=current_frame Stat = RT_DBaseGetField(DB,n,STAT_FLD) if(Stat == 0) { # Unknown Stat = RT_YInRangeLocate(Last,n=n,x=AREA_X,y=AREA_Y,w=AREA_W,h=AREA_H,Baffle=BAFFLE,Thresh=THRESH,Lo=LUMA_MIN,Hi=LUMA_MAX) ? 1 : 2 if(Stat==1) { # BLUE Blue_x = YIRL_X / 2 * 2 Blue_y = YIRL_Y / 2 * 2 Blue_w = (YIRL_W + 1) / 2 * 2 Blue_h = (YIRL_H + 1) / 2 * 2 RT_DBaseSet(DB,n,Stat, -1,-1,-1, Blue_X,Blue_Y,Blue_W,Blue_H) } Else { # NOT BLUE Frame_S = n For(i=n-1,0,-1) { # Step Backwards looking for previous BLUE # i is Always either KNOWN BLUE or Unknown Stat = RT_DBaseGetField(DB,i,STAT_FLD) if(Stat == 0) { # Unknown if(RT_YInRangeLocate(Last,n=i,x=AREA_X,y=AREA_Y,w=AREA_W,h=AREA_H,Baffle=BAFFLE,Thresh=THRESH,Lo=LUMA_MIN,Hi=LUMA_MAX)) { Blue_x = YIRL_X / 2 * 2 Blue_y = YIRL_Y / 2 * 2 Blue_w = (YIRL_W + 1) / 2 * 2 Blue_h = (YIRL_H + 1) / 2 * 2 RT_DBaseSet(DB,i,1, -1,-1,-1, Blue_X,Blue_Y,Blue_W,Blue_H) # set BLUE stuff Frame_S = i + 1 # Start frame = BLUE + 1 i = 0 # Break } Else { Frame_S = i } # Non BLUE } else { # KNOWN BLUE Assert(Stat==1,"Internal Error #1 Stat="+String(Stat)) Frame_S = i + 1 # Start frame = BLUE + 1 i = 0 # Break } } Frame_E = n For(i=n+1,FrameCount-1) { # Step Forwards looking for next BLUE # i is Always either KNOWN BLUE or Unknown Stat = RT_DBaseGetField(DB,i,STAT_FLD) if(Stat == 0) { # Unknown if(RT_YInRangeLocate(Last,n=i,x=AREA_X,y=AREA_Y,w=AREA_W,h=AREA_H,Baffle=BAFFLE,Thresh=THRESH,Lo=LUMA_MIN,Hi=LUMA_MAX)) { Blue_x = YIRL_X / 2 * 2 Blue_y = YIRL_Y / 2 * 2 Blue_w = (YIRL_W + 1) / 2 * 2 Blue_h = (YIRL_H + 1) / 2 * 2 RT_DBaseSet(DB,i,1, -1,-1,-1, Blue_X,Blue_Y,Blue_W,Blue_H) # set BLUE stuff Frame_E = i - 1 # End frame = BLUE - 1 i = FrameCount-1 # Break } Else { Frame_E = i } # Non BLUE } else { # KNOWN BLUE Assert(Stat==1,"Internal Error #2 Stat="+String(Stat)) Frame_E = i - 1 # End frame = BLUE - 1 i = FrameCount-1 # Break } } SelIx = (Frame_E - Frame_S) / 2 Frame_M = (SEL2ND) ? Frame_E-SelIx : Frame_S + SelIx for(i=Frame_S,Frame_E) { Stat = (i==Frame_M)?3:2 RT_DBaseSet(DB,i,Stat, Frame_S,Frame_M,Frame_E, -1,-1,-1,-1) } Stat = (n==Frame_M)?3:2 } } # End, if(Stat == 0) # Here, Stat=1=BLUE, =2 non-blue Frame - not chosen, 3=Chosen Frame if(Stat==1) { # BLUE if(SHOW) { Blue_x = RT_DBaseGetField(DB,n,BLUE_X_FLD) Blue_y = RT_DBaseGetField(DB,n,BLUE_Y_FLD) Blue_w = RT_DBaseGetField(DB,n,BLUE_W_FLD) Blue_h = RT_DBaseGetField(DB,n,BLUE_H_FLD) Mrk = Last.BlankClip(Length=1,Width=Blue_w,Height=Blue_h,Color=$FFFF00) Msk = Hit_Marker(Blue_w,Blue_h,False) Overlay(Mrk,x=Blue_x,y=Blue_y,Mask=Msk,Mode="Blend",Opacity=0.3) Subtitle(RT_String("%d ] BLUE LED, detect x=%d y=%d w=%d h=%d",n,Blue_x,Blue_y,Blue_w,Blue_h),Size=48,Align=1) } } else if(Stat==3 || SHOW) { Frame_S = RT_DBaseGetField(DB,n,FRM_S_FLD) Frame_E = RT_DBaseGetField(DB,n,FRM_E_FLD) (SHOW) ? Subtitle(RT_String("%d ] S=%d E=%d Len=%d",n,Frame_S,Frame_E,Frame_E-Frame_S+1),Size=48) : NOP if(Stat==3) { # Write To Frames File if(!SEL2ND || n == Frame_S + ((Frame_E - Frame_S) / 2)) { RT_WriteFile(FRAMES,"%d",n,Append=n!=0) (SHOW) ? Subtitle(RT_String("Writing"),Size=48,y=48) : NOP } else { RT_WriteFile(FRAMES,"%d # 2nd of middle pair",n,Append=n!=0) (SHOW) ? Subtitle(RT_String("Writing, 2nd of middle pair"),Size=48,y=48) : NOP } } } Return Last """ SSS = (SETUP_BLUE) ? SCRIPT_0 : SCRIPT_1 ScriptClip(SSS) Return Last Function Hit_Marker(int W, Int H, Bool "Hit", Int "BW", Int "BH",Int "PW",Int "PH",Bool "YV12",Bool "Mod2") { /* Req RT_Stats & mt_tools v2. http://forum.doom9.org/showthread.php?t=174527 Creates a marker mask WxH, for use with Overlay as Mask arg. Intended for use via some kind of detector to show detection Hit, or Miss. Returns Single frame clip with null audio, the marker top left hand side is aligned to 0,0. Default return clip colorspace is Y8 for Avisynth v2.6 and above, or YV12 if defunct version. Args:- W,H, Size of marker mask (can be odd), return clip dimensions are rounded up to next multiple of 2 if YV12 return clip. Bare minimum usable size is 4x4 with defaulted BW, BH, PW, PH. HIT, Default False, returns marker as angled corners (Thickness set by BW and BH). True, returns marker as angled corners + outer perimeter where perimeter thickness set by PW and PH. BW, Default Max(W/8,1). Horizontal thickness of the marker corners. BH, Default Max(H/8,1). Vertical thickness of the marker corners. PW, Default Max(BW/8,1). Horizontal thickness of the vertical perimeter. PH, Default Max(BH/8,1). Vertical thickness of the horizontal perimeter. YV12, Default False if Avisynth version 2.6 or greater(Y8), else true(YV12). Selects return clip colorspace. Mod2, Default True. If Y8 then round odd dimensions up modulo 2 (the mask is still WxH). Example:- Import("Hit_Marker.avs") WW=128 HH=WW HIT=True BlankClip Yell=Last.BlankClip(Width=WW,Height=HH,Length=1,Color=$FFFF00) Return OverLay(Yell,x=(Width-WW)/2,y=(Height-HH)/2,mask=Hit_Marker(WW,HH,HIT)) */ Hit=Default(hit,False) BW=Max(Default(BW,W/8),1) BH=Max(Default(BH,H/8),1) BW2=(W>4)?BW*2:BW BH2=(H>4)?BH*2:BH PW=Max(Default(PW,BW/8),1) PH=Max(Default(PH,BH/8),1) is26 = VersionNumber>=2.6 YV12=(!is26) ? True : Default(YV12,False) Mod2=Default(Mod2,True) Mod = (YV12||Mod2) ? 2 : 1 CanvasW=(W+Mod-1)/Mod*Mod CanvasH=(H+Mod-1)/Mod*Mod Rpn= RT_String("x %d < x %d >= | y %d < | y %d >= | x %d < x %d >= | & y %d < y %d >= | & ",BW,W-BW,BH,H-BH,BW2,W-BW2,BH2,H-BH2) Rpn= (Hit) ? Rpn + RT_String("x %d < x %d >= | y %d < | y %d >= | | ",PW,W-PW,PH,H-PH) : Rpn Rpn= Rpn + RT_String("x %d < y %d < & & 255 0 ?",W,H) Blankclip(width=CanvasW,height=CanvasH,Length=1,pixel_type=YV12?"YV12":"Y8").Killaudio return mt_lutspa(relative = false,yExpr=Rpn, chroma = "-128") } Code:
# Blue_LED_FrameSel.avs # Requires FrameSel plugin. (OK for HBD so long as dont use FrameSel SHOW arg). # Requires Frames.txt as generated by Blue_LED_Detect.avs FN = "MBGV0403.MXF".RT_GetFullPathName FRAMES = "Frames.txt".RT_GetFullPathName ############ VFLIP = True # Vertical Flip if upside down REJECT = False # If True then show all rejected frames instead of selected frames LWLibavVideoSource(FN) (VFLIP) ? FlipVertical : NOP # FrameSel, DONT USE SHOW ARG if NOT 8 bit. Return FrameSel(Last,Cmd=FRAMES,Ordered=True,REJECT=REJECT) Blue Detect Frame [SHOW=true] Non Blue selected frame [SHOW=true] EDIT: I can possibly mod current script, (I'll leave above in-situ), to auto scan [will seem to pause for some time], and then do equivalent to calling the FrameSel script, and be ready to output final clip in eg VDub2 Save AVI or whatever. All in single script, and auto deleting the DBase file on clip closure. ScriptClip MUST have same number of output frames as input, and also same size/colorspace etc, that is why you are ending up with many dupes at end of clip. [The framecount, size, colorspace, is fixed as soon as frameserving begins] EDIT: Is the BLUE_LED detection working as per requirement ? Also, is it required that you can execute two or more separate instances of the script simultaneously ?
__________________
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 May 2021 at 16:39. |
3rd May 2021, 19:23 | #4 | Link |
Registered User
Join Date: Feb 2002
Location: California
Posts: 2,723
|
My guess is that you can use one or two lines of code, simply using the YDDifference function built into AVISynth. I do this all the time to find "flash frames," my term for the grossly overexposed frame that you get in a movie camera at the first frame when the camera is still coming up to speed, and the shutter blade is rotating too slowly, resulting in overexposure.
All you need to do is compare the current frame to each adjacent frame, and when this bidirectional metric blows up, you have found your LED frame. |
3rd May 2021, 20:13 | #5 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,042
|
YDifference just tells absolute difference, could be going lighter, or darker, if different to prev, then could be black to blue or blue to black,
if same then could be both black or both blue. Something additional is needed [ie Averageluma or similar on current frame]. If just picking 1st non blue frame after blue, then dont think you need bother about next frame at all, only previous. You still got lots of dupes at end to remove. EDIT: Also, there is maybe need to specifiy what exactly a blue frame is, ie how much blue, is any blue at all considered blue. My detector looks for a 'chunk of blue of a minimum size [avoid any noise] and possibly moving [as Blue LED does]. 6] With current settings, this is considered [2nd of 2] Not Blue [but could be tweaked to consider as blue] 7] Blue 8] Not blue [1 of 1] 9] Blue The detector is looking for a chunk of blue of a certain size & 'density'. And the fact that its a blue LED dont really make a whole helluva lot of difference, brightness will quite suffice to detect.
__________________
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 May 2021 at 20:40. |
3rd May 2021, 20:21 | #6 | Link |
Registered User
Join Date: Feb 2002
Location: California
Posts: 2,723
|
I use the ratio of YDifferenceToNext and YDifferenceToPrevious. This gets rid of the problem of how these metrics vary over time as the nature of the video changes. I posted such a detection script several years ago and, with StainlessS' help, turned it into a pretty useful detection script for finding individual "bad" frames. The LED flash is a classic bad frame, and my detection script should therefore work perfectly. Here is the link:
Finding individual "bad" frames in video; save frame number; or repair My finished script appears in post #6. |
3rd May 2021, 20:55 | #7 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,042
|
With current clip cap speeds, there can be single or multiple [2] of either blue or non blue frames,
any single would appear as a flash in a YDifferenceToNext and YDifferenceToPrevious ratio thingy, whether it be black flash or blue flash. You still need to be able to tell one from other. I've deliberately made my detector be able to cope with (single or) many blue and/or (single or) many black frames, if cap speeds were to be changed. EDIT: Simple-ish detector would test luma [AverageLuma, or maybe YPlaneMax] and if BELOW some threshold, then also test if sufficiently different to prev frame, if so then is first non blue. [ie current frame TEST AREA is BLACK, prev frame TEST AREA is NOT BLACK] EDIT: Fixed, I originally wrote "Above". EDIT: Yep, Maybe YPlaneMax(threshold=100/256.0) # where threshold = 0.4% Percent of extreme [possible noise] pixels to ignore.
__________________
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 May 2021 at 21:14. |
3rd May 2021, 21:30 | #8 | Link | ||
Registered User
Join Date: Apr 2021
Posts: 128
|
Hi,
I was very excited to find your script, it's great to have such a tool for my setup! Thanks again very much for the work. Ok, thanks. But...you know, I think i'll leave my "script" on the side for the moment and focus on yours. Your functional proposals are interesting. The more is automated, the best it is. But I am far from asking any more, as it is already time spent for you and so great compared to what I can write! Quote:
Quote:
On my side, half way: It behaves as if one part of it would be too fast for another part. It ends with only some frames numbers into the txt file. Same with/without showing metrics+marker. Code:
Text file: 0 11 52 68 121 140 302 321 371 495 701 718 743 766 782 816 844 849 Error Window: Error parsing plugin string at position 0: Error parsing Func plugin parameters: unknown character 'n' Error parsing ConditionalSelect plugin parameters: unknown character 'n' Error parsing ConditionalSelect plugin parameters: unknown character 'n' Error parsing ConditionalFilter plugin parameters: unknown character 'n' Error parsing ConditionalFilter plugin parameters: unknown character 'n' Error parsing ConditionalFilter plugin parameters: unknown character 'n' Error parsing ScriptClip plugin parameters: unknown character 'n' Error parsing ScriptClip plugin parameters: unknown character 'n' Error parsing WriteFile plugin parameters: unknown character 'n' Error parsing WriteFile plugin parameters: + without preceeding argument Error parsing WriteFileIf plugin parameters: unknown character 'n' Error parsing WriteFileIf plugin parameters: + without preceeding argument Error parsing WriteFileStart plugin parameters: unknown character 'n' Error parsing WriteFileStart plugin parameters: + without preceeding argument Error parsing WriteFileEnd plugin parameters: unknown character 'n' Error parsing WriteFileEnd plugin parameters: + without preceeding argument Error parsing WriteFile plugin parameters: unknown character 'n' Error parsing WriteFile plugin parameters: + without preceeding argument Error parsing WriteFileIf plugin parameters: unknown character 'n' Error parsing WriteFileIf plugin parameters: + without preceeding argument Error parsing WriteFileStart plugin parameters: unknown character 'n' Error parsing WriteFileStart plugin parameters: + without preceeding argument Error parsing WriteFileEnd plugin parameters: unknown character 'n' Error parsing WriteFileEnd plugin parameters: + without preceeding argument Error parsing propSet plugin parameters: unknown character 'a' Error parsing propSetInt plugin parameters: unknown character 'n' Error parsing propSetFloat plugin parameters: unknown character 'n' Error parsing propSetString plugin parameters: unknown character 'n' Error parsing propSetArray plugin parameters: unknown character 'n' Error parsing propSet plugin parameters: unknown character 'a' Error parsing propSet plugin parameters: unknown character 'a' Error parsing propSet plugin parameters: unknown character 'a' Error parsing propSet plugin parameters: unknown character 'a' Error parsing OnCPU plugin parameters: unknown character 'n' Error parsing OnCPU plugin parameters: unknown character 'n' I use AVS+ 3.7.0 on a win10 PC. and going to search the way to determine the version of the DLLs EDIT: I tried many times, to be sure. Deleting the db, lwi and text file between attempts. The source file (...403.mxf) is in the same directory. Last edited by chmars; 3rd May 2021 at 22:32. Reason: it works. |
||
3rd May 2021, 22:35 | #10 | Link | ||
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,042
|
I cannot make my ver$ fully automatic.
TWriteAVI(), could have made possible but cannot write files > 2GB, nor supports HBD. [I cannot mod for > 2GB, I dont speak x86 assy nor do I know how to mod for DML AVI spec supporting > 2GB files.] If TWriteAVI suppored both HBD and > 2GB files, would be a [near] walk in the park. [EDIT: Only small amount of x86 assy in TWriteAVI, main prob is the DML AVI spec >2GB stuff] This stuff Quote:
but referring to deleting the DB has me puzzled. Quote:
__________________
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 May 2021 at 22:57. |
||
4th May 2021, 01:08 | #12 | Link | |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,042
|
Quote:
chmars, Metrics viewer, for adjusting test area coords and thresholds. Using same method should work pretty well. Choose Detection_Threshold midway between displayed metrics for minimum Blue_LED frame, and maximum Non_blue_LED frame. Also can choose metrics as for 8 bit or native bit depth eg 10 bit for your posted clip. [8 Bit will be easily more than sufficient (and more familiar values)]. Code:
# Requires Grunt() plugin LWLibavVideoSource(".\MBGV0403.MXF") ############ TEST_X = 374 TEST_Y = 210 TEST_W = 372 TEST_H = 700 BITS8 = True # Metrics are as 8 bit MMDIFTH = 0.4 # YPlaneMinMaxDifference Threshold (100.0/256.0) about 0.4 % [Percentage of extreme (noise) pixels to ignore]. VFLIP = True # Vertical Flip if upside down ############ (VFLIP) ? FlipVertical : NOP Show_TestArea(TEST_X,TEST_Y,TEST_W,TEST_H,BITS8,MMDIFTH) Return Last Function Show_TestArea(clip c,int x,int y,int w,int h,Bool "Bits8",Float "MMDifTh") { Bits8 = Default(Bits8,False) # If True, then metrics are for 8 bit Th = Default(MMDifTh,0.4) # YPlaneMinMaxDifference Threshold (%) tc = c.Crop(x,y,w,h) tc = Bits8 ? tc.ConvertBits(8).ConvertToYV12 : tc SSS="""Return Subtitle(String(current_frame)+String(tc.YPlaneMinMaxDifference(threshold=Th),"] %.1f"),Size=48)""" c.ScriptClip(SSS, Args="tc,Th") Return Last.OverLay(c.BlankClip(Length=1,Width=w,Height=h,Color=$FFFF00),x=x,y=y,Opacity=0.1) } 23] Blue_LED [frame number, then Metric ie YPlaneMinMaxDifference(threshold=0.4) in 8 Bit] 24] Black
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 4th May 2021 at 02:38. |
|
4th May 2021, 01:25 | #13 | Link | |
Registered User
Join Date: Mar 2019
Posts: 48
|
Quote:
https://www.ebay.com/b/Film-Scanner-...0/bn_108187128 |
|
4th May 2021, 01:42 | #14 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,042
|
Not as much 'fun' as DIY, then Fred/Johns scripts for the ultimate results.
Maybe
__________________
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 ??? |
4th May 2021, 05:31 | #15 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,042
|
Here is simpler detect [or will be when slimmed down] script, test version to see if the YPlaneMinMaxDifference thingy works OK.
Code:
LWLibavVideoSource(".\MBGV0403.MXF") ############ TEST_X = 374 # Test AREA COORDS (Even only) TEST_Y = 210 # Ditto TEST_W = 372 # Ditto TEST_H = 700 # Ditto BITS8 = True # Metrics are as 8 bit DETTH = 50.0 # Detection Threshold (50 is 8 bit thresh) MMDIFTH = 0.4 # YPlaneMinMaxDifference Threshold (100.0/256.0) about 0.4 % [Percentage of extreme (noise) pixels to ignore]. VFLIP = True # Vertical Flip if upside down FRAMES = ".\Frames.txt" ############ (VFLIP) ? FlipVertical : NOP ############ FRAMES=FRAMES.RT_getFullPathName RT_FileDelete(FRAMES) tc = Crop(TEST_X,TEST_Y,TEST_W,TEST_H) tc = Bits8 ? tc.ConvertBits(8).ConvertToYV12 : tc SSS = """ DetCur = tc.YPlaneMinMaxDifference(threshold=MMDifTh) DetPrv = tc.YPlaneMinMaxDifference(threshold=MMDifTh,offset=-1) T1= DetCur < DetTh T2= DetPrv >= DetTh T3 = (T1 && (current_frame==0 || T2)) (T3) ? RT_WriteFile(FRAMES,"%d",current_frame,Append=true) : NOP s= RT_string("%d] DetCur=%d(%.1s) DetPev = %d(%.1s) T=%s",current_frame,DetCur,T1,DetPrv,T2,T3) Subtitle(s,size=48) Return Last """ ScriptClip(SSS) Output identical frame numbers to original script except this one outputs 91 and original 90. Output of this will extract good frames using the same Framsel script.
__________________
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 ??? |
4th May 2021, 06:00 | #16 | Link | ||
Registered User
Join Date: Apr 2021
Posts: 128
|
I made you spend enough time already. I was not asking seriously. Your script is infinitely better than wha I could do and works perfectly. Fits perfectly my needs.
You are right, the errors output are present even with Version(). Nothing to do with your script. Your script. It misses lots of good frames when I run it in Avspmod 2.5.1, but everything is ok in Avspmod 2.6.7.5. Deleting the DB and all that was generated by your script was just a way to restart from zero with no elements in the directory that could (remember, i am a total noob) have perturbed the results and made me report wrongly. Quote:
Quote:
Also, the price/quality from certain "professional" services I could see is alas far from what you describe. I also ha e seen some regrets in this direction while reading the The power of Avisynth: restoring old 8mm films. |
||
4th May 2021, 12:45 | #17 | Link | |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,042
|
Quote:
AVSI's should really only contain eg constants [like the colors_rgb.avsi thing], OR, script function definitions [there might be a few additional exceptions]. It should not contain script to eg try to load some clip, and process it. [This is my suspected problem - if it fails with "Version()" then is failing in erroneous script before it even gets to Version() whosit]. [Remove them all, then add then back, maybe one at a time until problem script is revealed with "Version()" script.] [It is possible that there is an *.AVS script in plugins, with code not intended for AVSI script, AVS+ also loads AVS from plugins, assuming that you forgot to rename to AVSI (pre-AVS+ did not auto load AVS)]. You did not have to delete the DB, RT_DBaseAlloc() initializes a new DBase, whether existing or not. The Chosen YPlaneMinMaxDifference(threshold=0.4) builtin runtime filter whotsit, counts all pixels values into an array [each element a population count for the pixel value that is same as element array index]. For YMax, It scans array elements from topmost downwards [one at a time] until sum of population is greater or equal to 0.4%, and ignores any extreme values in array ABOVE that element. If there are a few extreme pixels [less than 0.4%] at top end, then these are ignored, if the highest pop count in array has population of 0.4% or more, then nothing is ignored. Same sort of thing happens at the bottom of array for the YMin thingy. Final result of YPlaneMinMaxDifference(0.4) is the difference between these top and bottom chosen array index's. Above roughly correct, hope that it made some sense. EDIT: YPlaneMinMaxDifference seems to work at least as well as the original detection method with yellow marker, and could be substituted in the original DBase detector [probably also faster]. [I will likely do that].
__________________
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 May 2021 at 13:24. |
|
4th May 2021, 16:18 | #18 | Link | |
Registered User
Join Date: Apr 2021
Posts: 128
|
I tried to empty the plugins dirs. Error window says the same.
But this happens only when I use Avspmod 2.5.1, not 2.6.7.5. As long scripts are working, is it really a "must solve"? I didn't see your new detect version. much faster! and so shorter. Thank you for your explanations. I feel like a cat in an astrophysics conference: I get the very basic principles but not much more. My knowledge is not rich enough and my English neither is. I tried the detector as it is in your post #15, without the DB part. It creates the text list of frames to keep. Then, I can generate the clip with FrameSel.avs. So... I am sorry to ask, it is certainly obvious for most people but what is the DB part for? Or, by saying Quote:
If you have time, would you agree to write some comments into the detector lines so I could understand easier how it works? Thank you, BR |
|
4th May 2021, 16:53 | #19 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,042
|
The DB thing was a detector, the one in post #15 is another detector with a different detection device/method,
both create a frames file. The 2nd [#15] one writes the first frame after BLUE_LED, no matter how many consecutive BLUES or BLACKS there are, the original DB one selects the middle BLACK frame, so if your timings differed, and/or LED or equivalent was not so precise, it would give a better chance of selecting good frame. I was just making a script that might be usable [hackable] in other circumstances, if with a different 'BLUE_LED' indicator, so more flexible, maybe. I'll add comments to final versions.
__________________
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 ??? |
4th May 2021, 17:12 | #20 | Link | |
Registered User
Join Date: Apr 2021
Posts: 128
|
Beautyfull!
In my case, I can adjust the LED start and stop times at the 1/1000 of second scale. So there is no need of possibility choosing the kept frame. But that could be useful for a more analogic system. I made some tries with higher resolutions also. It works perfect after ajusting the size + pos of the detection zone. It's a detail but I also made a modification to name the txt file with a part of the name of the clip to avoid mixing by error. While testing it with several clips, I thought back to your idea of making both scripts into one. This would be very handy as with lots of clips to treat, it represents many manipulations: Quote:
|
|
Tags |
image analysis decimation |
Thread Tools | Search this Thread |
Display Modes | |
|
|