问题描述
我正在开发基于LSB-DCT的图像隐写术,其中我必须应用LSB到图像的DCT系数数据嵌入到JPEG.i'm新的所有this.so搜索和阅读一些研究论文他们缺乏关于DCT.i后的过程的许多信息也在stackoverflow上阅读了很多问题和答案,并且更困惑。这里有问题:
1-reasearch论文和在网上他们都使用8x8块大小从图像为DCT。如果图像的分辨率没有完全分为8x8块像724 x 520.
520/8 = 65但724/8 = 90.5
2 - 如果我有很多块和一些信息隐藏我们认为可以适合5块。我仍然需要取剩余的块和idct的dct。
3 - 我需要应用量化后dct然后应用lsb或我可以应用lsb直接??
4研究论文没有提及任何关于不触摸量化的dct系数值为0和1,第一个值。我应该使用他们还是不是?那么为何不??我得到它关于0,因为它是高频分量,并删除JPEG中压缩..我不做任何压缩...我可以使用它,仍然产生相同的JPEG文件
在量化中,我们用量化矩阵划分DCT系数,并舍去值。相反,我必须将DCT系数乘以量化矩阵。
有关DCT和随后的IDCT的注释:
研究论文:
JPEG隐写术
如果你想保存你的图像到jpeg,你必须按照jpeg编码过程。不幸的是,我读过的文章说的不是正义。完整的过程如下()):
- RGB到YCbCr转换(可选),
- 对色度通道进行子采样(可选),
- / li>
- 像素值重排,
- DCT,
- 基于压缩率/质量的量化,
- 以锯齿形图案排序系数,
- 熵编码;最常见的是哈夫曼编码和运行长度编码(RLE)。
实际上有,例如标题,节标记,以存储DC和AC系数等。然后,存在标准仅被宽松地定义并且它们的实现可以在编解码器之间变化的方面,例如,子采样算法,量化表和熵编码。也就是说,大多数软件符合通用JFIF标准,可以通过各种软件读取。如果你想让你的jpeg文件做同样的事情,准备写一个编码器几百(约一千)行代码。你最好借用一个已经在互联网上发表的编码器,而不是自己写的。您可以先查看用C语言编写的,并构成许多其他jpeg编解码器的基础, a href =http://bitmiracle.com/libjpeg/ =nofollow> C#实施或甚至版本的启发。
在某些伪代码中,编码/解码过程可以
function saveToJpeg(pixels,fileout){
// pixels是一个2D或3D数组包含你的原始像素值
// blocks是一个大小为8x8的二维数组列表,包含像素值
blocks = splitBlocks(pixels);
//类似于块的列表,但是对于DCT系数
coeffs = dct(blocks);
saveCoefficients(coeffs,fileout);
}
函数loadJpeg(filein){
coeffs = readCoefficients(filein);
blocks = idct(coeffs);
pixels = combineBlocks(blocks);
return pixels;
}
对于隐身术,您可以按以下方式修改。
function embedSecretToJpeg(pixels,secret,fileout){
blocks = splitBlocks(pixels);
coeffs = dct(blocks);
modified_coeffs = embedSecret(coeffs,secret);
saveCoefficients(modified_coeffs,fileout);
}
function extractSecretFromJpeg(filein){
coeffs = readCoefficients(filein);
secret = extractSecret(coeffs);
return secret;
}
如果您的封面图片已经在jpeg中,则不需要加载与解码器到像素,然后将其传递给编码器以嵌入您的消息。
function embedSecretToJpeg(pixels,secret,filein,fileout){
coeffs = readCoefficients filein);
modified_coeffs = embedSecret(coeffs,secret);
saveCoefficients(modified_coeffs,fileout);
}
就您的问题而言,1,2,3和5
问题1 :一般来说,您想要填充图片具有必要数量的行/列,使得宽度和高度都可被8整除。在内部,编码器将跟踪填充的行/列,使得解码器将在重构之后丢弃它们。这些虚拟行/列的像素值的选择取决于您,但建议您不要使用常量值,因为它会导致,这与正弦函数的正弦函数的傅立叶变换有关。
问题2 :虽然您只需修改几个块,但编码过程需要将其全部转换,以便将它们存储到文件中。
问题3 :您必须量化浮点DCT系数,因为它是无损地存储到文件的。您可以在量化步骤后将其修改为您的内容。
问题4 :没有人阻止您修改任何系数,记住每个系数影响一个块中的所有64个像素。 DC系数和引入最大的失真,所以你可能想远离他们。更具体地,由于DC系数被存储的方式,修改一个将把失真推广到所有后面的块。因为大多数高频系数是0,所以它们是有效的用RLE压缩。修改0系数可以将其翻转为1(如果你正在进行基本的LSB替换),这会中断这种有效的压缩。
最后,一些算法存储他们的秘密任何非零系数,并将跳过任何0。但是,如果您尝试修改1,它可能会翻转为0,在提取过程中,您将盲目跳过阅读它。因此,这样的算法不会靠近任何具有值1或0的系数。
问题5 :在解码时,系数与相应的量化表值。例如,DC系数为309.443,量化给出 round(309.443 / 16)= 19
。舍入位在这里是有损部分,不允许重建309.433。因此,相反的只是 19 * 16 = 304
。
隐写术中DCT的其他用途
诸如DCT和DWT的频率变换可以在隐写术中用于在频域中嵌入秘密,但不一定将隐形图像存储到jpeg。这个过程是像素 - > DCT - >系数 - >修改系数 - > IDCT - >像素,这是你发送到接收器。因此,格式的选择在这里很重要。如果您决定将像素保存为jpeg,则您在DCT系数中的秘密。
I'm working on LSB-DCT based Image steganography in which i have to apply LSB to DCT coefficients of the image for data embedding to JPEG.i'm new to all this.so searched and read some research papers they all lack a lot of information regarding the process after DCT.i also read many questions and answers on stackoverflow too and got more confused.
here are the questions:
1-reasearch paper and in question on the web they all are using 8x8 block size from image for DCT..what i should do if the resolution of image does not completely divides into 8x8 blocks like 724 x 520.
520 / 8 = 65 but 724 / 8 = 90.5
2-if i have a lot of blocks and some information to hide which we suppose can fit into 5 blocks..do i still need to take dct of the remaining blocks and and idct.
3-do i need to apply quantization after dct and then apply lsb or i can apply lsb directly??
4-research papers are not mentioning anything about not to touch quantized dct coefficients with value 0 and 1 and the first value..now should i use them or not?? and why not?? i get it about the 0 because it's was high frequency components and is removed in JPEG for compression..and i'm not doing any compression..so can i use it and still produce the same JPEG file???
5-in quantization we divide the DCT Coefficients with quantization matrix and round off the values.in reverse,i have to multiply quantization matrix with DCT Coefficients just..no undo for round off???
For the Comment on DCT and then IDCT:
From different Research Papers:
JPEG steganography
If you want to save your image to jpeg, you have to follow the jpeg encoding process. Unfortunately, papers most I've read say don't do it justice. The complete process is the following (wiki summary of a 182-page specifications book):
- RGB to YCbCr conversion (optional),
- subsampling of the chroma channels (optional),
- 8x8 block splitting,
- pixel value recentering,
- DCT,
- quantisation based on compression ratio/quality,
- order the coefficients in a zigzag pattern, and
- entropy encoding; most frequently involving Huffman coding and run-length encoding (RLE).
There are actually a lot more details involved, such as headers, section markers, specifics of how to store the DC and AC coefficients, etc. Then, there are aspects that the standard has only loosely defined and their implementation can vary between codecs, e.g., subsampling algorithm, quantisation tables and entropy encoding. That said, most pieces of software abide by the general JFIF standard and can be read by various software. If you want your jpeg file to do the same, be prepared to write hundreds (to about a thousand) lines of code just for an encoder. You're better off borrowing an encoder that has already been published on the internet than writing your own. You can start by looking into libjpeg which is written in C and forms the basis of many other jpeg codecs, its C# implementation or even a Java version inspired by it.
In some pseudocode, the encoding/decoding process can be described as follows.
function saveToJpeg(pixels, fileout) {
// pixels is a 2D or 3D array containing your raw pixel values
// blocks is a list of 2D arrays of size 8x8 each, containing pixel values
blocks = splitBlocks(pixels);
// a list similar to blocks, but for the DCT coefficients
coeffs = dct(blocks);
saveCoefficients(coeffs, fileout);
}
function loadJpeg(filein) {
coeffs = readCoefficients(filein);
blocks = idct(coeffs);
pixels = combineBlocks(blocks);
return pixels;
}
For steganography, you'd modify it as follows.
function embedSecretToJpeg(pixels, secret, fileout) {
blocks = splitBlocks(pixels);
coeffs = dct(blocks);
modified_coeffs = embedSecret(coeffs, secret);
saveCoefficients(modified_coeffs, fileout);
}
function extractSecretFromJpeg(filein) {
coeffs = readCoefficients(filein);
secret = extractSecret(coeffs);
return secret;
}
If your cover image is already in jpeg, there is no need to load it with a decoder to pixels and then pass it to an encoder to embed your message. You can do this instead.
function embedSecretToJpeg(pixels, secret, filein, fileout) {
coeffs = readCoefficients(filein);
modified_coeffs = embedSecret(coeffs, secret);
saveCoefficients(modified_coeffs, fileout);
}
As far as your questions are concerned, 1, 2, 3 and 5 should be taken care of by the encoder/decoder unless you're writing one yourself.
Question 1: Generally, you want to pad the image with the necessary number of rows/columns so that both the width and height are divisible by 8. Internally, the encoder will keep track of the padded rows/columns, so that the decoder will discard them after reconstruction. The choice of pixel value for these dummy rows/columns is up to you, but you're advised against using a constant value because it will result to ringing artifacts which has to do with the fact that the Fourier transform of a square wave being the sinc function.
Question 2: While you'll modify only a few blocks, the encoding process requires you to transform them all so they can be stored to a file.
Question 3: You have to quantise the float DCT coefficients as that's what's stored losslessly to a file. You can modify them to your heart's content after the quantisation step.
Question 4: Nobody prevents you from modifying any coefficient, but you have to remember each coefficient affects all 64 pixels in a block. The DC coefficient and the low frequency AC ones introduce the biggest distortions, so you might want to stay away from them. More specifically, because of the way the DC coefficients are stored, modifying one would propage the distortion to all following blocks.
Since most high frequency coefficients are 0, they are efficiently compressed with RLE. Modifying a 0 coefficient may flip it to a 1 (if you're doing basic LSB substitution), which disrupts this efficient compression.
Lastly, some algorithms store their secret in any non-zero coefficients and will skip any 0s. However, if you attempted to modify a 1, it might flip to a 0 and in the extraction process you'd blindly skip reading it. Therefore, such algorithms don't go near any coefficients with the value of 1 or 0.
Question 5: In decoding you just multiply the coefficient with the respective quantisation table value. For example, the DC coefficient is 309.443 and quantisation gives you round(309.443 / 16) = 19
. The rounding off bit is the lossy part here, which doesn't allow you to reconstruct 309.433. So the reverse is simply 19 * 16 = 304
.
Other uses of DCT in steganography
Frequency transforms, such as DCT and DWT can be used in steganography to embed the secret in the frequency domain but not necessarily store the stego image to jpeg. This process is pixels -> DCT -> coefficients -> modify coefficients -> IDCT -> pixels, which is what you send to the receiver. As such, the choice of format matters here. If you decide to save your pixels to jpeg, your secret in the DCT coefficients may be disturbed by another layer of quantisation from the jpeg encoding.
这篇关于基于LSB-DCT的图像隐写术的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!