import gradio as gr import cv2 import numpy as np from PIL import Image, ImageEnhance from gradio_imageslider import ImageSlider def apply_filter(image, filter_type, intensity): # PIL 이미지를 numpy array로 변환 image = np.array(image) # 강도를 0.0에서 1.0 사이로 정규화 normalized_intensity = intensity / 100.0 if filter_type == "Grayscale": return convert_to_grayscale(image) elif filter_type == "Soft Glow": # 기본 10% 강도에서 시작하여 최대 100% 강도까지 조절 base_intensity = 0.1 adjusted_intensity = base_intensity + (normalized_intensity * (1 - base_intensity)) gaussian = cv2.GaussianBlur(image, (15, 15), 0) soft_glow = cv2.addWeighted(image, 1 - adjusted_intensity, gaussian, adjusted_intensity, 0) return soft_glow elif filter_type == "Portrait Enhancer": # 기본 50% 강도에서 시작하여 최대 100% 강도까지 조절 base_intensity = 0.5 adjusted_intensity = base_intensity + (normalized_intensity * (1 - base_intensity)) image_pil = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) enhancer = ImageEnhance.Sharpness(image_pil) image_pil = enhancer.enhance(1 + 0.5 * adjusted_intensity) # 강도 반영 enhancer = ImageEnhance.Color(image_pil) image_pil = enhancer.enhance(1 + 0.5 * adjusted_intensity) # 강도 반영 enhanced_image = cv2.cvtColor(np.array(image_pil), cv2.COLOR_RGB2BGR) return enhanced_image elif filter_type == "Warm Tone": # 따뜻한 톤 적용 warm_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) warm_image = cv2.applyColorMap(warm_image, cv2.COLORMAP_AUTUMN) return cv2.cvtColor(warm_image, cv2.COLOR_RGB2BGR) elif filter_type == "Cold Tone": # 차가운 톤 적용 cold_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) cold_image = cv2.applyColorMap(cold_image, cv2.COLORMAP_WINTER) return cv2.cvtColor(cold_image, cv2.COLOR_RGB2BGR) elif filter_type == "High-Key": high_key = cv2.convertScaleAbs(image, alpha=1.0 + 0.8 * normalized_intensity, beta=30) return high_key elif filter_type == "Low-Key": low_key = cv2.convertScaleAbs(image, alpha=1.0 - 0.7 * normalized_intensity, beta=-30) return low_key elif filter_type == "Haze": haze = cv2.addWeighted(image, 1.0 - 0.7 * normalized_intensity, np.full(image.shape, 255, dtype=np.uint8), 0.3 * normalized_intensity, 0) return haze else: return image def convert_to_grayscale(image): gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) return cv2.cvtColor(gray_image, cv2.COLOR_GRAY2BGR) # 필터 적용 후 일관성을 위해 BGR로 변환 def convert_and_save(image, filter_type, intensity): filtered_image = apply_filter(image, filter_type, intensity) # numpy array를 PIL 이미지로 변환 original_image_pil = Image.fromarray(cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)) filtered_image_pil = Image.fromarray(filtered_image) return original_image_pil, filtered_image_pil # 원본과 필터 적용된 이미지를 반환 def get_filter_description(filter_type): descriptions = { "Grayscale": "이미지를 흑백으로 변환합니다.", "Soft Glow": "부드러운 빛을 추가하여 이미지를 은은하게 만듭니다.", "Portrait Enhancer": "피부 톤을 균일하게 하고 선명도를 조절하여 인물을 더욱 돋보이게 만듭니다.", "Warm Tone": "따뜻한 색조를 추가하여 이미지에 온기를 더합니다.", "Cold Tone": "차가운 색조를 추가하여 이미지에 시원함을 더합니다.", "High-Key": "밝고 화사한 이미지를 만들어냅니다.", "Low-Key": "어두운 톤을 강조하여 분위기 있는 이미지를 만듭니다.", "Haze": "부드럽고 흐릿한 효과를 추가하여 몽환적인 이미지를 만듭니다." } return descriptions.get(filter_type, "") with gr.Blocks() as iface: with gr.Row(): with gr.Column(): image_input = gr.Image(type="pil", label="이미지 업로드") filter_input = gr.Radio( ["Grayscale", "Soft Glow", "Portrait Enhancer", "Warm Tone", "Cold Tone", "High-Key", "Low-Key", "Haze"], label="필터 선택", value="Soft Glow" ) intensity_slider = gr.Slider(1, 100, value=50, label="필터 강도") description_output = gr.Markdown(get_filter_description("Soft Glow")) with gr.Column(): slider_output = ImageSlider(label="Before and After", type="pil") filter_input.change(fn=get_filter_description, inputs=filter_input, outputs=description_output) process_button = gr.Button("필터 적용") process_button.click( fn=convert_and_save, inputs=[image_input, filter_input, intensity_slider], outputs=slider_output ) iface.title = "인물 사진에 최적화된 필터" iface.description = "인물 사진에 최적화된 다양한 필터를 적용할 수 있습니다." iface.launch()