Esempio n. 1
0
def correct_image(context, frame_base: Frame, list_correction: list):
    logger = logging.getLogger(__name__)

    # load context
    scale_factor = context.scale_factor

    predictive_vectors = []
    out_image = Frame()
    out_image.create_new(frame_base.width, frame_base.height)
    out_image.copy_image(frame_base)
    scale_factor = int(scale_factor)
    block_size = context.correction_block_size

    for x in range(int(len(list_correction) /
                       4)):  # / 4 because each there's 4 data points per block
        predictive_vectors.append(
            DisplacementVector(int(list_correction[x * 4 + 0]),
                               int(list_correction[x * 4 + 1]),
                               int(list_correction[x * 4 + 2]),
                               int(list_correction[x * 4 + 3])))
    # copy over predictive vectors into new image
    for vector in predictive_vectors:
        out_image.copy_block(frame_base, block_size * scale_factor,
                             vector.x_2 * scale_factor,
                             vector.y_2 * scale_factor,
                             vector.x_1 * scale_factor,
                             vector.y_1 * scale_factor)

    return out_image
Esempio n. 2
0
def pframe_image(context,
                 frame_next: Frame, frame_previous: Frame, frame_residual: Frame,
                 list_residual: list, list_predictive: list):
    """
    Create a new image using residuals and predictive vectors.
    Roughly, we can describe this method as

        frame_next = Transfrom(frame_previous, list_predictive) + frame_residuals.

    Although frame_residuals needs to also be transformed.

    Method Tasks:
        - Move blocks from frame_previous into frame_next using list_predictive
        - Move blocks from frame_residual into frame_next using list_residuals
    """

    # load context
    predictive_vectors = []
    residual_vectors = []
    scale_factor = int(context.scale_factor)
    block_size = context.block_size
    bleed = context.bleed

    # load lists into vector displacements
    for x in range(int(len(list_residual) / 4)):
        residual_vectors.append(DisplacementVector(int(list_residual[x * 4 + 0]),
                                                   int(list_residual[x * 4 + 1]),
                                                   int(list_residual[x * 4 + 2]),
                                                   int(list_residual[x * 4 + 3])))

    # Neat optimization trick - there's no need for pframe to copy over a block if the vectors
    # point to the same place. In merge.py we just need to load the previous frame into the current frame
    # To reach this optimization. 
    for x in range(int(len(list_predictive) / 4)):
        if int(list_predictive[x * 4 + 0]) != int(list_predictive[x * 4 + 1]) and \
                int(list_predictive[x * 4 + 2]) != int(list_predictive[x * 4 + 3]):
            predictive_vectors.append(DisplacementVector(int(list_predictive[x * 4 + 0]),
                                                         int(list_predictive[x * 4 + 1]),
                                                         int(list_predictive[x * 4 + 2]),
                                                         int(list_predictive[x * 4 + 3])))

    # copy over blocks from one image to the others using the vectors generated by waifu2x_cpp
    for vector in predictive_vectors:
        frame_next.copy_block(frame_previous, block_size * scale_factor,
                              vector.x_2 * scale_factor,
                              vector.y_2 * scale_factor,
                              vector.x_1 * scale_factor,
                              vector.y_1 * scale_factor)

    # copy over inversion vectors (the difference images) into new image using vectors generated by waifu2x_cpp
    for vector in residual_vectors:
        frame_next.copy_block(frame_residual, block_size * scale_factor,
                              (vector.x_2 * (block_size + bleed * 2)) * scale_factor + (bleed * scale_factor),
                              (vector.y_2 * (block_size + bleed * 2)) * scale_factor + (bleed * scale_factor),
                              vector.x_1 * scale_factor,
                              vector.y_1 * scale_factor)

    return frame_next
