Project

General

Profile

Code » History » Version 9

Faiq Sayyidan SETIAWAN, 10/31/2024 03:53 PM

1 1 Faiq Sayyidan SETIAWAN
---
2
3 6 Faiq Sayyidan SETIAWAN
*[[/|Home]]*   |   *[[Team Members]]*   |   *[[Project Description]]*   |   *[[Code]]*   |   *[[UML Diagrams]]*   |   *[[Results]]*   |
4 1 Faiq Sayyidan SETIAWAN
5
---
6 2 Faiq Sayyidan SETIAWAN
7
h1=. <pre>
8 3 Faiq Sayyidan SETIAWAN
Code </pre>
9 4 Faiq Sayyidan SETIAWAN
10
h2. alpha_blending_v2.py: everything
11
12
<pre><code class="python">
13
import tkinter as tk
14
15
from tkinter import filedialog, messagebox
16
17
from tkinter import ttk
18
19
import configparser
20
21
import cv2
22
23
import numpy as np
24
25
import os
26
27
import logging
28
29
from PIL import Image, ImageTk
30
31
# Setup logging
32
33
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
34
35
# ConfigReader class definition
36
37
class ConfigReader:
38
39 7 Faiq Sayyidan SETIAWAN
    def __init__(self, config_path=None):
40 9 Faiq Sayyidan SETIAWAN
41 7 Faiq Sayyidan SETIAWAN
        # Assume some initialization using config_path
42 9 Faiq Sayyidan SETIAWAN
43 7 Faiq Sayyidan SETIAWAN
        self.config_path = config_path
44 9 Faiq Sayyidan SETIAWAN
45 7 Faiq Sayyidan SETIAWAN
        # Add other initialization logic here
46 9 Faiq Sayyidan SETIAWAN
47 1 Faiq Sayyidan SETIAWAN
        self.config_parser = configparser.ConfigParser()
48 9 Faiq Sayyidan SETIAWAN
49 7 Faiq Sayyidan SETIAWAN
        if config_path is not None and os.path.exists(config_path):
50 9 Faiq Sayyidan SETIAWAN
51 7 Faiq Sayyidan SETIAWAN
            self.config_parser.read(config_path)
52 4 Faiq Sayyidan SETIAWAN
53
    def getImageName(self):
54
55
        return str(self.config_parser['DEFAULT']['image_name'])
56
57
    def getProjectedImageWidth(self):
58
59
        return int(self.config_parser['DEFAULT']['projected_image_width'])
60
61
    def getProjectedOverlapWidth(self):
62
63
        return int(self.config_parser['DEFAULT']['projected_overlap_width'])
64
65
    def getGamma(self):
66
67
        return float(self.config_parser['DEFAULT']['gamma'])
68
69
    def getImageSide(self):
70
71
        return int(self.config_parser['DEFAULT']['image_side'])
72
73 1 Faiq Sayyidan SETIAWAN
    def getTransparencyFactor(self):
74
75
        return float(self.config_parser['DEFAULT'].get('transparency_factor', 1.0))
76
77 7 Faiq Sayyidan SETIAWAN
    def setParameters(self, parameters):
78 9 Faiq Sayyidan SETIAWAN
79 7 Faiq Sayyidan SETIAWAN
        # The parameters is a dictionary with key-value pairs
80 9 Faiq Sayyidan SETIAWAN
81 7 Faiq Sayyidan SETIAWAN
        if 'DEFAULT' not in self.config_parser:
82 9 Faiq Sayyidan SETIAWAN
83 7 Faiq Sayyidan SETIAWAN
            self.config_parser['DEFAULT'] = {}
84 9 Faiq Sayyidan SETIAWAN
85 7 Faiq Sayyidan SETIAWAN
        
86 9 Faiq Sayyidan SETIAWAN
87 7 Faiq Sayyidan SETIAWAN
        for key, value in parameters.items():
88 9 Faiq Sayyidan SETIAWAN
89 7 Faiq Sayyidan SETIAWAN
            self.config_parser['DEFAULT'][key] = str(value)
90 1 Faiq Sayyidan SETIAWAN
91 9 Faiq Sayyidan SETIAWAN
    def saveConfig(self, path):
92
93 1 Faiq Sayyidan SETIAWAN
        with open(path, 'w') as configfile:
94 9 Faiq Sayyidan SETIAWAN
95 7 Faiq Sayyidan SETIAWAN
            self.config_parser.write(configfile)
96
97 4 Faiq Sayyidan SETIAWAN
# MainDisplay class definition
98
99
class MainDisplay:
100
101
    def readImage(self, image_path):
102
103
        # Loads an image from the specified path with 3 channels (BGR)
104
105
        image = cv2.imread(image_path, cv2.IMREAD_COLOR)
106
107
        if image is None:
108
109
            logging.error(f"Error loading image at {image_path}")
110
111
        else:
112
113
            logging.info(f"Loaded image {image_path} with shape: {image.shape}")
114
115
        return image
116
117
    def setImage(self, image):
118
119
        # Placeholder for image processing if necessary
120
121
        # Here you can modify or prepare the image before displaying
122
123
        logging.info(f"Setting image with shape: {image.shape}")
124
125
        return image
126
127
# MaskCreator class definition
128
129
class MaskCreator:
130
131
    def __init__(self, image, transparency_factor):
132
133
        self.__image = image
134
135
        self.__alpha_gradient = None
136
137
        self.__gamma_corrected = None
138
139
        self.result_image = None
140
141
        self.__mask = None
142
143
        self.transparency_factor = transparency_factor
144
145
    def smoothstep(self, edge0, edge1, x):
146
147
        # Smoothstep function for smoother transition (non-linear gradient)
148
149
        x = np.clip((x - edge0) / (edge1 - edge0), 0, 1)
150 1 Faiq Sayyidan SETIAWAN
151 4 Faiq Sayyidan SETIAWAN
        return x * x * (3 - 2 * x)
152
153 9 Faiq Sayyidan SETIAWAN
    def createMask(self, image_side, mask_width, image_width):
154 4 Faiq Sayyidan SETIAWAN
155
        self.__mask = self.__image.shape[1] * mask_width // image_width
156
157
        gradient = np.linspace(0, 1, self.__mask)
158
159
        # Apply smoothstep to create a smoother gradient
160
161
        smooth_gradient = self.smoothstep(0, 1, gradient)
162
163
        # Apply transparency factor to adjust the strength of the blending
164
165
        smooth_gradient = smooth_gradient * self.transparency_factor
166
167
        if image_side == 1:
168
169
            # Gradient from transparent to opaque (middle to right)
170
171
            self.__alpha_gradient = smooth_gradient
172
173
        elif image_side == 0:
174
175
            # Gradient from opaque to transparent (left to middle)
176
177
            self.__alpha_gradient = smooth_gradient[::-1]  # Reverse for the left side
178
179
    def gammaCorrection(self, gamma):
180
181
        # Apply gamma correction
182
183
        inv_gamma = 1.0 / gamma
184
185
        table = np.array([((i / 255.0) ** inv_gamma) * 255
186
187
                          for i in np.arange(256)]).astype("uint8")
