Ejemplo n.º 1
0
    def test_operator_norm_l2(self):
        L2 = ops.L2Norm(image_size[0] * image_size[1], dtype=global_dtype, backend=global_backend)

        # Check forward operator
        assert np.sum(np.abs(L2 * yp.vec(self.x) - 0.5 * yp.norm(yp.vec(self.x)) ** 2)) < eps, '%f' % np.sum(np.abs(L2 * yp.vec(self.x) - 0.5 * yp.norm(yp.vec(self.x)) ** 2))

        # Check gradient
        L2.gradient_check()
Ejemplo n.º 2
0
    def test_mechanical_operator_vector_sum(self):
        ''' Mechanical test of an operator-vector sum '''
        # Test sum operations here
        A_s = self.A + self.y

        # Forward operator
        assert np.sum(np.abs(A_s * yp.vec(self.x) - (self.A * yp.vec(self.x) + self.y))) < eps

        # Adjoint
        assert np.sum(np.abs(A_s.H(yp.vec(self.x)) - self.A.H(yp.vec(self.x)))) < eps

        # Gradient Numerical Check
        self.A.gradient_check()
Ejemplo n.º 3
0
    def test_operator_matrix_multiply(self):
        matrix_size = (10,10)
        m = yp.rand(matrix_size, global_dtype, global_backend)
        xm = yp.rand(matrix_size[1], global_dtype, global_backend)
        M = ops.MatrixMultiply(m)

        # Check Forward operator
        assert yp.sumb(yp.abs(yp.vec(yp.changeBackend(M * xm, 'numpy')) - yp.vec(yp.changeBackend(m, 'numpy').dot(yp.changeBackend(xm, 'numpy'))))) < eps, "%f" % yp.sumb(yp.abs(yp.changeBackend(M * xm, 'numpy') - yp.changeBackend(m, 'numpy').dot(yp.changeBackend(xm, 'numpy'))[:, np.newaxis]))

        # Check Adjoint
        assert yp.sumb(yp.abs(yp.vec(yp.changeBackend(M.H * xm, 'numpy')) - yp.vec(np.conj(yp.changeBackend(m, 'numpy').T).dot(yp.changeBackend(xm, 'numpy'))))) < eps, "%f" % yp.sumb(yp.abs(yp.changeBackend(M.H * xm, 'numpy') - np.conj(yp.changeBackend(m, 'numpy').T).dot(yp.changeBackend(xm, 'numpy'))[:, np.newaxis]))

        # Check gradient
        M.gradient_check()
Ejemplo n.º 4
0
    def test_mechanical_gradient_3(self):
        ''' Mechanical test for an inner linear operator with outer non-linear operator '''

        L2 = ops.L2Norm(image_size[0] * image_size[1], dtype=global_dtype, backend=global_backend)
        # Data difference function
        Delta = (self.A - self.y)

        # Objective Function
        O = L2 * Delta

        # Check forward operator
        assert np.all(np.abs(O(yp.vec(self.x)) - 0.5 * np.sum(np.abs(Delta * yp.vec(self.x)) ** 2)) < eps)

        # Check gradient operator (adjoint form)
        O.gradient_check()
Ejemplo n.º 5
0
    def test_operator_convolution_circular(self):
        ''' Circular Convolution Operator '''
        # Generate circular convolution operator
        C = ops.Convolution(self.h)

        # Test forward operator
        conv2 = lambda x, h: yp.changeBackend(np.fft.ifftshift((np.fft.ifft2(np.fft.fft2(x, axes=(0,1), norm='ortho') * np.fft.fft2(h, axes=(0,1), norm='ortho'), axes=(0,1), norm='ortho')), axes=(0,1)).astype(yp.getNativeDatatype(global_dtype, 'numpy')), global_backend)

        x_np = yp.changeBackend(self.x, 'numpy')
        h_np = yp.changeBackend(self.h, 'numpy')

        assert np.sum(np.abs(yp.reshape(C * yp.vec(self.x), image_size) - conv2(x_np, h_np)) ** 2) < 1e-3, \
            'SSE (%.4e) is greater than tolerance (%.4e)' % ((np.sum(np.abs((C * yp.vec(self.x)).reshape(image_size)-conv2(x,h)))), eps)

        # Check gradient
        C.gradient_check()
