我正在做一个项目,用Python制作一个基于DCT的隐写术程序,我在Github中找到了一个工作模型。但是,该程序只能在其中一个RGB通道上编码。导致图像变色。使用OpenCV和DCT将图像分割为RGB波段,仅在蓝色通道上进行量化,然后将其与其他通道组合。是否有办法使其在所有通道上工作或避免变色
我参考了RGB图像上的dct压缩以找到解决方案,并发现必须对所有3个波段分别进行dct和量化,然后进行压缩。我在这里也应该这样做吗?如中所述,在所有波段对同一信息进行三次编码以避免变色
编码算法
def encode_image(self,img,secret_msg):
secret=secret_msg
self.message = str(len(secret))+'*'+secret
print(self.message)
self.bitMess = self.toBits()
print(self.bitMess)
row,col = img.shape[:2]
self.oriRow, self.oriCol = row, col
if((col/8)*(row/8)<len(secret)):
print("Error: Message too large to encode in image")
return False
#make divisible by 8x8
if row%8 != 0 or col%8 != 0:
img = self.addPadd(img, row, col)
row,col = img.shape[:2]
##col, row = img.size
#split image into RGB channels
bImg,gImg,rImg = cv2.split(img)
def enc(bImg):
#message to be hid in blue channel so converted to type float32 for dct function
bImg = np.float32(bImg)
#break into 8x8 blocks
imgBlocks = [np.round(bImg[j:j+8, i:i+8]-128) for (j,i) in itertools.product(range(0,row,8),
range(0,col,8))]
#Blocks are run through DCT function
dctBlocks = [np.round(cv2.dct(img_Block)) for img_Block in imgBlocks]
#blocks then run through quantization table
quantizedDCT = [np.round(dct_Block/quant) for dct_Block in dctBlocks]
#set LSB in DC value corresponding bit of message
messIndex = 0
letterIndex = 0
for quantizedBlock in quantizedDCT:
#find LSB in DC coeff and replace with message bit
DC = quantizedBlock[0][0]
DC = np.uint8(DC)
DC = np.unpackbits(DC)
DC[7] = self.bitMess[messIndex][letterIndex]
DC = np.packbits(DC)
DC = np.float32(DC)
DC= DC-255
quantizedBlock[0][0] = DC
letterIndex = letterIndex+1
if letterIndex == 8:
letterIndex = 0
messIndex = messIndex + 1
if messIndex == len(self.message):
break
#blocks run inversely through quantization table
sImgBlocks = [quantizedBlock *quant+128 for quantizedBlock in quantizedDCT]
#blocks run through inverse DCT
sImgDCT = [cv2.idct(B)+128 for B in sImgBlocks]
#puts the new image back together
sImg=[]
for chunkRowBlocks in self.chunks(sImgDCT, col/8):
for rowBlockNum in range(8):
for block in chunkRowBlocks:
sImg.extend(block[rowBlockNum])
sImg = np.array(sImg).reshape(row, col)
#converted from type float32
sImg = np.uint8(sImg)
return sImg
bImg=enc(bImg)
#show(sImg)
sImg = cv2.merge((bImg,gImg,rImg))
return sImg
解码算法
def decode_image(self,img):
row,col = img.shape[:2]
messSize = None
messageBits = []
buff = 0
#split image into RGB channels
bImg,gImg,rImg = cv2.split(img)
#message hid in blue channel so converted to type float32 for dct function
bImg = np.float32(bImg)
#break into 8x8 blocks
imgBlocks = [bImg[j:j+8, i:i+8]-128 for (j,i) in itertools.product(range(0,row,8),
range(0,col,8))]
#blocks run through quantization table
dctBlocks = [cv2.dct(img_Block) for img_Block in imgBlocks]
#quantizedDCT = [dct_Block/ (quant) for dct_Block in dctBlocks]
quantizedDCT = [dct_Block/quant for dct_Block in dctBlocks]
i=0
#message extracted from LSB of DC coeff
for quantizedBlock in quantizedDCT:
DC = quantizedBlock[0][0]
DC = np.uint8(DC)
DC = np.unpackbits(DC)
if DC[7] == 1:
buff+=(0 & 1) << (7-i)
elif DC[7] == 0:
buff+=(1&1) << (7-i)
i=1+i
if i == 8:
messageBits.append(chr(buff))
buff = 0
i =0
if messageBits[-1] == '*' and messSize is None:
try:
messSize = int(''.join(messageBits[:-1]))
except:
pass
if len(messageBits) - len(str(messSize)) - 1 == messSize:
return ''.join(messageBits)[len(str(messSize))+1:]
#blocks run inversely through quantization table
sImgBlocks = [quantizedBlock *quant+128 for quantizedBlock in quantizedDCT]
#blocks run through inverse DCT
#sImgBlocks = [cv2.idct(B)+128 for B in quantizedDCT]
#puts the new image back together
sImg=[]
for chunkRowBlocks in self.chunks(sImgBlocks, col/8):
for rowBlockNum in range(8):
for block in chunkRowBlocks:
sImg.extend(block[rowBlockNum])
sImg = np.array(sImg).reshape(row, col)
#converted from type float32
sImg = np.uint8(sImg)
sImg = cv2.merge((sImg,gImg,rImg))
##sImg.save(img)
#dct_decoded_image_file = "dct_" + original_image_file
#cv2.imwrite(dct_decoded_image_file,sImg)
return ''
"""Helper function to 'stitch' new image back together"""
def chunks(self, l, n):
m = int(n)
for i in range(0, len(l), m):
yield l[i:i + m]
def addPadd(self,img, row, col):
img = cv2.resize(img,(col+(8-col%8),row+(8-row%8)))
return img
def toBits(self):
bits = []
for char in self.message:
binval = bin(ord(char))[2:].rjust(8,'0')
bits.append(binval)
self.numBits = bin(len(bits))[2:].rjust(8,'0')
return bits
目前没有回答
相关问题 更多 >
编程相关推荐