Skip to content

Commit f697e60

Browse files
committedJun 18, 2024
tf bro
1 parent 530f414 commit f697e60

7 files changed

+200
-408
lines changed
 

‎dct_functions.py

-8
This file was deleted.

‎dct_comparison.py ‎dct_module.py

+21-44
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
import numpy as np
2+
from scipy.fftpack import dct, idct
23
import time
3-
import matplotlib.pyplot as plt
4-
import threading
54
import queue
6-
from dct_functions import dct2, idct2
75

86
def dct2_manual(matrix):
97
N = matrix.shape[0]
@@ -33,10 +31,17 @@ def idct2_manual(matrix):
3331
result[x, y] = sum_val
3432
return result
3533

34+
def dct2(matrix):
35+
return dct(dct(matrix.T, norm='ortho').T, norm='ortho')
36+
37+
def idct2(matrix):
38+
return idct(idct(matrix.T, norm='ortho').T, norm='ortho')
39+
3640
def compare_dct2_algorithms(progress_queue, plot_queue):
37-
sizes = [8, 16, 32, 64]
41+
sizes = [8, 16, 32]
3842
manual_times = []
3943
library_times = []
44+
iterations = 10 # Numero di iterazioni per mediare i tempi
4045

4146
total_steps = len(sizes) * 2
4247
step = 0
@@ -45,52 +50,24 @@ def compare_dct2_algorithms(progress_queue, plot_queue):
4550
print("size: ", size)
4651
matrix = np.random.rand(size, size).astype(np.float32)
4752

53+
# Misurazione dei tempi per l'algoritmo manuale
4854
start_time = time.time()
49-
dct2_manual(matrix)
50-
manual_times.append(time.time() - start_time)
55+
for _ in range(iterations):
56+
dct2_manual(matrix)
57+
manual_times.append((time.time() - start_time) / iterations)
5158
step += 1
5259
progress_queue.put((step / total_steps) * 100)
5360

61+
# Misurazione dei tempi per l'algoritmo della libreria
5462
start_time = time.time()
55-
dct2(matrix)
56-
library_times.append(time.time() - start_time)
63+
for _ in range(iterations):
64+
dct2(matrix)
65+
library_times.append((time.time() - start_time) / iterations)
5766
step += 1
5867
progress_queue.put((step / total_steps) * 100)
59-
68+
print("Sizes: ", sizes)
69+
print("Manual times: ", manual_times)
70+
print("Library times: ", library_times)
71+
6072
progress_queue.put("done")
6173
plot_queue.put((sizes, manual_times, library_times))
62-
63-
def compare_dct2_algorithms_thread(progress_var, progress_bar, root):
64-
progress_queue = queue.Queue()
65-
plot_queue = queue.Queue()
66-
threading.Thread(target=compare_dct2_algorithms, args=(progress_queue, plot_queue)).start()
67-
root.after(100, check_progress, progress_queue, progress_var, progress_bar, root)
68-
root.after(100, check_plot, plot_queue, root)
69-
70-
def check_progress(progress_queue, progress_var, progress_bar, root):
71-
try:
72-
progress = progress_queue.get_nowait()
73-
if progress == "done":
74-
return
75-
progress_var.set(progress)
76-
progress_bar.update_idletasks()
77-
except queue.Empty:
78-
pass
79-
root.after(100, check_progress, progress_queue, progress_var, progress_bar, root)
80-
81-
def check_plot(plot_queue, root):
82-
try:
83-
plot_data = plot_queue.get_nowait()
84-
sizes, manual_times, library_times = plot_data
85-
86-
plt.figure()
87-
plt.plot(sizes, manual_times, label='Manual DCT2 ', marker='o')
88-
plt.plot(sizes, library_times, label='Library DCT2', marker='o')
89-
plt.xlabel('Matrix size (N)')
90-
plt.ylabel('Time (s)')
91-
plt.yscale('log')
92-
plt.legend()
93-
plt.title('Comparison of DCT2 Algorithms')
94-
plt.show()
95-
except queue.Empty:
96-
root.after(100, check_plot, plot_queue, root)

