Select Git revision
testppm.elf
__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