Skip to content
Snippets Groups Projects
Select Git revision
  • input_conditionals
  • master default protected
  • caml2
  • caml
  • cache
5 results

testppm.elf

Blame
  • __init__.py 8.71 KiB
    import numpy as np
    
    from math import pi
    from numpy import cos
    
    class _Linear_Operations_1D():
        def __init__(self, _nb):
            self.nb = _nb
            self.nc = _nb*8+2
            
        def __call__(self, **argv):
            _op = argv.get('operation')
            _par = argv.get('parameters')
            
            if(_op == 'demosaicking'):
                return self._demosaicking(_par)
            elif(_op == 'convolution'):
                return self._convolve(_par)
            elif(_op == 'selection'):
                return self._selection()
            elif(_op == 'permutation'):
                return self._permutation()
            elif(_op == 'transpose'):
                return self._transpose()
            elif(_op == 'dct'):
                return self._dct()
            
        def _demosaicking(self, _channel):  
            if(_channel == 'R'):
                return self._MatConvolution1D(self.nb)(color=_channel)
            elif(_channel == 'G'):
                return self._MatConvolution1D(self.nb)(color=_channel)
            elif(_channel == 'B'):
                return self._MatConvolution1D(self.nb)(color=_channel)
            elif(_channel == 'Y'):
                return 0.299*self._MatConvolution1D(self.nb)(color='R')+0.587*self._MatConvolution1D(self.nb)(color='G')+0.114*self._MatConvolution1D(self.nb)(color='B')
            elif(_channel == 'Cb'):
                return -0.169*self._MatConvolution1D(self.nb)(color='R')-0.331*self._MatConvolution1D(self.nb)(color='G')+0.5*self._MatConvolution1D(self.nb)(color='B')
            elif(_channel == 'Cr'):
                return 0.5*self._MatConvolution1D(self.nb)(color='R')-0.419*self._MatConvolution1D(self.nb)(color='G')-0.081*self._MatConvolution1D(self.nb)(color='B')
            
        def _convolve(self, _kernel):
            return self._MatConvolution1D(self.nb)(kernel = _kernel)
        
        def _selection(self):
            n_c_2 = self.nb*8
        
            S = np.zeros((n_c_2**2,self.nc**2))
            id_pix = np.eye(n_c_2)
            for i in range(n_c_2):
                S[i*n_c_2:(i+1)*n_c_2,self.nc*(i+1)+1:self.nc*(i+1)+1+n_c_2] = id_pix
                
            return S
        
        def _permutation(self): 
            perm_coeff_dct = np.zeros(((self.nb*8)**2,(self.nb*8)**2))
            id_8_8 = np.eye(8)
            
            for k in range(self.nb):# bloc index y-axis
                for j in range(self.nb):# bloc index x-axis
                    for i in range(8): # bloc line
                        perm_coeff_dct[j*64 + k*self.nb*64 + i*8: j*64 + 8 +k*self.nb*64 + i*8, k*self.nb*64 + i*self.nb*8 + j*8 : k*self.nb*64 + i*self.nb*8+8 + j*8] = id_8_8 
    
            ### Bloc position
            #+ FAG
            #+ BCD
            #+ HEI
    
            ### Observations
            #+ CABDEFGHI            
            P_E = np.zeros(((self.nb*8)**2,(self.nb*8)**2))            
            if self.nb==3:
                P_E[:64,:] =     perm_coeff_dct[4*64:5*64,:]
                P_E[64:2*64,:] =     perm_coeff_dct[64:2*64,:]
                P_E[2*64:3*64,:] =     perm_coeff_dct[3*64:4*64,:]
                P_E[3*64:4*64,:] =     perm_coeff_dct[5*64:6*64,:]
                P_E[4*64:5*64,:] =     perm_coeff_dct[7*64:8*64,:]
                P_E[5*64:6*64,:] =     perm_coeff_dct[:1*64,:]
                P_E[6*64:7*64,:] =     perm_coeff_dct[2*64:3*64,:]
                P_E[7*64:8*64,:] =     perm_coeff_dct[6*64:7*64,:]
                P_E[8*64:9*64,:] =     perm_coeff_dct[8*64:,:]
            else:
                P_E = perm_coeff_dct
            return P_E
        
        def _transpose(self):
            return 0
    
        def _dct(self):
            n_c_2 = self.nb*8
    
            N = 8
            pi = np.pi
            C = np.sqrt(2.0/N)
            a, b, c, d, e, f, g = C*cos(pi/4) , C*cos(pi/16), C*cos(pi/8), C*cos(3*pi/16), C*cos(5*pi/16), C*cos(3*pi/8), C*cos(7*pi/16)
    
            A = np.array([\
                        [a,a,a,a,a,a,a,a], \
                        [b,d,e,g,-g,-e,-d,-b], \
                        [c,f,-f,-c,-c,-f,f,c], \
                        [d,-g,-b,-e,e,b,g,-d], \
                        [a,-a,-a,a,a,-a,-a,a], \
                        [e,-b,g,d,-d,-g,b,-e], \
                        [f,-c,c,-f,-f,c,-c,f], \
                        [g,-e,d,-b,b,-d,e,-g]])
    
            DCT_mat_on_vec = np.zeros((64,64))
    
            for i in range(8):
                DCT_mat_on_vec[i*8:i*8+8,i*8:i*8+8]=A
    
            idx =  np.arange(64)
            idx = idx.reshape((8,8), order='C')
            idx_T = idx.T
            idx_F = idx_T.flatten('C')
            mat_T = np.zeros((64,64))
            for i in range(64):
                mat_T[i,idx_F[i]]=1
    
            DCT_T_vec = np.dot(DCT_mat_on_vec, mat_T)
    
    
            T = np.dot(DCT_T_vec,DCT_T_vec)
    
            D_T = np.zeros((n_c_2**2,n_c_2**2))
    
            for i in range(self.nb**2):
                D_T[i*64: i*64+64, i*64: i*64+64] = T[:,:]
    
            return D_T
    
        class _MatConvolution1D():
            class limits():
                def __init__(self, _min, _max):
                    self.min, self.max = _min, _max
    
                def __call__(self, _i):
                    if(_i < self.min):
                        return self.min
                    elif(_i > self.max):
                        return self.max
                    else:
                        return _i
                
            def __init__(self, _nb):
                self.nb = _nb
                self.n = _nb*4
                self.l = self.limits(0, 2*self.n+2)
    
                #Demosaicking kernels
                self.kR = (1/4.0)*np.array([[1, 2, 1], [2, 4, 2], [1, 2, 1]])
                self.kG = (1/4.0)*np.array([[0, 1, 0], [1, 4, 1], [0, 1, 0]])
                self.kB = (1/4.0)*np.array([[1, 2, 1], [2, 4, 2], [1, 2, 1]])
    
                self.maskR = np.kron(np.ones((2, 2)), np.array([[0, 1], [0, 0]]))[:3, :3].astype(bool)
                self.maskG = np.kron(np.ones((2, 2)), np.array([[1, 0], [0, 1]]))[:3, :3].astype(bool)
                self.maskB = np.kron(np.ones((2, 2)), np.array([[0, 0], [1, 0]]))[:3, :3].astype(bool)
    
            def __call__(self, kernel = None, color = None):
                self.demosaicking = False
    
                if(color == 'R'):
                    self.demosaicking, self.kernel, self.mask = True, self.kR, self.maskR
                elif(color == 'G'):
                    self.demosaicking, self.kernel, self.mask = True, self.kG, self.maskG 
                elif(color == 'B'):
                    self.demosaicking, self.kernel, self.mask = True, self.kB, self.maskB
    
                if(kernel is not None):
                    self.kernel = np.array(kernel)
    
                block_conv = np.zeros(((2*self.n + 2)**2, (2*self.n + 2)**2))
                _offset = self.kernel.shape[0]
                _l, _r = int(np.floor(_offset/2.0)), int(np.ceil(_offset/2.0))
    
                if(self.demosaicking):
                    canvas = np.kron(np.ones((4*self.nb+2, 4*self.nb+2)), self.mask[:2, :2])[1:-1, 1:-1].astype(bool)
                    for i in range(0, 2*self.n+2, 1):
                        for j in range(0, 2*self.n+2, 1):
                            _M = canvas[self.l(i-_l):self.l(i+_r), self.l(j-_l):self.l(j+_r)]
                            _K = self.kernel[self.l(i-_l)-(i-_l):_offset+self.l(i+_r)-(i+_r), 
                                             self.l(j-_l)-(j-_l):_offset+self.l(j+_r)-(j+_r)]
    
                            conv_mat = np.zeros((2*self.n + 2, 2*self.n + 2))
                            conv_mat[self.l(i-_l):self.l(i+_r), self.l(j-_l):self.l(j+_r)] = _M*_K
                            block_conv[i*(2*self.n + 2)+j, :] = np.ravel(conv_mat)
                else:
                    for i in range(0, 2*self.n + 2, 1):
                        for j in range(0, 2*self.n + 2, 1):
                            conv_mat = np.zeros((2*self.n + 2, 2*self.n + 2))
                            conv_mat[self.l(i-_l):self.l(i+_r), self.l(j-_l):self.l(j+_r)] = self.kernel[self.l(i-_l)-(i-_l):_offset+self.l(i+_r)-(i+_r), 
                                                                                                         self.l(j-_l)-(j-_l):_offset+self.l(j+_r)-(j+_r)]
                            block_conv[i*(2*self.n + 2)+j, :] = np.ravel(conv_mat)
    
                return block_conv
    
    def getConvolutionMatrix(_kernel):
        return _Linear_Operations_1D(1)(operation = 'convolution', parameters = _kernel)
    
    def getConvolutionDemosaickingMatrix(_nb, _channel):
        return _Linear_Operations_1D(_nb)(operation = 'demosaicking', parameters = _channel)
    
    def getSelectionMatrix(_nb):
        return _Linear_Operations_1D(_nb)(operation = 'selection')
    
    def getPermutationMatrix(_nb):
        return _Linear_Operations_1D(_nb)(operation = 'permutation')
    
    def getTransposeMatrix(_nb):
        return _Linear_Operations_1D(_nb)(operation = 'transpose')
    
    def getDctMatrix(_nb):
        return _Linear_Operations_1D(_nb)(operation = 'dct')
    
    def getPhotositesToDctMatrix(_nb, _channel):
        M_D = getConvolutionDemosaickingMatrix(_nb, _channel)
        M_S = getSelectionMatrix(_nb)
        M_P = getPermutationMatrix(_nb)
        M_T = getDctMatrix(_nb)
        M = np.dot(M_T, np.dot(M_P, np.dot(M_S, M_D)))
        return M