cytometer/utils.py
def keras2skimage_transform(keras_transform, input_shape, output_shape='same'):
    """
    Convert an affine transform from keras to skimage format. This can then be used to apply a
    transformation to an image (transform_im) or point set (transform_coords).

    Note: Currently, the implemented parameters are:
      * scaling ('zx', 'zy')
      * rotation ('theta')
      * translation ('tx', 'ty')
      * shear ('shear' in counter-clockwise degrees)
      * flip around the x-axis ('flip_vertical')
      * flip around the y-axis ('flip_horizontal')
    Ignored:
      * 'channel_shift_intensity'
      * 'brightness'

    Note 2: Rotations in keras are referred to the centre of the image.
    Rotations in skimage are referred to the origin of coordinates (x, y)=(0, 0).

    :param keras_transform: Dictionary with transform in keras format, as returned by
    keras.get_random_transform. E.g.
    {'theta': -43.1, 'tx': 0, 'ty': 0, 'shear': 4.3, 'zx': 1, 'zy': 1, 'flip_horizontal': 0,
     'flip_vertical': 0, 'channel_shift_intensity': None, 'brightness': None}
    :param input_shape: Tuple with (width, height) size of input image.
    :param output_shape: (def 'same')
        * 'same': The output has the same size as the input. Usually, this will crop out parts of the
                  transformed image.
        * 'full': The output will be large enough to contain the full transformed image. In general,
        the output image won't have the same centre as the output image produced with 'same'.
        * Tuple with (height, width) size of output image. Note: This option produces an output with the
        same centre as 'same'.
    :return:
    * transform_skimage: skimage.transform._geometric.ProjectiveTransform with same affine
    transform.
    * output_shape: (height, width)
    """

    # input image's centre
    im_centre = np.array([(input_shape[1] - 1) / 2, (input_shape[0] - 1) / 2])  # (x, y)

    # move image's centre to origin of coordinates
    transform_skimage_center = EuclideanTransform(translation=-im_centre)

    # affine transformation
    transform_skimage_affine = AffineTransform(matrix=None, scale=(keras_transform['zx'], keras_transform['zy']),
                                               rotation=keras_transform['theta'] / 180.0 * np.pi,
                                               shear=keras_transform['shear'] / 180.0 * np.pi,
                                               translation=(keras_transform['tx'], keras_transform['ty']))

    # horizontal flip
    if keras_transform['flip_horizontal'] == 1:
        transform_skimage_horizontal_flip = EuclideanTransform(np.array([[-1, 0, 0],
                                                                         [0, 1, 0],
                                                                         [0, 0, 1]]))
    else:
        transform_skimage_horizontal_flip = EuclideanTransform(None)

    # vertical flip
    if keras_transform['flip_vertical'] == 1:
        transform_skimage_vertical_flip = EuclideanTransform(np.array([[1, 0, 0],
                                                                       [0, -1, 0],
                                                                       [0, 0, 1]]))
    else:
        transform_skimage_vertical_flip = EuclideanTransform(None)

    # composition of all transformations
    transform_skimage = transform_skimage_center \
                        + transform_skimage_affine \
                        + transform_skimage_horizontal_flip \
                        + transform_skimage_vertical_flip \
                        + transform_skimage_center.inverse

    if output_shape == 'full':

        # input image bounding box's corners
        x0 = 0
        y0 = 0
        xend = input_shape[1] - 1
        yend = input_shape[0] - 1
        corner_coords = np.array([[x0, y0],
                                  [xend, y0],
                                  [xend, yend],
                                  [x0, yend]])

        # apply the same image transformation to the input bounding box
        corner_coords = matrix_transform(corner_coords, transform_skimage.params)  # (x, y)

        # bounding box containing the whole output image
        bbox_out = np.array([np.min(corner_coords, axis=0), np.max(corner_coords, axis=0)])  # (x, y)

        # bottom-left and top-right corners of the output bounding box
        bbox_out_min = np.min(bbox_out, axis=0)  # (x, y)
        bbox_out_max = np.max(bbox_out, axis=0)  # (x, y)

        # size of the output image is the size of the output bounding box
        output_shape = np.ceil(bbox_out_max - bbox_out_min + np.array([1, 1]))  # (x, y)
        output_shape = output_shape[::-1]  # (row, col)

        # move bottom left of bounding box to origin of coordinates, so no part of the image will be
        # cropped
        transform_translate = EuclideanTransform(translation=-bbox_out_min)
        transform_skimage = transform_skimage + transform_translate

    elif output_shape == 'same':

        # size of the output image is the size of the input image
        output_shape = input_shape[0:2]

        # no translation correction needed

    else:  # user provides numerical output size

        # correction of centre point if output size is not the same as the input image size
        shape_correction = (np.array(output_shape) - np.array(input_shape[0:2])) / 2.0
        transform_translate = EuclideanTransform(translation=shape_correction)

        transform_skimage = transform_skimage + transform_translate

    if type(output_shape) == np.ndarray:
        output_shape = tuple(output_shape.astype(np.int64))
    return transform_skimage, output_shape

    Convert an affine transform from keras to skimage format. This can then be used to apply a
    transformation to an image (transform_im) or point set (transform_coords).

    Note: Currently, the implemented parameters are:
      * scaling ('zx', 'zy')
      * rotation ('theta')
      * translation ('tx', 'ty')
      * shear ('shear' in counter-clockwise degrees)
      * flip around the x-axis ('flip_vertical')
      * flip around the y-axis ('flip_horizontal')
    Ignored:
      * 'channel_shift_intensity'
      * 'brightness'

    Note 2: Rotations in keras are referred to the centre of the image.
    Rotations in skimage are referred to the origin of coordinates (x, y)=(0, 0).

    :param keras_transform: Dictionary with transform in keras format, as returned by
    keras.get_random_transform. E.g.
    {'theta': -43.1, 'tx': 0, 'ty': 0, 'shear': 4.3, 'zx': 1, 'zy': 1, 'flip_horizontal': 0,
     'flip_vertical': 0, 'channel_shift_intensity': None, 'brightness': None}
    :param input_shape: Tuple with (width, height) size of input image.
    :param output_shape: (def 'same')
        * 'same': The output has the same size as the input. Usually, this will crop out parts of the
                  transformed image.
        * 'full': The output will be large enough to contain the full transformed image. In general,
        the output image won't have the same centre as the output image produced with 'same'.
        * Tuple with (height, width) size of output image. Note: This option produces an output with the
        same centre as 'same'.
    :return:
    * transform_skimage: skimage.transform._geometric.ProjectiveTransform with same affine
    transform.
    * output_shape: (height, width)
    
