OpenCV使用LSB方法提取图像
OpenCV extracting image using LSB method
免责声明:这是家庭作业的一部分,但是,它已经通过了。我只是在为未来的专业知识寻找正确的解决方案。
这个程序的目标是使用 Python OpenCV 库来实现图像 -> 图像隐写术(Embedding/Extracting 图像包含在其他图像中)。这是使用最低有效位 (LSB) 方法对两个大小相等的图像完成的。
该程序允许用户选择用于嵌入的位数,因此使用 1 位时,人眼几乎无法察觉嵌入的图像,而使用 7 位时,您可以清楚地辨认出隐藏的图像。
我已经正确地实现了嵌入,方法是从秘密图像中获取每个 RGB 字节的最高有效位 (MSB),并将它们设置在封面图像的 LSB 位置。
我的问题是在嵌入后提取秘密图像。代码运行后,我留下的图像似乎只是它的蓝色表示。我不确定哪里出错了,但我觉得这与我的位操作技术或 OpenCV 库的使用有关。非常感谢任何帮助,提前致谢!
提取代码:
import cv2
import numpy
def extract(img1, bitsUsed):
print "Extracting..."
# Import image & get dimensions
img = cv2.imread(img1)
h = img.shape[0]
w = img.shape[1]
# Create new image to extract secret image
# Same dimensions, and rgb channel
secretImg = numpy.zeros((h,w,3), numpy.uint8)
x, y = 0, 0
# Loop thru each pixel
while x < w:
while y < h:
# Grab the LSB (based on bitsUsed from embedding)
lsb_B = img.item(y,x,0) & bitsUsed
lsb_G = img.item(y,x,1) & bitsUsed
lsb_R = img.item(y,x,2) & bitsUsed
# Place those bits into MSB positions on new img
secretImg.itemset((y,x,0), lsb_B << (8 - bitsUsed))
secretImg.itemset((y,x,0), lsb_G << (8 - bitsUsed))
secretImg.itemset((y,x,0), lsb_R << (8 - bitsUsed))
y += 1
y = 0
x += 1
cv2.imwrite("extractedImg.png", secretImg)
njuffa 是正确的。在提取中,当你只嵌入了 1 位时,你想与 0b00000001 (1) 进行 AND,2 位与 0b00000011 (3),3 位与 0b00000111 (7) 等。通常,对于 k
嵌入位,你想要掩码 2**k - 1
.
此外,cv2.imread()
将生成一个 numpy 像素数组。您可以矢量化您的计算,而不是遍历每个像素。总而言之,这就是您的代码的样子。
import cv2
def embed(cover_file, secret_file, k):
cover = cv2.imread(cover_file)
secret = cv2.imread(secret_file)
mask = 256 - 2**k
stego = (cover & mask) | (secret >> (8 - k))
cv2.imwrite('stego.png', stego)
def extract(stego_file, k):
stego = cv2.imread(stego_file)
mask = 2**k - 1
output = (stego & mask) << (8 - k)
cv2.imwrite('extracted.png', output)
免责声明:这是家庭作业的一部分,但是,它已经通过了。我只是在为未来的专业知识寻找正确的解决方案。
这个程序的目标是使用 Python OpenCV 库来实现图像 -> 图像隐写术(Embedding/Extracting 图像包含在其他图像中)。这是使用最低有效位 (LSB) 方法对两个大小相等的图像完成的。
该程序允许用户选择用于嵌入的位数,因此使用 1 位时,人眼几乎无法察觉嵌入的图像,而使用 7 位时,您可以清楚地辨认出隐藏的图像。
我已经正确地实现了嵌入,方法是从秘密图像中获取每个 RGB 字节的最高有效位 (MSB),并将它们设置在封面图像的 LSB 位置。
我的问题是在嵌入后提取秘密图像。代码运行后,我留下的图像似乎只是它的蓝色表示。我不确定哪里出错了,但我觉得这与我的位操作技术或 OpenCV 库的使用有关。非常感谢任何帮助,提前致谢!
提取代码:
import cv2
import numpy
def extract(img1, bitsUsed):
print "Extracting..."
# Import image & get dimensions
img = cv2.imread(img1)
h = img.shape[0]
w = img.shape[1]
# Create new image to extract secret image
# Same dimensions, and rgb channel
secretImg = numpy.zeros((h,w,3), numpy.uint8)
x, y = 0, 0
# Loop thru each pixel
while x < w:
while y < h:
# Grab the LSB (based on bitsUsed from embedding)
lsb_B = img.item(y,x,0) & bitsUsed
lsb_G = img.item(y,x,1) & bitsUsed
lsb_R = img.item(y,x,2) & bitsUsed
# Place those bits into MSB positions on new img
secretImg.itemset((y,x,0), lsb_B << (8 - bitsUsed))
secretImg.itemset((y,x,0), lsb_G << (8 - bitsUsed))
secretImg.itemset((y,x,0), lsb_R << (8 - bitsUsed))
y += 1
y = 0
x += 1
cv2.imwrite("extractedImg.png", secretImg)
njuffa 是正确的。在提取中,当你只嵌入了 1 位时,你想与 0b00000001 (1) 进行 AND,2 位与 0b00000011 (3),3 位与 0b00000111 (7) 等。通常,对于 k
嵌入位,你想要掩码 2**k - 1
.
此外,cv2.imread()
将生成一个 numpy 像素数组。您可以矢量化您的计算,而不是遍历每个像素。总而言之,这就是您的代码的样子。
import cv2
def embed(cover_file, secret_file, k):
cover = cv2.imread(cover_file)
secret = cv2.imread(secret_file)
mask = 256 - 2**k
stego = (cover & mask) | (secret >> (8 - k))
cv2.imwrite('stego.png', stego)
def extract(stego_file, k):
stego = cv2.imread(stego_file)
mask = 2**k - 1
output = (stego & mask) << (8 - k)
cv2.imwrite('extracted.png', output)