188
189
        self.__gamma_corrected = cv2.LUT(self.__image, table)
190
191
        logging.info(f"Applied gamma correction with gamma={gamma}")
192
193 1 Faiq Sayyidan SETIAWAN
        # Save gamma corrected image for inspection
194 4 Faiq Sayyidan SETIAWAN
195
        cv2.imwrite("gamma_corrected.png", self.__gamma_corrected)
196
197 9 Faiq Sayyidan SETIAWAN
    def alphaBlending(self, image_side):
198 4 Faiq Sayyidan SETIAWAN
199
        """
200
201
        Applies alpha blending on the gamma-corrected image.
202
203
        Combines the gamma-corrected part of the image with a black background using the alpha gradient mask.
204
205
        """
206
207
        # Initialize result_image to be the gamma-corrected image
208
209
        self.result_image = self.__gamma_corrected.copy()
210
211
        if image_side == 1:  # Right side
212
213
            # Create a region of interest (ROI) where blending will occur (right side of the image)
214
215
            roi = self.result_image[:, :self.__mask].astype(np.float32)
216
217
            # Create black background for blending
218
219
            black_background = np.zeros_like(roi, dtype=np.float32)
220
221
            # Apply the alpha mask to blend gamma-corrected image with black background
222
223
            alpha = self.__alpha_gradient.reshape(1, -1, 1).astype(np.float32)
224
225
            blended = (alpha * roi + (1 - alpha) * black_background)
226
227
            blended = np.clip(blended, 0, 255).astype(np.uint8)
228
229
            # Place the blended region back in the result image
230
231
            self.result_image[:, :self.__mask] = blended
232
233
            logging.info(f"Applied alpha blending on the right side with mask width {self.__mask}")
234
235
            # Save blended region for debugging
236
237
            cv2.imwrite("blended_right_side.png", blended)
238
239
        elif image_side == 0:  # Left side
240
241
            # Create a region of interest (ROI) where blending will occur (left side of the image)
242
243
            roi = self.result_image[:, -self.__mask:].astype(np.float32)
244
245
            # Create black background for blending
246
247
            black_background = np.zeros_like(roi, dtype=np.float32)
248
249
            # Apply the alpha mask to blend gamma-corrected image with black background
250
251
            alpha = self.__alpha_gradient.reshape(1, -1, 1).astype(np.float32)
252
253
            blended = (alpha * roi + (1 - alpha) * black_background)
254
255
            blended = np.clip(blended, 0, 255).astype(np.uint8)
256
257
            # Place the blended region back in the result image
258
259
            self.result_image[:, -self.__mask:] = blended
260
261 1 Faiq Sayyidan SETIAWAN
            logging.info(f"Applied alpha blending on the left side with mask width {self.__mask}")
262
263
            # Save blended region for debugging
264
265
            cv2.imwrite("blended_left_side.png", blended)
266
267 9 Faiq Sayyidan SETIAWAN
def processImage(image_path, params, main_display):
268 4 Faiq Sayyidan SETIAWAN
269 1 Faiq Sayyidan SETIAWAN
    """
270 9 Faiq Sayyidan SETIAWAN
271 1 Faiq Sayyidan SETIAWAN
    Processes an image based on the provided parameters.
272
273
    Args:
274 9 Faiq Sayyidan SETIAWAN
275 1 Faiq Sayyidan SETIAWAN
        image_path (str): Path to the image file.
276 9 Faiq Sayyidan SETIAWAN
277 1 Faiq Sayyidan SETIAWAN
        params (dict): Parameters for image processing.
278 9 Faiq Sayyidan SETIAWAN
279 1 Faiq Sayyidan SETIAWAN
        main_display (MainDisplay): Instance of MainDisplay for image operations.
280 7 Faiq Sayyidan SETIAWAN
281 4 Faiq Sayyidan SETIAWAN
    Returns:
282 9 Faiq Sayyidan SETIAWAN
283 1 Faiq Sayyidan SETIAWAN
        tuple: Processed image and its corresponding name.
284 9 Faiq Sayyidan SETIAWAN
285 1 Faiq Sayyidan SETIAWAN
    """
286 4 Faiq Sayyidan SETIAWAN
287 1 Faiq Sayyidan SETIAWAN
    # Retrieve parameters from params dictionary
288 9 Faiq Sayyidan SETIAWAN
289 1 Faiq Sayyidan SETIAWAN
    mask_width = params.get('projected_overlap_width')
290 9 Faiq Sayyidan SETIAWAN
291 1 Faiq Sayyidan SETIAWAN
    image_width = params.get('projected_image_width')
292 9 Faiq Sayyidan SETIAWAN
293 7 Faiq Sayyidan SETIAWAN
    gamma = params.get('gamma')
294 9 Faiq Sayyidan SETIAWAN
295 1 Faiq Sayyidan SETIAWAN
    image_side = params.get('image_side')
296 9 Faiq Sayyidan SETIAWAN
297 1 Faiq Sayyidan SETIAWAN
    transparency_factor = params.get('transparency_factor')
298 4 Faiq Sayyidan SETIAWAN
299 1 Faiq Sayyidan SETIAWAN
    # Determine image side name
300 9 Faiq Sayyidan SETIAWAN
301 1 Faiq Sayyidan SETIAWAN
    if image_side == 0:
302 9 Faiq Sayyidan SETIAWAN
303 1 Faiq Sayyidan SETIAWAN
        image_name = 'left'
304 9 Faiq Sayyidan SETIAWAN
305 1 Faiq Sayyidan SETIAWAN
    elif image_side == 1:
306 9 Faiq Sayyidan SETIAWAN
307 1 Faiq Sayyidan SETIAWAN
        image_name = 'right'
308 9 Faiq Sayyidan SETIAWAN
309 4 Faiq Sayyidan SETIAWAN
    else:
310 9 Faiq Sayyidan SETIAWAN
311 1 Faiq Sayyidan SETIAWAN
        logging.error(f"Invalid ImageSide value. Use 0 for left image, 1 for right image.")
312 9 Faiq Sayyidan SETIAWAN
313 4 Faiq Sayyidan SETIAWAN
        return None, None
314
315 1 Faiq Sayyidan SETIAWAN
    # Load image
316 9 Faiq Sayyidan SETIAWAN
317 1 Faiq Sayyidan SETIAWAN
    image = main_display.readImage(image_path)
318 4 Faiq Sayyidan SETIAWAN
319
    if image is None:
320 9 Faiq Sayyidan SETIAWAN
321 1 Faiq Sayyidan SETIAWAN
        logging.error(f"Image loading failed for {image_path}. Skipping...")
322 9 Faiq Sayyidan SETIAWAN
323 1 Faiq Sayyidan SETIAWAN
        return None, None
324 4 Faiq Sayyidan SETIAWAN
325
    # Initialize result image
326 9 Faiq Sayyidan SETIAWAN
327 1 Faiq Sayyidan SETIAWAN
    result_image = main_display.setImage(image).copy()
