Пример #1
0
    def make_window(self):
        self.update_config()
        x_tile = self.config['xtile']
        y_tile = self.config['ytile']
        x_off = self.config['xoff']
        y_off = self.config['yoff']
        fade = self.config['fade']
        # adjust config to suit actual window
        in_data = self.in_frame.as_numpy(dtype=numpy.float32)
        if in_data.shape[1] != y_tile:
            y_off = y_off * in_data.shape[1] // y_tile
            y_tile = in_data.shape[1]
        if in_data.shape[2] != x_tile:
            x_off = x_off * in_data.shape[2] // x_tile
            x_tile = in_data.shape[2]
        out_frame = Frame()
        out_frame.initialise(self.in_frame)
        audit = out_frame.metadata.get('audit')
        audit += 'data = InverseWindow(data)\n'
        audit += '    size: %d x %d, offset: %d x %d\n' % (
            y_tile, x_tile, y_off, x_off)
        audit += '    fade: %s\n' % fade
        out_frame.metadata.set('audit', audit)

        result = numpy.empty(in_data.shape, dtype=numpy.float32)
        x_overlap = x_tile - x_off
        y_overlap = y_tile - y_off
        for y in range(y_tile):
            y0 = y
            while y0 >= y_off:
                y0 -= y_off
            for x in range(x_tile):
                x0 = x
                while x0 >= x_off:
                    x0 -= x_off
                # get window value of this and neighbouring tiles
                centre = in_data[0, y, x, 0]
                neighbours = []
                for j in range(y0, y_tile, y_off):
                    for i in range(x0, x_tile, x_off):
                        if j == y and i == x:
                            continue
                        neighbours.append(in_data[0, j, i, 0])
                if not neighbours:
                    result[0, y, x, 0] = 1.0 / max(centre, 0.000001)
                elif fade == 'minsnr':
                    result[0, y, x, 0] = centre / (
                        (centre ** 2) + sum(map(lambda x: x ** 2, neighbours)))
                elif fade == 'linear':
                    result[0, y, x, 0] = 1.0 / (centre + sum(neighbours))
                else:
                    biggest = max(neighbours)
                    if centre > biggest:
                        result[0, y, x, 0] = 1.0 / max(centre, 0.000001)
                    elif centre < biggest:
                        result[0, y, x, 0] = 0.0
                    else:
                        result[0, y, x, 0] = 0.5 / max(centre, 0.000001)
        out_frame.data = result
        self.send('inv_window', out_frame)
