Sam*_*eem 2 compression jpeg steganography image dct
我正在研究基于 LSB-DCT 的图像隐写术,其中我必须将 LSB 应用于图像的 DCT 系数以将数据嵌入到 JPEG。我对这一切都不熟悉。所以搜索并阅读了一些研究论文,他们都缺乏很多关于 DCT.i 之后过程的信息也在 stackoverflow 上阅读了许多问题和答案,并且变得更加困惑。
以下是问题:
1-研究论文和网络上的问题,他们都使用来自图像的 8x8 块大小进行 DCT ..如果图像的分辨率没有完全分成 8x8 块,如 724 x 520,我应该怎么做。520
/ 8 = 65 但是724 / 8 = 90.5
2-如果我有很多块和一些要隐藏的信息,我们认为它们可以放入 5 个块中..我是否仍然需要对剩余块和 idct 进行 dct。
3-我需要在 dct 之后应用量化然后应用 lsb 还是我可以直接应用 lsb ?
4 篇研究论文没有提到不涉及值为 0 和 1 以及第一个值的量化 dct 系数。现在我应该使用它们还是不使用它们?那么为何不??我知道它是 0,因为它是高频分量,并且在 JPEG 中被删除以进行压缩......而且我没有进行任何压缩......所以我可以使用它并仍然生成相同的 JPEG 文件吗???
5-in 量化我们将 DCT 系数与量化矩阵相除并四舍五入。相反,我必须将量化矩阵与 DCT 系数相乘......不能撤消四舍五入???
对于 DCT 和 IDCT 的评论:
如果要将图像保存为 jpeg,则必须遵循 jpeg 编码过程。不幸的是,我读过的大多数论文都说不公正。整个过程是以下(维基总结一的182页的书规格):
实际上涉及更多细节,例如标题、部分标记、如何存储 DC 和 AC 系数的细节等。然后,有些方面标准只是松散地定义,它们的实现可能因编解码器而异,例如、子采样算法、量化表和熵编码。也就是说,大多数软件都遵循通用的 JFIF 标准,并且可以被各种软件读取。如果您希望 jpeg 文件也这样做,请准备好为编码器编写数百(到大约一千)行代码。你最好借用一个已经在互联网上发布的编码器,而不是自己编写。您可以首先查看用 C 编写的libjpeg,它是许多其他 jpeg 编解码器的基础,它的C# 实现,甚至是受它启发的Java版本。
在一些伪代码中,编码/解码过程可以描述如下。
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;
}
Run Code Online (Sandbox Code Playgroud)
对于隐写术,您可以对其进行如下修改。
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;
}
Run Code Online (Sandbox Code Playgroud)
如果您的封面图像已经是 jpeg 格式,则无需使用解码器将其加载到像素,然后将其传递给编码器以嵌入您的消息。你可以这样做。
function embedSecretToJpeg(pixels, secret, filein, fileout) {
coeffs = readCoefficients(filein);
modified_coeffs = embedSecret(coeffs, secret);
saveCoefficients(modified_coeffs, fileout);
}
Run Code Online (Sandbox Code Playgroud)
就您的问题而言,编码器/解码器应处理 1、2、3 和 5,除非您自己编写。
问题 1:通常,您希望用必要数量的行/列填充图像,以便宽度和高度都可以被 8 整除。在内部,编码器将跟踪填充的行/列,以便解码器重建后丢弃它们。这些虚拟行/列的像素值的选择取决于您,但建议您不要使用恒定值,因为它会导致振铃伪影,这与方波的傅立叶变换是正弦函数。
问题 2:虽然您只会修改几个块,但编码过程要求您将它们全部转换,以便将它们存储到文件中。
问题 3:您必须量化浮点 DCT 系数,因为这是无损存储到文件的内容。在量化步骤之后,您可以根据自己的喜好修改它们。
问题 4:没有人阻止您修改任何系数,但您必须记住每个系数都会影响块中的所有 64 个像素。DC 系数和低频 AC系数引入了最大的失真,因此您可能希望远离它们。更具体地说,由于 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 和 DWT)可用于隐写术以将秘密嵌入频域中,但不一定将隐写图像存储为 jpeg。这个过程是像素 -> DCT -> 系数 -> 修改系数 -> IDCT -> 像素,这就是你发送给接收器的内容。因此,格式的选择在这里很重要。如果您决定将像素保存为 jpeg,您在 DCT 系数中的秘密可能会被jpeg 编码的另一层量化所干扰。
| 归档时间: |
|
| 查看次数: |
3094 次 |
| 最近记录: |