Convert an affine transform from keras to skimage format. This can then be used to apply a
transformation to an image (transform_im) or point set (transform_coords).



Note 2: Rotations in keras are referred to the centre of the image.
Rotations in skimage are referred to the origin of coordinates (x, y)=(0, 0).
Convert an affine transform from keras to skimage format . This can then be used to apply a transformation to an image ( transform_im ) or point set ( transform_coords ) . Note 2 : Rotations in keras are referred to the centre of the image . Rotations in skimage are referred to the origin of coordinates ( x y ) = ( 0 0 ) .
def keras2skimage_transform(keras_transform, input_shape, output_shape='same'):
    im_centre = np.array([(input_shape[1] - 1) / 2, (input_shape[0] - 1) / 2])  
    transform_skimage_center = EuclideanTransform(translation=-im_centre)
    transform_skimage_affine = AffineTransform(matrix=None, scale=(keras_transform['zx'], keras_transform['zy']),
                                               rotation=keras_transform['theta'] / 180.0 * np.pi,
                                               shear=keras_transform['shear'] / 180.0 * np.pi,
                                               translation=(keras_transform['tx'], keras_transform['ty']))
    if keras_transform['flip_horizontal'] == 1:
        transform_skimage_horizontal_flip = EuclideanTransform(np.array([[-1, 0, 0],
                                                                         [0, 1, 0],
                                                                         [0, 0, 1]]))
    else:
        transform_skimage_horizontal_flip = EuclideanTransform(None)
    if keras_transform['flip_vertical'] == 1:
        transform_skimage_vertical_flip = EuclideanTransform(np.array([[1, 0, 0],
                                                                       [0, -1, 0],
                                                                       [0, 0, 1]]))
    else:
        transform_skimage_vertical_flip = EuclideanTransform(None)
    transform_skimage = transform_skimage_center \
                        + transform_skimage_affine \
                        + transform_skimage_horizontal_flip \
                        + transform_skimage_vertical_flip \
                        + transform_skimage_center.inverse
    if output_shape == 'full':
        x0 = 0
        y0 = 0
        xend = input_shape[1] - 1
        yend = input_shape[0] - 1
        corner_coords = np.array([[x0, y0],
                                  [xend, y0],
                                  [xend, yend],
                                  [x0, yend]])
        corner_coords = matrix_transform(corner_coords, transform_skimage.params)  
        bbox_out = np.array([np.min(corner_coords, axis=0), np.max(corner_coords, axis=0)])  
        bbox_out_min = np.min(bbox_out, axis=0)  
        bbox_out_max = np.max(bbox_out, axis=0)  
        output_shape = np.ceil(bbox_out_max - bbox_out_min + np.array([1, 1]))  
        output_shape = output_shape[::-1]  
        transform_translate = EuclideanTransform(translation=-bbox_out_min)
        transform_skimage = transform_skimage + transform_translate
    elif output_shape == 'same':
        output_shape = input_shape[0:2]
    else:  
        shape_correction = (np.array(output_shape) - np.array(input_shape[0:2])) / 2.0
        transform_translate = EuclideanTransform(translation=shape_correction)
        transform_skimage = transform_skimage + transform_translate
    if type(output_shape) == np.ndarray:
        output_shape = tuple(output_shape.astype(np.int64))
    return transform_skimage, output_shape
