Сокрытие текстового сообщения в 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");

Ответы (0 шт):