Serg4451D commited on
Commit
8bb0c57
·
verified ·
1 Parent(s): d7c28e9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +127 -112
app.py CHANGED
@@ -1,119 +1,134 @@
1
  import gradio as gr
2
- import cv2
3
  import numpy as np
4
- from PIL import Image
5
- import os
6
-
7
- # Функции улучшения изображения
8
-
9
- def resize_lanczos(image, scale_factor):
10
- """Апскейл изображения с помощью интерполяции Ланцоша."""
11
- width = int(image.shape[1] * scale_factor)
12
- height = int(image.shape[0] * scale_factor)
13
- return cv2.resize(image, (width, height), interpolation=cv2.INTER_LANCZOS4)
14
-
15
- def resize_dcci(image, scale_factor):
16
- """Апскейл изображения с помощью DCCI (Directional Cubic Convolution Interpolation)."""
17
- # DCCI требует на вход изображение в формате PIL Image
18
- pil_image = Image.fromarray(image)
19
-
20
- # Определение новых размеров
21
- width, height = pil_image.size
22
- new_width = int(width * scale_factor)
23
- new_height = int(height * scale_factor)
24
-
25
- # Используем Image.resize с методом Image.Resampling.LANCZOS, который
26
- # является приближением DCCI в библиотеке Pillow
27
- resized_image = pil_image.resize((new_width, new_height), Image.Resampling.LANCZOS)
28
-
29
- return np.array(resized_image)
30
-
31
- def denoise_image(image, strength=10, photo_render=10, color_render=10):
32
- """Подавление шума на изображении с помощью Non-local Means Denoising."""
33
- return cv2.fastNlMeansDenoisingColored(image, None, strength, photo_render, 7, 21)
34
-
35
- def sharpen_image(image, strength=1.5, radius=1):
36
- """Повышение резкости изображения с помощью Unsharp Masking."""
37
- blurred = cv2.GaussianBlur(image, (0, 0), radius)
38
- sharpened = cv2.addWeighted(image, strength, blurred, 1-strength, 0)
39
- return sharpened
40
-
41
- def enhance_details(image, strength=5, radius=50):
42
- """Улучшение деталей с помощью Bilateral Filter."""
43
- return cv2.detailEnhance(image, sigma_s=radius, sigma_r=strength/100.0)
44
-
45
- def adjust_contrast_brightness(image, contrast=1.0, brightness=0):
46
- """Регулировка контрастности и яркости."""
47
- return cv2.convertScaleAbs(image, alpha=contrast, beta=brightness)
48
-
49
- def enhance_image(image, scale_factor, denoise_strength, sharpen_strength, detail_strength, contrast, brightness, use_dcci, use_lanczos):
50
- """Основная функция для улучшения и апскейла изображения."""
51
-
52
- # Конвертация в формат OpenCV, если на вход подана PIL Image
53
- if isinstance(image, Image.Image):
54
- image = np.array(image)
55
-
56
- # 1. Подавление шума
57
- if denoise_strength > 0:
58
- image = denoise_image(image, strength=denoise_strength)
59
-
60
- # 2. Апскейл
61
- if use_dcci:
62
- image = resize_dcci(image, scale_factor)
63
- elif use_lanczos:
64
- image = resize_lanczos(image, scale_factor)
65
- else:
66
- image = resize_dcci(image, scale_factor) # DCCI по умолчанию
67
-
68
- # 3. Повышение резкости
69
- if sharpen_strength > 0:
70
- image = sharpen_image(image, strength=sharpen_strength/10.0 + 1)
71
-
72
- # 4. Улучшение деталей
73
- if detail_strength > 0:
74
- image = enhance_details(image, strength=detail_strength, radius=50)
75
-
76
- # 5. Регулировка контрастности и яркости
77
- image = adjust_contrast_brightness(image, contrast=contrast, brightness=brightness)
78
-
79
- return image
80
-
81
- # Создание интерфейса Gradio
82
- def process_image_gradio(image, scale_factor, denoise_strength, sharpen_strength, detail_strength, contrast, brightness, use_dcci, use_lanczos):
83
- """Обработка изображения через интерфейс Gradio."""
84
- # Обработка изображения
85
- enhanced_image = enhance_image(image, scale_factor, denoise_strength, sharpen_strength, detail_strength, contrast, brightness, use_dcci, use_lanczos)
86
-
87
- return enhanced_image
88
-
89
- # Компоненты Gradio
90
- inputs = [
91
- gr.Image(type="numpy", label="Исходное изображение"),
92
- gr.Slider(minimum=1, maximum=4, step=0.1, value=2, label="Коэффициент увеличения"),
93
- gr.Slider(minimum=0, maximum=30, step=1, value=10, label="Сила подавления шума"),
94
- gr.Slider(minimum=0, maximum=20, step=1, value=5, label="Сила повышения резкости"),
95
- gr.Slider(minimum=0, maximum=10, step=1, value=0, label="Сила улучшения деталей"),
96
- gr.Slider(minimum=0.5, maximum=2.0, step=0.1, value=1.0, label="Контрастность"),
97
- gr.Slider(minimum=-50, maximum=50, step=1, value=0, label="Яркость"),
98
- gr.Checkbox(value=False, label="Использовать DCCI (более качественный, но медленный)"),
99
- gr.Checkbox(value=True, label="Использовать Lanczos (быстрый)"),
100
- ]
101
- outputs = gr.Image(type="numpy", label="Улучшенное изображение")
102
-
103
- title = "Улучшение и апскейл изображений"
104
- description = "Приложение для улучшения качества и увеличения разрешения фотографий. Используются алгоритмы: интерполяция Ланцоша/DCCI, подавление шума (Non-local Means Denoising), повышение резкости (Unsharp Masking), улучшение деталей (Bilateral Filter) и регулировка контрастности/яркости."
105
-
106
- # Запуск интерфейса
 
 
 
 
 
 
 
 
 
