def extract(self, watermarked_array, coeficient_index): msg = '' block_manager = BlocksImage(watermarked_array) for block in range(block_manager.max_num_blocks()): msg += self.__extract__(block, coeficient_index) return utils.bin2char(msg)
def insert(self, cover_array, msg=None): ''' obj.insert(cover_array, msg) => (np.numpy): Return a watermarked work (stego work) with specified message. ''' # Initial Values count = 0 # Binary message bin_msg = utils.char2bin(msg) # Creating copy watermarked_array = np.copy(cover_array) # Depth of the image if len(watermarked_array.shape) == 2: red_watermarked_array = watermarked_array else: # Red component red_watermarked_array = watermarked_array[:, :, 0] # Instance block_instace_8x8 = BlocksImage(red_watermarked_array) # Increasing the hash function # self.hashf = increase(self.hashf, block_instace_8x8.max_num_blocks()) # Checking the embedding capacity embd_cap = block_instace_8x8.max_num_blocks() * 8 if len(bin_msg) > embd_cap: raise ExceededCapacity for i in range(block_instace_8x8.max_num_blocks()): block8x8 = block_instace_8x8[i] block_transf8x8 = self.ortho_matrix.direct(block8x8) vac = utils.vzig_zag_scan(block_transf8x8) for k in range(1, 9): # TODO: l deleted # vac[k] = np.sign(vac[k]) * utils.replace( # abs(round(vac[k])), bin_msg[i % (len(bin_msg))] # ) if count < len(bin_msg): vac[k] = np.sign(vac[k]) * utils.replace( abs(round(vac[k])), bin_msg[count]) count += 1 block_transf8x8 = utils.mzig_zag_scan(vac) block_instace_8x8[i] = self.ortho_matrix.inverse(block_transf8x8) return watermarked_array
def extract(self, ws_array, msg=None): ''' obj.get(watermarked_array) => (np.numpy): Return the message. ''' extracted_lsb = '' # Depth of the image if len(ws_array.shape) == 2: red_ws_array = ws_array else: # Red component red_ws_array = ws_array[:, :, 0] # Instance block_instace_8x8 = BlocksImage(red_ws_array) # Extraction process for i in range(block_instace_8x8.max_num_blocks()): block8x8 = block_instace_8x8[i] block_transf8x8 = self.ortho_matrix.direct(block8x8) vac = utils.vzig_zag_scan(block_transf8x8) for k in range(1, 9): extracted_lsb += utils.ext_lsb(abs(round(vac[k]))) return utils.bin2char(extracted_lsb)
def test_element_modification(self): image = np.array([[0.98838329, 0.92974977, 0.40523466, 0.41932678], [0.40426586, 0.44543487, 0.67170983, 0.46135769], [0.85925337, 0.59646605, 0.38249919, 0.8737707], [0.85925337, 0.59646605, 0.45148745, 0.79845514]]) new_block = np.array([[0.40426582, 0.92974977], [0.40426586, 0.44543487]]) blocks = BlocksImage(image, 2, 2) block = blocks[0] block[0][0] = 0.40426582 np.testing.assert_array_equal(blocks[0], new_block)
def extract(self, ws_work, block_shape=(8, 8), **kwargs): ''' Get bit hidden an return it Arguments: index -- index of coefficient where bit will be extracted ''' msg = '' blocks = BlocksImage(ws_work, *block_shape) for block in blocks: bit = self.hider.extract(block, **kwargs) msg += str(bit) return msg
def test_set_block(self): image = np.array([[ 0.72996436, 0.30220469, 0.26302874, 0.45926106, 0.83229292, 0.36547379, 0.04903042, 0.80401489 ], [ 0.95165122, 0.0834489, 0.6329711, 0.70563593, 0.30838541, 0.85019345, 0.82915152, 0.66390158 ], [ 0.73101532, 0.48981373, 0.23543479, 0.34432725, 0.64965507, 0.56053218, 0.87013326, 0.31057878 ], [ 0.25541202, 0.7590065, 0.34833583, 0.87539685, 0.15707788, 0.12932102, 0.82317562, 0.27748149 ], [ 0.12185236, 0.46868408, 0.95256657, 0.11167148, 0.14111763, 0.20679031, 0.38810133, 0.86408796 ], [ 0.22420372, 0.69550787, 0.97781245, 0.65326647, 0.86442453, 0.82161094, 0.09722554, 0.69971431 ], [ 0.08751724, 0.77511339, 0.77809499, 0.31933827, 0.24950535, 0.83073389, 0.35378153, 0.24732298 ], [ 0.17390554, 0.83968645, 0.35554425, 0.83599189, 0.87064086, 0.84453971, 0.96192682, 0.79401981 ]]) new_block = np.array([[0.4949508, 0.46024612], [0.83870684, 0.36445031]]) modified_image = np.copy(image) modified_image[4, 2] = 0.4949508 modified_image[4, 3] = 0.46024612 modified_image[5, 2] = 0.83870684 modified_image[5, 3] = 0.36445031 blocks = BlocksImage(image, 2, 2) blocks[9] = new_block np.testing.assert_array_equal(image, modified_image)
def insert(self, cover, msg, block_shape=(8, 8), **kwargs): ''' Hide a bit Arguments: bit -- bit to hide index -- index of coefficient where bit will be hidden ''' data = np.copy(cover) blocks = BlocksImage(data, *block_shape) for i in range(len(msg)): try: blocks[i] = self.hider.insert(blocks[i], msg[i], **kwargs) except IndexError as e: raise ValueError("Capacity exceded.") from e return data
def test_block_image_is_iterable(self): ''' Test capacity of iterate over the blocks. ''' image = np.array([[0.98838329, 0.92974977, 0.40523466, 0.41932678], [0.40426586, 0.44543487, 0.67170983, 0.46135769], [0.85925337, 0.59646605, 0.38249919, 0.8737707], [0.85925337, 0.59646605, 0.45148745, 0.79845514]]) expected = [ np.array([[0.98838329, 0.92974977], [0.40426586, 0.44543487]]), np.array([[0.40523466, 0.41932678], [0.67170983, 0.46135769]]), np.array([[0.85925337, 0.59646605], [0.85925337, 0.59646605]]), np.array([[0.38249919, 0.8737707], [0.45148745, 0.79845514]]), ] blocks = BlocksImage(image, 2, 2) for index, block in enumerate(blocks): np.testing.assert_array_equal(block, expected[index])
def test_set_block_out_of_range(self): image = np.array([[ 0.72996436, 0.30220469, 0.26302874, 0.45926106, 0.83229292, 0.36547379, 0.04903042, 0.80401489 ], [ 0.95165122, 0.0834489, 0.6329711, 0.70563593, 0.30838541, 0.85019345, 0.82915152, 0.66390158 ], [ 0.73101532, 0.48981373, 0.23543479, 0.34432725, 0.64965507, 0.56053218, 0.87013326, 0.31057878 ], [ 0.25541202, 0.7590065, 0.34833583, 0.87539685, 0.15707788, 0.12932102, 0.82317562, 0.27748149 ], [ 0.12185236, 0.46868408, 0.95256657, 0.11167148, 0.14111763, 0.20679031, 0.38810133, 0.86408796 ], [ 0.22420372, 0.69550787, 0.97781245, 0.65326647, 0.86442453, 0.82161094, 0.09722554, 0.69971431 ], [ 0.08751724, 0.77511339, 0.77809499, 0.31933827, 0.24950535, 0.83073389, 0.35378153, 0.24732298 ], [ 0.17390554, 0.83968645, 0.35554425, 0.83599189, 0.87064086, 0.84453971, 0.96192682, 0.79401981 ]]) new_block = np.array([[0.4949508, 0.46024612], [0.83870684, 0.36445031]]) blocks = BlocksImage(image, 2, 2) with self.assertRaises(IndexError, msg="There is no such block"): blocks[16] = new_block
def insert(self, cover_array, msg, coeficient_index): # Binary data bin_msg = utils.char2bin(msg) # Cover copy and block generation watermarked_array = np.copy(cover_array) block_instance_8x8 = BlocksImage(watermarked_array) # Checking the embedding capacity embd_cap = block_instance_8x8.max_num_blocks() self.validate_capacity(bin_msg, embd_cap) # insertion process for index, bit in enumerate(bin_msg): block8x8 = block_instance_8x8.get_block(index) block_transf8x8 = self.__insert__(bit, block8x8, coeficient_index) block_instance_8x8.set_block( self.ortho_matrix.inverse(block_transf8x8), index) return watermarked_array
def test_init_custom_dimension(self): image = MagicMock() block_manager = BlocksImage(image, 4, 8) self.assertEqual(block_manager.matrix, image) self.assertEqual(block_manager.size_block_rows, 4) self.assertEqual(block_manager.size_block_cols, 8)