def keras2skimage_transform ( keras_transform , input_shape , output_shape = 'same' ) : im_centre = np . array ( [ ( input_shape [ 1 ] - 1 ) / 2 , ( input_shape [ 0 ] - 1 ) / 2 ] ) transform_skimage_center = EuclideanTransform ( translation = - im_centre ) transform_skimage_affine = AffineTransform ( matrix = None , scale = ( keras_transform [ 'zx' ] , keras_transform [ 'zy' ] ) , rotation = keras_transform [ 'theta' ] / 180.0 * np . pi , shear = keras_transform [ 'shear' ] / 180.0 * np . pi , translation = ( keras_transform [ 'tx' ] , keras_transform [ 'ty' ] ) ) if keras_transform [ 'flip_horizontal' ] == 1 : transform_skimage_horizontal_flip = EuclideanTransform ( np . array ( [ [ - 1 , 0 , 0 ] , [ 0 , 1 , 0 ] , [ 0 , 0 , 1 ] ] ) ) else : transform_skimage_horizontal_flip = EuclideanTransform ( None ) if keras_transform [ 'flip_vertical' ] == 1 : transform_skimage_vertical_flip = EuclideanTransform ( np . array ( [ [ 1 , 0 , 0 ] , [ 0 , - 1 , 0 ] , [ 0 , 0 , 1 ] ] ) ) else : transform_skimage_vertical_flip = EuclideanTransform ( None ) transform_skimage = transform_skimage_center + transform_skimage_affine + transform_skimage_horizontal_flip + transform_skimage_vertical_flip + transform_skimage_center . inverse if output_shape == 'full' : x0 = 0 y0 = 0 xend = input_shape [ 1 ] - 1 yend = input_shape [ 0 ] - 1 corner_coords = np . array ( [ [ x0 , y0 ] , [ xend , y0 ] , [ xend , yend ] , [ x0 , yend ] ] ) corner_coords = matrix_transform ( corner_coords , transform_skimage . params ) bbox_out = np . array ( [ np . min ( corner_coords , axis = 0 ) , np . max ( corner_coords , axis = 0 ) ] ) bbox_out_min = np . min ( bbox_out , axis = 0 ) bbox_out_max = np . max ( bbox_out , axis = 0 ) output_shape = np . ceil ( bbox_out_max - bbox_out_min + np . array ( [ 1 , 1 ] ) ) output_shape = output_shape [ : : - 1 ] transform_translate = EuclideanTransform ( translation = - bbox_out_min ) transform_skimage = transform_skimage + transform_translate elif output_shape == 'same' : output_shape = input_shape [ 0 : 2 ] else : shape_correction = ( np . array ( output_shape ) - np . array ( input_shape [ 0 : 2 ] ) ) / 2.0 transform_translate = EuclideanTransform ( translation = shape_correction ) transform_skimage = transform_skimage + transform_translate if type ( output_shape ) == np . ndarray : output_shape = tuple ( output_shape . astype ( np . int64 ) ) return transform_skimage , output_shape
Convert an affine transform from keras to skimage format.
Convert an affine transform from keras to skimage format .
"""
    Convert an affine transform from keras to skimage format. This can then be used to apply a
    transformation to an image (transform_im) or point set (transform_coords).

    Note: Currently, the implemented parameters are:
      * scaling ('zx', 'zy')
      * rotation ('theta')
      * translation ('tx', 'ty')
      * shear ('shear' in counter-clockwise degrees)
      * flip around the x-axis ('flip_vertical')
      * flip around the y-axis ('flip_horizontal')
    Ignored:
      * 'channel_shift_intensity'
      * 'brightness'

    Note 2: Rotations in keras are referred to the centre of the image.
    Rotations in skimage are referred to the origin of coordinates (x, y)=(0, 0).

    :param keras_transform: Dictionary with transform in keras format, as returned by
    keras.get_random_transform. E.g.
    {'theta': -43.1, 'tx': 0, 'ty': 0, 'shear': 4.3, 'zx': 1, 'zy': 1, 'flip_horizontal': 0,
     'flip_vertical': 0, 'channel_shift_intensity': None, 'brightness': None}
    :param input_shape: Tuple with (width, height) size of input image.
    :param output_shape: (def 'same')
        * 'same': The output has the same size as the input. Usually, this will crop out parts of the
                  transformed image.
        * 'full': The output will be large enough to contain the full transformed image. In general,
        the output image won't have the same centre as the output image produced with 'same'.
        * Tuple with (height, width) size of output image. Note: This option produces an output with the
        same centre as 'same'.
    :return:
    * transform_skimage: skimage.transform._geometric.ProjectiveTransform with same affine
    transform.
    * output_shape: (height, width)
    """ # input image's centre # (x, y) # move image's centre to origin of coordinates # affine transformation # horizontal flip # vertical flip # composition of all transformations # input image bounding box's corners # apply the same image transformation to the input bounding box # (x, y) # bounding box containing the whole output image # (x, y) # bottom-left and top-right corners of the output bounding box # (x, y) # (x, y) # size of the output image is the size of the output bounding box # (x, y) # (row, col) # move bottom left of bounding box to origin of coordinates, so no part of the image will be # cropped # size of the output image is the size of the input image # no translation correction needed # user provides numerical output size # correction of centre point if output size is not the same as the input image size
skimage.transform._geometric.ProjectiveTransform with same affine
transform.
output_shape: (height, width)
skimage . transform . _geometric . ProjectiveTransform with same affine transform . output_shape : ( height width )
keras_transform
Dictionary with transform in keras format, as returned by
keras.get_random_transform. E.g.
Dictionary with transform in keras format as returned by keras . get_random_transform . E . g .
input_shape
Tuple with (width, height) size of input image.
Tuple with ( width height ) size of input image .
output_shape
(def 'same')
'same': The output has the same size as the input. Usually, this will crop out parts of the
transformed image.
'full': The output will be large enough to contain the full transformed image. In general,
the output image won't have the same centre as the output image produced with 'same'.
Tuple with (height, width) size of output image. Note: This option produces an output with the
same centre as 'same'.
( def ' same ' ) ' same ' : The output has the same size as the input . Usually this will crop out parts of the transformed image . ' full ' : The output will be large enough to contain the full transformed image . In general the output image won ' t have the same centre as the output image produced with ' same ' . Tuple with ( height width ) size of output image . Note : This option produces an output with the same centre as ' same ' .