Пример #2
0
 def __init__(self, config={}, **kwds):
     super(ModulateUV, self).__init__(config=config, **kwds)
     cell = numpy.empty([4, 8, 4, 2], dtype=numpy.float32)
     # phase is in "quarter cycles"
     phase = 2.5     # integer part of start is arbitrary
     v_axis_switch = 1
     for z in range(cell.shape[0]):
         for f in range(2):
             for y in range(f, cell.shape[1], 2):
                 phase = phase % 4
                 for x in range(cell.shape[2]):
                     cell[z, y, x, 0] = math.sin(phase * math.pi / 2.0)
                     cell[z, y, x, 1] = math.cos(phase * math.pi / 2.0) * v_axis_switch
                     # 4 fsc sampling, so fsc advances by 1/4 cycle per sample
                     phase += 1
                 # "quarter line offset" retards by 1/4 cycle per field line
                 phase -= 1
                 v_axis_switch *= -1
             # 313 lines in 1st field, 312 lines in 2nd
             if f == 0:
                 remainder = 313 - (cell.shape[1] // 2)
             else:
                 remainder = 312 - (cell.shape[1] // 2)
             phase -= remainder
             if remainder % 2:
                 v_axis_switch *= -1
             # "25 Hz offset" adds 1/2 cycle per field period
             phase += 2
     cell_frame = Frame()
     cell_frame.data = cell
     cell_frame.type = 'cell'
     audit = cell_frame.metadata.get('audit')
     audit += 'data = PAL subcarrier modulation cell\n'
     cell_frame.metadata.set('audit', audit)
     self.cell(cell_frame)
Пример #3
0
def Window2D(name, x_tile, y_tile, sym, function_1D, x_params={}, y_params={}):
    if x_tile == 1:
        x_win = numpy.array([1.0], dtype=numpy.float32)
    elif sym:
        x_win = function_1D(x_tile, **x_params)
    else:
        x_win = function_1D(x_tile + 1, **x_params)[:-1]
    if y_tile == 1:
        y_win = numpy.array([1.0], dtype=numpy.float32)
    elif sym:
        y_win = function_1D(y_tile, **y_params)
    else:
        y_win = function_1D(y_tile + 1, **y_params)[:-1]
    x_win = x_win.reshape((1, 1, -1, 1))
    y_win = y_win.reshape((1, -1, 1, 1))
    out_frame = Frame()
    out_frame.data = x_win * y_win
    out_frame.type = 'win'
    audit = out_frame.metadata.get('audit')
    audit += 'data = %sWindow()\n' % name
    audit += '    size: %d x %d\n' % (y_tile, x_tile)
    audit += '    symmetric: %s\n' % (str(sym))
    extras = []
    for key, value in x_params.items():
        extras.append('%s: %s' % (key, str(value)))
    if extras:
        audit += '    horiz params: %s\n' % (', '.join(extras))
    extras = []
    for key, value in y_params.items():
        extras.append('%s: %s' % (key, str(value)))
    if extras:
        audit += '    vert params: %s\n' % (', '.join(extras))
    out_frame.metadata.set('audit', audit)
    return out_frame
Пример #4
0
def HHIPreFilter(config={}):
    """HHI pre-interlace filter.

    A widely used prefilter to prevent line twitter when converting
    sequential images to interlace.

    Coefficients taken from: 'Specification of a Generic Format
    Converter', S. Pigeon, L. Vandendorpe, L. Cuvelier and B. Maison,
    CEC RACE/HAMLET Deliverable no R2110/WP2/DS/S/006/b1, September
    1995. http://www.stephanepigeon.com/Docs/deliv2.pdf

    """

    fil = numpy.array(
        [-4, 8, 25, -123, 230, 728, 230, -123, 25, 8, -4],
        dtype=numpy.float32).reshape((-1, 1, 1)) / numpy.float32(1000)
    resize = Resize(config=config)
    out_frame = Frame()
    out_frame.data = fil
    out_frame.type = 'fil'
    audit = out_frame.metadata.get('audit')
    audit += 'data = HHI pre-interlace filter\n'
    out_frame.metadata.set('audit', audit)
    resize.filter(out_frame)
    return resize
Пример #5
0
def Window2D(name, x_tile, y_tile, function_1D, x_params={}, y_params={}):
    if x_tile == 1:
        x_win = numpy.array([1.0], dtype=numpy.float32)
    else:
        x_win = function_1D(x_tile, **x_params)
    if y_tile == 1:
        y_win = numpy.array([1.0], dtype=numpy.float32)
    else:
        y_win = function_1D(y_tile, **y_params)
    result = numpy.empty([1, y_win.shape[0], x_win.shape[0], 1],
                         dtype=numpy.float32)
    for y in range(result.shape[1]):
        for x in range(result.shape[2]):
            result[0, y, x, 0] = x_win[x] * y_win[y]
    out_frame = Frame()
    out_frame.data = result
    out_frame.type = 'win'
    audit = out_frame.metadata.get('audit')
    audit += 'data = %sWindow()\n' % name
    audit += '    size: %d x %d\n' % (y_tile, x_tile)
    extras = []
    for key, value in x_params.items():
        extras.append('%s: %s' % (key, str(value)))
    if extras:
        audit += '    horiz params: %s\n' % (', '.join(extras))
    extras = []
    for key, value in y_params.items():
        extras.append('%s: %s' % (key, str(value)))
    if extras:
        audit += '    vert params: %s\n' % (', '.join(extras))
    out_frame.metadata.set('audit', audit)
    return out_frame
Пример #6
0
def GaussianFilterCore(x_sigma=0.0, y_sigma=0.0):
    """Gaussian filter generator core.

    Alternative to the :py:class:`GaussianFilter` component that can be
    used to make a non-reconfigurable resizer::

        resize = Resize()
        resize.filter(GaussianFilterCore(x_sigma=1.5))
        ...
        start(..., resize, ...)
        ...

    :keyword float x_sigma: Horizontal standard deviation parameter.

    :keyword float y_sigma: Vertical standard deviation parameter.

    :return: A :py:class:`~pyctools.core.frame.Frame` object containing the
        filter.

    """
    def filter_1D(sigma):
        alpha = 1.0 / (2.0 * (max(sigma, 0.0001) ** 2.0))
        coefs = []
        coef = 1.0
        while coef > 0.0001:
            coefs.append(coef)
            coef = math.exp(-(alpha * (float(len(coefs) ** 2))))
        fil_dim = len(coefs) - 1
        result = numpy.zeros(1 + (fil_dim * 2), dtype=numpy.float32)
        for n, coef in enumerate(coefs):
            result[fil_dim - n] = coef
            result[fil_dim + n] = coef
        # normalise result
        result /= result.sum()
        return result

    x_sigma = max(x_sigma, 0.0)
    y_sigma = max(y_sigma, 0.0)
    x_fil = filter_1D(x_sigma)
    y_fil = filter_1D(y_sigma)
    result = numpy.empty(
        [y_fil.shape[0], x_fil.shape[0], 1], dtype=numpy.float32)
    for y in range(y_fil.shape[0]):
        for x in range(x_fil.shape[0]):
            result[y, x, 0] = x_fil[x] * y_fil[y]
    out_frame = Frame()
    out_frame.data = result
    out_frame.type = 'fil'
    audit = out_frame.metadata.get('audit')
    audit += 'data = GaussianFilter()\n'
    if x_sigma != 0.0:
        audit += '    x_sigma: %g\n' % (x_sigma)
    if y_sigma != 0.0:
        audit += '    y_sigma: %g\n' % (y_sigma)
    out_frame.metadata.set('audit', audit)
    return out_frame
Пример #7
0
    def process_frame(self):
        self.update_config()
        x_tile = self.config['xtile']
        y_tile = self.config['ytile']
        x_off = self.config['xoff']
        y_off = self.config['yoff']
        fade = self.config['fade']
        in_frame = self.input_buffer['input'].get()
        self.window(in_frame)
        out_frame = Frame()
        out_frame.initialise(in_frame)
        audit = out_frame.metadata.get('audit')
        audit += 'data = InverseWindow(data)\n'
        audit += '    size: %d x %d, offset: %d x %d\n' % (y_tile, x_tile,
                                                           y_off, x_off)
        audit += '    fade: %s\n' % fade
        out_frame.metadata.set('audit', audit)

        in_data = in_frame.as_numpy(dtype=numpy.float32)
        result = numpy.empty(in_data.shape, dtype=numpy.float32)
        x_overlap = x_tile - x_off
        y_overlap = y_tile - y_off
        for y in range(y_tile):
            y0 = y
            while y0 >= y_off:
                y0 -= y_off
            for x in range(x_tile):
                x0 = x
                while x0 >= x_off:
                    x0 -= x_off
                # get window value of this and neighbouring tiles
                centre = in_data[0, y, x, 0]
                neighbours = []
                for j in range(y0, y_tile, y_off):
                    for i in range(x0, x_tile, x_off):
                        if j == y and i == x:
                            continue
                        neighbours.append(in_data[0, j, i, 0])
                if not neighbours:
                    result[0, y, x, 0] = 1.0 / max(centre, 0.000001)
                elif fade == 'minsnr':
                    result[0, y, x, 0] = centre / (
                        (centre**2) + sum(map(lambda x: x**2, neighbours)))
                elif fade == 'linear':
                    result[0, y, x, 0] = 1.0 / (centre + sum(neighbours))
                else:
                    biggest = max(neighbours)
                    if centre > biggest:
                        result[0, y, x, 0] = 1.0 / max(centre, 0.000001)
                    elif centre < biggest:
                        result[0, y, x, 0] = 0.0
                    else:
                        result[0, y, x, 0] = 0.5 / max(centre, 0.000001)
        out_frame.data = result
        self.inv_window(out_frame)
Пример #8
0
 def __init__(self, config={}, **kwds):
     super(CtoUV, self).__init__(config=config, **kwds)
     mat = Frame()
     mat.data = numpy.array([[2.02 / 0.886], [1.14 / 0.701]],
                            dtype=numpy.float32)
     mat.type = 'mat'
     audit = mat.metadata.get('audit')
     audit += 'data = PAL -> CbCr matrix\n'
     audit += '    values: %s\n' % (str(mat.data))
     mat.metadata.set('audit', audit)
     self.matrix(mat)
Пример #9
0
 def __init__(self, config={}, **kwds):
     super(UVtoC, self).__init__(config=config, **kwds)
     mat = Frame()
     mat.data = numpy.array(
         [[2.0 * 0.886 / 2.02, 2.0 * 0.701 / 1.14]], dtype=numpy.float32)
     mat.type = 'mat'
     audit = mat.metadata.get('audit')
     audit += 'data = Modulated CbCr -> PAL chroma matrix\n'
     audit += '    values: %s\n' % (str(mat.data))
     mat.metadata.set('audit', audit)
     self.matrix(mat)
Пример #10
0
 def __init__(self, config={}, **kwds):
     super(CtoUV, self).__init__(config=config, **kwds)
     mat = Frame()
     mat.data = numpy.array(
         [[2.02 / 0.886], [1.14 / 0.701]], dtype=numpy.float32)
     mat.type = 'mat'
     audit = mat.metadata.get('audit')
     audit += 'data = PAL -> CbCr matrix\n'
     audit += '    values: %s\n' % (str(mat.data))
     mat.metadata.set('audit', audit)
     self.matrix(mat)
Пример #11
0
 def make_window(self):
     self.update_config()
     x_tile = self.config['xtile']
     y_tile = self.config['ytile']
     sym = self.config['sym']
     combine2D = self.config['combine2D']
     function = self.config['function']
     alpha = self.config['alpha']
     function_1D, has_alpha = self.functions[function]
     if combine2D == 'square' or x_tile == 1 or y_tile == 1:
         if x_tile == 1:
             x_win = numpy.array([1.0])
         elif sym:
             x_win = function_1D(x_tile, alpha)
         else:
             x_win = function_1D(x_tile + 1, alpha)[:-1]
         if y_tile == 1:
             y_win = numpy.array([1.0])
         elif sym:
             y_win = function_1D(y_tile, alpha)
         else:
             y_win = function_1D(y_tile + 1, alpha)[:-1]
         x_win = x_win.reshape((1, 1, -1, 1))
         y_win = y_win.reshape((1, -1, 1, 1))
         window = x_win * y_win
     else:
         xc, yc = x_tile // 2, y_tile // 2
         if sym:
             xc, yc = xc - 0.5, yc - 0.5
         func_win = numpy.zeros((2049,), dtype=pt_float)
         func_win[0:1025] = function_1D(2049, alpha)[1024:]
         window = numpy.empty((1, y_tile, x_tile, 1), dtype=pt_float)
         for y in range(y_tile):
             for x in range(x_tile):
                 window[0, y, x, 0] = math.sqrt((((x - xc) / x_tile) ** 2) +
                                                (((y - yc) / y_tile) ** 2))
         if combine2D == 'round2':
             window /= math.sqrt(2.0)
         window = numpy.interp(
             window, numpy.linspace(0, 1.0, func_win.shape[0]), func_win)
     out_frame = Frame()
     out_frame.data = window.astype(pt_float)
     out_frame.type = 'win'
     audit = out_frame.metadata.get('audit')
     audit += 'data = %sWindow()\n' % function
     audit += '    size: %d x %d\n' % (y_tile, x_tile)
     audit += '    symmetric: %s\n' % str(sym)
     if has_alpha:
         audit += '    alpha: %g\n' % alpha
     out_frame.metadata.set('audit', audit)
     self.send('output', out_frame)
Пример #12
0
def GaussianFilterCore(x_sigma=0.0, y_sigma=0.0):
    """

    :keyword float x_sigma: Horizontal standard deviation parameter.

    :keyword float y_sigma: Vertical standard deviation parameter.

    :return: A :py:class:`~pyctools.core.frame.Frame` object containing the
        filter.

    """
    def filter_1D(sigma):
        alpha = 1.0 / (2.0 * (max(sigma, 0.0001)**2.0))
        coefs = []
        coef = 1.0
        while coef > 0.0001:
            coefs.append(coef)
            coef = math.exp(-(alpha * (float(len(coefs)**2))))
        fil_dim = len(coefs) - 1
        result = numpy.zeros(1 + (fil_dim * 2), dtype=numpy.float32)
        for n, coef in enumerate(coefs):
            result[fil_dim - n] = coef
            result[fil_dim + n] = coef
        # normalise result
        result /= result.sum()
        return result

    x_sigma = max(x_sigma, 0.0)
    y_sigma = max(y_sigma, 0.0)
    x_fil = filter_1D(x_sigma)
    y_fil = filter_1D(y_sigma)
    result = numpy.empty([y_fil.shape[0], x_fil.shape[0], 1],
                         dtype=numpy.float32)
    for y in range(y_fil.shape[0]):
        for x in range(x_fil.shape[0]):
            result[y, x, 0] = x_fil[x] * y_fil[y]
    out_frame = Frame()
    out_frame.data = result
    out_frame.type = 'fil'
    audit = out_frame.metadata.get('audit')
    audit += 'data = GaussianFilter()\n'
    if x_sigma != 0.0:
        audit += '    x_sigma: %g\n' % (x_sigma)
    if y_sigma != 0.0:
        audit += '    y_sigma: %g\n' % (y_sigma)
    out_frame.metadata.set('audit', audit)
    return out_frame
Пример #13
0
 def on_start(self):
     self.update_config()
     if (self.config['mode'] != '2Dthresh'
             and not self.input_buffer['threshold'].available()):
         # create null threshold frame and put it on input queue so
         # we don't wait for one to arrive
         self.threshold_frame = Frame()
         self.threshold(self.threshold_frame)
Пример #14
0
 def __init__(self, config={}, **kwds):
     super(FTFilterUV_2Dthresh, self).__init__(xtile=32,
                                               ytile=16,
                                               mode='2Dthresh',
                                               config=config,
                                               **kwds)
     threshold = Frame()
     threshold.data = numpy.array(
         [[6, 6, 6, 6, 6], [6, 6, 6, 6, 6], [6, 6, 6, 6, 6],
          [6, 6, 6, 6, 6], [6, 6, 6, 6, 6], [6, 6, 6, 6, 6],
          [6, 6, 6, 6, 6], [6, 6, 6, 6, 6], [6, 6, 6, 6, 6]],
         dtype=numpy.float32) / numpy.float32(10.0)
     threshold.type = 'thresh'
     audit = threshold.metadata.get('audit')
     audit += 'data = transform PAL decoder thresholds\n'
     threshold.metadata.set('audit', audit)
     self.threshold(threshold)
Пример #15
0
 def __init__(self, config={}, **kwds):
     super(FTFilterUV_2Dthresh, self).__init__(
         xtile=32, ytile=16, mode='2Dthresh', config=config, **kwds)
     threshold = Frame()
     threshold.data = numpy.array(
         [[6, 6, 6, 6, 6],
          [6, 6, 6, 6, 6],
          [6, 6, 6, 6, 6],
          [6, 6, 6, 6, 6],
          [6, 6, 6, 6, 6],
          [6, 6, 6, 6, 6],
          [6, 6, 6, 6, 6],
          [6, 6, 6, 6, 6],
          [6, 6, 6, 6, 6]], dtype=numpy.float32) / numpy.float32(10.0)
     threshold.type = 'thresh'
     audit = threshold.metadata.get('audit')
     audit += 'data = transform PAL decoder thresholds\n'
     threshold.metadata.set('audit', audit)
     self.threshold(threshold)
Пример #16
0
 def gen_process(self):
     # wait for self.output to be connected
     while self.output.__self__ == self:
         yield 1
         time.sleep(0.01)
     # read file
     self.update_config()
     path = self.config['path']
     out_frame = Frame()
     image = PIL.Image.open(path)
     # send output frame
     out_frame.data = image
     out_frame.type = image.mode
     out_frame.frame_no = 0
     out_frame.metadata.from_file(path)
     audit = out_frame.metadata.get('audit')
     audit += 'data = %s\n' % path
     out_frame.metadata.set('audit', audit)
     self.output(out_frame)
     # shut down pipeline
     self.output(None)
     self.stop()
Пример #17
0
 def on_set_config(self):
     super(ModulateUV, self).on_set_config()
     self.update_config()
     # phase is in "quarter cycles"
     phase = float(self.config['sc_phase']) + 0.5
     v_axis_switch = int(self.config['VAS_phase'])
     cell = numpy.empty([4, 8, 4, 2], dtype=numpy.float32)
     for z in range(cell.shape[0]):
         for f in range(2):
             for y in range(f, cell.shape[1], 2):
                 phase = phase % 4
                 for x in range(cell.shape[2]):
                     cell[z, y, x, 0] = math.sin(phase * math.pi / 2.0)
                     cell[z, y, x, 1] = math.cos(
                         phase * math.pi / 2.0) * v_axis_switch
                     # 4 fsc sampling, so fsc advances by 1/4 cycle per sample
                     phase += 1
                 # "quarter line offset" retards by 1/4 cycle per field line
                 phase -= 1
                 v_axis_switch *= -1
             # 313 lines in 1st field, 312 lines in 2nd
             if f == 0:
                 remainder = 313 - (cell.shape[1] // 2)
             else:
                 remainder = 312 - (cell.shape[1] // 2)
             phase -= remainder
             if remainder % 2:
                 v_axis_switch *= -1
             # "25 Hz offset" adds 1/2 cycle per field period
             phase += 2
     cell_frame = Frame()
     cell_frame.data = cell
     cell_frame.type = 'cell'
     audit = cell_frame.metadata.get('audit')
     audit += 'data = PAL subcarrier modulation cell\n'
     cell_frame.metadata.set('audit', audit)
     self.cell(cell_frame)
Пример #18
0
 def on_start(self):
     # read file
     self.update_config()
     path = self.config['path']
     out_frame = Frame()
     image = cv2.imread(path, cv2.IMREAD_UNCHANGED)
     # scale data
     if image.dtype == numpy.uint8:
         pass
     elif image.dtype == numpy.uint16:
         image = image.astype(numpy.float32) / numpy.float32(2 ** 8)
     else:
         self.logger.error('Cannot handle %s data type', str(image.dtype))
         self.stop()
         return
     # rearrange components
     if image.shape[2] == 4:
         # RGBA image
         B = image[:, :, 0]
         G = image[:, :, 1]
         R = image[:, :, 2]
         A = image[:, :, 3]
         image = numpy.dstack((R, G, B, A))
         out_frame.type = 'RGBA'
     elif image.shape[2] == 3:
         # RGB image
         B = image[:, :, 0]
         G = image[:, :, 1]
         R = image[:, :, 2]
         image = numpy.dstack((R, G, B))
         out_frame.type = 'RGB'
     elif image.shape[2] == 1:
         out_frame.type = 'Y'
     else:
         out_frame.type = '???'
     # send output frame
     out_frame.data = image
     out_frame.frame_no = 0
     out_frame.metadata.from_file(path)
     audit = out_frame.metadata.get('audit')
     audit += 'data = {}\n'.format(path)
     out_frame.metadata.set('audit', audit)
     self.send('output', out_frame)
     # shut down pipeline
     self.stop()
Пример #19
0
def FilterGeneratorCore(x_up=1,
                        x_down=1,
                        x_ap=1,
                        x_cut=100,
                        y_up=1,
                        y_down=1,
                        y_ap=1,
                        y_cut=100):
    """

    :keyword int x_up: Horizontal up-conversion factor.

    :keyword int x_down: Horizontal down-conversion factor.

    :keyword int x_ap: Horizontal filter aperture.

    :keyword int x_cut: Horizontal cut frequency adjustment.

    :keyword int y_up: Vertical up-conversion factor.

    :keyword int y_down: Vertical down-conversion factor.

    :keyword int y_ap: Vertical filter aperture.

    :keyword int y_cut: Vertical cut frequency adjustment.

    :return: A :py:class:`~pyctools.core.frame.Frame` object containing the
        filter.

    """
    def filter_1D(up, down, ap, cut_adj):
        nyquist_freq = float(min(up, down)) / float(2 * up * down)
        cut_adj = float(cut_adj) / 100.0
        coefs = []
        n = 1
        while True:
            theta_1 = float(n) * math.pi * 2.0 * nyquist_freq
            theta_2 = theta_1 * 2.0 / float(ap)
            if theta_2 >= math.pi:
                break
            theta_1 *= cut_adj
            coef = math.sin(theta_1) / theta_1
            win = 0.5 * (1.0 + math.cos(theta_2))
            coef = coef * win
            if abs(coef) < 1.0e-16:
                coef = 0.0
            coefs.append(coef)
            n += 1
        fil_dim = len(coefs)
        result = numpy.ones(1 + (fil_dim * 2), dtype=numpy.float32)
        n = 1
        for coef in coefs:
            result[fil_dim - n] = coef
            result[fil_dim + n] = coef
            n += 1
        # normalise gain of each phase
        phases = (up * down) // min(up, down)
        for n in range(phases):
            result[n::phases] /= result[n::phases].sum()
        result /= float(phases)
        return result

    x_up = max(x_up, 1)
    x_down = max(x_down, 1)
    x_ap = max(x_ap, 1)
    x_cut = max(x_cut, 1)
    y_up = max(y_up, 1)
    y_down = max(y_down, 1)
    y_ap = max(y_ap, 1)
    y_cut = max(y_cut, 1)
    x_fil = filter_1D(x_up, x_down, x_ap, x_cut)
    y_fil = filter_1D(y_up, y_down, y_ap, y_cut)
    result = numpy.empty([y_fil.shape[0], x_fil.shape[0], 1],
                         dtype=numpy.float32)
    for y in range(y_fil.shape[0]):
        for x in range(x_fil.shape[0]):
            result[y, x, 0] = x_fil[x] * y_fil[y]
    out_frame = Frame()
    out_frame.data = result
    out_frame.type = 'fil'
    audit = out_frame.metadata.get('audit')
    audit += 'data = FilterGenerator()\n'
    if x_up != 1 or x_down != 1 or x_ap != 1:
        audit += '    x_up: %d, x_down: %d, x_ap: %d, x_cut: %d%%\n' % (
            x_up, x_down, x_ap, x_cut)
    if y_up != 1 or y_down != 1 or y_ap != 1:
        audit += '    y_up: %d, y_down: %d, y_ap: %d, y_cut: %d%%\n' % (
            y_up, y_down, y_ap, y_cut)
    out_frame.metadata.set('audit', audit)
    return out_frame
Пример #20
0
def FilterGeneratorCore(x_up=1, x_down=1, x_ap=1, x_cut=100,
                        y_up=1, y_down=1, y_ap=1, y_cut=100):
    """Classic filter generator core.

    Alternative to the :py:class:`FilterGenerator` component that can be
    used to make a non-reconfigurable resizer::

        resize = Resize(xup=2)
        resize.filter(FilterGeneratorCore(xup=2, xaperture=16))
        ...
        start(..., resize, ...)
        ...

    :keyword int x_up: Horizontal up-conversion factor.

    :keyword int x_down: Horizontal down-conversion factor.

    :keyword int x_ap: Horizontal filter aperture.

    :keyword int x_cut: Horizontal cut frequency adjustment.

    :keyword int y_up: Vertical up-conversion factor.

    :keyword int y_down: Vertical down-conversion factor.

    :keyword int y_ap: Vertical filter aperture.

    :keyword int y_cut: Vertical cut frequency adjustment.

    :return: A :py:class:`~pyctools.core.frame.Frame` object containing the
        filter.

    """
    def filter_1D(up, down, ap, cut_adj):
        nyquist_freq = float(min(up, down)) / float(2 * up * down)
        cut_adj = float(cut_adj) / 100.0
        coefs = []
        n = 1
        while True:
            theta_1 = float(n) * math.pi * 2.0 * nyquist_freq
            theta_2 = theta_1 * 2.0 / float(ap)
            if theta_2 >= math.pi:
                break
            theta_1 *= cut_adj
            coef = math.sin(theta_1) / theta_1
            win = 0.5 * (1.0 + math.cos(theta_2))
            coef = coef * win
            if abs(coef) < 1.0e-16:
                coef = 0.0
            coefs.append(coef)
            n += 1
        fil_dim = len(coefs)
        result = numpy.ones(1 + (fil_dim * 2), dtype=numpy.float32)
        n = 1
        for coef in coefs:
            result[fil_dim - n] = coef
            result[fil_dim + n] = coef
            n += 1
        # normalise gain of each phase
        phases = (up * down) // min(up, down)
        for n in range(phases):
            result[n::phases] /= result[n::phases].sum()
        result /= float(phases)
        return result

    x_up = max(x_up, 1)
    x_down = max(x_down, 1)
    x_ap = max(x_ap, 1)
    x_cut = max(x_cut, 1)
    y_up = max(y_up, 1)
    y_down = max(y_down, 1)
    y_ap = max(y_ap, 1)
    y_cut = max(y_cut, 1)
    x_fil = filter_1D(x_up, x_down, x_ap, x_cut)
    y_fil = filter_1D(y_up, y_down, y_ap, y_cut)
    result = numpy.empty(
        [y_fil.shape[0], x_fil.shape[0], 1], dtype=numpy.float32)
    for y in range(y_fil.shape[0]):
        for x in range(x_fil.shape[0]):
            result[y, x, 0] = x_fil[x] * y_fil[y]
    out_frame = Frame()
    out_frame.data = result
    out_frame.type = 'fil'
    audit = out_frame.metadata.get('audit')
    audit += 'data = FilterGenerator()\n'
    if x_up != 1 or x_down != 1 or x_ap != 1:
        audit += '    x_up: %d, x_down: %d, x_ap: %d, x_cut: %d%%\n' % (
            x_up, x_down, x_ap, x_cut)
    if y_up != 1 or y_down != 1 or y_ap != 1:
        audit += '    y_up: %d, y_down: %d, y_ap: %d, y_cut: %d%%\n' % (
            y_up, y_down, y_ap, y_cut)
    out_frame.metadata.set('audit', audit)
    return out_frame
Пример #21
0
 def on_start(self):
     # read file
     self.update_config()
     path = self.config['path']
     with Raw(filename=path) as raw:
         raw.options.auto_brightness = False
         raw.options.rotation = 0
         raw.options.use_camera_profile = self.config['use_camera_profile']
         raw.options.brightness = self.config['brightness']
         raw.options.highlight_mode = getattr(
             highlight_modes, self.config['highlight_mode'])
         raw.options.chromatic_aberration = (
             self.config['red_scale'], self.config['blue_scale'])
         if self.config['crop']:
             w, h = Metadata().from_file(path).image_size()
             x = (raw.metadata.width - w) // 2
             y = (raw.metadata.height - h) // 2
             raw.options.cropbox = x, y, w, h
         raw.options.gamma = getattr(gamma_curves, self.config['gamma'])
         raw.options.colorspace = getattr(
             colorspaces, self.config['colourspace'])
         raw.options.interpolation = getattr(
             interpolation, self.config['interpolation'])
         raw.options.bps = (8, 16)[self.config['16bit']]
         noise_threshold = self.config['noise_threshold']
         if noise_threshold != 0:
             raw.options.noise_threshold = noise_threshold
         wb = {
             'auto'   : self.config['wb_auto'],
             'camera' : self.config['wb_camera'],
             }
         if self.config['wb_greybox']:
             wb['greybox'] = eval('(' + self.config['wb_greybox'] + ')')
         if self.config['wb_rgbg']:
             wb['rgbg'] = eval('(' + self.config['wb_rgbg'] + ')')
         raw.options.white_balance = WhiteBalance(**wb)
         data = raw.to_buffer()
         if self.config['16bit']:
             image = numpy.frombuffer(data, dtype=numpy.uint16)
             clip_count = numpy.count_nonzero(
                 numpy.greater_equal(image, (2 ** 16) - 1))
             image = image.astype(pt_float) / pt_float(256.0)
         else:
             image = numpy.frombuffer(data, dtype=numpy.uint8)
             clip_count = numpy.count_nonzero(
                 numpy.greater_equal(image, (2 ** 8) - 1))
         if clip_count > 0:
             print('Pixels at clipping limit:', clip_count)
         image = image.reshape((raw.metadata.height, raw.metadata.width, 3))
     out_frame = Frame()
     # send output frame
     out_frame.data = image
     out_frame.type = 'RGB'
     out_frame.frame_no = 0
     out_frame.metadata.from_file(path)
     audit = out_frame.metadata.get('audit')
     audit += 'data = %s\n' % path
     out_frame.metadata.set('audit', audit)
     self.send('output', out_frame)
     # shut down pipeline
     self.stop()