def dctBlock(blockList): '''对每一个块进行dct变换''' # dct计算的矩阵是一个二维矩阵,所以直接把三维图像塞进来的话容易报错如上, # 如果要处理三维图像(三通道)可以把rgb三个维度一个一个丢进来dct,最后合成一个三维矩阵保存成彩色图像。 # 本实验不用考虑以上这点,灰度图本来就是二维的 # 同时,需要注意的是,要用np.float32把矩阵转换成32位浮点精度,这才是dct能处理的精度。所以必不可少。 return [cv.dct(np.float32(block)) for block in blockList]
def classify_pHash(image1,image2): image1 = cv2.resize(image1,(32,32)) image2 = cv2.resize(image2,(32,32)) gray1 = cv2.cvtColor(image1,cv2.COLOR_BGR2GRAY) gray2 = cv2.cvtColor(image2,cv2.COLOR_BGR2GRAY) # 将灰度图转为浮点型,再进行dct变换 dct1 = cv2.dct(np.float32(gray1)) dct2 = cv2.dct(np.float32(gray2)) # 取左上角的8*8,这些代表图片的最低频率 # 这个操作等价于c++中利用opencv实现的掩码操作 # 在python中进行掩码操作,可以直接这样取出图像矩阵的某一部分 dct1_roi = dct1[0:8,0:8] dct2_roi = dct2[0:8,0:8] hash1 = getHash(dct1_roi) hash2 = getHash(dct2_roi) return Hamming_distance(hash1,hash2)
def embed(self,mess): # вычислить блоки коэффициентов DCT из изображения DCT_blocks = [np.round(cv2.dct(block)) for block in self.blocks] # разделить каждый коэффициент на величину квантования quantizedDCT = [np.round(DCT_block/self.quant) for DCT_block in DCT_blocks] # quantizedDCT = [np.round(DCT_block/1) for DCT_block in DCT_blocks] # перевести сообщение в двоичную форму mess = self.binary_text(mess) messIndex = 0 # вставлять каждый бит сообщения в 1-й коэффициент каждого блока for block in quantizedDCT: DC = int(block[0,0]) if DC % 2 == 0: DC ^= int(mess[messIndex]) else: DC ^= int(mess[messIndex]) ^ 1 block[0,0] = np.float32(DC) messIndex += 1 if messIndex == len(mess): break if messIndex < len(mess)-1: raise StegaException("not enough spaces to embed") # умножить каждый коэффициент на значение квантования DCT_blocks = [block * self.quant for block in quantizedDCT] # DCT_blocks = [block * 1 for block in quantizedDCT] # рассчитать обратное DCT, чтобы получить значения изображения Img_blocks = [np.round(cv2.idct(block)) for block in DCT_blocks] # изменить форму блоков в форму изображения img = self.reshape(Img_blocks) # img = cv2.resize(img,(self.oricol,self.orirow)) return img
def jpeg_gray(x): output = np.zeros(x.shape, dtype=int) w = x.shape[0] h = x.shape[1] quantization_table = np.array([ [16, 11, 10, 16, 24, 40, 51, 61], [12, 12, 14, 19, 26, 58, 60, 55], [14, 13, 16, 24, 40, 57, 69, 56], [14, 17, 22, 29, 51, 87, 80, 62], [18, 22, 37, 56, 68, 109, 103, 77], [24, 36, 55, 64, 81, 104, 113, 92], [49, 64, 78, 87, 103, 121, 120, 101], [72, 92, 95, 98, 112, 100, 103, 99] ]) for i in range(0, h, 8): for j in range(0, w, 8): sample = x[j:j+8, i:i+8] dct = np.around(cv2.dct(sample.astype(float))) dct_quant = np.around(np.divide(dct, quantization_table)) scaled_quant = np.multiply(dct_quant, quantization_table) out_block = np.around(cv2.idct(scaled_quant)) output[j:j+8, i:i+8] = out_block output = output/np.amax(output)*255 print(np.amax(output)) return output.astype(np.uint8)
def embed(self, mess): # calculate DCT coefficients blocks from image DCT_blocks = [np.round(cv2.dct(block)) for block in self.blocks] # divide each coefficient by quantization value quantizedDCT = [ np.round(DCT_block / self.quant) for DCT_block in DCT_blocks ] # quantizedDCT = [np.round(DCT_block/1) for DCT_block in DCT_blocks] # translate message to binary form mess = self.binary_text(mess) messIndex = 0 # embed each bit of message to the 1st coefficient of each block for block in quantizedDCT: DC = int(block[0, 0]) if DC % 2 == 0: DC ^= int(mess[messIndex]) else: DC ^= int(mess[messIndex]) ^ 1 block[0, 0] = np.float32(DC) messIndex += 1 if messIndex == len(mess): break if messIndex < len(mess) - 1: raise StegaException("not enough spaces to embed") # multiply each coefficient with quantization value DCT_blocks = [block * self.quant for block in quantizedDCT] # DCT_blocks = [block * 1 for block in quantizedDCT] # calculate inverse DCT to get image's values Img_blocks = [np.round(cv2.idct(block)) for block in DCT_blocks] # reshape blocks to image form img = self.reshape(Img_blocks) # img = cv2.resize(img,(self.oricol,self.orirow)) return img
def DCT_IDCT_OpenCv(image): dct = cv2.dct(np.float32(image), flags=cv2.DFT_COMPLEX_OUTPUT) cosine = np.log(np.abs(dct)) iimage = cv2.idct(dct) Plt_Contrast(image, cosine, iimage)
def statistic(self): # вычислить блоки коэффициентов DCT из изображения DCT_blocks = [np.round(cv2.dct(block)) for block in self.blocks] # разделить каждый коэффициент на величину квантования quantizedDCT = [np.round(DCT_block/self.quant) for DCT_block in DCT_blocks] import matplotlib.pyplot as plt histogram = [] for block in quantizedDCT: for i in range(8): for j in range(8): val = float(block[i,j]) histogram.append(val) plt.hist(histogram,bins = 100) plt.show()
def statistic(self): # calculate DCT coefficients blocks from image DCT_blocks = [np.round(cv2.dct(block)) for block in self.blocks] # divide each coefficient by quantization value quantizedDCT = [ np.round(DCT_block / self.quant) for DCT_block in DCT_blocks ] import matplotlib.pyplot as plt histogram = [] for block in quantizedDCT: for i in range(8): for j in range(8): val = float(block[i, j]) histogram.append(val) plt.hist(histogram, bins=100) plt.show()
def pHash(img): # 缩放32*32 img = cv2.resize(img, (32, 32)) # , interpolation=cv2.INTER_CUBIC # 转换为灰度图 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 将灰度图转为浮点型,再进行dct变换 dct = cv2.dct(np.float32(gray)) # opencv实现的掩码操作 dct_roi = dct[0:8, 0:8] hash = [] avreage = np.mean(dct_roi) for i in range(dct_roi.shape[0]): for j in range(dct_roi.shape[1]): if dct_roi[i, j] > avreage: hash.append(1) else: hash.append(0) return hash
def extract(self): # вычислить блоки коэффициентов DCT из изображения DCT_blocks = [np.round(cv2.dct(block)) for block in self.blocks] # разделить каждый коэффициент на величину квантования quantizedDCT = [np.round(DCT_block/self.quant) for DCT_block in DCT_blocks] # quantizedDCT = [np.round(DCT_block/1) for DCT_block in DCT_blocks] length = self.read_bits(quantizedDCT[:16]) length = int(length,2) cursor = 16 mess = "" for _ in range(length): c = self.read_bits(quantizedDCT[cursor:cursor+8]) c = int(c,2) ch = chr(c) mess += ch cursor += 8 if cursor >= len(quantizedDCT): raise StegaException("Your image hasn't been embed!!") return mess
def extract(self): # calculate DCT coefficients blocks from image DCT_blocks = [np.round(cv2.dct(block)) for block in self.blocks] # divide each coefficient by quantization value quantizedDCT = [ np.round(DCT_block / self.quant) for DCT_block in DCT_blocks ] # quantizedDCT = [np.round(DCT_block/1) for DCT_block in DCT_blocks] length = self.read_bits(quantizedDCT[:16]) length = int(length, 2) cursor = 16 mess = "" for _ in range(length): c = self.read_bits(quantizedDCT[cursor:cursor + 8]) c = int(c, 2) ch = chr(c) mess += ch cursor += 8 if cursor >= len(quantizedDCT): raise StegaException("Your image hasn't been embed!!") return mess
for i in range(104): for j in range(40): # this for last 40 times due to the width of array idd = random.randint(0, len(id_list) - 1) for d in range(5): imgA[i, j * 5 + d] = id_list[idd][d] imgB = numpy.zeros([104, 200], dtype=numpy.float32) # filling of this new array from A encoded picture huffA = [] for i in range(0, 104, 8): for j in range(0, 200, 8): huffman_encoding(imgA[i:(i + 8), j:(j + 8)], huffA) # filling of this new array from B encoded picture huffB = [] for i in range(0, 104, 8): for j in range(0, 200, 8): imgB[i:(i + 8), j:(j + 8)] = cv2.dct(imgA[i:(i + 8), j:(j + 8)]) imgB[i:(i + 8), j:(j + 8)] = numpy.ceil( numpy.divide(imgB[i:(i + 8), j:(j + 8)], quant_array)) huffman_encoding(imgB[i:(i + 8), j:(j + 8)], huffB) imgA_size = len(''.join(huffA)) imgB_size = len(''.join(huffB)) comp_ratios.append(imgA_size / imgB_size) #store ratio of current iteration final_ratio = sum(comp_ratios) / len( comp_ratios) #The final ratio with huffman encoding print("Avg compression ratio: " + str(final_ratio))
[14, 17, 22, 29, 51, 87, 80, 62], [18, 22, 37, 56, 68, 109, 103, 77], [24, 35, 55, 64, 81, 104, 113, 92], [49, 64, 78, 87, 103, 121, 120, 101], [72, 92, 95, 98, 112, 100, 103, 99]]) imageA_after_huffman = [] for i in range(0, 104, 8): for j in range(0, 200, 8): huffman_encoding(imageA[i:(i + 8), j:(j + 8)], imageA_after_huffman) imageB_after_huffman = [] for i in range(0, 104, 8): for j in range(0, 200, 8): imageB[i:(i + 8), j:(j + 8)] = cv2.dct(imageA[i:(i + 8), j:(j + 8)]) imageB[i:(i + 8), j:(j + 8)] = np.ceil( np.divide(imageB[i:(i + 8), j:(j + 8)], quantization_table)) #imageC[i:(i+8),j:(j+8)] = np.multiply(quantization_table, imageB[i:(i+8),j:(j+8)]) #imageC[i:(i+8),j:(j+8)] = np.round(cv2.idct(imageC[i:(i+8),j:(j+8)])) huffman_encoding(imageB[i:(i + 8), j:(j + 8)], imageB_after_huffman) imageA_bits = len(''.join(imageA_after_huffman)) imageB_bits = len(''.join(imageB_after_huffman)) logos_simpiesis.append(imageA_bits / imageB_bits) print("\nAverage compression ratio: " + str(sum(logos_simpiesis) / len(logos_simpiesis))) input("\nPress any button to exit the program...")
def blocks_dct(blocks): dct_blocks = [] for blocks_no in range(len(blocks)): dct_block = cv2.dct(blocks[blocks_no]) dct_blocks.append(dct_block) return dct_blocks