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. Domains: forum.doom9.org / forum.doom9.net / forum.doom9.se |
|
|
#1 | Link |
|
Registered User
Join Date: Oct 2001
Posts: 106
|
measure luma variance within block (e.g. 8x8) of pixels?
I would like to more finely and more selectively add dither/grain to flat "blocks" in my source clip to avoid banding and noticeable macro blocks when encoding with x264 (note: for a great example of this, look at 007 Skyfall at 46:28 as Bond is opening the reflective door in a dark scene. Even a low crf like 18 or less looks like crap when encoding this scene).
Right now I'm using the dither plugin, which works wonders using Dither_add_grain16. However, I'm going with the shotgun approach and running it for all my movie encodes since I can't possibly check each and every result to ensure there is no banding, but this adds unnecessary complexity (slower encodes and larger files) to all scenes even though it's the exception to the rule that a scene exists like the Bond one I described above. That's why I'm wondering if there's a way to measuring the amount of luma variation that exists within each block of pixels of some size (let's say 8x8) so that I can construct a mask that only adds dither to those blocks which have very little luma variation (and therefore little complexity). It looks as though there was a plugin called Blockbuster which did something similar, though I can't seem to get the .dll I found to work with any of the newer Avisynth builds. Thanks for any suggestions |
|
|
|
|
|
#2 | Link |
|
Registered User
Join Date: Mar 2014
Posts: 308
|
If you want to measure the amount of "variation" for each block of pixels, you could easily make something out of mt_inpand_multi/mt_expand_multi and mt_makediff.
However, for the problem you're facing, a somewhat commonly used solution is to just use a luma mask to add more noise to dark areas and less to bright areas, since that's where banding is most visible. You could also try raising aq-strength or using aq-mode 3 in x264. If you're not already using 10-bit encoding, try that too if your use case supports that, though this would slow encodes down significantly. |
|
|
|
|
|
#3 | Link |
|
Registered User
Join Date: Jan 2010
Posts: 270
|
The easiest somewhat correct "amount of variation for each block" you can get is using STD for each pixel and applying dctfilter to it (adjust the radius of std calculation area for possibly better results).
Code:
mt_luts(last, "std", mt_square(1), "y").mt_lut("x 15 *")
dctfilter(1,0,0,0,0,0,0,0).grayscale()
Code:
mt_edge("min/max", 0, 255, 0, 255).mt_lut("x 5 *")
dctfilter(1,0,0,0,0,0,0,0).grayscale()
From my experience what colors suggested works okay. You can combine luma mask with reversed edge mask of course to avoid adding noise to dark lines if you have those, but it's rarely needed. Last edited by TurboPascal7; 6th August 2014 at 12:23. |
|
|
|
|
|
#5 | Link | |
|
Registered User
Join Date: Oct 2001
Posts: 106
|
Quote:
Code:
mt_edge(mode="prewitt",thy1=0,thy2=32).mt_invert() After I wrote my original post, I realized I could use the same edge mask I was using but resize it down a great deal and then resize back up to create the blocking I was looking for. That, combined with a low threshold for mt_binarize does a pretty good job of approximating what I was after by targeting larger, flat portions with dither. I found these settings to provide a great compromise between file size and quality. I also do use --aq-mode=3 which is found in kMod or tMod builds of x264, which colour also suggested. Code:
vGrainMask=mt_edge(mode="prewitt",thy1=0,thy2=32).BilinearResize((width/16)*2,(height/16)*2).BilinearResize(width,height).grayscale().mt_binarize(threshold=3, upper=true) Dither_convert_8_to_16() vGrain=Dither_add_grain16(var=0.6,uvar=0,lsb_in=true) Dither_merge16_8(vGrain, vGrainMask, u=2, v=2) DitherPost(mode=3) Last edited by bennynihon; 7th August 2014 at 17:08. |
|
|
|
|
|
|
#6 | Link |
|
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,498
|
@JohnMeyer, the stuff I think you may be referring to was AvgLumaDif by Forensic (I coded it),
I also asked if it could be use for blocking detection but Forensic thought not. I think you should find it via my sig, I never did add it the RT_stats, (which is a bit oversized as it is). this lot should bring back memories: http://forum.doom9.org/search.php?searchid=6865543
__________________
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 ??? |
|
|
|
|
|
#7 | Link |
|
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,498
|
Looks like I only posted a copy to Forensic, thought I had made public, anyway, here tis, but not I think want you want.
http://www.mediafire.com/download/1b...AvgLumaDif.zip
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 7th August 2014 at 02:07. |
|
|
|
|
|
#8 | Link | |
|
Registered User
Join Date: Oct 2001
Posts: 106
|
Quote:
Ultimately I wanted to archive my Blu-ray collection and encode them at an acceptable quality without banding. But since I couldn't possible manually determine which movies or scenes needed added grain to avoid banding during encoding, I was after an approach that works well for every case. And blindly adding grain to all movies without consideration to the amount already in the source was unacceptable, since that will result in unnecessarily large encoded files. This appears to do the trick. Last edited by bennynihon; 7th August 2014 at 17:08. |
|
|
|
|
![]() |
|
|