我正在研究频域隐写术,我的任务是利用FFT在JPEG图片中隐藏文本信息。我用C#编写了一些代码,它拍摄一张图片,准备FFT算法并使用FFT计算其频域。输入图片为here,FFT算法的结果为here。然后此代码得到文本消息,从图片中获取复数值并更改此复数值的最低有效位(LSB)。在此之后,我们在this pucture中修改了频域,如您所见,有一条从中心到右侧加密的消息。但是当我尝试在修改后的图片中使用IFFT时,输出的结果是white picture。很明显我在改变频域的时候损坏了图片。这段代码有什么问题吗?
下面是详细注解的代码:
// Uploading image
var image = AForge.Imaging.Image.FromFile("input.jpg");
// Find the nearest power of 2 dimensions
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)));
// Resize the image to the nearest power of 2 dimensions
Bitmap resizedImage = new Bitmap(image, width, height);
// Converting image to grayscale
Grayscale filter = new Grayscale(0.2125, 0.7154, 0.0721);
Bitmap grayImage = filter.Apply(resizedImage);
// Converting image to the ComplexImage
ComplexImage complexImage = ComplexImage.FromBitmap(grayImage);
// Applying FFT
complexImage.ForwardFourierTransform();
// Saving result of FFT
complexImage.ToBitmap().Save("fourier.jpg");
// -------------------------------------------------------------------------
// Converting text message to binary
string textMessage = "Hello world";
byte[] messageBytes = Encoding.Unicode.GetBytes(textMessage);
BitArray messageBits = new BitArray(messageBytes);
// Embedding text bits into the frequency domain
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];
// Replacing the LSB of the real and imaginary parts with a bit from the message
complexValue.Re = SetLeastSignificantBit(complexValue.Re, messageBits[bitIndex++]);
complexValue.Im = SetLeastSignificantBit(complexValue.Im, messageBits[bitIndex++]);
// Applying new value
complexImage.Data[y, x] = complexValue;
}
}
// Setting LSB
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");
// Applying IFFT
complexImage.BackwardFourierTransform();
complexImage.ToBitmap().Save("output.jpg");
字符串
1条答案
按热度按时间busg9geu1#
经过研究,我知道最好不要使用LSB方法,而是改变频域的“null”值,加上或减去频率数据的真实的部分。“Null”值是从频率数据中取的
ComplexImage[x, y]
的真实的值,它等于零。在本代码中,我使用左上角找到“null”。值。此外,在频域中移动时,最好避免频域的中间,因为它可能会导致麻烦和不正确的编码数据。一些加密代码示例:字符串
当我使用此代码进行加密时,图像可能会略有变化,但它并不重要。此外,此算法应检查“非空”值,因为我们不能从中获取数据。因此,有一些方法可以改进此方法,但基本上它是有效的。