Ejemplo n.º 6
0
    def test_operator_wavelet(self):
        ''' Wavelet Transform Operator '''
        import pywt
        wavelet_list = ['db1', 'haar', 'rbio1.1', 'bior1.1', 'bior4.4', 'sym12']
        for wavelet_test in wavelet_list:
            # Wavelet Transform
            W = ops.WaveletTransform(image_size, wavelet_type=wavelet_test, use_cycle_spinning=False)

            # Check forward operation
            coeffs = pywt.wavedecn(self.x, wavelet=wavelet_test)
            x_wavelet, coeff_slices = pywt.coeffs_to_array(coeffs)
            assert yp.sumb(yp.abs(yp.changeBackend(W * self.x, 'numpy') - x_wavelet)) < eps, "Difference %.6e"

            # Check inverse operation
            coeffs_from_arr = pywt.array_to_coeffs(x_wavelet, coeff_slices)
            cam_recon = pywt.waverecn(coeffs_from_arr, wavelet=wavelet_test)
            assert yp.sumb(yp.abs(W.H * W * self.x - self.x)) < 1e-2

            # Ensure that the wavelet transform isn't just identity (weird bug)
            if W.shape[1] is yp.size(self.x):
                assert yp.sumb(yp.abs(W * yp.vec(self.x) - yp.vec(self.x))) > 1e-2, "%s" % wavelet_test
Ejemplo n.º 7
0
    def test_operator_stacking_nonlinear(self):
        # Create list of operators
        op_list_nonlinear = [
                    ops.FourierTransform(image_size),
                    ops.Identity(image_size),
                    ops.Exponential(image_size)
        ]
        # Horizontally stacked operators
        H_nl = ops.Hstack(op_list_nonlinear)

        # Vertically stack x for forward operator
        x3 = yp.changeBackend(np.vstack((self.x, self.x, self.x)), global_backend)

        # Check forward operation
        y2 = yp.zeros(op_list_nonlinear[0].shape[0], op_list_nonlinear[0].dtype, op_list_nonlinear[0].backend)
        for op in op_list_nonlinear:
            y2 = y2 + yp.vec(op * self.x)

        assert yp.sumb(yp.abs(yp.vec(H_nl(x3)) - y2)) < eps, "%.4e" % yp.sumb(yp.abs(yp.vec(H_nl(x3)) - y2))

        # Check gradient
        H_nl.gradient_check()

        # Create vertically stacked operator
        V_nl = ops.Vstack(op_list_nonlinear)

        # Check forward operator
        y3 = np.empty((0,image_size[1]), dtype=yp.getNativeDatatype(global_dtype, 'numpy'))
        for index, op in enumerate(op_list_nonlinear):
            y3 = np.append(y3, (op * self.x), axis=0)

        y3 = yp.changeBackend(y3, global_backend)

        assert yp.sumb(yp.abs(V_nl * self.x - y3)) < eps, "%.4e" % yp.sumb(yp.abs(V_nl * self.x - y3))

        # Check gradient
        V_nl.gradient_check()
Ejemplo n.º 8
0
    def test_mechanical_gradient_4(self):
        ''' Mechanical test for an outer non-linear operator with outer non-linear operator and a linear operator in-between'''
        shift_true = np.asarray((-5,3)).astype(yp.getNativeDatatype(global_dtype, 'numpy'))

        # Inner non-linear operator, linear operator in middle, and norm on outside
        F = ops.FourierTransform(image_size, dtype=global_dtype, backend=global_backend)
        D_object = ops.Diagonalize((F * yp.vec(self.x)).reshape(image_size), label='D_{object}', dtype=global_dtype, backend=global_backend)
        R = ops.PhaseRamp(image_size, dtype=global_dtype, backend=global_backend)
        A_shift = F.H * D_object * R
        y = A_shift(shift_true)
        L2 = ops.L2Norm(image_size[0] * image_size[1], dtype=global_dtype, backend=global_backend)
        objective = L2 * (A_shift - self.y)

        # Check gradient
        objective.gradient_check()
Ejemplo n.º 9
0
    def test_operator_norm_l1(self):
        L1 = ops.L1Norm(image_size[0] * image_size[1], dtype=global_dtype)

        # Forward operator
        assert np.sum(np.abs(L1 * yp.vec(self.x) - np.sum(np.abs(yp.vec(self.x))))) < eps