328 9 Faiq Sayyidan SETIAWAN
329 4 Faiq Sayyidan SETIAWAN
    cv2.imwrite("initial_result_image.png", result_image)  # Save initial image
330 1 Faiq Sayyidan SETIAWAN
331
    # Initialize MaskCreator
332 9 Faiq Sayyidan SETIAWAN
333 4 Faiq Sayyidan SETIAWAN
    mask_creator = MaskCreator(image, transparency_factor)
334 1 Faiq Sayyidan SETIAWAN
335 4 Faiq Sayyidan SETIAWAN
    # Apply image modifications
336 9 Faiq Sayyidan SETIAWAN
337
    mask_creator.createMask(image_side, mask_width, image_width)
338
339 1 Faiq Sayyidan SETIAWAN
    mask_creator.gammaCorrection(gamma)
340 9 Faiq Sayyidan SETIAWAN
341 1 Faiq Sayyidan SETIAWAN
    mask_creator.result_image = result_image
342
343 9 Faiq Sayyidan SETIAWAN
    mask_creator.alphaBlending(image_side)
344
345 1 Faiq Sayyidan SETIAWAN
    # Save final result for inspection
346 9 Faiq Sayyidan SETIAWAN
347 1 Faiq Sayyidan SETIAWAN
    cv2.imwrite("final_result_image.png", mask_creator.result_image)
348
349
    return mask_creator.result_image, image_name
350 7 Faiq Sayyidan SETIAWAN
351 9 Faiq Sayyidan SETIAWAN
def saveImage(image, name):
352 1 Faiq Sayyidan SETIAWAN
353
    """
354 4 Faiq Sayyidan SETIAWAN
355 1 Faiq Sayyidan SETIAWAN
    Save the processed image to the project folder.
356
357 4 Faiq Sayyidan SETIAWAN
    Args:
358 1 Faiq Sayyidan SETIAWAN
359
        image (np.ndarray): The image to be saved.
360 4 Faiq Sayyidan SETIAWAN
361 1 Faiq Sayyidan SETIAWAN
        name (str): Name of the image (left or right).
362
363
    """
364
365
    # Define the output path
366
367
    output_dir = os.path.join(os.getcwd(), "processed_images")
368
369
    os.makedirs(output_dir, exist_ok=True)
370
371
    # Create the output file name
372
373
    output_path = os.path.join(output_dir, f"processed_image_{name}.png")
374
375
    # Save the image
376
377
    cv2.imwrite(output_path, image)
378
379
    logging.info(f"Saved processed image: {output_path}")
380
381
# GUI Application class definition
382
383
class ImageProcessingApp:
384 9 Faiq Sayyidan SETIAWAN
385 1 Faiq Sayyidan SETIAWAN
    def __init__(self, root):
386 9 Faiq Sayyidan SETIAWAN
387 1 Faiq Sayyidan SETIAWAN
        self.root = root
388 9 Faiq Sayyidan SETIAWAN
389 1 Faiq Sayyidan SETIAWAN
        self.root.title("Image Processing Application")
390 7 Faiq Sayyidan SETIAWAN
391 1 Faiq Sayyidan SETIAWAN
        # Initialize variables
392 9 Faiq Sayyidan SETIAWAN
393 7 Faiq Sayyidan SETIAWAN
        self.left_image_path = "" 
394 9 Faiq Sayyidan SETIAWAN
395 1 Faiq Sayyidan SETIAWAN
        self.right_image_path = "" 
396 9 Faiq Sayyidan SETIAWAN
397 1 Faiq Sayyidan SETIAWAN
        self.left_params = {}
398 9 Faiq Sayyidan SETIAWAN
399 7 Faiq Sayyidan SETIAWAN
        self.right_params = {}
400 9 Faiq Sayyidan SETIAWAN
401 1 Faiq Sayyidan SETIAWAN
        self.processed_images = {}
402
403
        # Create notebook (tabs)
404 9 Faiq Sayyidan SETIAWAN
405 1 Faiq Sayyidan SETIAWAN
        self.notebook = ttk.Notebook(root)
406 9 Faiq Sayyidan SETIAWAN
407 1 Faiq Sayyidan SETIAWAN
        self.notebook.pack(expand=True, fill='both')
408 7 Faiq Sayyidan SETIAWAN
409
        # Create frames for each tab
410 9 Faiq Sayyidan SETIAWAN
411 1 Faiq Sayyidan SETIAWAN
        self.tab_left = ttk.Frame(self.notebook)
412 9 Faiq Sayyidan SETIAWAN
413 1 Faiq Sayyidan SETIAWAN
        self.tab_right = ttk.Frame(self.notebook)
414 9 Faiq Sayyidan SETIAWAN
415 1 Faiq Sayyidan SETIAWAN
        self.tab_settings = ttk.Frame(self.notebook)
416 9 Faiq Sayyidan SETIAWAN
417 1 Faiq Sayyidan SETIAWAN
        self.tab_preview = ttk.Frame(self.notebook)
418
419
        self.notebook.add(self.tab_left, text='Left Image')
420 9 Faiq Sayyidan SETIAWAN
421 1 Faiq Sayyidan SETIAWAN
        self.notebook.add(self.tab_right, text='Right Image')
422 9 Faiq Sayyidan SETIAWAN
423 1 Faiq Sayyidan SETIAWAN
        self.notebook.add(self.tab_settings, text='Settings')
424 9 Faiq Sayyidan SETIAWAN
425 1 Faiq Sayyidan SETIAWAN
        self.notebook.add(self.tab_preview, text='Preview')
426
427 7 Faiq Sayyidan SETIAWAN
        # Setup each tab
428 1 Faiq Sayyidan SETIAWAN
429 9 Faiq Sayyidan SETIAWAN
        self.setupLeftTab()
430
431
        self.setupRightTab()
432
433
        self.setupSettingsTab()
434
435
        self.setupPreviewTab()
436
437 7 Faiq Sayyidan SETIAWAN
        # Process and Save Button
438 9 Faiq Sayyidan SETIAWAN
439
        self.process_button = tk.Button(root, text="Process and Save Images", command=self.processAndSave)
440
441 1 Faiq Sayyidan SETIAWAN
        self.process_button.pack(pady=10)
442 7 Faiq Sayyidan SETIAWAN
443
        # Progress Bar
444 9 Faiq Sayyidan SETIAWAN
445 7 Faiq Sayyidan SETIAWAN
        self.progress_bar = ttk.Progressbar(root, orient="horizontal", length=400, mode="determinate")
446 9 Faiq Sayyidan SETIAWAN
447 1 Faiq Sayyidan SETIAWAN
        self.progress_bar.pack(pady=10)
448 7 Faiq Sayyidan SETIAWAN
449 9 Faiq Sayyidan SETIAWAN
    def setupLeftTab(self):
450
451 7 Faiq Sayyidan SETIAWAN
        frame = self.tab_left
452 1 Faiq Sayyidan SETIAWAN
453
        # Select Image Button
454 9 Faiq Sayyidan SETIAWAN
455
        btn_select = tk.Button(frame, text="Select Left Image", command=self.selectLeftImage)
