|
| 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