コード例 #1
0
ファイル: demosaic.py プロジェクト: themathgeek13/plenpy
def get_demosaiced(img: ndarray,
                   pattern: str = 'GRBG',
                   method: str = 'bilinear') -> ndarray:
    """Get a demosaiced RGB image from a raw image.

    This function is a wrapper of the demosaicing functions supplied by the
    ``color_demosaicing`` package.

    Args:
        img: Input image, greyscale, of shape (x,y).

        pattern: Bayer filter pattern that the input image is modulated with.
            Patterns are: 'RGGB', 'BGGR', 'GRBG', 'GBRG'.

            Default: 'GRBG'

        method: Algorithm used to calculate the demosaiced image.\n
            * 'bilinear': Simple bilinear interpolation of color values
            * 'malvar2004': Algorithm introduced by Malvar et. al. [R3]_
            * 'menon2007': Algorithm introduced by Menon et. al. [R4]_,


    Returns:
        Demosaiced RGB-color image of shape (x,y,3) of
        dtype :class:`numpy.float64`.

    References:
        .. [R3]  H.S. Malvar,  Li-wei He, and  R. Cutler (2004).
           High-quality linear interpolation for demosaicing of
           Bayer-patterned color images.
           IEEE International Conference on Acoustics, Speech, and Signal
           Processing, Proceedings. (ICASSP '04).
           DOI: 10.1109/ICASSP.2004.1326587

        .. [R4]  D. Menon, S. Andriani, G. Calvagno (2007).
           Demosaicing With Directional Filtering and a posteriori Decision.
           IEEE Transactions on Image Processing (Volume: 16, Issue: 1)
           DOI: 10.1109/TIP.2006.884928

    """

    param_list = ["bilinear", "malvar2004", "menon2007"]

    # Do demosaicing with specified method
    if method not in param_list:
        raise ValueError(
            f"The specified method {method} is none of the supported "
            f"methods: {param_list}.")

    elif method == "bilinear":
        return demosaicing_CFA_Bayer_bilinear(img.astype(np.float64),
                                              pattern=pattern)

    elif method == "malvar2004":
        return demosaicing_CFA_Bayer_Malvar2004(img.astype(np.float64),
                                                pattern=pattern)

    elif method == "menon2007":
        return demosaicing_CFA_Bayer_Menon2007(img.astype(np.float64),
                                               pattern=pattern)
コード例 #2
0
ファイル: edges.py プロジェクト: 000o0/triangler
    def compute(img: ndarray, k_size: int = 3) -> ndarray:
        im = img.astype(np.float)
        width, height, c = im.shape
        if c > 1:
            img = 0.2126 * im[:, :, 0] + 0.7152 * im[:, :,
                                                     1] + 0.0722 * im[:, :, 2]
        else:
            img = im

        assert k_size == 3 or k_size == 5

        if k_size == 3:
            kh = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]], dtype=np.float)
            kv = np.array([[1, 2, 1], [0, 0, 0], [-1, -2, -1]], dtype=np.float)
        else:
            kh = np.array(
                [
                    [-1, -2, 0, 2, 1],
                    [-4, -8, 0, 8, 4],
                    [-6, -12, 0, 12, 6],
                    [-4, -8, 0, 8, 4],
                    [-1, -2, 0, 2, 1],
                ],
                dtype=np.float,
            )
            kv = np.array(
                [
                    [1, 4, 6, 4, 1],
                    [2, 8, 12, 8, 2],
                    [0, 0, 0, 0, 0],
                    [-2, -8, -12, -8, -2],
                    [-1, -4, -6, -4, -1],
                ],
                dtype=np.float,
            )

        gx = convolve2d(img, kh, mode="same", boundary="symm")
        gy = convolve2d(img, kv, mode="same", boundary="symm")

        g = np.sqrt(gx * gx + gy * gy)
        g *= 255.0 / np.max(g)

        return g
