Сокрытие текстового сообщения в JPEG изображение на основе сокрытия в частотной области изображения с помощью БПФ
Я изучаю стеганографию в частотной области. Моя задача - скрыть текстовую информацию в изображении JPEG с помощью быстрого преобразования Фурье. Я подготовил код на C#, который берет JPEG изображение, подготавливает его к алгоритму БПФ (чтобы изображение соответствовало требованиям БПФ) и вычисляет его частотную область с помощью БПФ. Входное изображение - здесь, результат алгоритма БПФ - здесь. Затем этот код берет текстовое сообщение, комплексное значение из изображения и изменяет наименьший значимый бит (LSB) этого комплексного значения. Результат шифровки показан в здесь, и, как вы можете видеть, там зашифровано сообщение от центра к правому краю слева направо. Но когда я пытаюсь использовать обратный алгоритм БПФ в измененном изображении, на выходе получается просто белое изображение. Таким образом, очевидно, что я каким-то образом повреждаю изображение при смене частотной области. Что может быть не так с этим кодом и как его можно исправить?
Код с подробными комментариями приведен ниже:
// Загрузка исходного изображения
var image = AForge.Imaging.Image.FromFile("input.jpg");
// Найти ближайшую степень двух и растянуть изображение (одно из требований БПФ)
int width = (int)Math.Pow(2, Math.Ceiling(Math.Log(image.Width, 2)));
int height = (int)Math.Pow(2, Math.Ceiling(Math.Log(image.Height, 2)));
// Изменение размера изображения
Bitmap resizedImage = new Bitmap(image, width, height);
// Конвертация изображения в grayscale 8bpp (также требование БПФ)
Grayscale filter = new Grayscale(0.2125, 0.7154, 0.0721);
Bitmap grayImage = filter.Apply(resizedImage);
// Конвертация изображения в ComplexImage
ComplexImage complexImage = ComplexImage.FromBitmap(grayImage);
// Применение БПФ
complexImage.ForwardFourierTransform();
// Сохранение результата БПФ в картинке
complexImage.ToBitmap().Save("fourier.jpg");
// -------------------------------------------------------------------------
// Конвертация текстового сообщения в битовый формат
string textMessage = "Hello world";
byte[] messageBytes = Encoding.Unicode.GetBytes(textMessage);
BitArray messageBits = new BitArray(messageBytes);
// Зашифровка текста с помощью битов сообщения
int bitIndex = 0;
for (int y = complexImage.Height / 2; y < complexImage.Height; y++)
{
for (int x = complexImage.Width / 2; x < complexImage.Width; x++)
{
if (bitIndex >= messageBits.Length)
{
break;
}
// Getting complex value of frequency
Complex complexValue = complexImage.Data[y, x];
// Замена LSB действительной и мнимой частей на бит из сообщения
complexValue.Re = SetLeastSignificantBit(complexValue.Re, messageBits[bitIndex++]);
complexValue.Im = SetLeastSignificantBit(complexValue.Im, messageBits[bitIndex++]);
// Применение нового значения
complexImage.Data[y, x] = complexValue;
}
}
// Метод установки наименьшего значимого бита
static float SetLeastSignificantBit(double value, bool bit)
{
int intValue = BitConverter.ToInt32(BitConverter.GetBytes(value), 0);
intValue = bit ? (intValue | 1) : (intValue & ~1);
return BitConverter.ToSingle(BitConverter.GetBytes(intValue), 0);
}
// -------------------------------------------------------------------------
complexImage.ToBitmap().Save("fourier222.jpg");
// Применение обратного БПФ
complexImage.BackwardFourierTransform();
complexImage.ToBitmap().Save("output.jpg");