Advertisement
Guest User

Untitled

a guest
Jul 28th, 2013
309
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.61 KB | None | 0 0
  1. #finesharp.py - finesharp module for VapourSynth
  2. #original author : Didee (http://forum.doom9.org/showthread.php?t=166082)
  3.  
  4. # requirement: RemoveGrain.dll, Repair.dll
  5. #              VapourSynth r19 or later
  6.  
  7. import vapoursynth as vs
  8.  
  9. class InvalidArgument(Exception):
  10.     def __init__(self, value):
  11.         self.value = value
  12.     def __str__(self):
  13.         return repr(self.value)
  14.  
  15. def spline(x, coordinates):
  16.     def get_matrix(px, py, l):
  17.         matrix = []
  18.         matrix.append([(i == 0) * 1.0 for i in range(l + 1)])
  19.         for i in range(1, l - 1):
  20.             p = [0 for t in range(l + 1)]
  21.             p[i - 1] = px[i] - px[i - 1]
  22.             p[i] = 2 * (px[i + 1] - px[i - 1])
  23.             p[i + 1] = px[i + 1] - px[i]
  24.             p[l] = 6 * (((py[i + 1] - py[i]) / p[i + 1]) - (py[i] - py[i - 1]) / p[i - 1])
  25.             matrix.append(p)
  26.         matrix.append([(i == l - 1) * 1.0 for i in range(l + 1)])
  27.         return matrix
  28.  
  29.     def equation(matrix, dim):
  30.         for i in range(dim):
  31.             num = matrix[i][i]
  32.             for j in range(dim + 1):
  33.                 matrix[i][j] /= num
  34.             for j in range(dim):
  35.                 if i != j:
  36.                     a = matrix[j][i]
  37.                     for k in range(i, dim + 1):
  38.                         matrix[j][k] -= a * matrix[i][k]
  39.  
  40.     if not isinstance(coordinates, dict):
  41.         raise TypeError('coordinates must be a dict')
  42.  
  43.     length = len(coordinates)
  44.     if length < 3:
  45.         raise InvalidArgument('coordinates require at least three pairs')
  46.  
  47.     px = [key for key in coordinates.keys()]
  48.     py = [val for val in coordinates.values()]
  49.     matrix = get_matrix(px, py, length)
  50.     equation(matrix, length)
  51.     for i in range(length + 1):
  52.         if x >= px[i] and x <= px[i + 1]:
  53.             break
  54.     j = i + 1
  55.     h = px[j] - px[i]
  56.     s = matrix[j][length] * (x - px[i]) ** 3
  57.     s -= matrix[i][length] * (x - px[j]) ** 3
  58.     s /= 6 * h
  59.     s += (py[j] / h - h * matrix[j][length] / 6) * (x - px[i])
  60.     s -= (py[i] / h - h * matrix[i][length] / 6) * (x - px[j])
  61.     return s
  62.  
  63.  
  64. def clamp(minimum, x, maximum):
  65.     return int(max(minimum, min(round(x), maximum)))
  66.  
  67.  
  68. class FineSharp(object):
  69.     def __init__(self):
  70.         self.core = vs.get_core()
  71.         self.rgrain = self.core.avs.RemoveGrain
  72.         self.repair = self.core.avs.Repair
  73.         self.std = self.core.std
  74.         self.point = self.core.resize.Point
  75.         self.max = 255
  76.         self.mid = 128
  77.  
  78.     def mt_adddiff(self, c1, c2, planes=[0]):
  79.         expr = ('x y + {mid} -').format(mid=self.mid)
  80.         expr = [(i in planes) * expr for i in range(3)]
  81.         return self.std.Expr([c1, c2], expr)
  82.  
  83.     def mt_makediff(self, c1, c2, planes=[0]):
  84.         expr = ('x y - {mid} +').format(mid=self.mid)
  85.         expr = [(i in planes) * expr for i in range(3)]
  86.         return self.std.Expr([c1, c2], expr)
  87.  
  88.     def sharpen(self, clip, mode=1, sstr=2.0, cstr=None, xstr=0.19, lstr=1.49,
  89.                  pstr=1.272, ldmp=None):
  90.  
  91.         if clip.format.color_family != vs.YUV or clip.format.bits_per_sample != 8:
  92.             raise InvalidArgument('clip is not 8bit YUV.')
  93.  
  94.         mode = int(mode)
  95.         if abs(mode) > 3 or mode == 0:
  96.             raise InvalidArgument('mode must be 1, 2, 3, -1, -2 or -3.')
  97.  
  98.         sstr = float(sstr)
  99.         if sstr < 0.0:
  100.             raise InvalidArgument('sstr must be larger than zero.')
  101.  
  102.         if cstr is None:
  103.             cstr = spline(sstr, {0:0, 0.5:0.1, 1:0.6, 2:0.9, 2.5:1, 3:1.09,
  104.                                  3.5:1.15, 4:1.19, 8:1.249, 255:1.5})
  105.             if mode > 0:
  106.                 cstr **= 0.8
  107.         cstr = float(cstr)
  108.  
  109.         xstr = float(xstr)
  110.         if xstr < 0.0:
  111.             raise InvalidArgument('xstr must be larger than zero.')
  112.  
  113.         lstr = float(lstr)
  114.  
  115.         pstr = float(pstr)
  116.  
  117.         if ldmp is None:
  118.             ldmp = sstr + 0.1
  119.         ldmp = float(ldmp)
  120.  
  121.         rg = 20 - (mode > 0) * 9
  122.  
  123.         if sstr < 0.01 and cstr < 0.01 and xstr < 0.01:
  124.             return clip
  125.  
  126.         orig = None
  127.         if clip.format.id != vs.YUV420P8:
  128.             orig = clip
  129.             clip = self.point(clip, format=vs.YUV420P8)
  130.  
  131.         if abs(mode) == 1:
  132.             c2 = self.rgrain(self.rgrain(clip, 11, -1), 4, -1)
  133.         else:
  134.             c2 = self.rgrain(self.rgrain(clip, 4, -1), 11, -1)
  135.         if abs(mode) == 3:
  136.             c2 = self.rgrain(c2, 4, -1)
  137.  
  138.         expr = lambda x, y:(((((abs(x - y) / lstr) ** (1 / pstr)) * sstr) *
  139.                             ((x - y) / (abs(x - y) + 0.001))) *
  140.                             (((x - y) ** 2) / (((x - y) ** 2) + ldmp)) + 128)
  141.         diff = self.std.Lut2([clip, c2], function=expr, planes=0)
  142.  
  143.         shrp = clip
  144.         if sstr >= 0.01:
  145.             shrp = self.mt_adddiff(shrp, diff)
  146.            
  147.         if cstr >= 0.01:
  148.             diff = self.std.Lut(diff, planes=0,
  149.                                 function=lambda x: (x - self.mid) * cstr + self.mid)
  150.             diff = self.rgrain(diff, rg, -1)
  151.             shrp = self.mt_makediff(shrp, diff)
  152.            
  153.         if xstr >= 0.01:
  154.             xyshrp = self.std.Lut2([shrp, self.rgrain(shrp, 20, -1)], planes=0,
  155.                                    function=lambda x, y: x + (x - y) * 9.9)
  156.             rpshrp = self.repair(xyshrp, shrp, 12, 0)
  157.             shrp = self.std.Merge([rpshrp, shrp], [1 - xstr, 1.0, 1.0])
  158.  
  159.         if orig is not None:
  160.             shrp = self.std.ShufflePlanes([shrp, orig], [0, 1, 2], vs.YUV)
  161.  
  162.         return shrp
  163.  
  164.     def usage(self):
  165.         usage = '''
  166.    Small and relatively fast realtime-sharpening function, for 1080p,
  167.    or after scaling 720p -> 1080p during playback
  168.    (to make 720p look more like being 1080p)
  169.    It's a generic sharpener. Only for good quality sources!
  170.    (If the source is crap, FineSharp will happily sharpen the crap.) ;)
  171.    Noise/grain will be enhanced, too. The method is GENERIC.
  172.  
  173.    Modus operandi: A basic nonlinear sharpening method is performed,
  174.    then the *blurred* sharp-difference gets subtracted again.
  175.  
  176.  
  177.    sharpen(clip, mode=1, sstr=2.0, cstr=None, xstr=0.19, lstr=1.49,
  178.            pstr=1.272, ldmp=None)
  179.        mode: 1 to 3, weakest to strongest. When negative -1 to -3,
  180.              a broader kernel for equalisation is used.
  181.        sstr: strength of sharpening, 0.0 up to ??
  182.        cstr: strength of equalisation, 0.0 to ? 2.0 ?
  183.              (recomm. 0.5 to 1.25, default AUTO)
  184.        xstr: strength of XSharpen-style final sharpening, 0.0 to 1.0
  185.              (but, better don't go beyond 0.249 ...)
  186.        lstr: modifier for non-linear sharpening
  187.        pstr: exponent for non-linear sharpening
  188.        ldmp: "low damp", to not overenhance very small differences
  189.              (noise coming out of flat areas, default sstr+1)
  190. '''
  191.         return usage
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement