将秘密图像的每个像素的每一位嵌入到封面图像中
Embed every bit of every pixel of the secret image into the cover image
首先,我把封面图片看成了灰度图。
coverImage = cv2.imread(coverImagePath, 0)
然后我将封面图像传递给另一个函数以创建另一个较小的图像,而那个较小的图像就是我的秘密图像。
def makeSecretImage(coverImage):
copyImage = coverImage.copy()
secretImage = cv2.resize(copyImage, (100,100))
return secretImage
之后,我将这两张图片传递给我的嵌入函数,将秘密图片嵌入到封面图片中。我的意图是将秘密图像的每个像素的每一位嵌入到封面图像的 LSB 中,封面图像的 LSB 是随机选择的。此函数的最终输出是一个隐写图像,它看起来与封面图像完全相同,因为它只改变像素的 LSB。
def embedding(coverImage,secretImage, password):
indices = permute_indices(coverImage.shape, password)
for i in range (secretImage.shape[0]):
for j in range(secretImage.shape[1]):
x,y = next(indices)
#convert pixel to binary
pixels_cover = format(coverImage[x][y], '08b')
pixels_hide = format(secretImage[i][j], '08b')
binary = list(pixels_hide)
#error : keep overwriting the last bit
for dataIndex in range(0,8):
stegoImage = pixels_cover[:7] + binary[dataIndex]
dataIndex += 1
coverImage[x][y] = int(stegoImage, 2)
cv2.imwrite('StegoImage.png', coverImage)
然后读取隐写图像并将其传递给提取函数。在这里,我正在获取所选像素的最后一位并返回像素。然后将那些像素值放回黑色图像。但是我在这里遇到错误,因为它从隐写图像中读取了额外的像素。
def extracting(stgimg,secretImage, password):
Swidth, Sheight = stgimg.shape
Ewidth, Eheight = secretImage.shape
newPixel = []
pixelList = []
# create 2 blank images
OriImg = np.zeros((Swidth, Sheight, 1), np.uint8)
ExtractedImg = np.zeros((Ewidth, Eheight, 1), np.uint8)
indices = permute_indices(stgimg.shape, password)
for x in range(Swidth):
for y in range(Sheight):
a, b = next(indices)
stegopixel = format(stgimg[a][b], '08b')
bitValue = stegopixel[-1]
newPixel.append(bitValue)
for i in range(0, len(newPixel),8):
pixelBit = ''.join(newPixel[i:i+8])
pixelByte = int(pixelBit, 2)
pixelList.append(pixelByte)
img = np.array(pixelList, dtype=np.uint8).reshape(secretImage.shape)
cv2.imwrite('ExtractedImage.png', ExtractedImg)
首先,你有一个错误embedding
for dataIndex in range(0,8):
stegoImage = pixels_cover[:7] + binary[dataIndex]
dataIndex += 1
您在同一像素的 LSB 中隐藏了 8 位,有效地覆盖了它们并仅保留最后一位。您应该将每一位隐藏在不同的像素中,因此 您的封面图像中的像素至少需要比您的秘密所具有的像素多 8 倍。考虑到这一点
def embedding(coverImage, secretImage, password):
stegoImage = coverImage.copy()
indices = permute_indices(coverImage.shape, password)
for pixel in secretImage.flatten():
# no need for string "bit manipulation", straight up bitwise operations
for shift in range(7, -1, -1):
x, y = next(indices)
bit = (pixel >> shift) & 0x01
stegoImage[x,y] = (coverImage[x,y] & 0xfe) | bit
return stegoImage
然后
def extracting(stegoImage, password):
indices = permute_indices(stegoImage.shape, password)
pixels = []
for _ in range(secretImage.size):
pixel = 0
for _ in range(8):
x, y = next(indices)
bit = stegoImage[x,y] & 0x01
pixel = (pixel << 1) | bit
pixels.append(pixel)
pixels = np.array(pixels, dtype=np.uint8).reshape(secretImage.shape)
return pixels
编辑:我已经将上述函数修改为return图像数组而不是保存它们,所以我可以直接用原始输入进行测试。这也假设 permute_indices
仍然与定义的 .
相同
password = 'password'
coverImage = cv2.imread('original.png', 0)
secretImage = makeSecretImage(coverImage)
stegoImage = embedding(coverImage, secretImage, password)
extractedImage = extracting(stegoImage, password)
diff = coverImage.astype(int) - stegoImage
print(diff.min(), diff.max()) # Differences should be in the [-1, 1] range
print(np.all(secretImage == extractedImage)) # True
首先,我把封面图片看成了灰度图。
coverImage = cv2.imread(coverImagePath, 0)
然后我将封面图像传递给另一个函数以创建另一个较小的图像,而那个较小的图像就是我的秘密图像。
def makeSecretImage(coverImage):
copyImage = coverImage.copy()
secretImage = cv2.resize(copyImage, (100,100))
return secretImage
之后,我将这两张图片传递给我的嵌入函数,将秘密图片嵌入到封面图片中。我的意图是将秘密图像的每个像素的每一位嵌入到封面图像的 LSB 中,封面图像的 LSB 是随机选择的。此函数的最终输出是一个隐写图像,它看起来与封面图像完全相同,因为它只改变像素的 LSB。
def embedding(coverImage,secretImage, password):
indices = permute_indices(coverImage.shape, password)
for i in range (secretImage.shape[0]):
for j in range(secretImage.shape[1]):
x,y = next(indices)
#convert pixel to binary
pixels_cover = format(coverImage[x][y], '08b')
pixels_hide = format(secretImage[i][j], '08b')
binary = list(pixels_hide)
#error : keep overwriting the last bit
for dataIndex in range(0,8):
stegoImage = pixels_cover[:7] + binary[dataIndex]
dataIndex += 1
coverImage[x][y] = int(stegoImage, 2)
cv2.imwrite('StegoImage.png', coverImage)
然后读取隐写图像并将其传递给提取函数。在这里,我正在获取所选像素的最后一位并返回像素。然后将那些像素值放回黑色图像。但是我在这里遇到错误,因为它从隐写图像中读取了额外的像素。
def extracting(stgimg,secretImage, password):
Swidth, Sheight = stgimg.shape
Ewidth, Eheight = secretImage.shape
newPixel = []
pixelList = []
# create 2 blank images
OriImg = np.zeros((Swidth, Sheight, 1), np.uint8)
ExtractedImg = np.zeros((Ewidth, Eheight, 1), np.uint8)
indices = permute_indices(stgimg.shape, password)
for x in range(Swidth):
for y in range(Sheight):
a, b = next(indices)
stegopixel = format(stgimg[a][b], '08b')
bitValue = stegopixel[-1]
newPixel.append(bitValue)
for i in range(0, len(newPixel),8):
pixelBit = ''.join(newPixel[i:i+8])
pixelByte = int(pixelBit, 2)
pixelList.append(pixelByte)
img = np.array(pixelList, dtype=np.uint8).reshape(secretImage.shape)
cv2.imwrite('ExtractedImage.png', ExtractedImg)
首先,你有一个错误embedding
for dataIndex in range(0,8):
stegoImage = pixels_cover[:7] + binary[dataIndex]
dataIndex += 1
您在同一像素的 LSB 中隐藏了 8 位,有效地覆盖了它们并仅保留最后一位。您应该将每一位隐藏在不同的像素中,因此 您的封面图像中的像素至少需要比您的秘密所具有的像素多 8 倍。考虑到这一点
def embedding(coverImage, secretImage, password):
stegoImage = coverImage.copy()
indices = permute_indices(coverImage.shape, password)
for pixel in secretImage.flatten():
# no need for string "bit manipulation", straight up bitwise operations
for shift in range(7, -1, -1):
x, y = next(indices)
bit = (pixel >> shift) & 0x01
stegoImage[x,y] = (coverImage[x,y] & 0xfe) | bit
return stegoImage
然后
def extracting(stegoImage, password):
indices = permute_indices(stegoImage.shape, password)
pixels = []
for _ in range(secretImage.size):
pixel = 0
for _ in range(8):
x, y = next(indices)
bit = stegoImage[x,y] & 0x01
pixel = (pixel << 1) | bit
pixels.append(pixel)
pixels = np.array(pixels, dtype=np.uint8).reshape(secretImage.shape)
return pixels
编辑:我已经将上述函数修改为return图像数组而不是保存它们,所以我可以直接用原始输入进行测试。这也假设 permute_indices
仍然与定义的
password = 'password'
coverImage = cv2.imread('original.png', 0)
secretImage = makeSecretImage(coverImage)
stegoImage = embedding(coverImage, secretImage, password)
extractedImage = extracting(stegoImage, password)
diff = coverImage.astype(int) - stegoImage
print(diff.min(), diff.max()) # Differences should be in the [-1, 1] range
print(np.all(secretImage == extractedImage)) # True