-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcompress.py
170 lines (131 loc) · 4.36 KB
/
compress.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
import numpy as np
import matplotlib.pyplot as plt
import math
def EvenExtension(f):
'''
fe = EvenExtension(f)
Performs an even extension on the array f.
Input:
f is a 2D array
Output:
fe is the even extension of f
If f has dimensions NxM, then fe has dimensions
(2*N-2)x(2*M-2)
and fe[n,j]=fe[-n,j] for n=0,...,N-1
and fe[n,j]=fe[n,-j] for j=0,...,M-1
For example, if f is 5x4, then fe has dimensions 8x6.
IEvenExtension is the inverse of EvenExtension, so that
IEvenExtension(EvenExtension(f)) == f
for any matrix f.
'''
fe = np.concatenate((f,np.fliplr(f[:,1:-1])), axis=1)
fe = np.concatenate((fe, np.flipud(fe[1:-1,:])), axis=0)
return fe
def IEvenExtension(fe):
'''
f = IEvenExtension(fe)
Reverses the action of an even extension.
Input:
fe is a 2D array, assumed to contain an even extension
Output:
f is the sub-array that was used to generate the extension
If fe has dimensions KxL, then f has dimensions
ceil((K+1)/2) x ceil((L+1)/2)
For example, if fe is 8x6, then f is 5x4.
IEvenExtension is the inverse of EvenExtension, so that
IEvenExtension(EvenExtension(f)) == f
for any matrix f.
'''
e_dims = np.array(np.shape(fe))
dims = np.ceil((e_dims+1.)/2)
dims = np.array(dims, dtype=int)
f = fe[:dims[0], :dims[1]]
return f
def myDCT(f):
'''
Fdct = myDCT(f)
Computes the 2-D Discrete Cosine Transform of input image f.
It uses an even extension of f, along with the 2D-DFT.
This function is the inverse of myIDCT.
Input:
f is a 2-D array of real values
Output:
Fdct is a real-valued array the same size as f
'''
fe = EvenExtension(f) # Even extension of f
Fe = np.fft.fft2(fe).real # compute the DFT of Even extension of f
F = IEvenExtension(Fe) # Get Fdct using inverse of Even extension
return F
def myIDCT(Fdct):
'''
f = myIDCT(Fdct)
Computes the 2-D Inverse Discrete Cosine Transform (IDCT) of input
array Fdct. It uses an even extension of Fdct, along with the 2D-IDFT.
This function is the inverse of myDCT.
Input:
Fdct is a 2-D array of real values
Output:
f is a real-valued array the same size as Fdct
'''
Fedct = EvenExtension(Fdct) # Even extension of Fdct
fedct = np.fft.ifft2(Fedct).real # compute the IDFT of Even extension of Fdct
fdct = IEvenExtension(fedct) # Get fedct using inverse of Even extension
return fdct
# YOUR CODE HERE
# A couple functions to help you
def NumPixels(f):
'''
n = NumPixels(f) returns the total number of elements in the array f.
For example,
NumPixels( np.ones((5,4)) )
returns the value 20.
'''
return np.prod(np.shape(f))
def Show(g, title=''):
'''
Show(g, title='')
Displays the image g as a graylevel image with intensities
clipped to the range [0,255].
'''
plt.imshow(np.clip(g, a_min=0, a_max=255), cmap='gray');
plt.axis('off');
plt.title(title);
def myJPEGCompress(f, T, D):
'''
G = myJPEGCompress(f, T, D)
Input
f is the input image, a 2D array of real numbers
T is the tile size to break the input image into
D is the size of the block of Fourier coefficients to keep
(Bigger values of D result in less loss, but less compression)
Output
G is the compressed encoding of the image
Example: If f is 120x120, then
G = myJPEGCompress(f, 10, 4)
would return an array (G) of size 48x48.
'''
#G = f
l1 = np.shape(f)[0]
l2 = np.shape(f)[1]
G = []
i = 0
j = 0
while i < l1:
tD = []
while j < l2:
t = myDCT(f[i:i+T, j:j+T]) # compute DCT for TxT tile
d = t[:D, :D]
if j == 0:
tD = d
else :
tD = np.concatenate((tD,d),axis=1) # concatenate subarrays of tiles
j+=T
if i == 0:
G = tD
else :
G = np.concatenate((G,tD)) # concatenate each row
i+=T
j = 0
return G
f = plt.imread('image.jpg')[:,:,0]
Show(f, 'original')