Skip to content

Commit 1cfdebd

Browse files
committed
Completed
1 parent 17df806 commit 1cfdebd

18 files changed

+740
-59
lines changed

InterfaceFunctions.py

+35-12
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,18 @@ def __init__(self, master=None):
1818
self.rectangle_id = 0
1919
self.ratio = 0
2020
self.rotate_angle = 0
21+
self.forward_cache = list()
2122

2223
self.canvas = Canvas(self, bg="black", width=1280, height=720)
2324
self.canvas.place(relx=0.5, rely=0.5, anchor=CENTER)
2425

25-
def show_image(self, img=None):
26+
def show_image(self, image=None):
2627
self.clear_canvas()
2728

28-
if img is None:
29+
if image is None:
2930
image = self.master.processed_image.copy()
3031
else:
31-
image = img
32+
image = image
3233

3334
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
3435
height, width, channels = image.shape
@@ -54,24 +55,39 @@ def show_image(self, img=None):
5455
self.canvas.create_image(new_width / 2, new_height / 2, anchor=CENTER, image=self.shown_image)
5556

5657
def contrast(self):
58+
self.master.image_cache.append(self.master.processed_image.copy())
5759
contrast = (ImageEnhance.Contrast(Image.fromarray(self.master.processed_image))).enhance(1.1)
5860
self.master.processed_image = np.array(contrast)
61+
self.master.image_cache.append(self.master.processed_image.copy())
5962
self.show_image()
6063

6164
def flipping(self):
65+
self.master.image_cache.append(self.master.processed_image.copy())
6266
flipping_image = Image.fromarray(self.master.processed_image).copy()
6367
flipping_image = flipping_image.transpose(Image.FLIP_LEFT_RIGHT)
6468
self.master.processed_image = np.array(flipping_image).copy()
69+
self.master.image_cache.append(self.master.processed_image.copy())
6570
self.show_image()
6671

67-
def resizing(self, x=100, y=100):
72+
def resizing(self, x, y):
73+
if x or y == '':
74+
x, y = 500, 500
75+
else:
76+
x, y = int(x), int(y)
77+
self.master.image_cache.append(self.master.processed_image.copy())
6878
self.master.processed_image = np.array(Image.fromarray(self.master.processed_image).resize((x, y)))
79+
self.master.image_cache.append(self.master.processed_image.copy())
6980
self.show_image()
7081

7182
def rotate(self, rotateAngle):
83+
if rotateAngle == '':
84+
rotateAngle = 60
85+
else:
86+
float(rotateAngle)
7287
self.rotate_angle += rotateAngle
7388
self.master.rotating_image = np.array(Image.fromarray(self.master.processed_image).rotate(self.rotate_angle))
74-
self.show_image(img=self.master.rotating_image)
89+
self.master.image_cache.append(self.master.rotating_image.copy())
90+
self.show_image(image=self.master.rotating_image)
7591

7692
def activate_paste(self):
7793
self.canvas.bind("<ButtonPress>", self.start_paste)
@@ -114,11 +130,12 @@ def deactivate_crop(self):
114130
self.master.is_crop_state = False
115131

116132
def start_paste(self, event):
133+
self.master.image_cache.append(self.master.processed_image.copy())
117134
self.x = event.x
118135
self.y = event.y
119136

120137
def start_draw(self, event):
121-
self.master.drawing_cache.append(self.master.processed_image.copy())
138+
self.master.image_cache.append(self.master.processed_image.copy())
122139
self.x = event.x
123140
self.y = event.y
124141

@@ -152,6 +169,7 @@ def draw(self, event):
152169
self.y = event.y
153170

154171
def start_crop(self, event):
172+
self.master.image_cache.append(self.master.processed_image.copy())
155173
self.crop_start_x = event.x
156174
self.crop_start_y = event.y
157175

@@ -191,16 +209,21 @@ def end_crop(self, event):
191209
y = slice(start_y, end_y, 1)
192210

193211
self.master.processed_image = self.master.processed_image[y, x]
212+
self.master.image_cache.append(self.master.processed_image.copy())
194213

195214
self.show_image()
196215

197216
def clear_canvas(self):
198217
self.canvas.delete("all")
199218

200-
def clear_draw(self):
201-
# if u use some filter or adjust after drawing, u lost your filter and adjust changes when released clear draw
202-
# But if u want to not to lost your changes u should add self.master.drawing_cache[0]
203-
# to other parts with processed image. U should change drawing_cache[0] when you change processed_image
204-
if self.master.drawing_cache:
205-
self.master.processed_image = self.master.drawing_cache.pop()
219+
def undo_image(self):
220+
if self.master.image_cache:
221+
self.master.processed_image = self.master.image_cache.pop()
222+
self.forward_cache.append(self.master.processed_image)
223+
self.show_image()
224+
225+
def forward_image(self):
226+
if self.forward_cache:
227+
self.master.processed_image = self.forward_cache.pop()
228+
self.master.image_cache.append(self.master.processed_image)
206229
self.show_image()

