SHOW:
|
|
- or go back to the newest paste.
| 1 | # http://avisynth.nl/index.php/FineDehalo | |
| 2 | - | # 1.1 mod |
| 2 | + | # 1.1 mod2 |
| 3 | # | |
| 4 | # This program is free software. It comes without any warranty, to | |
| 5 | # the extent permitted by applicable law. You can redistribute it | |
| 6 | # and/or modify it under the terms of the Do What The Fuck You Want | |
| 7 | # To Public License, Version 2, as published by Sam Hocevar. See | |
| 8 | # http://sam.zoy.org/wtfpl/COPYING for more details. | |
| 9 | ||
| 10 | Function FineDehalo (clip src, float "rx", float "ry", int "thmi", int "thma", int "thlimi", int "thlima", float "darkstr", float "brightstr", int "showmask", float "contra", bool "excl", float "edgeproc", string "exdehalo") | |
| 11 | {
| |
| 12 | rx = Default (rx, 2) | |
| 13 | ry = Default (ry, rx) | |
| 14 | thmi = Default (thmi, 80) | |
| 15 | thma = Default (thma, 128) | |
| 16 | thlimi = Default (thlimi, 50) | |
| 17 | thlima = Default (thlima, 100) | |
| 18 | darkstr = Default (darkstr, 1.0) | |
| 19 | brightstr = Default (brightstr, 1.0) | |
| 20 | showmask = Default (showmask, 0) | |
| 21 | contra = Default (contra, 0.0) | |
| 22 | excl = Default (excl, true) | |
| 23 | edgeproc = Default (edgeproc, 0.0) | |
| 24 | ||
| 25 | rx_i = Round (rx) | |
| 26 | ry_i = Round (ry) | |
| 27 | ||
| 28 | src | |
| 29 | ||
| 30 | ||
| 31 | ### Dehaloing ### | |
| 32 | ||
| 33 | dehaloed = defined(exdehalo) ? eval("last." + exdehalo) : DeHalo_alpha (rx=rx, ry=ry, darkstr=darkstr, brightstr=brightstr)
| |
| 34 | ||
| 35 | # Contrasharpening | |
| 36 | dehaloed = (contra > 0) | |
| 37 | \ ? dehaloed.FineDehalo_contrasharp (src, contra) | |
| 38 | \ : dehaloed | |
| 39 | ||
| 40 | ||
| 41 | ### Main edges ### | |
| 42 | ||
| 43 | # Basic edge detection, thresholding will be applied later. | |
| 44 | edges = mt_edge (mode="prewitt", thY1=0, thY2=255) | |
| 45 | ||
| 46 | # Keeps only the sharpest edges (line edges) | |
| 47 | strong = edges.mt_lut (expr="x "+String(thmi)+" - "+String(thma-thmi)+" / 255 *") | |
| 48 | ||
| 49 | # Extends them to include the potential halos | |
| 50 | large = strong.mt_expand_multi (sw=rx_i, sh=ry_i) | |
| 51 | ||
| 52 | ||
| 53 | ### Exclusion zones ### | |
| 54 | ||
| 55 | # When two edges are close from each other (both edges of a single | |
| 56 | # line or multiple parallel color bands), the halo removal | |
| 57 | # oversmoothes them or makes seriously bleed the bands, producing | |
| 58 | # annoying artifacts. Therefore we have to produce a mask to exclude | |
| 59 | # these zones from the halo removal. | |
| 60 | ||
| 61 | # Includes more edges than previously, but ignores simple details | |
| 62 | light = edges.mt_lut (expr="x "+String(thlimi)+" - "+String(thlima-thlimi)+" / 255 *") | |
| 63 | ||
| 64 | # To build the exclusion zone, we make grow the edge mask, then shrink | |
| 65 | # it to its original shape. During the growing stage, close adjacent | |
| 66 | # edge masks will join and merge, forming a solid area, which will | |
| 67 | # remain solid even after the shrinking stage. | |
| 68 | ||
| 69 | # Mask growing | |
| 70 | shrink = light.mt_expand_multi (sw=rx_i, sh=ry_i, mode="ellipse") | |
| 71 | ||
| 72 | # At this point, because the mask was made of a shades of grey, we may | |
| 73 | # end up with large areas of dark grey after shrinking. To avoid this, | |
| 74 | # we amplify and saturate the mask here (actually we could even | |
| 75 | # binarize it). | |
| 76 | shrink = shrink.mt_lut ("x 4 *")
| |
| 77 | ||
| 78 | # Mask shrinking | |
| 79 | shrink = shrink.mt_inpand_multi (sw=rx_i, sh=ry_i, mode="ellipse") | |
| 80 | ||
| 81 | # This mask is almost binary, which will produce distinct | |
| 82 | # discontinuities once applied. Then we have to smooth it. | |
| 83 | shrink = shrink.RemoveGrain (20, -1) | |
| 84 | shrink = shrink.RemoveGrain (20, -1) | |
| 85 | ||
| 86 | ||
| 87 | ### Final mask building ### | |
| 88 | ||
| 89 | # Previous mask may be a bit weak on the pure edge side, so we ensure | |
| 90 | # that the main edges are really excluded. We do not want them to be | |
| 91 | # smoothed by the halo removal. | |
| 92 | shr_med = (excl) ? mt_logic (strong, shrink, mode="max") : strong | |
| 93 | ||
| 94 | # Substracts masks and amplifies the difference to be sure we get 255 | |
| 95 | # on the areas to be processed. | |
| 96 | outside = mt_lutxy (large, shr_med, "x y - 2 *") | |
| 97 | ||
| 98 | # If edge processing is required, adds the edgemask | |
| 99 | ep_str = "x y "+String(edgeproc * 0.66)+" * +" | |
| 100 | outside = (edgeproc > 0) ? mt_lutxy (outside, strong, ep_str) : outside | |
| 101 | ||
| 102 | # Smooth again and amplify to grow the mask a bit, otherwise the halo | |
| 103 | # parts sticking to the edges could be missed. | |
| 104 | outside = outside.RemoveGrain (20, -1).mt_lut ("x 2 *")
| |
| 105 | ||
| 106 | ### Masking ### | |
| 107 | ||
| 108 | mt_merge (last, dehaloed, outside, y=3, u=2, v=2) | |
| 109 | ||
| 110 | (showmask == 1) ? outside.GreyScale () | |
| 111 | \ : (showmask == 2) ? shrink.GreyScale () | |
| 112 | \ : (showmask == 3) ? edges.GreyScale () | |
| 113 | \ : (showmask == 4) ? strong.GreyScale () | |
| 114 | \ : last | |
| 115 | } | |
| 116 | ||
| 117 | # level == 1.0 : normal contrasharp | |
| 118 | Function FineDehalo_contrasharp (clip dehaloed, clip src, float level) | |
| 119 | {
| |
| 120 | bb = dehaloed.RemoveGrain (11, -1) | |
| 121 | bb2 = bb.Repair (bb.Repair (bb.Medianblur (2, -256, -256), 1), 1) | |
| 122 | xd = mt_makediff (bb, bb2) | |
| 123 | xd = xd.mt_lut ("x 128 - 2.49 * "+String(level)+" * 128 +")
| |
| 124 | xdd = mt_lutxy ( | |
| 125 | \ xd, | |
| 126 | \ mt_makediff (src, dehaloed), | |
| 127 | \ "x 128 - y 128 - * 0 < 128 x 128 - abs y 128 - abs < x y ? ?" | |
| 128 | \ ) | |
| 129 | ||
| 130 | dehaloed.mt_adddiff (xdd, y=3, u=2, v=2) | |
| 131 | } | |
| 132 | ||
| 133 | ||
| 134 | ||
| 135 | ||
| 136 | # Try to remove 2nd order halos. | |
| 137 | Function FineDehalo2 (clip src, string "hconv", string "vconv", int "showmask") | |
| 138 | {
| |
| 139 | hconv = Default (hconv, "-1 -2 0 0 40 0 0 -2 -1") | |
| 140 | vconv = Default (vconv, "-2 -1 0 0 40 0 0 -1 -2") | |
| 141 | showmask = Default (showmask, 0) | |
| 142 | ||
| 143 | src | |
| 144 | fix_h = mt_convolution (horizontal="1", vertical=vconv, y=3, u=2, v=2) | |
| 145 | fix_v = mt_convolution (horizontal=hconv, vertical="1", y=3, u=2, v=2) | |
| 146 | edges_h = mt_edge (mode="1 2 1 0 0 0 -1 -2 -1", thY1=0, thY2=255) | |
| 147 | edges_v = mt_edge (mode="1 0 -1 2 0 -2 1 0 -1", thY1=0, thY2=255) | |
| 148 | mask_h = edges_h #.mt_lut (expr="x 2 *") | |
| 149 | mask_v = edges_v #.mt_lut (expr="x 2 *") | |
| 150 | temp_h = mt_lutxy (mask_h, mask_v, expr="x 3 * y -") | |
| 151 | temp_v = mt_lutxy (mask_v, mask_h, expr="x 3 * y -") | |
| 152 | mask_h = temp_h | |
| 153 | mask_v = temp_v | |
| 154 | ||
| 155 | mask_h = mask_h.FineDehalo2_grow_mask ("vertical")
| |
| 156 | mask_v = mask_v.FineDehalo2_grow_mask ("horizontal")
| |
| 157 | ||
| 158 | src | |
| 159 | mt_merge (last, fix_h, mask_h, y=3, u=2, v=2) | |
| 160 | mt_merge (last, fix_v, mask_v, y=3, u=2, v=2) | |
| 161 | ||
| 162 | (showmask == 1) ? mt_logic (mask_h, mask_v, mode="max").GreyScale () | |
| 163 | \ : last | |
| 164 | } | |
| 165 | ||
| 166 | Function FineDehalo2_grow_mask (clip mask, string mode) | |
| 167 | {
| |
| 168 | Assert ((mode == "horizontal" || mode == "vertical"), "Wrong mode") | |
| 169 | ||
| 170 | mask | |
| 171 | mt_expand (mode=mode).mt_inpand (mode=mode) | |
| 172 | mask_1 = mt_expand (mode=mode) | |
| 173 | mask_2 = mask_1.mt_expand (mode=mode).mt_expand (mode=mode) | |
| 174 | mt_lutxy (mask_2, mask_1, expr="x y -") | |
| 175 | RemoveGrain (12, -1).mt_lut (expr="x 1.8 *") | |
| 176 | } | |
| 177 | ||
| 178 | Function FineDehaloanalog (clip src) | |
| 179 | {
| |
| 180 | src | |
| 181 | FineDehalo(exdehalo="""DeHaloHmod(2,exdehalo="DeHalo_alpha_mt(darkstr=0.2,brightstr=0.8).VHSHaloremover(4,3,200,100,0.5)",thr=255,analog=true)""") | |
| 182 | } |