456
457 7 Faiq Sayyidan SETIAWAN
        btn_select.pack(pady=5)
458 1 Faiq Sayyidan SETIAWAN
459 7 Faiq Sayyidan SETIAWAN
        # Display selected image path
460 9 Faiq Sayyidan SETIAWAN
461 7 Faiq Sayyidan SETIAWAN
        self.left_image_label = tk.Label(frame, text="No image selected", wraplength=300, anchor="w", justify="left")
462 9 Faiq Sayyidan SETIAWAN
463 1 Faiq Sayyidan SETIAWAN
        self.left_image_label.pack(padx=10, pady=5)
464 7 Faiq Sayyidan SETIAWAN
465
        # Parameters for left image
466 9 Faiq Sayyidan SETIAWAN
467 7 Faiq Sayyidan SETIAWAN
        params_frame = tk.LabelFrame(frame, text="Left Image Parameters", padx=10, pady=10)
468 9 Faiq Sayyidan SETIAWAN
469 1 Faiq Sayyidan SETIAWAN
        params_frame.pack(padx=10, pady=10, fill="x")
470
471 7 Faiq Sayyidan SETIAWAN
        # Projected Image Width
472 9 Faiq Sayyidan SETIAWAN
473 7 Faiq Sayyidan SETIAWAN
        tk.Label(params_frame, text="Projected Image Width:").grid(row=0, column=0, sticky="e")
474 9 Faiq Sayyidan SETIAWAN
475 7 Faiq Sayyidan SETIAWAN
        self.left_projected_image_width = tk.Entry(params_frame)
476 9 Faiq Sayyidan SETIAWAN
477 7 Faiq Sayyidan SETIAWAN
        self.left_projected_image_width.insert(0, "800")
478 9 Faiq Sayyidan SETIAWAN
479 7 Faiq Sayyidan SETIAWAN
        self.left_projected_image_width.grid(row=0, column=1, pady=2, sticky="w")
480 1 Faiq Sayyidan SETIAWAN
481 7 Faiq Sayyidan SETIAWAN
        # Projected Overlap Width
482 9 Faiq Sayyidan SETIAWAN
483 7 Faiq Sayyidan SETIAWAN
        tk.Label(params_frame, text="Projected Overlap Width:").grid(row=1, column=0, sticky="e")
484 9 Faiq Sayyidan SETIAWAN
485 7 Faiq Sayyidan SETIAWAN
        self.left_projected_overlap_width = tk.Entry(params_frame)
486 9 Faiq Sayyidan SETIAWAN
487 7 Faiq Sayyidan SETIAWAN
        self.left_projected_overlap_width.insert(0, "100")
488 9 Faiq Sayyidan SETIAWAN
489 7 Faiq Sayyidan SETIAWAN
        self.left_projected_overlap_width.grid(row=1, column=1, pady=2, sticky="w")
490 1 Faiq Sayyidan SETIAWAN
491 7 Faiq Sayyidan SETIAWAN
        # Gamma
492 9 Faiq Sayyidan SETIAWAN
493 7 Faiq Sayyidan SETIAWAN
        tk.Label(params_frame, text="Gamma:").grid(row=2, column=0, sticky="e")
494 9 Faiq Sayyidan SETIAWAN
495 7 Faiq Sayyidan SETIAWAN
        self.left_gamma = tk.Entry(params_frame)
496 9 Faiq Sayyidan SETIAWAN
497 7 Faiq Sayyidan SETIAWAN
        self.left_gamma.insert(0, "1.0")
498 9 Faiq Sayyidan SETIAWAN
499 7 Faiq Sayyidan SETIAWAN
        self.left_gamma.grid(row=2, column=1, pady=2, sticky="w")
500 1 Faiq Sayyidan SETIAWAN
501 7 Faiq Sayyidan SETIAWAN
        # Image Side
502 9 Faiq Sayyidan SETIAWAN
503 7 Faiq Sayyidan SETIAWAN
        tk.Label(params_frame, text="Image Side:").grid(row=3, column=0, sticky="e")
504 9 Faiq Sayyidan SETIAWAN
505 1 Faiq Sayyidan SETIAWAN
        self.left_image_side = tk.IntVar(value=0)  # Default to left
506 9 Faiq Sayyidan SETIAWAN
507 7 Faiq Sayyidan SETIAWAN
        tk.Radiobutton(params_frame, text="Left", variable=self.left_image_side, value=0).grid(row=3, column=1, sticky="w")
508 9 Faiq Sayyidan SETIAWAN
509 1 Faiq Sayyidan SETIAWAN
        tk.Radiobutton(params_frame, text="Right", variable=self.left_image_side, value=1).grid(row=3, column=1, padx=60, sticky="w")
510
511 7 Faiq Sayyidan SETIAWAN
        # Transparency Factor
512 9 Faiq Sayyidan SETIAWAN
513 7 Faiq Sayyidan SETIAWAN
        tk.Label(params_frame, text="Transparency Factor:").grid(row=4, column=0, sticky="e")
514 9 Faiq Sayyidan SETIAWAN
515 1 Faiq Sayyidan SETIAWAN
        self.left_transparency_factor = tk.Entry(params_frame)
516 9 Faiq Sayyidan SETIAWAN
517 7 Faiq Sayyidan SETIAWAN
        self.left_transparency_factor.insert(0, "1.0")
518 9 Faiq Sayyidan SETIAWAN
519 7 Faiq Sayyidan SETIAWAN
        self.left_transparency_factor.grid(row=4, column=1, pady=2, sticky="w")
520 1 Faiq Sayyidan SETIAWAN
521 9 Faiq Sayyidan SETIAWAN
    def setupRightTab(self):
522
523 7 Faiq Sayyidan SETIAWAN
        frame = self.tab_right
524 1 Faiq Sayyidan SETIAWAN
525 7 Faiq Sayyidan SETIAWAN
        # Select Image Button
526 9 Faiq Sayyidan SETIAWAN
527
        btn_select = tk.Button(frame, text="Select Right Image", command=self.selectRightImage)
528
529 7 Faiq Sayyidan SETIAWAN
        btn_select.pack(pady=5)
530 1 Faiq Sayyidan SETIAWAN
531
        # Display selected image path
532 9 Faiq Sayyidan SETIAWAN
533 7 Faiq Sayyidan SETIAWAN
        self.right_image_label = tk.Label(frame, text="No image selected", wraplength=300, anchor="w", justify="left")
534 9 Faiq Sayyidan SETIAWAN
535 7 Faiq Sayyidan SETIAWAN
        self.right_image_label.pack(padx=10, pady=5)
536 1 Faiq Sayyidan SETIAWAN
537
        # Parameters for right image
538 9 Faiq Sayyidan SETIAWAN
539 7 Faiq Sayyidan SETIAWAN
        params_frame = tk.LabelFrame(frame, text="Right Image Parameters", padx=10, pady=10)
540 9 Faiq Sayyidan SETIAWAN
541 7 Faiq Sayyidan SETIAWAN
        params_frame.pack(padx=10, pady=10, fill="x")
542 1 Faiq Sayyidan SETIAWAN
543 7 Faiq Sayyidan SETIAWAN
        # Projected Image Width