コード例 #3
0
def conv2d(data_in: ndarray, kernel: ndarray, stride: int = 1):
    """
    Perform a 2D convolution over a batch of tensors. This is equivalent to

     output[b, i, j, k] =
         sum_{di, dj, q} input[b, strides[1] * i + di, strides[2] * j + dj, q] *
                         filter[di, dj, q, k]

    :param data_in: Input data tensor with shape [batch, height, width, channels_in]
    :param kernel: Convolution kernel tensor with shape [kernel_height, kernel_width, channels_in, channels_out]
    :param stride: Integer for the step width
    :return: Tensor with shape [batch, height/stride, width/stride, channels_out]
    """

    # Obtain shapes
    fh, fw, kin_ch, kout_ch = kernel.shape
    batch, in_h, in_w, in_ch = data_in.shape

    if kin_ch != in_ch:
        raise ValueError("Input channel mismatch")

    # Check if the filter has an uneven width
    assert (1 == fh % 2)
    assert (1 == fw % 2)

    # Find the midpoint of the filter. This only works for odd filter sizes
    fh2 = int((fh - 1) / 2)
    fw2 = int((fw - 1) / 2)

    # Given an input tensor of shape [batch, in_height, in_width, in_channels] and a filter / kernel tensor of
    # shape [filter_height, filter_width, in_channels, out_channels], this op performs the following:
    #
    # 1) Flattens the filter to a 2-D matrix with shape [filter_height * filter_width * in_channels,
    # output_channels].
    #
    # 2) Extracts image patches from the input tensor to form a virtual tensor of shape [batch,
    # out_height, out_width, filter_height * filter_width * in_channels].
    #
    # 3) For each patch, right-multiplies the
    # filter matrix and the image patch vector
    if kernel.dtype.kind in 'ui':  # check if datatype is unsigned or integer
        out = np.zeros(shape=[batch, in_h, in_w, kout_ch], dtype=np.int32)
    else:
        out = np.zeros(shape=[batch, in_h, in_w, kout_ch], dtype=data_in.dtype)
    # pad input
    in_padded = np.pad(data_in, ((0, 0), (fh2, fh2), (fw2, fw2), (0, 0)),
                       'constant',
                       constant_values=(0, 0))
    # in_padded = np.pad(data_in, ((0, 0), (30, 30), (30, 30), (0, 0)), 'constant', constant_values=(0, 0))
    # img = np.squeeze(in_padded)
    # fig, ax = plt.subplots()
    # _im = ax.imshow(img, cmap='gray')
    # fig.colorbar(_im)
    # plt.show()

    # kflat = np.reshape(kernel, newshape=(-1, kout_ch))
    # vout = np.zeros(shape=(batch, in_h, in_w, fh * fw * in_ch))  # create virtual out
    #
    # for b in range(batch):
    #     for i in range(in_h):
    #         for j in range(in_w):
    #             vout[b, i, j, :] = np.reshape(in_padded[b, i:i+fh, j:j+fw, :], newshape=(-1))
    #
    # out = np.dot(vout, kflat)

    # output[b, i, j, k] =
    #     sum_{di, dj, q} input[b, strides[1] * i + di, strides[2] * j + dj, q] *
    #                     filter[di, dj, q, k]

    for b in range(batch):
        for k in range(kout_ch):
            # k = kernel[:, :, q, k]  # 2d kernel

            # Perform convolution
            i_out, j_out = 0, 0
            for i in range(0, in_h, stride):
                for j in range(0, in_w, stride):
                    patch = in_padded[b, i:i + fh,
                                      j:j + fw, :]  # 3d tensor 3x3x16

                    if kernel.dtype.kind in 'ui':  # check if datatype is unsigned or integer
                        patch16 = patch.astype(np.int16)
                        kernel16 = kernel.astype(np.int16)
                        temp = patch16 * kernel16[:, :, :, k]
                        temp = temp.flatten().astype(np.int64)
                        # patch_sum = np.sum(patch * kernel[:, :, :, k], axis=(0, 1, 2))  # sum along all axis
                        # min_value = np.iinfo(kernel.dtype).min
                        # max_value = np.iinfo(kernel.dtype).max
                        patch_sum = np.sum(temp)
                        out[b, i_out, j_out, k] = patch_sum
                    else:
                        # patch_sum is always int64
                        patch_sum = np.sum(patch * kernel[:, :, :, k],
                                           axis=(0, 1,
                                                 2))  # sum along all axis
                        out[b, i_out, j_out, k] = patch_sum
                    j_out += 1
                j_out = 0
                i_out += 1

    return out