‎gui_module.py

+136
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
import tkinter as tk
2+
from tkinter import ttk, filedialog, messagebox
3+
from PIL import Image, ImageTk
4+
import os
5+
from image_processing_module import process_image, resize_image
6+
import threading
7+
import queue
8+
import matplotlib.pyplot as plt
9+
from dct_module import compare_dct2_algorithms
10+
11+
def load_image():
12+
file_path = filedialog.askopenfilename(filetypes=[("BMP files", "*.bmp")])
13+
if not file_path:
14+
return
15+
16+
file_label.config(text=file_path)
17+
original_image = Image.open(file_path)
18+
resized_original_image = resize_image(original_image, 400, 400)
19+
original_photo = ImageTk.PhotoImage(resized_original_image)
20+
img_label.config(image=original_photo)
21+
img_label.image = original_photo
22+
23+
try:
24+
F = int(f_entry.get() or 10)
25+
d = int(d_entry.get() or 7)
26+
except ValueError:
27+
messagebox.showerror("Error", "Invalid F or d value")
28+
return
29+
30+
original_size = os.path.getsize(file_path)
31+
compressed_file_path = process_image(file_path, F, d)
32+
if compressed_file_path:
33+
compressed_size = os.path.getsize(compressed_file_path)
34+
compression_ratio = 100 * (original_size - compressed_size) / original_size
35+
compression_label.config(text=f"Dimensione originale: {original_size} bytes\n"
36+
f"Dimensione compressa: {compressed_size} bytes\n"
37+
f"Compressione: {compression_ratio:.2f}%")
38+
39+
compressed_image = Image.open(compressed_file_path)
40+
resized_compressed_image = resize_image(compressed_image, 400, 400)
41+
compressed_photo = ImageTk.PhotoImage(resized_compressed_image)
42+
compressed_img_label.config(image=compressed_photo)
43+
compressed_img_label.image = compressed_photo
44+
45+
def toggle_normalize():
46+
global normalize_coefficients
47+
normalize_coefficients = not normalize_coefficients
48+
print("normalize_coefficients set to", normalize_coefficients)
49+
50+
def compare_dct2_algorithms_thread(progress_var, progress_bar):
51+
progress_queue = queue.Queue()
52+
plot_queue = queue.Queue()
53+
threading.Thread(target=compare_dct2_algorithms, args=(progress_queue, plot_queue)).start()
54+
root.after(100, check_progress, progress_queue, progress_var, progress_bar)
55+
root.after(100, check_plot, plot_queue)
56+
57+
def check_progress(progress_queue, progress_var, progress_bar):
58+
try:
59+
progress = progress_queue.get_nowait()
60+
if progress == "done":
61+
return
62+
progress_var.set(progress)
63+
progress_bar.update_idletasks()
64+
except queue.Empty:
65+
pass
66+
root.after(100, check_progress, progress_queue, progress_var, progress_bar)
67+
68+
def check_plot(plot_queue):
69+
try:
70+
plot_data = plot_queue.get_nowait()
71+
sizes, manual_times, library_times = plot_data
72+
73+
plt.figure()
74+
plt.plot(sizes, manual_times, label='Manual DCT2 ', marker='o')
75+
plt.plot(sizes, library_times, label='Library DCT2', marker='o')
76+
plt.xlabel('Matrix size (N)')
77+
plt.ylabel('Time (s)')
78+
plt.yscale('log')
79+
plt.legend()
80+
plt.title('Comparison of DCT2 Algorithms')
81+
plt.show()
82+
except queue.Empty:
83+
root.after(100, check_plot, plot_queue)
84+
85+
root = tk.Tk()
86+
root.title("Compressione di immagini tramite la DCT")
87+
88+
root.geometry("800x600")
89+
90+
# Menu bar
91+
menu_bar = tk.Menu(root)
92+
root.config(menu=menu_bar)
93+
94+
# Create a Notebook
95+
notebook = ttk.Notebook(root)
96+
notebook.pack(expand=True, fill='both')
97+
98+
# Create frames for each tab
99+
dct_frame = ttk.Frame(notebook)
100+
hello_frame = ttk.Frame(notebook)
101+
102+
notebook.add(dct_frame, text="DCT")
103+
notebook.add(hello_frame, text=("Comp"))
104+
105+
f_entry = tk.Entry(dct_frame)
106+
f_entry.insert(0, "10")
107+
d_entry = tk.Entry(dct_frame)
108+
d_entry.insert(0, "7")
109+
110+
normalize_button = tk.Checkbutton(dct_frame, text="“Normalizzare coefficenti DTC”", command=toggle_normalize)
111+
load_button = tk.Button(dct_frame, text="“Load .bmp image”", command=load_image)
112+
file_label = tk.Label(dct_frame, text="“Nessun file selezionato”")
113+
compression_label = tk.Label(dct_frame, text="””")
114+
115+
image_frame = tk.Frame(dct_frame)
116+
image_frame.pack()
117+
118+
img_label = tk.Label(image_frame)
119+
compressed_img_label = tk.Label(image_frame)
120+
f_entry.pack()
121+
d_entry.pack()
122+
normalize_button.pack()
123+
load_button.pack()
124+
file_label.pack()
125+
compression_label.pack()
126+
img_label.pack(side=tk.LEFT)
127+
compressed_img_label.pack(side=tk.LEFT)
128+
129+
progress_var = tk.DoubleVar()
130+
progress_bar = ttk.Progressbar(hello_frame, variable=progress_var, maximum=100)
131+
progress_bar.pack(pady=10)
132+
133+
compare_button = tk.Button(hello_frame, text="“Compare DCT2 Algorithms”", command=lambda: compare_dct2_algorithms_thread(progress_var, progress_bar))
134+
compare_button.pack()
135+
136+
root.mainloop()