544 9 Faiq Sayyidan SETIAWAN
545 7 Faiq Sayyidan SETIAWAN
        tk.Label(params_frame, text="Projected Image Width:").grid(row=0, column=0, sticky="e")
546 9 Faiq Sayyidan SETIAWAN
547 1 Faiq Sayyidan SETIAWAN
        self.right_projected_image_width = tk.Entry(params_frame)
548 9 Faiq Sayyidan SETIAWAN
549 7 Faiq Sayyidan SETIAWAN
        self.right_projected_image_width.insert(0, "800")
550 9 Faiq Sayyidan SETIAWAN
551 7 Faiq Sayyidan SETIAWAN
        self.right_projected_image_width.grid(row=0, column=1, pady=2, sticky="w")
552 1 Faiq Sayyidan SETIAWAN
553 7 Faiq Sayyidan SETIAWAN
        # Projected Overlap Width
554 9 Faiq Sayyidan SETIAWAN
555 1 Faiq Sayyidan SETIAWAN
        tk.Label(params_frame, text="Projected Overlap Width:").grid(row=1, column=0, sticky="e")
556 9 Faiq Sayyidan SETIAWAN
557 7 Faiq Sayyidan SETIAWAN
        self.right_projected_overlap_width = tk.Entry(params_frame)
558 9 Faiq Sayyidan SETIAWAN
559 7 Faiq Sayyidan SETIAWAN
        self.right_projected_overlap_width.insert(0, "100")
560 9 Faiq Sayyidan SETIAWAN
561 7 Faiq Sayyidan SETIAWAN
        self.right_projected_overlap_width.grid(row=1, column=1, pady=2, sticky="w")
562 1 Faiq Sayyidan SETIAWAN
563 7 Faiq Sayyidan SETIAWAN
        # Gamma
564 9 Faiq Sayyidan SETIAWAN
565 1 Faiq Sayyidan SETIAWAN
        tk.Label(params_frame, text="Gamma:").grid(row=2, column=0, sticky="e")
566 9 Faiq Sayyidan SETIAWAN
567 7 Faiq Sayyidan SETIAWAN
        self.right_gamma = tk.Entry(params_frame)
568 9 Faiq Sayyidan SETIAWAN
569 7 Faiq Sayyidan SETIAWAN
        self.right_gamma.insert(0, "1.0")
570 9 Faiq Sayyidan SETIAWAN
571 7 Faiq Sayyidan SETIAWAN
        self.right_gamma.grid(row=2, column=1, pady=2, sticky="w")
572 1 Faiq Sayyidan SETIAWAN
573 7 Faiq Sayyidan SETIAWAN
        # Image Side
574 9 Faiq Sayyidan SETIAWAN
575 1 Faiq Sayyidan SETIAWAN
        tk.Label(params_frame, text="Image Side:").grid(row=3, column=0, sticky="e")
576 9 Faiq Sayyidan SETIAWAN
577 1 Faiq Sayyidan SETIAWAN
        self.right_image_side = tk.IntVar(value=1)  # Default to right
578 9 Faiq Sayyidan SETIAWAN
579 1 Faiq Sayyidan SETIAWAN
        tk.Radiobutton(params_frame, text="Left", variable=self.right_image_side, value=0).grid(row=3, column=1, sticky="w")
580 9 Faiq Sayyidan SETIAWAN
581 1 Faiq Sayyidan SETIAWAN
        tk.Radiobutton(params_frame, text="Right", variable=self.right_image_side, value=1).grid(row=3, column=1, padx=60, sticky="w")
582
583
        # Transparency Factor
584 9 Faiq Sayyidan SETIAWAN
585 1 Faiq Sayyidan SETIAWAN
        tk.Label(params_frame, text="Transparency Factor:").grid(row=4, column=0, sticky="e")
586 9 Faiq Sayyidan SETIAWAN
587 7 Faiq Sayyidan SETIAWAN
        self.right_transparency_factor = tk.Entry(params_frame)
588 9 Faiq Sayyidan SETIAWAN
589 1 Faiq Sayyidan SETIAWAN
        self.right_transparency_factor.insert(0, "1.0")
590 9 Faiq Sayyidan SETIAWAN
591 1 Faiq Sayyidan SETIAWAN
        self.right_transparency_factor.grid(row=4, column=1, pady=2, sticky="w")
592 7 Faiq Sayyidan SETIAWAN
593 9 Faiq Sayyidan SETIAWAN
    def setupSettingsTab(self):
594
595 1 Faiq Sayyidan SETIAWAN
        frame = self.tab_settings
596 7 Faiq Sayyidan SETIAWAN
597 1 Faiq Sayyidan SETIAWAN
        # Configurations can be saved or loaded here
598
599 9 Faiq Sayyidan SETIAWAN
        saveConfig_btn = tk.Button(frame, text="Save Configuration", command=self.saveConfiguration)
600
601
        saveConfig_btn.pack(pady=10)
602
603
        load_config_btn = tk.Button(frame, text="Load Configuration", command=self.loadConfiguration)
604
605 7 Faiq Sayyidan SETIAWAN
        load_config_btn.pack(pady=10)
606 1 Faiq Sayyidan SETIAWAN
607 9 Faiq Sayyidan SETIAWAN
    def setupPreviewTab(self):
608
609 7 Faiq Sayyidan SETIAWAN
        frame = self.tab_preview
610 1 Faiq Sayyidan SETIAWAN
611
        # Labels to display images
612 9 Faiq Sayyidan SETIAWAN
613 1 Faiq Sayyidan SETIAWAN
        self.original_image_label = tk.Label(frame, text="Original Image")
614 9 Faiq Sayyidan SETIAWAN
615 1 Faiq Sayyidan SETIAWAN
        self.original_image_label.pack(side="left", padx=10, pady=10)
616
617
        self.processed_image_label = tk.Label(frame, text="Processed Image")
618 9 Faiq Sayyidan SETIAWAN
619 1 Faiq Sayyidan SETIAWAN
        self.processed_image_label.pack(side="right", padx=10, pady=10)
620 7 Faiq Sayyidan SETIAWAN
621 9 Faiq Sayyidan SETIAWAN
    def selectLeftImage(self):
622
623 1 Faiq Sayyidan SETIAWAN
        path = filedialog.askopenfilename(title="Select Left Image",
624 9 Faiq Sayyidan SETIAWAN
625 7 Faiq Sayyidan SETIAWAN
                                          filetypes=[("Image files", "*.png *.jpg *.jpeg *.bmp")])
626 9 Faiq Sayyidan SETIAWAN
627 7 Faiq Sayyidan SETIAWAN
        if path:
628 9 Faiq Sayyidan SETIAWAN
629 7 Faiq Sayyidan SETIAWAN
            self.left_image_path = path
630 9 Faiq Sayyidan SETIAWAN
631 7 Faiq Sayyidan SETIAWAN
            self.left_image_label.config(text=os.path.basename(path))
632 9 Faiq Sayyidan SETIAWAN
633 7 Faiq Sayyidan SETIAWAN
            logging.info(f"Selected left image: {path}")