Ejemplo n.º 10
0
def demosaic(frame,
             order='grbg',
             bayer_coupling_matrix=None,
             debug=False,
             white_balance=False):

    # bayer_coupling_matrix = None
    # bgrg: cells very green
    # rggb: slight gteen tint

    """Demosaic a frame"""
    frame_out = yp.zeros((int(yp.shape(frame)[0] / 2), int(yp.shape(frame)[1] / 2), 3), yp.getDatatype(frame), yp.getBackend(frame))

    if bayer_coupling_matrix is not None:
        frame_vec = yp.zeros((4, int(yp.shape(frame)[0] * yp.shape(frame)[1] / 4)), yp.getDatatype(frame), yp.getBackend(frame))

        # Cast bayer coupling matrix
        bayer_coupling_matrix = yp.cast(bayer_coupling_matrix,
                                        yp.getDatatype(frame),
                                        yp.getBackend(frame))

        # Define frame vector
        for bayer_pattern_index in range(4):
            pixel_offsets = (0, 0)
            if bayer_pattern_index == 3:
                img_sub = frame[pixel_offsets[0]::2, pixel_offsets[1]::2]
            elif bayer_pattern_index == 1:
                img_sub = frame[pixel_offsets[0]::2, pixel_offsets[1] + 1::2]
            elif bayer_pattern_index == 2:
                img_sub = frame[pixel_offsets[0] + 1::2, pixel_offsets[1]::2]
            elif bayer_pattern_index == 0:
                img_sub = frame[pixel_offsets[0] + 1::2, pixel_offsets[1] + 1::2]
            frame_vec[bayer_pattern_index, :] = yp.dcopy(yp.vec(img_sub))
            if debug:
                print("Channel %d mean is %g" % (bayer_pattern_index, yp.scalar(yp.real(yp.sum(img_sub)))))

        # Perform demosaic using least squares
        result = yp.linalg.lstsq(bayer_coupling_matrix, frame_vec)

        result -= yp.amin(result)
        result /= yp.amax(result)
        for channel in range(3):
            values = result[channel]
            frame_out[:, :, channel] = yp.reshape(values, ((yp.shape(frame_out)[0], yp.shape(frame_out)[1])))
            if white_balance:
                frame_out[:, :, channel] -= yp.amin(frame_out[:, :, channel])
                frame_out[:, :, channel] /= yp.amax(frame_out[:, :, channel])
        return frame_out
    else:
        frame_out = yp.zeros((int(yp.shape(frame)[0] / 2), int(yp.shape(frame)[1] / 2), 3),
                             dtype=yp.getDatatype(frame), backend=yp.getBackend(frame))

        # Get color order from order variable
        b_index = order.find('b')
        r_index = order.find('r')
        g1_index = order.find('g')

        # Get g2 from intersection of sets
        g2_index = set(list(range(4))).difference({b_index, r_index, g1_index}).pop()
        #  +-----+-----+
        #  |  0  |  1  |
        #  +-----+-----|
        #  |  2  |  3  |
        #  +-----+-----|

        if debug:
            import matplotlib.pyplot as plt
            plt.figure()
            plt.imshow(frame[:12, :12])

        r_start = (int(r_index in [2, 3]), int(r_index in [1, 3]))
        g1_start = (int(g1_index in [2, 3]), int(g1_index in [1, 3]))
        g2_start = (int(g2_index in [2, 3]), int(g2_index in [1, 3]))
        b_start = (int(b_index in [2, 3]), int(b_index in [1, 3]))

        frame_out[:, :, 0] = frame[r_start[0]::2, r_start[1]::2]
        frame_out[:, :, 1] = (frame[g1_start[0]::2, g1_start[1]::2] + frame[g2_start[0]::2, g2_start[1]::2]) / 2.0
        frame_out[:, :, 2] = frame[b_start[0]::2, b_start[1]::2]

        # normalize
        frame_out /= yp.max(frame_out)

        # Perform white balancing if desired
        if white_balance:
            clims = []
            for channel in range(3):
                clims.append(yp.max(frame_out[:, :, channel]))
                frame_out[:, :, channel] /= yp.max(frame_out[:, :, channel])

        # Return frame
        return frame_out