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 |
2nd June 2015, 04:52 | #1 | Link | |
Registered User
Join Date: Mar 2011
Posts: 4,823
|
InpaintFunc.avs - Different result depending on Avisynth version
Has anybody noticed, and/or knows the reason why, InpaintFunc seems to work better when using Avisynth+, as opposed to Avisynth 2.6? At least in DeBlend mode. I'm not sure about the other modes yet.
I'm using Avisynth 2.6 RC3 at the moment but I'm pretty sure when I was using 2.6 RC1 it was exactly the same. Here's three screenshots to demonstrate the difference. All I'm doing is switching the Avisynth version MeGUI uses. The script is exactly the same, with the exception of not loading the ImageSeq plugin for Avisynth 2.6 as it's a built-in function. Quote:
InpaintFunc & Avisynth 2.6 InpaintFunc & Avisynth+ |
|
2nd June 2015, 09:04 | #2 | Link |
Join Date: Mar 2006
Location: Barcelona
Posts: 5,034
|
Post a sample clip so we can reproduce this.
__________________
Groucho's Avisynth Stuff |
2nd June 2015, 10:31 | #3 | Link | |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Perhaps Avisynth+ has had some mod to work around this problem
Quote:
EDIT: The suggested mod to use min/max instead of PixelClip was adopted in Avisynth v2.6, perhaps AVS+ did something different. EDIT: Maybe AVS+ even put back PixelClip, not realizing that it is a bug. EDIT: Where the bug reliant code lives in InPaintFunc (about the script middle) Code:
# crop of the part of the image where is the logo + mask creation # ================================================================ cropped = clp.crop(a,b,c,d) in = (RGB32 == true) ? cropped : cropped.converttoRGB24() in2 = (spd == true) ? in.SelectRangeEvery (every=20, length=speed) : in Masque = imagesource(mask,start=0,end=1).converttoRGB32 Masque = Masque.crop(a,b,c,d).levels(127,1,128,0,255) Masque = Masque.mask(Masque) BlendedMask = Masque.DirtyBlur().levels(0,1,75,0,255) BlendedMask = BlendedMask.mask(BlendedMask) RepairMask = BlendedMask.levels(0,1,255,0,pp) RepairEdge = Masque.DirtyBlur().levels(0,1,255,0,900) RepairEdge = RepairEdge.DirtyBlur().levels(0,1,75,0,pp)
__________________
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; 2nd June 2015 at 11:32. |
|
2nd June 2015, 12:38 | #4 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Here a test script [EDIT: RGB Levels Input on left half, output on right half frame]
Code:
RESULT=0 GSCript(""" for(n=0,255) { current_frame = n # Pretend we are in runtime, ie make AverageLuma work EDIT: should be 0 but dont matter color = (n * 256 + n) * 256 + n C=BlankClip(Length=1,Color=color,width=320) CR=C.Levels(0,1.0,255,0,900) CRV = CR.ShowGreen(pixel_type="YV12").AverageLuma CR=CR.SUBTITLE(String(CRV,"%.1f"),align=5) C=C.SUBTITLE(String(n),align=5) C=StackHorizontal(C,CR) RESULT = (RESULT.IsClip) ? RESULT + C : C } """) RESULT Pixelclip bugged Levels will flip from white(255) to black(0) at input = 164 under eg v2.58 Does AVS+ produce identical output to AVS 26 ? EDIT: InPaintFunc requires something that produces same as bugged Levels(0,1.0,255,0,900) for RGB post processing, eg set all input range 164 and above to 0 before call to Levels(0,1.0,255,0,900) [mt lut stuff Planar only, what else would work ?].
__________________
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 June 2015 at 00:47. |
2nd June 2015, 12:56 | #5 | Link |
Moderator
Join Date: Nov 2001
Location: Netherlands
Posts: 6,364
|
I don't understand your post (#3). Are you saying that levels(0,1,255,0,900) gives different results for AviSynth and AviSynth+?
I also don't understand your comments about PixelClip versus min/max which IanB later changed (in 2011). See http://forum.doom9.org/showthread.ph...ight=PixelClip PixelClip was only applied for RGB clips and only on the end result (not on the input parameters). I see that IanB corrected it to use min/max (in 2011), but i don't see why it should have made a difference except for the end values larger than the upperbound 255+320. edit: did "Array out of bounds territory." mean that it would return 0? edit2: AviSynth+ uses the same code as far as i can see: Code:
map[i] = clamp(int(p+0.5), 0, 255); // and 16,235) when coring=true template<typename T> T clamp(T n, T min, T max) { n = n > max ? max : n; return n < min ? min : n; } Last edited by Wilbert; 2nd June 2015 at 13:14. |
2nd June 2015, 13:08 | #6 | Link | ||
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Wilbert,see the test script in post 4, try on both v2.58 and v2.6 to see difference.
Quote:
Quote:
I'll install AVS+ and see. Will post an edit here in a few moments.
__________________
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 ??? |
||
2nd June 2015, 13:14 | #7 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Just tested, AVS+ produces non bugged results, ie same as Avisynth v2.6 standard, so above PixelClip bug is nothing to do with the OP problem
(But InPaintFunc could still do with a resolution to correct the PixelClip fixed problem).
__________________
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 ??? |
2nd June 2015, 14:52 | #8 | Link |
Registered User
Join Date: Mar 2011
Posts: 4,823
|
Wow, thanks guys, especially StainlessS. You've overwhelmed me a bit. I'll have to re-read the posts and regroup. I might need to get back with some more info as required tomorrow, but for the moment I can at least confirm that levels(0,1,255,0,900) produces the same result using both Avisynth 2.6 and Avisynth+.
I'm working on a sample at the moment. I'll try to upload it tonight but it's getting late, so if it takes too much messing about...... tomorrow. Thanks. |
2nd June 2015, 15:11 | #9 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Here a fix for v2.6 (and AVS+ v2.6) to make the InPaintFunc.avs mask work as in v2.58 prior to Levels bug fix.
Not related to the OP problem but there is a problem with the current InPaintFunc script in v2.6, perhaps only where different post processing mode. Fix, replace Levels(0,1.0,255,0,900) with call to IPF_Mask() [req mask tools] Code:
Function IPF_Mask(clip c) { c.ShowGreen(pixel_type="YV12").Mt_Lut(Mt_Polish("(x >= 164) ? 0 : x")) Return MergeRGB(Last,Last,Last).Levels(0,1.0,255,0,900) } RESULT=0 GSCript(""" for(n=0,255) { current_frame = n # Pretend we are in runtime, ie make AverageLuma work EDIT: should be 0 but dont matter color = (n * 256 + n) * 256 + n C=BlankClip(Length=1,Color=color,width=320) # CR=C.Levels(0,1.0,255,0,900) CR=C.IPF_Mask() CRV = CR.ShowGreen(pixel_type="YV12").AverageLuma CR=CR.SUBTITLE(String(CRV,"%.1f"),align=5) C=C.SUBTITLE(String(n),align=5) C=StackHorizontal(C,CR) RESULT = (RESULT.IsClip) ? RESULT + C : C } """) RESULT EDIT: IPF_Mask returns RGB32 as supplied to Levels by Masque.DirtyBlur in original script Code:
RepairEdge = Masque.DirtyBlur().levels(0,1,255,0,900)
__________________
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 June 2015 at 00:48. |
2nd June 2015, 15:33 | #10 | Link |
Registered User
Join Date: Mar 2011
Posts: 4,823
|
Okay..... a sample turned out to be pretty easy to come up with. It's part of an old AVI from a TV capture.
First, how it looks using my PC. The top pic is MeGUI displaying the script whilst using the portable version of Avisynth+ that comes with it, the bottom pic is MPC-HC displaying the same script via the "installed" Avisynth 2.6.0.6 Edit: I Added an image of the original video without logo removal. To help check I'm not using some odd version of InpaintFunc or AVSInpaint I've included all the relevant files in the zip file below. AVSInpaint.avsi is just the script I have in the Avisynth plugins folder to "autoload" AVSInpaint.dll There's around 40 seconds of the video from an AVI that I split off and remuxed as MKV with the bitmap I'm using for logo removal and the script for encoding etc. I'll be interested to learn if this is a "my PC" problem or if it's typical. I'm using XP if it matters. Cheers. InpaintFunc sample files.zip (I kept it fun-size. It's only about 4MB) Last edited by hello_hello; 2nd June 2015 at 15:57. |
2nd June 2015, 16:03 | #12 | Link | |
Join Date: Mar 2006
Location: Barcelona
Posts: 5,034
|
Quote:
AVS+ r1825 and AVS 2.6 official show the problem as in your second pic. Edit: All official Avisynth versions down to 2.5.7 seem to have the problem.
__________________
Groucho's Avisynth Stuff Last edited by Groucho2004; 2nd June 2015 at 16:31. |
|
2nd June 2015, 16:13 | #13 | Link |
Registered User
Join Date: Mar 2011
Posts: 4,823
|
The Avisynth+ dll in MeGUI's folder shows version 2.6.0.5 via the right click properties menu.
It seems you're right though...... there's only one Avisynth+ update file inside MeGUI's updates folder and it's labelled avisynthplus-r1576.7z, and Avisynth 2.6.0.5 can be found within. |
2nd June 2015, 16:56 | #14 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Hello, Hello_Hello
Tested with v2.58 (will not load ImageSeq under v2.58 so comment out) The v2.6 standard result looks pretty much the same as in v2.58, kinda just what I expected as the AVS+ frames look weird to me for InPaintFunc output, dont know what its doing but AVS+ is the odd one and not v2.6 standard (despite AVS+ looking perhaps better). EDIT: Did not see Groucho's edit.
__________________
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; 2nd June 2015 at 17:01. |
2nd June 2015, 17:10 | #15 | Link |
Join Date: Mar 2006
Location: Barcelona
Posts: 5,034
|
To be more specific: AVS+ r1576 and r1689 show the behaviour as in pic 1. All versions after these and all official AVS versions look like pic 2.
__________________
Groucho's Avisynth Stuff |
2nd June 2015, 17:51 | #16 | Link | |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Hello, Hello_Hello
Suggest you touch up your mask, the crud revealed in v2.6 standard is due to the mask not completely covering the logo as can be seen when Show=true (shimmering logo will not be removed, need to cover halos, compression artifacts etc around logo) ie Code:
InpaintFunc(mask="D:\_HELLO_HELLO\test.bmp", loc="84,4,-480,-276", mode="Deblend", speed=20, ppmode=3, pp=75,Reset=True,Show=True) There is another problem in the script which I gave a fix for but was never incorporated and that is something to do with re-saving the masks (otherwise sometimes not written out to file). Here is the fix post:- http://forum.doom9.org/showthread.ph...09#post1443309 Here both the fixes combined Code:
# crop of the part of the image where is the logo + mask creation # ================================================================ cropped = clp.crop(a,b,c,d) in = (RGB32 == true) ? cropped : cropped.converttoRGB24() in2 = (spd == true) ? in.SelectRangeEvery (every=20, length=speed) : in Masque = imagesource(mask,start=0,end=1).converttoRGB32 Masque = Masque.crop(a,b,c,d).levels(127,1,128,0,255) Masque = Masque.mask(Masque) BlendedMask = Masque.DirtyBlur().levels(0,1,75,0,255) BlendedMask = BlendedMask.mask(BlendedMask) RepairMask = BlendedMask.levels(0,1,255,0,pp) #RepairEdge = Masque.DirtyBlur().levels(0,1,255,0,900) # ssS fix (removed) RepairEdge = Masque.DirtyBlur().IPF_Mask() # ssS fix (added) RepairEdge = RepairEdge.DirtyBlur().levels(0,1,75,0,pp) # check for an existing computed mask. If it doesn't exist or if reset = true --> computation # =========================================================================================== ID = mask + "InpaintFunc" + string(a) + string(b) + string(c) + string(d) + string(speed) Logo = (reset == true) ? eval(""" in2.analyzelogo(Masque).trim(0,-1).converttoRGB32 imagewriter(ID,0,1,"ebmp") """) : eval(""" try {imagesource(ID + "%06d.ebmp",0,0)} catch (dummy) { show=true # ssS fix (added) in2.analyzelogo(Masque).trim(0,-1).converttoRGB32 imagewriter(ID,0,1,"ebmp") }""") Code:
Function IPF_Mask(clip c) { # ssS fix (added), Correction for fixed Levels bug. Returns RGB32 c.ShowGreen(pixel_type="YV12").Mt_Lut(Mt_Polish("(x >= 164) ? 0 : x")) Return MergeRGB(Last,Last,Last).Levels(0,1.0,255,0,900) } EDIT: You can remove the Reset=True arg when Show=True fix is added to InPaintFunc script. With Show=True fix, if bmp is bad/not existent will auto show the masks (forcing bmp to be written), just close this and re-open, 2nd time will use the newly written bmp. (A better solution than Show=True would use v2.6 Echo somewhere). By the way, I think the script makes global changes to clip (not just logo area) might want to chop out area of interest and process just that and omit two colorspace conversions to boot (for most of the frame). EDIT: posted by Wilbert Quote:
after levels it would be too late to do anything, Levels(0,1.0,255,0,900) with input 164 must result in 255+320 (have not checked this), I got the 164 from the bugged behaviour of the posted GScript script under v2.58 (where levels uses PixelClip rather than min/max). End result is that IPF_Mask() produces the same as v2.58 Levels using PixelClip which InPaintFunc relies upon to produce 'hollowed out' edge masks. I think that it does not matter at all in the posted Hello_Hello example, but only because the mask is too thin to 'hollow out', it is also too thin (needs dilation) to produce a good de-logo'd 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 ??? Last edited by StainlessS; 3rd June 2015 at 07:21. |
|
3rd June 2015, 10:46 | #17 | Link |
Registered User
Join Date: Mar 2011
Posts: 4,823
|
Firstly,
StainlessS.... you mentioned touching up the mask, but I'm not sure what to touch up. What I'm seeing when I open the mask bitmap in Irfanview and increase it to around 8x it's original size is this: Which looks nothing like the mask when show=true is being used: Given the mask is a bitmap, could it be some sort of subsampling or resizing issue when it's converted? Although no...... it looks the same when MeGUI is using Avisynth+ and show=true is included in the script. When using show=true should the top right picture be an accurate representation of the end result? Because when using Avisynth 2.6, frame number 386 looks like this: But the actual script output is this: StainlessS, All of the above was after applying your suggested changes to the script but I gather they weren't expected to fix the problem. I thought I'd mention it though. I did wonder if Avisynth+ 2.6.0.5 being the "odd one out", the output from the other Avisynth versions would be what's "expected" while the Avisynth+ output is not, even though it tends to remove more logo. Having not used InpaintFunc until recently, but only with Avisynth+, I'd assumed it's output was normal until I noticed the difference. Could someone tell me....... Avisynth+ and Avisynth 2.6 tend to be opposite ends of the scale to some extend. Avisynth+ removes the logo completely but the surrounding area (in this case a rough square slightly larger than the logo) tends to look "processed". Mostly you need to view the video in motion to see it, but it varies from almost impossible to detect to being not much better than typical "ugly blob" logo removal. On the other hand there's generally not the same "processed block" when using Avisynth 2.6, but at the same time it doesn't remove all of the logo. Which of those would be considered more "typical" in DeBlend mode? That's been the extent of my further experimenting to date. I haven't discovered anything at all, although maybe provided some useful information?..... but whether the Avisynth 2.6 output should be considered correct or if it's the Avisynth+ output that's right, is it likely we'll ever discover why they're different? Cheers. Last edited by hello_hello; 3rd June 2015 at 11:22. |
3rd June 2015, 11:15 | #18 | Link |
Registered User
Join Date: Mar 2011
Posts: 4,823
|
I tried again with a new mask. Something "overdone" compared to what I previously assumed would be needed. The Avisynth result did improve and only the ghost of logos past remained, but it's obvious due to the visible processed "square" area when using Avisynth+ that somehow, in some way, it must mean there's more/different processing going on when Avisynth+ 2.6.0.5 is used. I wonder why?
Avisynth 2.6.0.6 Avisynth+ 2.6.0.5 Now.... how to achieve an output that's a compromise between those two..... Oh.... I did notice a little difference between the behaviour of the original script and the StainlessS modded version. When opening a script with the "original" InpaintFunc included and no ebmp file has been created, there's a waiting period and the script eventually opens outputting the de-logoed video. The StainlessS version opens as though show=true was included in the script and to see the de-logoed output it needs to be previewed a second time. Was that intentional StainlessS? Thanks! Last edited by hello_hello; 3rd June 2015 at 11:24. |
3rd June 2015, 12:41 | #19 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Mobile currently.
Yes intentional and mentioned in edit. I think the avs+ result is due to it eg not using the mask during post process repair (or something like that, is may be doing temporal soften on whole rectangular area, this might be fault in overlay with mask or similar in avs +) Edit: the mask in top middle will show shimmering where the mask is too thin, due to eg compression artefacts that are bigger than the logo but affected by it.
__________________
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 June 2015 at 12:51. |
3rd June 2015, 14:33 | #20 | Link | ||
Registered User
Join Date: Mar 2011
Posts: 4,823
|
Sorry I missed that.
Is it safe to change "show" to false here? I did so without any apparent side effects so far. Quote:
I initially thought I'd end up with a bunch of "show=true" encodes but for reasons I don't understand that doesn't happen, however somewhere along the way MeGUI still sees the resolution of the script with show=true active and thinks it needs to compensate for a change in resolution by getting all anamorphic..... or something like that..... and the upshot of it is the encoded version comes out looking something like this: With show=false it's business as usual. Quote:
Thanks for all the help everyone. I've got a better idea as to what's going on now. PS StainlessS, Could I get you to assume I'm Avisynth stupid and elaborate on what you meant by the following. Being Avisynth stupid I'm not sure I understand what you meant. Do you mean to somehow do this when encoding and removing the logo? Thanks. "By the way, I think the script makes global changes to clip (not just logo area) might want to chop out area of interest and process just that and omit two colorspace conversions to boot (for most of the frame)." Last edited by hello_hello; 3rd June 2015 at 14:37. |
||
Thread Tools | Search this Thread |
Display Modes | |
|
|