634 1 Faiq Sayyidan SETIAWAN
635 9 Faiq Sayyidan SETIAWAN
    def selectRightImage(self):
636
637 7 Faiq Sayyidan SETIAWAN
        path = filedialog.askopenfilename(title="Select Right Image",
638 9 Faiq Sayyidan SETIAWAN
639 7 Faiq Sayyidan SETIAWAN
                                          filetypes=[("Image files", "*.png *.jpg *.jpeg *.bmp")])
640 9 Faiq Sayyidan SETIAWAN
641 7 Faiq Sayyidan SETIAWAN
        if path:
642 9 Faiq Sayyidan SETIAWAN
643 7 Faiq Sayyidan SETIAWAN
            self.right_image_path = path
644 9 Faiq Sayyidan SETIAWAN
645 7 Faiq Sayyidan SETIAWAN
            self.right_image_label.config(text=os.path.basename(path))
646 9 Faiq Sayyidan SETIAWAN
647 1 Faiq Sayyidan SETIAWAN
            logging.info(f"Selected right image: {path}")
648
649 9 Faiq Sayyidan SETIAWAN
    def saveConfiguration(self):
650
651 7 Faiq Sayyidan SETIAWAN
        config = ConfigReader()
652 1 Faiq Sayyidan SETIAWAN
653
        # Left Image Parameters
654 9 Faiq Sayyidan SETIAWAN
655 7 Faiq Sayyidan SETIAWAN
        if self.left_image_path:
656 9 Faiq Sayyidan SETIAWAN
657 7 Faiq Sayyidan SETIAWAN
            config.setParameters({
658 9 Faiq Sayyidan SETIAWAN
659 7 Faiq Sayyidan SETIAWAN
                'image_name': self.left_image_path,
660 9 Faiq Sayyidan SETIAWAN
661 7 Faiq Sayyidan SETIAWAN
                'projected_image_width': self.left_projected_image_width.get(),
662 9 Faiq Sayyidan SETIAWAN
663 7 Faiq Sayyidan SETIAWAN
                'projected_overlap_width': self.left_projected_overlap_width.get(),
664 9 Faiq Sayyidan SETIAWAN
665 7 Faiq Sayyidan SETIAWAN
                'gamma': self.left_gamma.get(),
666 9 Faiq Sayyidan SETIAWAN
667 7 Faiq Sayyidan SETIAWAN
                'image_side': self.left_image_side.get(),
668 9 Faiq Sayyidan SETIAWAN
669 7 Faiq Sayyidan SETIAWAN
                'transparency_factor': self.left_transparency_factor.get()
670 9 Faiq Sayyidan SETIAWAN
671 7 Faiq Sayyidan SETIAWAN
            })
672 1 Faiq Sayyidan SETIAWAN
673
        # Right Image Parameters
674 9 Faiq Sayyidan SETIAWAN
675 1 Faiq Sayyidan SETIAWAN
        if self.right_image_path:
676 9 Faiq Sayyidan SETIAWAN
677 1 Faiq Sayyidan SETIAWAN
            config.setParameters({
678 9 Faiq Sayyidan SETIAWAN
679 1 Faiq Sayyidan SETIAWAN
                'image_name': self.right_image_path,
680 9 Faiq Sayyidan SETIAWAN
681 1 Faiq Sayyidan SETIAWAN
                'projected_image_width': self.right_projected_image_width.get(),
682 9 Faiq Sayyidan SETIAWAN
683 7 Faiq Sayyidan SETIAWAN
                'projected_overlap_width': self.right_projected_overlap_width.get(),
684 9 Faiq Sayyidan SETIAWAN
685 7 Faiq Sayyidan SETIAWAN
                'gamma': self.right_gamma.get(),
686 9 Faiq Sayyidan SETIAWAN
687 7 Faiq Sayyidan SETIAWAN
                'image_side': self.right_image_side.get(),
688 9 Faiq Sayyidan SETIAWAN
689 7 Faiq Sayyidan SETIAWAN
                'transparency_factor': self.right_transparency_factor.get()
690 9 Faiq Sayyidan SETIAWAN
691 7 Faiq Sayyidan SETIAWAN
            })
692 1 Faiq Sayyidan SETIAWAN
693 7 Faiq Sayyidan SETIAWAN
        # Save to file
694 9 Faiq Sayyidan SETIAWAN
695 7 Faiq Sayyidan SETIAWAN
        save_path = filedialog.asksaveasfilename(title="Save Configuration",
696 9 Faiq Sayyidan SETIAWAN
697 1 Faiq Sayyidan SETIAWAN
                                                 defaultextension=".ini",
698 9 Faiq Sayyidan SETIAWAN
699 7 Faiq Sayyidan SETIAWAN
                                                 filetypes=[("INI files", "*.ini")])
700 9 Faiq Sayyidan SETIAWAN
701 7 Faiq Sayyidan SETIAWAN
        if save_path:
702 9 Faiq Sayyidan SETIAWAN
703
            config.saveConfig(save_path)
704
705 7 Faiq Sayyidan SETIAWAN
            messagebox.showinfo("Success", f"Configuration saved to {save_path}")
706 9 Faiq Sayyidan SETIAWAN
707 7 Faiq Sayyidan SETIAWAN
            logging.info(f"Configuration saved to {save_path}")
708 1 Faiq Sayyidan SETIAWAN
709 9 Faiq Sayyidan SETIAWAN
    def loadConfiguration(self):
710
711 7 Faiq Sayyidan SETIAWAN
        load_path = filedialog.askopenfilename(title="Load Configuration",
712 9 Faiq Sayyidan SETIAWAN
713 7 Faiq Sayyidan SETIAWAN
                                               filetypes=[("INI files", "*.ini")])
714 9 Faiq Sayyidan SETIAWAN
715 1 Faiq Sayyidan SETIAWAN
        if load_path and os.path.exists(load_path):
716 9 Faiq Sayyidan SETIAWAN
717 7 Faiq Sayyidan SETIAWAN
            config = ConfigReader(load_path)
718 1 Faiq Sayyidan SETIAWAN
719 7 Faiq Sayyidan SETIAWAN
            # Load left image parameters
720 9 Faiq Sayyidan SETIAWAN
721 7 Faiq Sayyidan SETIAWAN
            self.left_image_path = config.getImageName()
722 9 Faiq Sayyidan SETIAWAN
723 7 Faiq Sayyidan SETIAWAN
            if self.left_image_path and os.path.exists(self.left_image_path):
724 9 Faiq Sayyidan SETIAWAN
725 1 Faiq Sayyidan SETIAWAN
                self.left_image_label.config(text=os.path.basename(self.left_image_path))
726 9 Faiq Sayyidan SETIAWAN
727 7 Faiq Sayyidan SETIAWAN
            self.left_projected_image_width.delete(0, tk.END)
728 9 Faiq Sayyidan SETIAWAN
729 7 Faiq Sayyidan SETIAWAN
            self.left_projected_image_width.insert(0, config.getProjectedImageWidth())