Esempio n. 3
0
def pframe_image(context,
                 frame_next: Frame, frame_previous: Frame, frame_residual: Frame,
                 list_residual: list, list_predictive: list):
    """
    Create a new image using residuals and predictive vectors.
    Roughly, we can describe this method as

        frame_next = Transfrom(frame_previous, list_predictive) + frame_residuals.

    Although frame_residuals needs to also be transformed.

    Method Tasks:
        - Move blocks from frame_previous into frame_next using list_predictive
        - Move blocks from frame_residual into frame_next using list_residuals
    """

    # load context
    scale_factor = int(context.scale_factor)
    block_size = context.block_size
    bleed = context.bleed

    for x in range(int(len(list_predictive) / 4)):

        # Neat optimization trick - there's no need for pframe to copy over a block if the vectors
        # point to the same place. In merge.py we just need to load the previous frame into the current frame
        # to reach this optimization.
        if int(list_predictive[x * 4 + 0]) != int(list_predictive[x * 4 + 1]) \
                and \
                int(list_predictive[x * 4 + 2]) != int(list_predictive[x * 4 + 3]):
            # load the vector
            vector = DisplacementVector(int(list_predictive[x * 4 + 0]),
                                        int(list_predictive[x * 4 + 1]),
                                        int(list_predictive[x * 4 + 2]),
                                        int(list_predictive[x * 4 + 3]))

            # apply the vector
            frame_next.copy_block(frame_previous, block_size * scale_factor,
                                  vector.x_2 * scale_factor,
                                  vector.y_2 * scale_factor,
                                  vector.x_1 * scale_factor,
                                  vector.y_1 * scale_factor)

    for x in range(int(len(list_residual) / 4)):
        # load every element in the list into a vector
        vector = DisplacementVector(int(list_residual[x * 4 + 0]),
                                    int(list_residual[x * 4 + 1]),
                                    int(list_residual[x * 4 + 2]),
                                    int(list_residual[x * 4 + 3]))

        # apply that vector to the image
        frame_next.copy_block(frame_residual, block_size * scale_factor,
                              (vector.x_2 * (block_size + bleed * 2)) * scale_factor + (bleed * scale_factor),
                              (vector.y_2 * (block_size + bleed * 2)) * scale_factor + (bleed * scale_factor),
                              vector.x_1 * scale_factor,
                              vector.y_1 * scale_factor)

    return frame_next
Esempio n. 4
0
def make_difference_image(context: Context, raw_frame: Frame,
                          list_difference: list, list_predictive: list):
    difference_vectors = []
    buffer = 5
    block_size = context.block_size
    bleed = context.bleed

    # first make a 'bleeded' version of input_frame
    # so we can preform numpy calculations w.o having to catch
    bleed_frame = raw_frame.create_bleeded_image(buffer)

    # if there are no items in 'differences' but have list_predictives
    # then the two frames are identical, so no differences image needed.
    if not list_difference and list_predictive:
        out_image = Frame()
        out_image.create_new(1, 1)
        return out_image

    # if there are neither any predictive or inversions
    # then the frame is a brand new frame with no resemblence to previous frame.
    # in this case copy the entire frame over
    if not list_difference and not list_predictive:
        out_image = Frame()
        out_image.create_new(raw_frame.width, raw_frame.height)
        out_image.copy_image(raw_frame)
        return out_image

    # turn the list of differences into a list of vectors
    for x in range(int(len(list_difference) / 4)):
        difference_vectors.append(
            DisplacementVector(int(list_difference[x * 4]),
                               int(list_difference[x * 4 + 1]),
                               int(list_difference[x * 4 + 2]),
                               int(list_difference[x * 4 + 3])))

    # size of output image is determined based off how many differences there are
    image_size = int(math.sqrt(len(list_difference) / 4) + 1) * (block_size +
                                                                 bleed * 2)
    out_image = Frame()
    out_image.create_new(image_size, image_size)

    # move every block from the complete frame to the differences frame using vectors.
    for vector in difference_vectors:
        out_image.copy_block(bleed_frame, block_size + bleed * 2,
                             vector.x_1 + buffer - bleed,
                             vector.y_1 + buffer + -bleed,
                             vector.x_2 * (block_size + bleed * 2),
                             vector.y_2 * (block_size + bleed * 2))

    return out_image