107
  iface = gr.Interface(
108
- fn=process_image_gradio,
109
- inputs=inputs,
110
- outputs=outputs,
111
- title=title,
112
- description=description,
113
- examples=[
114
- [os.path.join(os.path.dirname(__file__), "example.jpg"), 2, 10, 5, 0, 1.0, 0, False, True],
 
 
 
115
  ],
116
- cache_examples=False
 
 
 
117
  )
118
 
119
  iface.launch()
 
1
  import gradio as gr
2
+ from PIL import Image, ImageFilter
3
  import numpy as np
4
+
5
+ def lossless_compression(image, reduction_percent, target_size_kb, auto_mode):
6
+ """
7
+ Сжимает изображение без потерь качества, уменьшая количество пикселей и применяя алгоритмы для сохранения деталей.
8
+
9
+ Args:
10
+ image: Входное изображение (PIL Image).
11
+ reduction_percent: Процент уменьшения пикселей по горизонтали (0-100).
12
+ target_size_kb: Желаемый размер файла в килобайтах (используется в автоматическом режиме).
13
+ auto_mode: Флаг автоматического режима (True/False).
14
+
15
+ Returns:
16
+ Сжатое изображение (PIL Image).
17
+ """
18
+
19
+ if auto_mode:
20
+ # Автоматический подбор параметров сжатия
21
+ reduction_percent, quality = auto_adjust_compression(image, target_size_kb)
22
+ else:
23
+ # Ручной режим, используем заданный процент уменьшения
24
+ quality = 95 # Базовое качество JPEG, можно настроить
25
+
26
+ # 1. Уменьшение количества пикселей по горизонтали
27
+ width, height = image.size
28
+ new_width = int(width * (1 - reduction_percent / 100))
29
+ resized_image = image.resize((new_width, height), Image.LANCZOS)
30
+
31
+ # 2. Растягивание обратно фильтром Ланцоша
32
+ stretched_image = resized_image.resize((width, height), Image.LANCZOS)
33
+
34
+ # 3. Адаптивное размытие (уменьшение шума и артефактов)
35
+ blurred_image = adaptive_blur(stretched_image)
36
+
37
+ # 4. Повышение резкости (компенсация размытия)
38
+ sharpened_image = blurred_image.filter(ImageFilter.UnsharpMask(radius=1, percent=150, threshold=3))
39
+
40
+ # 5. Сохранение с оптимизированными параметрами
41
+ output_image = sharpened_image
42
+
43
+ # Преобразование изображения в формат, пригодный для сохранения в буфер
44
+ if output_image.mode != "RGB":
45
+ output_image = output_image.convert("RGB")
46
+
47
+ return output_image, reduction_percent, quality
48
+
49
+ def auto_adjust_compression(image, target_size_kb):
50
+ """
51
+ Автоматически подбирает параметры сжатия для достижения целевого размера файла.
52
+
53
+ Args:
54
+ image: Входное изображение (PIL Image).
55
+ target_size_kb: Желаемый размер файла в килобайтах.
56
+
57
+ Returns:
58
+ Оптимальный процент уменьшения, оптимальное качество JPEG.
59
+ """
60
+
61
+ # Очень грубая эвристика для начальной оценки. Нужно тестировать и улучшать
62
+ initial_reduction = min(50, int(100 * (1 - target_size_kb * 1024 / len(image.tobytes()))))
63
+ reduction_percent = initial_reduction
64
+ quality = 95
65
+
66
+ # Итеративно подбираем параметры, если нужно.
67
+ # В реальном приложении здесь может быть более сложный алгоритм
68
+ # с бинарным поиском или другими методами оптимизации.
69
+
70
+ return reduction_percent, quality
71
+
72
+ def adaptive_blur(image):
73
+ """
74
+ Применяет адаптивное размытие к изображению.
75
+
76
+ Args:
77
+ image: Входное изображение (PIL Image).
78
+
79
+ Returns:
80
+ Изображение с адаптивным размытием (PIL Image).
81
+ """
82
+ # Преобразуем изображение в массив NumPy для анализа
83
+ img_array = np.array(image)
84
+
85
+ # Простой пример адаптивного размытия:
86
+ # Сильнее размываем области с меньшим количеством деталей (меньше дисперсия)
87
+ # Это очень базовый пример, нужно улучшать в зависимости от задачи
88
+ std_dev = np.std(img_array)
89
+
90
+ if std_dev < 20: # Порог стандартного отклонения - настраиваемый параметр
91
+ # Применяем более сильное размытие
92
+ blurred_image = image.filter(ImageFilter.GaussianBlur(radius=2))
93
+ else:
94
+ # Применяем слабое размытие
95
+ blurred_image = image.filter(ImageFilter.GaussianBlur(radius=1))
96
+
97
+ return blurred_image
98
+
99
+ def save_compressed_image(image, quality, filename="compressed_image.jpg"):
100
+ """
101
+ Сохраняет сжатое изображение с указанным качеством.
102
+
103
+ Args:
104
+ image: PIL Image.
105
+ quality: Качество JPEG (0-100).
106
+ filename: Имя файла для сохранения.
107
+ """
108
+ image.save(filename, "JPEG", optimize=True, quality=quality)
109
+
110
+ # Интерфейс Gradio
111
+ def gradio_interface(image, reduction_percent, target_size_kb, auto_mode):
112
+ compressed_image, used_reduction, used_quality = lossless_compression(image, reduction_percent, target_size_kb, auto_mode)
113
+ save_compressed_image(compressed_image, used_quality)
114
+ return compressed_image, f"Использованное уменьшение: {used_reduction:.2f}%, Качество JPEG: {used_quality}"
115
+
116
  iface = gr.Interface(
117
+ fn=gradio_interface,
118
+ inputs=[
119
+ gr.Image(type="pil", label="Исходное изображение"),
120
+ gr.Slider(0, 50, step=1, value=12, label="Процент уменьшения пикселей по горизонтали (ручной режим)"),
121
+ gr.Slider(1, 200, step=1, value=50, label="Желаемый размер файла в KB (автоматический режим)"),
122
+ gr.Checkbox(label="Автоматический режим"),
123
+ ],
124
+ outputs=[
125
+ gr.Image(type="pil", label="Сжатое изображение"),
126
+ gr.Textbox(label="Параметры сжатия")
127
  ],
128
+ title="Сжатие изображений без потерь",
129
+ description="Уменьшает размер изображения, сохраняя визуальное качество. "
130
+ "Выберите автоматический режим или введите желаемый размер файла "
131
+ "или процент уменьшения пикселей вручную.",
132
  )
133
 
134
  iface.launch()