730 9 Faiq Sayyidan SETIAWAN
731 7 Faiq Sayyidan SETIAWAN
            self.left_projected_overlap_width.delete(0, tk.END)
732 9 Faiq Sayyidan SETIAWAN
733 7 Faiq Sayyidan SETIAWAN
            self.left_projected_overlap_width.insert(0, config.getProjectedOverlapWidth())
734 9 Faiq Sayyidan SETIAWAN
735 7 Faiq Sayyidan SETIAWAN
            self.left_gamma.delete(0, tk.END)
736 9 Faiq Sayyidan SETIAWAN
737 7 Faiq Sayyidan SETIAWAN
            self.left_gamma.insert(0, config.getGamma())
738 9 Faiq Sayyidan SETIAWAN
739 7 Faiq Sayyidan SETIAWAN
            self.left_image_side.set(config.getImageSide())
740 9 Faiq Sayyidan SETIAWAN
741 7 Faiq Sayyidan SETIAWAN
            self.left_transparency_factor.delete(0, tk.END)
742 9 Faiq Sayyidan SETIAWAN
743 7 Faiq Sayyidan SETIAWAN
            self.left_transparency_factor.insert(0, config.getTransparencyFactor())
744 1 Faiq Sayyidan SETIAWAN
745 7 Faiq Sayyidan SETIAWAN
            # Load right image parameters
746 9 Faiq Sayyidan SETIAWAN
747 7 Faiq Sayyidan SETIAWAN
            self.right_image_path = config.getImageName()
748 9 Faiq Sayyidan SETIAWAN
749 7 Faiq Sayyidan SETIAWAN
            if self.right_image_path and os.path.exists(self.right_image_path):
750 9 Faiq Sayyidan SETIAWAN
751 1 Faiq Sayyidan SETIAWAN
                self.right_image_label.config(text=os.path.basename(self.right_image_path))
752 9 Faiq Sayyidan SETIAWAN
753 1 Faiq Sayyidan SETIAWAN
            self.right_projected_image_width.delete(0, tk.END)
754 9 Faiq Sayyidan SETIAWAN
755 1 Faiq Sayyidan SETIAWAN
            self.right_projected_image_width.insert(0, config.getProjectedImageWidth())
756 9 Faiq Sayyidan SETIAWAN
757 1 Faiq Sayyidan SETIAWAN
            self.right_projected_overlap_width.delete(0, tk.END)
758 9 Faiq Sayyidan SETIAWAN
759 7 Faiq Sayyidan SETIAWAN
            self.right_projected_overlap_width.insert(0, config.getProjectedOverlapWidth())
760 9 Faiq Sayyidan SETIAWAN
761 1 Faiq Sayyidan SETIAWAN
            self.right_gamma.delete(0, tk.END)
762 9 Faiq Sayyidan SETIAWAN
763 1 Faiq Sayyidan SETIAWAN
            self.right_gamma.insert(0, config.getGamma())
764 9 Faiq Sayyidan SETIAWAN
765 1 Faiq Sayyidan SETIAWAN
            self.right_image_side.set(config.getImageSide())
766 9 Faiq Sayyidan SETIAWAN
767 1 Faiq Sayyidan SETIAWAN
            self.right_transparency_factor.delete(0, tk.END)
768 9 Faiq Sayyidan SETIAWAN
769 1 Faiq Sayyidan SETIAWAN
            self.right_transparency_factor.insert(0, config.getTransparencyFactor())
770 7 Faiq Sayyidan SETIAWAN
771 1 Faiq Sayyidan SETIAWAN
            messagebox.showinfo("Success", f"Configuration loaded from {load_path}")
772 9 Faiq Sayyidan SETIAWAN
773 1 Faiq Sayyidan SETIAWAN
            logging.info(f"Configuration loaded from {load_path}")
774 9 Faiq Sayyidan SETIAWAN
775 1 Faiq Sayyidan SETIAWAN
        else:
776 9 Faiq Sayyidan SETIAWAN
777 4 Faiq Sayyidan SETIAWAN
            messagebox.showerror("Error", "Failed to load configuration.")
778 7 Faiq Sayyidan SETIAWAN
779 9 Faiq Sayyidan SETIAWAN
    def processAndSave(self):
780
781 1 Faiq Sayyidan SETIAWAN
        # Validate inputs
782 9 Faiq Sayyidan SETIAWAN
783 1 Faiq Sayyidan SETIAWAN
        if not self.left_image_path or not self.right_image_path:
784 9 Faiq Sayyidan SETIAWAN
785 1 Faiq Sayyidan SETIAWAN
            messagebox.showerror("Error", "Please select both left and right images.")
786 9 Faiq Sayyidan SETIAWAN
787 1 Faiq Sayyidan SETIAWAN
            return
788 7 Faiq Sayyidan SETIAWAN
789 1 Faiq Sayyidan SETIAWAN
        # Collect parameters for left image
790 9 Faiq Sayyidan SETIAWAN
791 1 Faiq Sayyidan SETIAWAN
        left_params = {
792 9 Faiq Sayyidan SETIAWAN
793 1 Faiq Sayyidan SETIAWAN
            'image_name': self.left_image_path,
794 9 Faiq Sayyidan SETIAWAN
795 7 Faiq Sayyidan SETIAWAN
            'projected_image_width': int(self.left_projected_image_width.get()),
796 9 Faiq Sayyidan SETIAWAN
797 1 Faiq Sayyidan SETIAWAN
            'projected_overlap_width': int(self.left_projected_overlap_width.get()),
798 9 Faiq Sayyidan SETIAWAN
799 7 Faiq Sayyidan SETIAWAN
            'gamma': float(self.left_gamma.get()),
800 9 Faiq Sayyidan SETIAWAN
801 1 Faiq Sayyidan SETIAWAN
            'image_side': self.left_image_side.get(),
802 9 Faiq Sayyidan SETIAWAN
803 1 Faiq Sayyidan SETIAWAN
            'transparency_factor': float(self.left_transparency_factor.get())
804 9 Faiq Sayyidan SETIAWAN
805 1 Faiq Sayyidan SETIAWAN
        }
806
807 7 Faiq Sayyidan SETIAWAN
        # Collect parameters for right image
808 9 Faiq Sayyidan SETIAWAN
809 1 Faiq Sayyidan SETIAWAN
        right_params = {
810 9 Faiq Sayyidan SETIAWAN
811 1 Faiq Sayyidan SETIAWAN
            'image_name': self.right_image_path,
812 9 Faiq Sayyidan SETIAWAN
813 1 Faiq Sayyidan SETIAWAN
            'projected_image_width': int(self.right_projected_image_width.get()),
814 9 Faiq Sayyidan SETIAWAN
815 7 Faiq Sayyidan SETIAWAN
            'projected_overlap_width': int(self.right_projected_overlap_width.get()),
816 9 Faiq Sayyidan SETIAWAN
817 1 Faiq Sayyidan SETIAWAN
            'gamma': float(self.right_gamma.get()),
818 9 Faiq Sayyidan SETIAWAN
819 7 Faiq Sayyidan SETIAWAN
            'image_side': self.right_image_side.get(),
820 9 Faiq Sayyidan SETIAWAN
821 1 Faiq Sayyidan SETIAWAN
            'transparency_factor': float(self.right_transparency_factor.get())
822 9 Faiq Sayyidan SETIAWAN
823 1 Faiq Sayyidan SETIAWAN
        }