Esempio n. 5
0
def pframe_image(context, out_image: Frame, frame_base: Frame,
                 frame_inversion: Frame, list_differences: list,
                 list_predictive: list):
    # load context
    predictive_vectors = []
    difference_vectors = []
    scale_factor = int(context.scale_factor)
    block_size = context.block_size
    bleed = context.bleed

    # load lists into vector displacements
    for x in range(int(len(list_differences) / 4)):
        difference_vectors.append(
            DisplacementVector(int(list_differences[x * 4 + 0]),
                               int(list_differences[x * 4 + 1]),
                               int(list_differences[x * 4 + 2]),
                               int(list_differences[x * 4 + 3])))

    # Neat optimization trick - there's no need for pframe to copy over a block if the vectors
    # point to the same place. In merge.py we just need to load the previous frame into the current frame
    # To reach this optimization.
    for x in range(int(len(list_predictive) / 4)):
        if int(list_predictive[x * 4 + 0]) != int(list_predictive[x * 4 + 1]) and \
                int(list_predictive[x * 4 + 2]) != int(list_predictive[x * 4 + 3]):
            predictive_vectors.append(
                DisplacementVector(int(list_predictive[x * 4 + 0]),
                                   int(list_predictive[x * 4 + 1]),
                                   int(list_predictive[x * 4 + 2]),
                                   int(list_predictive[x * 4 + 3])))

    # copy over blocks from one image to the others using the vectors generated by waifu2x_cpp
    for vector in predictive_vectors:
        out_image.copy_block(frame_base, block_size * scale_factor,
                             vector.x_2 * scale_factor,
                             vector.y_2 * scale_factor,
                             vector.x_1 * scale_factor,
                             vector.y_1 * scale_factor)

    # copy over inversion vectors (the difference images) into new image using vectors generated by waifu2x_cpp
    for vector in difference_vectors:
        out_image.copy_block(
            frame_inversion, block_size * scale_factor,
            (vector.x_2 *
             (block_size + bleed * 2)) * scale_factor + (bleed * scale_factor),
            (vector.y_2 *
             (block_size + bleed * 2)) * scale_factor + (bleed * scale_factor),
            vector.x_1 * scale_factor, vector.y_1 * scale_factor)

    return out_image
Esempio n. 6
0
def debug_image(block_size, frame_base, list_predictive, list_differences,
                output_location):
    logger = logging.getLogger(__name__)

    difference_vectors = []
    predictive_vectors = []
    out_image = Frame()
    out_image.create_new(frame_base.width, frame_base.height)
    out_image.copy_image(frame_base)

    black_image = Frame()
    black_image.create_new(frame_base.width, frame_base.height)

    if not list_predictive and not list_differences:
        out_image.save_image(output_location)
        return

    if list_predictive and not list_differences:
        out_image.copy_image(frame_base)
        out_image.save_image(output_location)
        return

    # load list into vector displacements
    for x in range(int(len(list_differences) / 4)):
        difference_vectors.append(
            DisplacementVector(int(list_differences[x * 4]),
                               int(list_differences[x * 4 + 1]),
                               int(list_differences[x * 4 + 2]),
                               int(list_differences[x * 4 + 3])))
    for x in range(int(len(list_predictive) / 4)):
        if (int(list_predictive[x * 4 + 0]) != int(list_predictive[x * 4 + 1])) and \
                (int(list_predictive[x * 4 + 2]) != int(list_predictive[x * 4 + 3])):
            predictive_vectors.append(
                DisplacementVector(int(list_predictive[x * 4 + 0]),
                                   int(list_predictive[x * 4 + 1]),
                                   int(list_predictive[x * 4 + 2]),
                                   int(list_predictive[x * 4 + 3])))

    # copy over predictive vectors into new image
    for vector in difference_vectors:
        out_image.copy_block(black_image, block_size, vector.x_1, vector.y_1,
                             vector.x_1, vector.y_1)

    out_image.save_image_quality(output_location, 25)