‎image_compression.py ‎image_processing_module.py

+11-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import numpy as np
21
from PIL import Image, ImageOps
3-
from dct_functions import dct2, idct2
2+
import numpy as np
3+
import os
44

55
def process_image(file_path, F, d):
66
try:
@@ -29,6 +29,7 @@ def matrix_to_image(matrix):
2929
return Image.fromarray(np.uint8(normalized_matrix))
3030

3131
def apply_dct_and_idct(matrix, F, d):
32+
from dct_module import dct2, idct2
3233
height, width = matrix.shape
3334
compressed_matrix = np.zeros_like(matrix)
3435

@@ -50,3 +51,11 @@ def filter_frequencies(matrix, d):
5051
if k + l >= d:
5152
matrix[k, l] = 0
5253
return matrix
54+
55+
def resize_image(image, max_width, max_height):
56+
width, height = image.size
57+
if width > max_width or height > max_height:
58+
ratio = min(max_width / width, max_height / height)
59+
new_size = (int(width * ratio), int(height * ratio))
60+
image = image.resize(new_size)
61+
return image

‎main.py

+3-260
Original file line numberDiff line numberDiff line change
@@ -1,261 +1,4 @@
1-
#TODO: Dividere in moduli, testare scaling algoritmo
1+
from gui_module import *
22