824 4 Faiq Sayyidan SETIAWAN
825 1 Faiq Sayyidan SETIAWAN
        # Initialize main display
826 9 Faiq Sayyidan SETIAWAN
827 7 Faiq Sayyidan SETIAWAN
        main_display = MainDisplay()
828
829 1 Faiq Sayyidan SETIAWAN
        # Process left image
830 9 Faiq Sayyidan SETIAWAN
831 7 Faiq Sayyidan SETIAWAN
        self.progress_bar["value"] = 0
832 9 Faiq Sayyidan SETIAWAN
833 7 Faiq Sayyidan SETIAWAN
        self.root.update_idletasks()
834 9 Faiq Sayyidan SETIAWAN
835
        left_processed, left_name = processImage(self.left_image_path, left_params, main_display)
836
837 7 Faiq Sayyidan SETIAWAN
        if left_processed is not None and left_name is not None:
838 9 Faiq Sayyidan SETIAWAN
839 1 Faiq Sayyidan SETIAWAN
            self.processed_images[left_name] = left_processed
840 9 Faiq Sayyidan SETIAWAN
841
            saveImage(left_processed, left_name)
842
843 1 Faiq Sayyidan SETIAWAN
            self.progress_bar["value"] += 50
844 9 Faiq Sayyidan SETIAWAN
845 1 Faiq Sayyidan SETIAWAN
            self.root.update_idletasks()
846 7 Faiq Sayyidan SETIAWAN
847 1 Faiq Sayyidan SETIAWAN
        # Process right image
848 9 Faiq Sayyidan SETIAWAN
849
        right_processed, right_name = processImage(self.right_image_path, right_params, main_display)
850
851 1 Faiq Sayyidan SETIAWAN
        if right_processed is not None and right_name is not None:
852 9 Faiq Sayyidan SETIAWAN
853 1 Faiq Sayyidan SETIAWAN
            self.processed_images[right_name] = right_processed
854 9 Faiq Sayyidan SETIAWAN
855
            saveImage(right_processed, right_name)
856
857 1 Faiq Sayyidan SETIAWAN
            self.progress_bar["value"] += 50
858 9 Faiq Sayyidan SETIAWAN
859 7 Faiq Sayyidan SETIAWAN
            self.root.update_idletasks()
860
861 1 Faiq Sayyidan SETIAWAN
        # Display images
862 7 Faiq Sayyidan SETIAWAN
863 9 Faiq Sayyidan SETIAWAN
        self.displayPreview()
864
865 1 Faiq Sayyidan SETIAWAN
        # Finalize progress
866 9 Faiq Sayyidan SETIAWAN
867 1 Faiq Sayyidan SETIAWAN
        self.progress_bar["value"] = 100
868 9 Faiq Sayyidan SETIAWAN
869 1 Faiq Sayyidan SETIAWAN
        self.root.update_idletasks()
870 9 Faiq Sayyidan SETIAWAN
871 1 Faiq Sayyidan SETIAWAN
        messagebox.showinfo("Processing Complete", "Images processed and saved successfully.")
872 7 Faiq Sayyidan SETIAWAN
873 9 Faiq Sayyidan SETIAWAN
    def displayPreview(self):
874
875 1 Faiq Sayyidan SETIAWAN
        # Display the first processed image as preview
876 9 Faiq Sayyidan SETIAWAN
877 1 Faiq Sayyidan SETIAWAN
        if self.processed_images:
878 9 Faiq Sayyidan SETIAWAN
879 7 Faiq Sayyidan SETIAWAN
            # For simplicity, display the first image
880 9 Faiq Sayyidan SETIAWAN
881 7 Faiq Sayyidan SETIAWAN
            name, img = next(iter(self.processed_images.items()))
882 9 Faiq Sayyidan SETIAWAN
883 4 Faiq Sayyidan SETIAWAN
            img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
884 9 Faiq Sayyidan SETIAWAN
885 7 Faiq Sayyidan SETIAWAN
            pil_img = Image.fromarray(img_rgb)
886 9 Faiq Sayyidan SETIAWAN
887 7 Faiq Sayyidan SETIAWAN
            pil_img = pil_img.resize((400, 300), Image.ANTIALIAS)
888 9 Faiq Sayyidan SETIAWAN
889 7 Faiq Sayyidan SETIAWAN
            img_tk = ImageTk.PhotoImage(pil_img)
890 9 Faiq Sayyidan SETIAWAN
891 4 Faiq Sayyidan SETIAWAN
            self.processed_image_label.config(image=img_tk)
892 9 Faiq Sayyidan SETIAWAN
893 7 Faiq Sayyidan SETIAWAN
            self.processed_image_label.image = img_tk
894
895
            # Load and display original image
896 9 Faiq Sayyidan SETIAWAN
897 4 Faiq Sayyidan SETIAWAN
            original_img = cv2.imread(self.left_image_path if name == 'left' else self.right_image_path, cv2.IMREAD_COLOR)
898 9 Faiq Sayyidan SETIAWAN
899 7 Faiq Sayyidan SETIAWAN
            if original_img is not None:
900 9 Faiq Sayyidan SETIAWAN
901 7 Faiq Sayyidan SETIAWAN
                original_rgb = cv2.cvtColor(original_img, cv2.COLOR_BGR2RGB)
902 9 Faiq Sayyidan SETIAWAN
903 4 Faiq Sayyidan SETIAWAN
                pil_original = Image.fromarray(original_rgb)
904 9 Faiq Sayyidan SETIAWAN
905 7 Faiq Sayyidan SETIAWAN
                pil_original = pil_original.resize((400, 300), Image.ANTIALIAS)
906 9 Faiq Sayyidan SETIAWAN
907 7 Faiq Sayyidan SETIAWAN
                original_tk = ImageTk.PhotoImage(pil_original)
908 9 Faiq Sayyidan SETIAWAN
909 7 Faiq Sayyidan SETIAWAN
                self.original_image_label.config(image=original_tk)
910 9 Faiq Sayyidan SETIAWAN
911 7 Faiq Sayyidan SETIAWAN
                self.original_image_label.image = original_tk
912
913 9 Faiq Sayyidan SETIAWAN
    def displayImage(self, processed_images):
914
915 7 Faiq Sayyidan SETIAWAN
        # This method can be expanded to display multiple images if needed
916 9 Faiq Sayyidan SETIAWAN
917 4 Faiq Sayyidan SETIAWAN
        pass
918
919
def main():
920
921
    root = tk.Tk()
922
923
    app = ImageProcessingApp(root)
924
925
    root.mainloop()
926
927
if __name__ == "__main__":
928 1 Faiq Sayyidan SETIAWAN
929
    main()
930 8 Faiq Sayyidan SETIAWAN
931 1 Faiq Sayyidan SETIAWAN
</code></pre>