ReadMe.docx

33.3 MB
Binary file not shown.

Sample_Images/Beethoven_9.Senfoni.mp3

8.57 MB
Binary file not shown.

Sample_Images/CreationOfAdam1.jpg

116 KB
Loading
7.62 KB
Binary file not shown.
9.06 KB
Binary file not shown.
3.9 KB
Binary file not shown.
5.04 KB
Binary file not shown.
6.81 KB
Binary file not shown.

__pycache__/interface.cpython-38.pyc

9.41 KB
Binary file not shown.

__pycache__/main.cpython-38.pyc

1.47 KB
Binary file not shown.

adjustingTopLevel.py

+240
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
from tkinter import Toplevel, Label, Scale, Button, HORIZONTAL
2+
import cv2
3+
import numpy as np
4+
5+
6+
class AdjustingTopLevel(Toplevel):
7+
8+
def __init__(self, master=None):
9+
Toplevel.__init__(self, master=master, width=255, height=765)
10+
11+
self.isGetApplied = False
12+
self.morphologyDict = {
13+
"isGetHistogram": [False, self.histogram_button_released],
14+
"isGetErosion": [False, True, cv2.MORPH_ERODE],
15+
"isGetDilation": [False, True, cv2.MORPH_DILATE],
16+
"isGetOpen": [False, True, cv2.MORPH_OPEN],
17+
"isGetClose": [False, True, cv2.MORPH_CLOSE],
18+
"isGetGradient": [False, True, cv2.MORPH_GRADIENT],
19+
"isGetTopHat": [False, True, cv2.MORPH_TOPHAT],
20+
"isGetBlackHat": [False, True, cv2.MORPH_BLACKHAT],
21+
"isGetEllipse": [False, True, cv2.MORPH_ELLIPSE],
22+
"isGetRect": [False, True, cv2.MORPH_RECT],
23+
"isGetCross": [False, True, cv2.MORPH_CROSS],
24+
"isGetLogged": [False, self.log_button_released],
25+
"isGetPowerLaw": [False, self.power_law_button_released]
26+
}
27+
self.brightness_value = 0
28+
self.previous_brightness_value = 0
29+
30+
self.original_image = self.master.processed_image
31+
self.processing_image = self.master.processed_image
32+
height, width, channels = self.processing_image.shape
33+
self.brightness_label = Label(self, text="Brightness Scale")
34+
self.brightness_scale = Scale(self, from_=0, to_=2, length=250, resolution=0.1,
35+
orient=HORIZONTAL)
36+
self.r_label = Label(self, text="Red Scale")
37+
self.r_scale = Scale(self, from_=-100, to_=100, length=250, resolution=1,
38+
orient=HORIZONTAL)
39+
self.g_label = Label(self, text="Green Scale")
40+
self.g_scale = Scale(self, from_=-100, to_=100, length=250, resolution=1,
41+
orient=HORIZONTAL)
42+
self.b_label = Label(self, text="Blue Scale")
43+
self.b_scale = Scale(self, from_=-100, to_=100, length=250, resolution=1,
44+
orient=HORIZONTAL)
45+
self.kernelSize_label = Label(self, text="Kernel Grid Size")
46+
self.kernelSize_scale = Scale(self, from_=1, to_=np.gcd(width, height), length=250, resolution=1,
47+
orient=HORIZONTAL)
48+
self.gammaSize_label = Label(self, text="Gamma Size")
49+
self.gammaSize_scale = Scale(self, from_=0.1, to_=10.0, length=250, resolution=0.1,
50+
orient=HORIZONTAL)
51+
self.clipLimitSize_label = Label(self, text="Clip Limit Size")
52+
self.clipLimitSize_scale = Scale(self, from_=2.0, to_=15.0, length=250, resolution=0.1,
53+
orient=HORIZONTAL)
54+
55+
self.histogram_button = Button(self, text="Histogram Equalization", width=20, font="ariel 11 bold")
56+
self.erosion_button = Button(self, text="Erosion", width=10, font="ariel 11 bold")
57+
self.dilation_button = Button(self, text="Dilation", width=10, font="ariel 11 bold")
58+
self.opening_button = Button(self, text="Opening", width=10, font="ariel 11 bold")
59+
self.closing_button = Button(self, text="Closing", width=10, font="ariel 11 bold")
60+
self.gradient_button = Button(self, text="Gradient", width=10, font="ariel 11 bold")
61+
self.topHat_button = Button(self, text="Top Hat", width=10, font="ariel 11 bold")
62+
self.blackHat_button = Button(self, text="Black Hat", width=10, font="ariel 11 bold")
63+
self.ellipse_button = Button(self, text="Ellipse", width=10, font="ariel 11 bold")
64+
self.rect_button = Button(self, text="Rect", width=10, font="ariel 11 bold")
65+
self.cross_button = Button(self, text="Cross", width=10, font="ariel 11 bold")
66+
self.log_button = Button(self, text="Log Transformation", width=20, font="ariel 11 bold")
67+
self.power_law_button = Button(self, text="Power-Law (Gamma)", width=20, font="ariel 11 bold")
68+
self.apply_button = Button(self, text="Apply")
69+
self.preview_button = Button(self, text="Preview")
70+
self.cancel_button = Button(self, text="Cancel")
71+
self.clear_button = Button(self, text="Clear")
72+
self.brightness_scale.set(1)
73+
self.kernelSize_scale.set(8)
74+
self.gammaSize_scale.set(0.5)
75+
self.clipLimitSize_scale.set(2.0)
76+
77+
self.histogram_button.bind("<ButtonRelease>", self.histogram_button_released)
78+
self.erosion_button.bind("<ButtonRelease>", self.erosion_button_released)
79+
self.dilation_button.bind("<ButtonRelease>", self.dilation_button_released)
80+
self.opening_button.bind("<ButtonRelease>", self.opening_button_released)
81+
self.closing_button.bind("<ButtonRelease>", self.closing_button_released)
82+
self.gradient_button.bind("<ButtonRelease>", self.gradient_button_released)
83+
self.topHat_button.bind("<ButtonRelease>", self.topHat_button_released)
84+
self.blackHat_button.bind("<ButtonRelease>", self.blackHat_button_released)
85+
self.ellipse_button.bind("<ButtonRelease>", self.ellipse_button_released)
86+
self.rect_button.bind("<ButtonRelease>", self.rect_button_released)
87+
self.cross_button.bind("<ButtonRelease>", self.cross_button_released)
88+
self.log_button.bind("<ButtonRelease>", self.log_button_released)
89+
self.power_law_button.bind("<ButtonRelease>", self.power_law_button_released)
90+
self.apply_button.bind("<ButtonRelease>", self.apply_button_released)
91+
self.preview_button.bind("<ButtonRelease>", self.preview_button_released)
92+
self.cancel_button.bind("<ButtonRelease>", self.cancel_button_released)
93+
self.clear_button.bind("<ButtonRelease>", self.clear_button_released)
94+
95+
self.brightness_label.place(x=95, y=0)
96+
self.brightness_scale.place(x=0, y=20)
97+
self.r_label.place(x=100, y=60)
98+
self.r_scale.place(x=0, y=80)
99+
self.g_label.place(x=100, y=120)
100+
self.g_scale.place(x=0, y=140)
101+
self.b_label.place(x=100, y=180)
102+
self.b_scale.place(x=0, y=200)
103+
self.kernelSize_label.place(x=90, y=240)
104+
self.kernelSize_scale.place(x=0, y=255)
105+
self.erosion_button.place(x=0, y=300)
106+
self.dilation_button.place(x=120, y=300)
107+
self.opening_button.place(x=0, y=340)
108+
self.closing_button.place(x=120, y=340)
109+
self.gradient_button.place(x=0, y=380)
110+
self.topHat_button.place(x=120, y=380)
111+
self.blackHat_button.place(x=0, y=420)
112+
self.ellipse_button.place(x=120, y=420)
113+
self.rect_button.place(x=0, y=460)
114+
self.cross_button.place(x=120, y=460)
115+
self.log_button.place(x=20, y=500)
116+
self.clipLimitSize_label.place(x=90, y=540)
117+
self.clipLimitSize_scale.place(x=0, y=560)
118+
self.histogram_button.place(x=20, y=600)
119+
self.gammaSize_label.place(x=95, y=640)
120+
self.gammaSize_scale.place(x=0, y=660)
121+
self.power_law_button.place(x=20, y=700)
122+
self.cancel_button.place(x=0, y=740)
123+
self.clear_button.place(x=90, y=740)
124+
self.preview_button.place(x=140, y=740)
125+
self.apply_button.place(x=200, y=740)
126+
127+
def histogram_button_released(self, event):
128+
self.morphologyDict["isGetHistogram"][0] = True
129+
ycrcb_img = cv2.cvtColor(self.processing_image, cv2.COLOR_RGB2YCrCb)
130+
ycrcb_img[:, :, 0] = cv2.equalizeHist(ycrcb_img[:, :, 0])
131+
132+
clahe = cv2.createCLAHE(clipLimit=float(self.clipLimitSize_scale.get()),
133+
tileGridSize=(int(self.kernelSize_scale.get()), int(self.kernelSize_scale.get())))
134+
ycrcb_img[:, :, 0] = clahe.apply(ycrcb_img[:, :, 0])
135+
self.processing_image = cv2.cvtColor(ycrcb_img, cv2.COLOR_YCrCb2RGB)
136+
137+
def get_kernel(self, morph_name):
138+
kernel = None
139+
size = int(self.kernelSize_scale.get())
140+
141+
try:
142+
kernel = cv2.getStructuringElement(shape=self.morphologyDict[morph_name][2], ksize=(size, size))
143+
except cv2.error:
144+
kernel = cv2.getStructuringElement(shape=cv2.MORPH_ELLIPSE, ksize=(size, size))
145+
finally:
146+
return kernel
147+
148+
def erosion_button_released(self, event):
149+
self.morphologyDict["isGetErosion"][0] = True
150+
151+
def dilation_button_released(self, event):
152+
self.morphologyDict["isGetDilation"][0] = True
153+
154+
def opening_button_released(self, event):
155+
self.morphologyDict["isGetOpen"][0] = True
156+
157+
def closing_button_released(self, event):
158+
self.morphologyDict["isGetClose"][0] = True
159+
160+
def gradient_button_released(self, event):
161+
self.morphologyDict["isGetGradient"][0] = True
162+
163+
def topHat_button_released(self, event):
164+
self.morphologyDict["isGetTopHat"][0] = True
165+
166+
def blackHat_button_released(self, event):
167+
self.morphologyDict["isGetBlackHat"][0] = True
168+
169+
def ellipse_button_released(self, event):
170+
self.morphologyDict["isGetEllipse"][0] = True
171+
172+
def rect_button_released(self, event):
173+
self.morphologyDict["isGetRect"][0] = True
174+
175+
def cross_button_released(self, event):
176+
self.morphologyDict["isGetCross"][0] = True
177+
178+
def log_button_released(self, event):
179+
self.morphologyDict["isGetLogged"][0] = True
180+
c = 255 / (np.log(1 + np.max(self.processing_image)))
181+
log_transformed = c * np.log(1 + self.processing_image)
182+
183+
self.processing_image = np.array(log_transformed, dtype=np.uint8)
184+
185+
def power_law_button_released(self, event):
186+
self.morphologyDict["isGetPowerLaw"][0] = True
187+
self.processing_image = np.array(255 * (self.processing_image / 255) ** float(self.gammaSize_scale.get()),
188+
dtype='uint8')
189+
190+
def preview_button_released(self, event):
191+
self.processing_image = cv2.convertScaleAbs(self.original_image, alpha=self.brightness_scale.get())
192+
b, g, r = cv2.split(self.processing_image)
193+
194+
for b_value in b:
195+
cv2.add(b_value, self.b_scale.get(), b_value)
196+
for g_value in g:
197+
cv2.add(g_value, self.g_scale.get(), g_value)
198+
for r_value in r:
199+
cv2.add(r_value, self.r_scale.get(), r_value)
200+
201+
self.processing_image = cv2.merge((b, g, r))
202+
203+
for key, value in self.morphologyDict.items():
204+
if value[0]:
205+
if value[1] is True:
206+
self.processing_image = cv2.morphologyEx(self.processing_image, value[2], self.get_kernel(key))
207+
else:
208+
value[1](event)
209+
self.show_image(self.processing_image)
210+
self.isGetApplied = True
211+
212+
def apply_button_released(self, event):
213+
if not self.isGetApplied:
214+
self.preview_button_released(event)
215+
self.master.image_cache.append(self.master.processed_image.copy())
216+
self.master.processed_image = self.processing_image
217+
self.close(event)
218+
219+
def cancel_button_released(self, event):
220+
self.close(event)
221+
222+
def show_image(self, img=None):
223+
self.master.interface_functions.show_image(image=img)
224+
225+
def clear_button_released(self, event):
226+
for values in self.morphologyDict.values():
227+
values[0] = False
228+
self.b_scale.set(0)
229+
self.r_scale.set(0)
230+
self.g_scale.set(0)
231+
self.brightness_scale.set(1.0)
232+
self.kernelSize_scale.set(8)
233+
self.gammaSize_scale.set(0.5)
234+
self.clipLimitSize_scale.set(2.0)
235+
self.processing_image = self.original_image.copy()
236+
self.show_image(self.processing_image)
237+
238+
def close(self, event):
239+
self.show_image()
240+
self.destroy()

0 commit comments

Comments
 (0)