3-
import tkinter as tk
4-
from tkinter import ttk, filedialog, messagebox
5-
from PIL import Image, ImageOps, ImageTk
6-
import numpy as np
7-
import time
8-
import matplotlib.pyplot as plt
9-
import os
10-
from scipy.fftpack import dct, idct
11-
import threading
12-
import queue
13-
14-
normalize_coefficients = False
15-
16-
def dct2_manual(matrix):
17-
N = matrix.shape[0]
18-
result = np.zeros_like(matrix, dtype=np.float32)
19-
for u in range(N):
20-
for v in range(N):
21-
sum_val = 0
22-
for x in range(N):
23-
for y in range(N):
24-
sum_val += matrix[x, y] * np.cos(np.pi * u * (2 * x + 1) / (2 * N)) * np.cos(np.pi * v * (2 * y + 1) / (2 * N))
25-
alpha_u = np.sqrt(1/N) if u == 0 else np.sqrt(2/N)
26-
alpha_v = np.sqrt(1/N) if v == 0 else np.sqrt(2/N)
27-
result[u, v] = alpha_u * alpha_v * sum_val
28-
return result
29-
30-
31-
32-
def idct2_manual(matrix):
33-
N = matrix.shape[0]
34-
result = np.zeros_like(matrix, dtype=np.float32)
35-
for x in range(N):
36-
for y in range(N):
37-
sum_val = 0
38-
for u in range(N):
39-
for v in range(N):
40-
alpha_u = np.sqrt(1/N) if u == 0 else np.sqrt(2/N)
41-
alpha_v = np.sqrt(1/N) if v == 0 else np.sqrt(2/N)
42-
sum_val += alpha_u * alpha_v * matrix[u, v] * np.cos(np.pi * u * (2 * x + 1) / (2 * N)) * np.cos(np.pi * v * (2 * y + 1) / (2 * N))
43-
result[x, y] = sum_val
44-
return result
45-
46-
def dct2(matrix):
47-
return dct(dct(matrix.T, norm='ortho').T, norm='ortho')
48-
49-
def idct2(matrix):
50-
return idct(idct(matrix.T, norm='ortho').T, norm='ortho')
51-
52-
def compare_dct2_algorithms(progress_queue, plot_queue):
53-
sizes = [8, 16, 32]
54-
manual_times = []
55-
library_times = []
56-
57-
total_steps = len(sizes) * 2
58-
step = 0
59-
60-
for size in sizes:
61-
print("size: ", size)
62-
matrix = np.random.rand(size, size).astype(np.float32)
63-
64-
start_time = time.time()
65-
dct2_manual(matrix)
66-
manual_times.append(time.time() - start_time)
67-
step += 1
68-
progress_queue.put((step / total_steps) * 100)
69-
70-
start_time = time.time()
71-
dct2(matrix)
72-
library_times.append(time.time() - start_time)
73-
step += 1
74-
progress_queue.put((step / total_steps) * 100)
75-
76-
progress_queue.put("done")
77-
plot_queue.put((sizes, manual_times, library_times))
78-
79-
def compare_dct2_algorithms_thread(progress_var, progress_bar):
80-
progress_queue = queue.Queue()
81-
plot_queue = queue.Queue()
82-
threading.Thread(target=compare_dct2_algorithms, args=(progress_queue, plot_queue)).start()
83-
root.after(100, check_progress, progress_queue, progress_var, progress_bar)
84-
root.after(100, check_plot, plot_queue)
85-
86-
def check_progress(progress_queue, progress_var, progress_bar):
87-
try:
88-
progress = progress_queue.get_nowait()
89-
if progress == "done":
90-
return
91-
progress_var.set(progress)
92-
progress_bar.update_idletasks()
93-
except queue.Empty:
94-
pass
95-
root.after(100, check_progress, progress_queue, progress_var, progress_bar)
96-
97-
def check_plot(plot_queue):
98-
try:
99-
plot_data = plot_queue.get_nowait()
100-
sizes, manual_times, library_times = plot_data
101-
102-
plt.figure()
103-
plt.plot(sizes, manual_times, label='Manual DCT2 ', marker='o')
104-
plt.plot(sizes, library_times, label='Library DCT2', marker='o')
105-
plt.xlabel('Matrix size (N)')
106-
plt.ylabel('Time (s)')
107-
plt.yscale('log')
108-
plt.legend()
109-
plt.title('Comparison of DCT2 Algorithms')
110-
plt.show()
111-
except queue.Empty:
112-
root.after(100, check_plot, plot_queue)
113-
114-
def process_image(file_path, F, d):
115-
try:
116-
img = Image.open(file_path).convert('L')
117-
except Exception as e:
118-
print(f"Error in opening image: {e}")
119-
return ""
120-
121-
gray_img = ImageOps.grayscale(img)
122-
matrix = image_to_matrix(gray_img)
123-
124-
compressed_matrix = apply_dct_and_idct(matrix, F, d)
125-
126-
compressed_img = matrix_to_image(compressed_matrix)
127-
compressed_file_path = "compressed_image.png"
128-
compressed_img.save(compressed_file_path)
129-
130-
return compressed_file_path
131-
132-
def image_to_matrix(img):
133-
return np.array(img, dtype=np.float32)
134-
135-
def matrix_to_image(matrix):
136-
min_val, max_val = matrix.min(), matrix.max()
137-
normalized_matrix = 255 * (matrix - min_val) / (max_val - min_val)
138-
return Image.fromarray(np.uint8(normalized_matrix))
139-
140-
def apply_dct_and_idct(matrix, F, d):
141-
height, width = matrix.shape
142-
compressed_matrix = np.zeros_like(matrix)
143-
144-
for y in range(0, height, F):
145-
for x in range(0, width, F):
146-
if y + F <= height and x + F <= width:
147-
block = matrix[y:y+F, x:x+F]
148-
dct_block = dct2(block)
149-
filtered_dct_block = filter_frequencies(dct_block, d)
150-
idct_block = idct2(filtered_dct_block)
151-
compressed_matrix[y:y+F, x:x+F] = idct_block
152-
153-
return compressed_matrix
154-
155-
def filter_frequencies(matrix, d):
156-
size = matrix.shape[0]
157-
for k in range(size):
158-
for l in range(size):
159-
if k + l >= d:
160-
matrix[k, l] = 0
161-
return matrix
162-
163-
def load_image():
164-
file_path = filedialog.askopenfilename(filetypes=[("BMP files", "*.bmp")])
165-
if not file_path:
166-
return
167-
168-
file_label.config(text=file_path)
169-
original_image = Image.open(file_path)
170-
resized_original_image = resize_image(original_image, 400, 400)
171-
original_photo = ImageTk.PhotoImage(resized_original_image)
172-
img_label.config(image=original_photo)
173-
img_label.image = original_photo
174-
175-
try:
176-
F = int(f_entry.get() or 10)
177-
d = int(d_entry.get() or 7)
178-
except ValueError:
179-
messagebox.showerror("Error", "Invalid F or d value")
180-
return
181-
182-
original_size = os.path.getsize(file_path)
183-
compressed_file_path = process_image(file_path, F, d)
184-
if compressed_file_path:
185-
compressed_size = os.path.getsize(compressed_file_path)
186-
compression_ratio = 100 * (original_size - compressed_size) / original_size
187-
compression_label.config(text=f"Dimensione originale: {original_size} bytes\n"
188-
f"Dimensione compressa: {compressed_size} bytes\n"
189-
f"Compressione: {compression_ratio:.2f}%")
190-
191-
compressed_image = Image.open(compressed_file_path)
192-
resized_compressed_image = resize_image(compressed_image, 400, 400)
193-
compressed_photo = ImageTk.PhotoImage(resized_compressed_image)
194-
compressed_img_label.config(image=compressed_photo)
195-
compressed_img_label.image = compressed_photo
196-
197-
def resize_image(image, max_width, max_height):
198-
width, height = image.size
199-
if width > max_width or height > max_height:
200-
ratio = min(max_width / width, max_height / height)
201-
new_size = (int(width * ratio), int(height * ratio))
202-
image = image.resize(new_size)
203-
return image
204-
205-
def toggle_normalize():
206-
global normalize_coefficients
207-
normalize_coefficients = not normalize_coefficients
208-
print("normalize_coefficients set to", normalize_coefficients)
209-
210-
root = tk.Tk()
211-
root.title("Compressione di immagini tramite la DCT")
212-
213-
root.geometry("800x600")
214-
215-
# Menu bar
216-
menu_bar = tk.Menu(root)
217-
root.config(menu=menu_bar)
218-
219-
# Create a Notebook
220-
notebook = ttk.Notebook(root)
221-
notebook.pack(expand=True, fill='both')
222-
223-
# Create frames for each tab
224-
dct_frame = ttk.Frame(notebook)
225-
hello_frame = ttk.Frame(notebook)
226-
227-
notebook.add(dct_frame, text="DCT")
228-
notebook.add(hello_frame, text=("Comp"))
229-
230-
f_entry = tk.Entry(dct_frame)
231-
f_entry.insert(0, "10")
232-
d_entry = tk.Entry(dct_frame)
233-
d_entry.insert(0, "7")
234-
235-
normalize_button = tk.Checkbutton(dct_frame, text="“Normalizzare coefficenti DTC”", command=toggle_normalize)
236-
load_button = tk.Button(dct_frame, text="“Load .bmp image”", command=load_image)
237-
file_label = tk.Label(dct_frame, text="“Nessun file selezionato”")
238-
compression_label = tk.Label(dct_frame, text="””")
239-
240-
image_frame = tk.Frame(dct_frame)
241-
image_frame.pack()
242-
243-
img_label = tk.Label(image_frame)
244-
compressed_img_label = tk.Label(image_frame)
245-
f_entry.pack()
246-
d_entry.pack()
247-
normalize_button.pack()
248-
load_button.pack()
249-
file_label.pack()
250-
compression_label.pack()
251-
img_label.pack(side=tk.LEFT)
252-
compressed_img_label.pack(side=tk.LEFT)
253-
254-
progress_var = tk.DoubleVar()
255-
progress_bar = ttk.Progressbar(hello_frame, variable=progress_var, maximum=100)
256-
progress_bar.pack(pady=10)
257-
258-
compare_button = tk.Button(hello_frame, text="“Compare DCT2 Algorithms”", command=lambda: compare_dct2_algorithms_thread(progress_var, progress_bar))
259-
compare_button.pack()
260-
261-
root.mainloop()
3+
if __name__ == "__main__":
4+
root.mainloop()