Esempio n. 7
0
def correct_image(context, frame_base: Frame, list_correction: list):
    """
    Try and fix some artifact-residuals by using the same image as reference.


    Method Tasks:
        - Load all the vectors for blocks pointing to a block with lower MSE
        - Apply all the vectors to the image to produce a more 'correct' image
    """

    logger = logging.getLogger(__name__)

    # load context
    scale_factor = context.scale_factor

    out_image = Frame()
    out_image.create_new(frame_base.width, frame_base.height)
    out_image.copy_image(frame_base)
    scale_factor = int(scale_factor)
    block_size = context.correction_block_size

    for x in range(int(len(list_correction) /
                       4)):  # / 4 because each there's 4 data points per block

        # load vector
        vector = DisplacementVector(int(list_correction[x * 4 + 0]),
                                    int(list_correction[x * 4 + 1]),
                                    int(list_correction[x * 4 + 2]),
                                    int(list_correction[x * 4 + 3]))

        # apply vector
        out_image.copy_block(frame_base, block_size * scale_factor,
                             vector.x_2 * scale_factor,
                             vector.y_2 * scale_factor,
                             vector.x_1 * scale_factor,
                             vector.y_1 * scale_factor)

    return out_image
Esempio n. 8
0
    def debug_image(block_size, frame_base, list_predictive, list_differences,
                    output_location):
        """
        Note:
            I haven't made an effort to maintain this method, as it's only for debugging.

        This section can best be explained through pictures. A visual way of expressing what 'debug'
        is doing is this section in the wiki.

        https://github.com/aka-katto/dandere2x/wiki/How-Dandere2x-Works#part-1-identifying-what-needs-to-be-drawn

        In other words, this method shows where residuals are, and is useful for finding good settings to use for a video.

        Inputs:
            - frame(x)
            - Residual vectors mapping frame(x)_residual -> frame(x)

        Output:
            - frame(x) minus frame(x)_residuals = debug_image
        """
        logger = logging.getLogger(__name__)

        difference_vectors = []
        predictive_vectors = []
        out_image = Frame()
        out_image.create_new(frame_base.width, frame_base.height)
        out_image.copy_image(frame_base)

        black_image = Frame()
        black_image.create_new(frame_base.width, frame_base.height)

        if not list_predictive and not list_differences:
            out_image.save_image(output_location)
            return

        if list_predictive and not list_differences:
            out_image.copy_image(frame_base)
            out_image.save_image(output_location)
            return

        # load list into vector displacements
        for x in range(int(len(list_differences) / 4)):
            difference_vectors.append(
                DisplacementVector(int(list_differences[x * 4]),
                                   int(list_differences[x * 4 + 1]),
                                   int(list_differences[x * 4 + 2]),
                                   int(list_differences[x * 4 + 3])))
        for x in range(int(len(list_predictive) / 4)):
            if (int(list_predictive[x * 4 + 0]) != int(list_predictive[x * 4 + 1])) and \
                    (int(list_predictive[x * 4 + 2]) != int(list_predictive[x * 4 + 3])):
                predictive_vectors.append(
                    DisplacementVector(int(list_predictive[x * 4 + 0]),
                                       int(list_predictive[x * 4 + 1]),
                                       int(list_predictive[x * 4 + 2]),
                                       int(list_predictive[x * 4 + 3])))

        # copy over predictive vectors into new image
        for vector in difference_vectors:
            out_image.copy_block(black_image, block_size, vector.x_1,
                                 vector.y_1, vector.x_1, vector.y_1)

        out_image.save_image_quality(output_location, 25)
