Files
CourseWork/core/utils.py
Игорь 56ff6d2492 Прописал код для core/utils.py
Добавлены вспомогательные функции для стеганографии LSB и DCT
2026-03-24 21:36:21 +03:00

128 lines
4.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
Вспомогательные функции для стеганографии
Модуль содержит утилиты для работы с текстом, битами и метриками качества
"""
import numpy as np
from math import log10, sqrt
def text_to_bits(text: str) -> str:
"""
Преобразует текст в строку битов.
Аргументы:
text (str): Входной текст (например, "Привет")
Возвращает:
str: Строка из '0' и '1' (например, "11010001...")
Пример:
>>> text_to_bits("A")
'01000001'
"""
# Кодируем текст в байты (UTF-8 поддерживает русский язык)
bytes_data = text.encode('utf-8')
# Преобразуем каждый байт в 8-битную строку и объединяем
bits = ''.join(format(byte, '08b') for byte in bytes_data)
return bits
def bits_to_text(bits: str) -> str:
"""
Преобразует строку битов обратно в текст.
Аргументы:
bits (str): Строка из '0' и '1' (длина должна быть кратна 8)
Возвращает:
str: Декодированный текст
Пример:
>>> bits_to_text("01000001")
'A'
"""
# Проверяем, что длина строки кратна 8
if len(bits) % 8 != 0:
raise ValueError("Длина битовой строки должна быть кратна 8")
# Разбиваем строку на блоки по 8 бит и преобразуем в байты
bytes_data = bytearray()
for i in range(0, len(bits), 8):
byte = bits[i:i + 8] # берем 8 бит
bytes_data.append(int(byte, 2)) # преобразуем из двоичной в число
# Декодируем байты в строку (UTF-8)
return bytes_data.decode('utf-8')
def calculate_psnr(original_path: str, modified_path: str) -> float:
"""
Вычисляет PSNR (Peak Signal-to-Noise Ratio) между двумя изображениями.
PSNR показывает, насколько сильно изменилось изображение после внедрения.
Чем выше значение, тем меньше изменений.
- PSNR > 40 dB: отличное качество (изменения практически незаметны)
- PSNR 30-40 dB: хорошее качество
- PSNR 20-30 dB: заметные искажения
- PSNR < 20 dB: сильные искажения
Аргументы:
original_path (str): Путь к исходному изображению
modified_path (str): Путь к измененному изображению
Возвращает:
float: Значение PSNR в децибелах (dB)
"""
from PIL import Image
# Загружаем изображения
img1 = Image.open(original_path).convert('RGB')
img2 = Image.open(modified_path).convert('RGB')
# Преобразуем в массивы numpy
img1_array = np.array(img1, dtype=np.float64)
img2_array = np.array(img2, dtype=np.float64)
# Вычисляем среднеквадратичную ошибку (MSE)
mse = np.mean((img1_array - img2_array) ** 2)
# Если MSE = 0, изображения идентичны
if mse == 0:
return float('inf')
# Максимальное значение пикселя (для RGB это 255)
max_pixel = 255.0
# Формула PSNR: 10 * log10(MAX^2 / MSE)
psnr = 10 * log10((max_pixel ** 2) / mse)
return psnr
def calculate_capacity(image_path: str) -> int:
"""
Рассчитывает максимальную вместимость изображения в байтах для LSB метода.
Для LSB: каждый пиксель (RGB) = 3 бита = 0.375 байта.
Аргументы:
image_path (str): Путь к изображению
Возвращает:
int: Максимальное количество байт, которое можно спрятать
"""
from PIL import Image
img = Image.open(image_path)
width, height = img.size
total_pixels = width * height
# 3 бита на пиксель, переводим в байты
max_bits = total_pixels * 3
max_bytes = max_bits // 8
return max_bytes