|
|
import gradio as gr |
|
|
import numpy as np |
|
|
import cv2 |
|
|
import math |
|
|
|
|
|
|
|
|
interpolation_map = { |
|
|
'Nearest': cv2.INTER_NEAREST, |
|
|
'Linear': cv2.INTER_LINEAR, |
|
|
'Cubic': cv2.INTER_CUBIC, |
|
|
'Area': cv2.INTER_AREA, |
|
|
'Lanczos4': cv2.INTER_LANCZOS4 |
|
|
} |
|
|
|
|
|
def resize_image_gaussian_smooth(image, target_width, target_height, interpolation_str, blur_sigma): |
|
|
""" |
|
|
Изменяет размер изображения и применяет Гауссово размытие. |
|
|
|
|
|
Args: |
|
|
image (np.ndarray): Входное изображение в формате NumPy RGB. |
|
|
target_width (int): Целевая ширина. |
|
|
target_height (int): Целевая высота. |
|
|
interpolation_str (str): Название метода интерполяции ('Nearest', 'Linear', etc.). |
|
|
blur_sigma (float): Стандартное отклонение для Гауссова фильтра (0 = без размытия). |
|
|
|
|
|
Returns: |
|
|
np.ndarray: Обработанное изображение в формате NumPy RGB, или None при ошибке. |
|
|
""" |
|
|
if image is None: |
|
|
gr.Warning("Сначала загрузите изображение!") |
|
|
return None |
|
|
if not (isinstance(target_width, (int, float)) and target_width > 0 and |
|
|
isinstance(target_height, (int, float)) and target_height > 0): |
|
|
gr.Warning("Ширина и высота должны быть положительными числами.") |
|
|
return None |
|
|
|
|
|
target_width = int(target_width) |
|
|
target_height = int(target_height) |
|
|
blur_sigma = float(blur_sigma) |
|
|
|
|
|
|
|
|
MAX_DIM = 8192 |
|
|
if target_width > MAX_DIM or target_height > MAX_DIM: |
|
|
gr.Warning(f"Слишком большой размер. Максимальная сторона: {MAX_DIM}px.") |
|
|
return None |
|
|
|
|
|
h_orig, w_orig, _ = image.shape |
|
|
print(f"Original size: {w_orig}x{h_orig}") |
|
|
print(f"Target size: {target_width}x{target_height}") |
|
|
print(f"Interpolation: {interpolation_str}") |
|
|
print(f"Gaussian Sigma: {blur_sigma}") |
|
|
|
|
|
|
|
|
|
|
|
interpolation_flag = interpolation_map.get(interpolation_str, cv2.INTER_LANCZOS4) |
|
|
|
|
|
|
|
|
|
|
|
img_bgr = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) |
|
|
|
|
|
try: |
|
|
resized_bgr = cv2.resize(img_bgr, (target_width, target_height), interpolation=interpolation_flag) |
|
|
except Exception as e: |
|
|
gr.Error(f"Ошибка при изменении размера: {e}") |
|
|
return None |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
result_bgr = resized_bgr |
|
|
if blur_sigma > 0.0: |
|
|
|
|
|
|
|
|
ksize = int(math.ceil(blur_sigma * 3)) * 2 + 1 |
|
|
print(f"Calculated Gaussian kernel size: ({ksize}, {ksize}) for sigma={blur_sigma}") |
|
|
try: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
result_bgr = cv2.GaussianBlur(resized_bgr, ksize=(0, 0), sigmaX=blur_sigma, sigmaY=blur_sigma) |
|
|
except Exception as e: |
|
|
gr.Error(f"Ошибка при применении размытия: {e}") |
|
|
return None |
|
|
|
|
|
|
|
|
|
|
|
result_rgb = cv2.cvtColor(result_bgr, cv2.COLOR_BGR2RGB) |
|
|
|
|
|
return result_rgb |
|
|
|
|
|
|
|
|
with gr.Blocks(theme=gr.themes.Soft()) as demo: |
|
|
gr.Markdown( |
|
|
""" |
|
|
# Масштабирование изображений с Гауссовым сглаживанием |
|
|
Загрузите изображение, выберите целевое разрешение, метод интерполяции и степень Гауссова размытия (для сглаживания). |
|
|
Это может имитировать эффект сглаживания от технологий типа NVIDIA DSR при даунскейлинге, |
|
|
или просто смягчить артефакты апскейлинга. |
|
|
""" |
|
|
) |
|
|
|
|
|
with gr.Row(): |
|
|
with gr.Column(scale=1): |
|
|
input_image = gr.Image(label="Входное изображение", type="numpy", height=300) |
|
|
interp_choice = gr.Dropdown( |
|
|
choices=list(interpolation_map.keys()), |
|
|
label="Метод интерполяции для масштабирования", |
|
|
value='Lanczos4' |
|
|
) |
|
|
target_w = gr.Number(label="Целевая ширина (px)", value=512, minimum=1, step=1, precision=0) |
|
|
target_h = gr.Number(label="Целевая высота (px)", value=512, minimum=1, step=1, precision=0) |
|
|
|
|
|
smoothness_sigma = gr.Slider( |
|
|
minimum=0.0, maximum=5.0, step=0.1, |
|
|
label="Сигма Гауссова размытия (0 = нет)", |
|
|
info="Применяется ПОСЛЕ масштабирования. Небольшие значения (0.3-0.8) могут сгладить пикселизацию апскейла или имитировать DSR-сглаживание даунскейла.", |
|
|
value=0.0 |
|
|
) |
|
|
submit_btn = gr.Button("Обработать изображение", variant="primary") |
|
|
|
|
|
with gr.Column(scale=1): |
|
|
output_image = gr.Image(label="Результат", type="numpy", height=400) |
|
|
|
|
|
gr.Markdown( |
|
|
"**Примечание о 13-tap Gaussian filter:** DSR использует специфический фильтр. " |
|
|
"Здесь применяется стандартный Гауссов фильтр *после* изменения размера. " |
|
|
"Параметр `Сигма` контролирует степень размытия." |
|
|
"Вы можете экспериментировать с `Сигмой` около 0.5-1.0 для имитации мягкого сглаживания." |
|
|
) |
|
|
|
|
|
|
|
|
submit_btn.click( |
|
|
fn=resize_image_gaussian_smooth, |
|
|
inputs=[input_image, target_w, target_h, interp_choice, smoothness_sigma], |
|
|
outputs=output_image |
|
|
) |
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
|
|
|
demo.launch() |