Esempio n. 9
0
    def make_residual_image(context: Context, raw_frame: Frame,
                            list_residual: list, list_predictive: list):
        """
        This section can best be explained through pictures. A visual way of expressing what 'make_residual_image'
        is doing is this section in the wiki.

        https://github.com/aka-katto/dandere2x/wiki/How-Dandere2x-Works#observation_3

        Inputs:
            - frame(x)
            - Residual vectors mapping frame(x)_residual -> frame(x)

        Output:
            - frame(x)_residual
        """

        # Some conditions to check before making a residual image, in both cases, we don't need to do any actual
        # processing in the function call, if these conditions hold true.
        if not list_residual and list_predictive:
            """
            If there are no items in 'list_residuals' but have list_predictives then the two frames are identical,
            so no residual image needed.
            """
            residual_image = Frame()
            residual_image.create_new(1, 1)
            return residual_image

        if not list_residual and not list_predictive:
            """ 
            If there are neither any predictive or inversions, then the frame is a brand new frame with no resemblence
            to previous frame. In this case, copy the entire frame over.
            """
            residual_image = Frame()
            residual_image.create_new(raw_frame.width, raw_frame.height)
            residual_image.copy_image(raw_frame)
            return residual_image

        buffer = 5
        block_size = context.block_size
        bleed = context.bleed
        """
        First make a 'bleeded' version of input_frame, as we need to create a buffer in the event the 'bleed'
        ends up going out of bounds. In other words, crop the image into an even larger image, so that if if we need
        to access out of bounds pixels, and place black pixels where it would be out of bounds. 
        """
        bleed_frame = raw_frame.create_bleeded_image(buffer)

        # size of output image is determined based off how many residuals there are
        image_size = int(math.sqrt(len(list_residual) / 4) + 1) * (block_size +
                                                                   bleed * 2)
        residual_image = Frame()
        residual_image.create_new(image_size, image_size)

        for x in range(int(len(list_residual) / 4)):
            # load every element in the list into a vector
            vector = DisplacementVector(int(list_residual[x * 4 + 0]),
                                        int(list_residual[x * 4 + 1]),
                                        int(list_residual[x * 4 + 2]),
                                        int(list_residual[x * 4 + 3]))

            # apply that vector to the image by copying over their respective blocks.
            residual_image.copy_block(bleed_frame, block_size + bleed * 2,
                                      vector.x_1 + buffer - bleed,
                                      vector.y_1 + buffer + -bleed,
                                      vector.x_2 * (block_size + bleed * 2),
                                      vector.y_2 * (block_size + bleed * 2))

        return residual_image
Esempio n. 10
0
def make_residual_image(context: Context, raw_frame: Frame,
                        list_residual: list, list_predictive: list):
    """
    This section can best be explained through pictures. A visual way of expressing what 'make_residual_image'
    is doing is this section in the wiki.

    https://github.com/aka-katto/dandere2x/wiki/How-Dandere2x-Works#observation_3

    Inputs:
        - frame(x)
        - Residual vectors mapping frame(x)_residual -> frame(x)

    Output:
        - frame(x)_residual
    """

    residual_vectors = []
    buffer = 5
    block_size = context.block_size
    bleed = context.bleed

    # first make a 'bleeded' version of input_frame, as we need to create a buffer in the event the 'bleed'
    # ends up going out of bounds.
    bleed_frame = raw_frame.create_bleeded_image(buffer)

    # if there are no items in 'list_residuals' but have list_predictives
    # then the two frames are identical, so no residual image needed.
    if not list_residual and list_predictive:
        out_image = Frame()
        out_image.create_new(1, 1)
        return out_image

    # if there are neither any predictive or inversions
    # then the frame is a brand new frame with no resemblence to previous frame.
    # in this case copy the entire frame over
    if not list_residual and not list_predictive:
        out_image = Frame()
        out_image.create_new(raw_frame.width, raw_frame.height)
        out_image.copy_image(raw_frame)
        return out_image

    # turn the list of residuals into a list of vectors
    for x in range(int(len(list_residual) / 4)):
        residual_vectors.append(
            DisplacementVector(int(list_residual[x * 4]),
                               int(list_residual[x * 4 + 1]),
                               int(list_residual[x * 4 + 2]),
                               int(list_residual[x * 4 + 3])))

    # size of output image is determined based off how many residuals there are
    image_size = int(math.sqrt(len(list_residual) / 4) + 1) * (block_size +
                                                               bleed * 2)
    out_image = Frame()
    out_image.create_new(image_size, image_size)

    # move every block from the complete frame to the residual frame using vectors.
    for vector in residual_vectors:
        out_image.copy_block(bleed_frame, block_size + bleed * 2,
                             vector.x_1 + buffer - bleed,
                             vector.y_1 + buffer + -bleed,
                             vector.x_2 * (block_size + bleed * 2),
                             vector.y_2 * (block_size + bleed * 2))

    return out_image