From d576f9979c3b7324ee8340267825833b07bda371 Mon Sep 17 00:00:00 2001 From: Hazel Noack Date: Wed, 7 May 2025 15:20:02 +0200 Subject: [PATCH] feat: ui --- deblur/symetric_kernel.py | 107 +++++++++++++++++++++++++++++++++++++- 1 file changed, 105 insertions(+), 2 deletions(-) diff --git a/deblur/symetric_kernel.py b/deblur/symetric_kernel.py index 0b88ce6..052b783 100644 --- a/deblur/symetric_kernel.py +++ b/deblur/symetric_kernel.py @@ -1,4 +1,16 @@ +import sys import numpy as np +import cv2 +from PyQt5.QtWidgets import ( + QApplication, QWidget, QLabel, QSlider, QVBoxLayout, + QHBoxLayout, QGridLayout, QPushButton, QFileDialog +) +from PyQt5.QtCore import Qt +from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas +from matplotlib.figure import Figure + +import os +os.environ.pop("QT_QPA_PLATFORM_PLUGIN_PATH", None) def generate_kernel(radius, sigma=None): @@ -30,6 +42,97 @@ def generate_kernel(radius, sigma=None): return kernel +class KernelVisualizer(QWidget): + def __init__(self): + super().__init__() + self.setWindowTitle("Gaussian Kernel Visualizer") + self.image = None + + self.load_button = QPushButton("Load Image") + self.load_button.clicked.connect(self.load_image) + + self.radius_slider = QSlider(Qt.Horizontal) + self.radius_slider.setRange(1, 30) + self.radius_slider.setValue(5) + + self.sigma_slider = QSlider(Qt.Horizontal) + self.sigma_slider.setRange(1, 100) + self.sigma_slider.setValue(15) + + self.radius_slider.valueChanged.connect(self.update_visualization) + self.sigma_slider.valueChanged.connect(self.update_visualization) + + self.kernel_fig = Figure(figsize=(3, 3)) + self.kernel_canvas = FigureCanvas(self.kernel_fig) + + self.image_fig = Figure(figsize=(6, 3)) + self.image_canvas = FigureCanvas(self.image_fig) + + layout = QVBoxLayout() + layout.addWidget(self.load_button) + + sliders_layout = QGridLayout() + sliders_layout.addWidget(QLabel("Radius:"), 0, 0) + sliders_layout.addWidget(self.radius_slider, 0, 1) + sliders_layout.addWidget(QLabel("Sigma:"), 1, 0) + sliders_layout.addWidget(self.sigma_slider, 1, 1) + + layout.addLayout(sliders_layout) + layout.addWidget(QLabel("Kernel Visualization:")) + layout.addWidget(self.kernel_canvas) + layout.addWidget(QLabel("Original and Blurred Image:")) + layout.addWidget(self.image_canvas) + + self.setLayout(layout) + self.update_visualization() + + def load_image(self): + fname, _ = QFileDialog.getOpenFileName(self, "Open Image", "", "Images (*.png *.jpg *.bmp *.jpeg)") + if fname: + img = cv2.imread(fname) + if img is not None: + self.image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) + self.update_visualization() + + def update_visualization(self): + radius = self.radius_slider.value() + sigma = self.sigma_slider.value() / 10.0 + kernel = generate_kernel(radius, sigma) + + # Kernel Visualization + self.kernel_fig.clear() + ax = self.kernel_fig.add_subplot(111) + cax = ax.imshow(kernel, cmap='hot') + self.kernel_fig.colorbar(cax, ax=ax) + ax.set_title(f"Kernel (r={radius}, σ={sigma:.2f})") + self.kernel_canvas.draw() + + if self.image is not None: + kernel_size = 2 * radius + 1 + blurred = cv2.GaussianBlur(self.image, (kernel_size, kernel_size), sigma) + + self.image_fig.clear() + ax1 = self.image_fig.add_subplot(121) + ax1.imshow(self.image, cmap='gray') + ax1.set_title("Original") + ax1.axis('off') + + ax2 = self.image_fig.add_subplot(122) + ax2.imshow(blurred, cmap='gray') + ax2.set_title("Blurred") + ax2.axis('off') + + self.image_canvas.draw() + else: + self.image_fig.clear() + ax = self.image_fig.add_subplot(111) + ax.text(0.5, 0.5, "No image loaded", fontsize=14, ha='center', va='center') + ax.axis('off') + self.image_canvas.draw() + + if __name__ == "__main__": - kernel = generate_kernel(radius=10, sigma=1) - print(kernel) + app = QApplication(sys.argv) + viewer = KernelVisualizer() + viewer.show() + sys.exit(app.exec_())