맥에서 오픈소스로

HSV + Trackbar + TkInter + OpenCV 본문

수학적 영상처리

HSV + Trackbar + TkInter + OpenCV

제갈티 2025. 2. 6. 13:46

import cv2
import numpy as np
import tkinter as tk
from tkinter import ttk
from tkinter import filedialog
from PIL import Image, ImageTk

class HSVColorFinder:
    def __init__(self, root):
        self.root = root
        self.root.title("HSV Color Finder")
        
        # 변수 초기화
        self.image = None
        self.photo = None
        self.current_image = None
        self.value_labels = {}  # 슬라이더 값 표시용 레이블
        
        # GUI 구성
        self.create_gui()
        
    def create_gui(self):
        # 프레임 생성
        control_frame = ttk.Frame(self.root)
        control_frame.pack(side=tk.LEFT, padx=10, pady=5)
        
        image_frame = ttk.Frame(self.root)
        image_frame.pack(side=tk.RIGHT, padx=10, pady=5)
        
        # 이미지 로드 버튼
        ttk.Button(control_frame, text="Load Image", command=self.load_image).pack(pady=5)
        
        # HSV 슬라이더 생성
        labels = ['H Min', 'S Min', 'V Min', 'H Max', 'S Max', 'V Max']
        self.sliders = {}
        
        for i, label in enumerate(labels):
            slider_frame = ttk.Frame(control_frame)
            slider_frame.pack(pady=2)
            
            ttk.Label(slider_frame, text=label, width=10).pack(side=tk.LEFT)
            
            max_val = 179 if 'H' in label else 255
            slider = ttk.Scale(slider_frame, 
                             from_=0, 
                             to=max_val, 
                             orient=tk.HORIZONTAL, 
                             length=200,
                             command=lambda v, l=label: self.on_slider_change(v, l))
            slider.pack(side=tk.LEFT, padx=5)
            self.sliders[label] = slider
            
            # 값 표시 레이블 추가
            value_label = ttk.Label(slider_frame, text="0", width=5)
            value_label.pack(side=tk.LEFT)
            self.value_labels[label] = value_label
            
            # Max 값들의 기본값 설정
            if 'Max' in label:
                slider.set(max_val)
                value_label.config(text=str(max_val))
        
        # 결과 표시 레이블
        self.image_label = ttk.Label(image_frame)
        self.image_label.pack()
        
    def on_slider_change(self, value, label):
        # 슬라이더 값 레이블 업데이트
        self.value_labels[label].config(text=str(int(float(value))))
        # 이미지 업데이트
        self.update_image()
        
    def load_image(self):
        file_path = filedialog.askopenfilename(
            filetypes=[("Image files", "*.png *.jpg *.jpeg *.bmp *.gif *.tiff")]
        )
        if file_path:
            self.image = cv2.imread(file_path)
            self.update_image()
    
    def update_image(self):
        if self.image is None:
            return
            
        # HSV 값 가져오기
        hmin = int(self.sliders['H Min'].get())
        smin = int(self.sliders['S Min'].get())
        vmin = int(self.sliders['V Min'].get())
        hmax = int(self.sliders['H Max'].get())
        smax = int(self.sliders['S Max'].get())
        vmax = int(self.sliders['V Max'].get())
        
        # HSV 변환 및 마스크 적용
        hsv = cv2.cvtColor(self.image, cv2.COLOR_BGR2HSV)
        lower = np.array([hmin, smin, vmin])
        upper = np.array([hmax, smax, vmax])
        mask = cv2.inRange(hsv, lower, upper)
        result = cv2.bitwise_and(self.image, self.image, mask=mask)
        
        # OpenCV BGR to RGB 변환
        result_rgb = cv2.cvtColor(result, cv2.COLOR_BGR2RGB)
        
        # 이미지 크기 조정 (필요한 경우)
        height, width = result_rgb.shape[:2]
        max_size = 600
        if width > max_size or height > max_size:
            scale = max_size / max(width, height)
            new_width = int(width * scale)
            new_height = int(height * scale)
            result_rgb = cv2.resize(result_rgb, (new_width, new_height))
        
        # PIL Image로 변환
        image = Image.fromarray(result_rgb)
        self.photo = ImageTk.PhotoImage(image=image)
        
        # 레이블 업데이트
        self.image_label.configure(image=self.photo)
        self.image_label.image = self.photo

def main():
    root = tk.Tk()
    app = HSVColorFinder(root)
    root.mainloop()

if __name__ == "__main__":
    main()