‎test_dct.py

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import unittest
2+
import numpy as np
3+
from dct_module import dct2_manual, idct2_manual, dct2, idct2
4+
5+
class TestDCT(unittest.TestCase):
6+
7+
def setUp(self):
8+
self.matrix = np.random.rand(8, 8).astype(np.float32)
9+
10+
def test_dct2_manual(self):
11+
dct_manual = dct2_manual(self.matrix)
12+
self.assertEqual(dct_manual.shape, self.matrix.shape)
13+
14+
def test_idct2_manual(self):
15+
dct_manual = dct2_manual(self.matrix)
16+
idct_manual = idct2_manual(dct_manual)
17+
np.testing.assert_almost_equal(self.matrix, idct_manual, decimal=5)
18+
19+
def test_dct2(self):
20+
dct_lib = dct2(self.matrix)
21+
self.assertEqual(dct_lib.shape, self.matrix.shape)
22+
23+
def test_idct2(self):
24+
dct_lib = dct2(self.matrix)
25+
idct_lib = idct2(dct_lib)
26+
np.testing.assert_almost_equal(self.matrix, idct_lib, decimal=5)
27+
28+
if __name__ == '__main__':
29+
unittest.main()

‎ui_setup.py

-94
This file was deleted.

0 commit comments

Comments
 (0)
Please sign in to comment.