def __getitem__(self, index: int): kind, fold, image_name, label = self.kinds[index], self.folds[ index], self.image_names[index], self.labels[index] if self.transforms: rot = random.randint(0, 3) flip = random.random() < 0.5 else: rot = 0 flip = False path = self.data_path / kind[0] / fold / image_name tmp = jio.read(str(path)) tmp = rot_and_flip_jpeg(tmp, rot, flip) cover, cover_dct, target_cover = self.__preprocess_strcture( tmp, label[0]) i = np.random.randint(low=1, high=self.num_classes) path = self.data_path / kind[i] / fold / image_name tmp = jio.read(str(path)) tmp = rot_and_flip_jpeg(tmp, rot, flip) stego, stego_dct, target_stego = self.__preprocess_strcture( tmp, label[i]) return torch.stack([cover, stego]), torch.stack( [cover_dct, stego_dct]), torch.stack([target_cover, target_stego])
def test_write_quant_table(self): """=> Test modifying a single element of quantization tables. """ for fpath in self.list_fpaths: for i in range(3): # Test 3 times jpeg = jpegio.read(fpath) fpath_no_ext, ext = os.path.splitext(fpath) fpath_modified = fpath_no_ext + "_modified" + ext ix_qt = np.random.randint(0, len(jpeg.quant_tables)) qt = jpeg.quant_tables[ix_qt] ix_row = np.random.randint(0, qt.shape[0]) ix_col = np.random.randint(0, qt.shape[1]) val = np.random.randint(1, 65535) qt[ix_row, ix_col] = val self.assertTrue(hasattr(jpeg, 'write')) jpeg.write(fpath_modified) jpeg_modified = jpegio.read(fpath_modified) qt_modified = jpeg_modified.quant_tables[ix_qt] self.assertEqual(qt[ix_row, ix_col], qt_modified[ix_row, ix_col]) del jpeg del jpeg_modified os.remove(fpath_modified)
def test_write_dct_coef(self): """=> Test modifying a single DCT coefficient. """ for fpath in self.list_fpaths: for i in range(3): # Test 3 times jpeg = jpegio.read(fpath) fpath_no_ext, ext = os.path.splitext(fpath) fpath_modified = fpath_no_ext + "_modified" + ext ix_coef_arr = np.random.randint(0, len(jpeg.coef_arrays)) coef_arr = jpeg.coef_arrays[ix_coef_arr] ix_row = np.random.randint(0, coef_arr.shape[0]) ix_col = np.random.randint(0, coef_arr.shape[1]) val = np.random.randint(-256, 256) coef_arr[ix_row, ix_col] = val self.assertTrue(hasattr(jpeg, 'write')) jpeg.write(fpath_modified) jpeg_modified = jpegio.read(fpath_modified) coef_arr_modified = jpeg_modified.coef_arrays[ix_coef_arr] self.assertEqual(coef_arr[ix_row, ix_col], coef_arr_modified[ix_row, ix_col]) del jpeg del jpeg_modified os.remove(fpath_modified)
def test_are_channel_sizes_same(self): """=> Test deciding sizes of all channels are identical. """ dpath = os.path.dirname(__file__) # False cases jpeg = jpegio.read(pjoin(dpath, 'images', 'arborgreens01.jpg')) self.assertFalse(jpeg.are_channel_sizes_same()) jpeg = jpegio.read(pjoin(dpath, 'images', 'cherries01.jpg')) self.assertFalse(jpeg.are_channel_sizes_same()) jpeg = jpegio.read(pjoin(dpath, 'images', 'football01.jpg')) self.assertFalse(jpeg.are_channel_sizes_same()) jpeg = jpegio.read(pjoin(dpath, 'images', 'greenlake01.jpg')) self.assertFalse(jpeg.are_channel_sizes_same()) # True cases jpeg = jpegio.read(pjoin(dpath, 'images', 'test01.jpg')) self.assertTrue(jpeg.are_channel_sizes_same()) jpeg = jpegio.read(pjoin(dpath, 'images', 'test02.jpg')) self.assertTrue(jpeg.are_channel_sizes_same()) jpeg = jpegio.read(pjoin(dpath, 'images', 'test03.jpg')) self.assertTrue(jpeg.are_channel_sizes_same()) jpeg = jpegio.read(pjoin(dpath, 'images', 'test04.jpg')) self.assertTrue(jpeg.are_channel_sizes_same()) jpeg = jpegio.read(pjoin(dpath, 'images', 'test05.jpg')) self.assertTrue(jpeg.are_channel_sizes_same())
def test_repeat_read_1000(self): """=> Check memory errors and garbage collection (1000 iterations). """ for i in range(1000): fpath = random.choice(self.list_fpaths) jpeg = jpegio.read(fpath) del jpeg
def JPEGdecompressYCbCr_v3(path): jpegStruct = jio.read(str(path)) [col, row] = np.meshgrid(range(8), range(8)) T = 0.5 * np.cos(np.pi * (2 * col + 1) * row / (2 * 8)) T[0, :] = T[0, :] / np.sqrt(2) img_dims = np.array(jpegStruct.coef_arrays[0].shape) n_blocks = img_dims // 8 broadcast_dims = (n_blocks[0], 8, n_blocks[1], 8) YCbCr = [] for i, dct_coeffs, in enumerate(jpegStruct.coef_arrays): if i == 0: QM = jpegStruct.quant_tables[i] else: QM = jpegStruct.quant_tables[1] t = np.broadcast_to(T.reshape(1, 8, 1, 8), broadcast_dims) qm = np.broadcast_to(QM.reshape(1, 8, 1, 8), broadcast_dims) dct_coeffs = dct_coeffs.reshape(broadcast_dims) a = np.transpose(t, axes=(0, 2, 3, 1)) b = (qm * dct_coeffs).transpose(0, 2, 1, 3) c = t.transpose(0, 2, 1, 3) z = a @ b @ c z = z.transpose(0, 2, 1, 3) YCbCr.append(z.reshape(img_dims)) return np.stack(YCbCr, -1).astype(np.float32)
def test_dct(): import jpegio as jpio image_fname = os.path.join(TEST_DATA_DIR, "Cover", "00002.jpg") image = cv2.imread(image_fname, cv2.IMREAD_GRAYSCALE) dct_y, dct_cb, dct_cr = compute_dct_fast(image_fname) y1 = idct8(dct_y) cb1 = idct8(dct_cb) cr1 = idct8(dct_cr) y88 = y1[:8, :8, 0] dct_y88 = dct_y[0, 0].reshape((8, 8)) jpegStruct = jpio.read(image_fname) qt = jpegStruct.quant_tables dct_matrix = jpegStruct.coef_arrays dct_y88_2 = jpegStruct.coef_arrays[0][:8, :8] * qt[0] y2 = idct8v2(jpegStruct.coef_arrays[0], qt[0]) y2_88 = y2[:8, :8, 0] cb2 = idct8v2(jpegStruct.coef_arrays[1], qt[1]) cr2 = idct8v2(jpegStruct.coef_arrays[2], qt[1]) print(dct_matrix)
def run_tool(): log.info("Running thread per elaborazione tool") print(IMAGE) jpeg = jio.read(IMAGE) coef_array = jpeg.coef_arrays[0] quant_tbl = jpeg.quant_tables[0] result = [] result.append(coef_array) result.append(quant_tbl) # salva risultati in opportuna directory result_path = MULTIMEDIA_DIRECTORY + '/' + result_uuid with open( result_path + '/' + 'result-' + str(analysis_uuid) + '.pkl', 'wb') as output: pickle.dump(result, output, pickle.HIGHEST_PROTOCOL) # TODO: rimuovere sleep, serve solo per fare test asincroni e ritardare l'output time.sleep(2) print('Invio ping di completamento analisi') gandalf_endpoint = 'http://localhost:8888/api/v1/projects/' + str( projectId) + '/ping?analysis_uuid=' + str(analysis_uuid) requests.post(gandalf_endpoint) print('Elaborazione finita!')
def dct_from_jpeg_imageio(path, ) -> Tuple[np.ndarray, np.ndarray, np.ndarray]: jpeg_struct = jpegio.read(path) dct_coefficients = jpeg_struct.coef_arrays # Get the quantised coefficients dct_y = np.array(dct_coefficients[0]) dct_cb = np.array(dct_coefficients[1]) dct_cr = np.array(dct_coefficients[2]) # Transform the arrays from e.g., (512, 512) to (64, 64, 64) by taking # sliding windows dct_y = dct_array_from_matrix(dct_y) dct_cb = dct_array_from_matrix(dct_cb) dct_cr = dct_array_from_matrix(dct_cr) # Get the relevant quantisation tables y_quant_table = jpeg_struct.quant_tables[0].reshape((64, )) cbcr_quant_table = jpeg_struct.quant_tables[1].reshape((64, )) # Multiply the values by their respective quantisation table. # Note: # - This is element-wise multiplication, not matrix multiplication. # - The Cb and Cr channels share the same quantisation table dct_y = dct_y * y_quant_table dct_cb = dct_cb * cbcr_quant_table dct_cr = dct_cr * cbcr_quant_table return dct_y, dct_cb, dct_cr
def jpeg_decompress_ycbcr(path: str) -> np.ndarray: jpeg_struct = jpegio.read(str(path)) [col, row] = np.meshgrid(range(8), range(8)) transformation = 0.5 * np.cos(np.pi * (2 * col + 1) * row / (2 * 8)) transformation[0, :] = transformation[0, :] / np.sqrt(2) img_dims = np.array(jpeg_struct.coef_arrays[0].shape) n_blocks = img_dims // 8 broadcast_dims = (n_blocks[0], 8, n_blocks[1], 8) y_cb_cr = [] for i, dct_coefficients, in enumerate(jpeg_struct.coef_arrays): if i == 0: qm = jpeg_struct.quant_tables[i] else: qm = jpeg_struct.quant_tables[1] t = np.broadcast_to(transformation.reshape(1, 8, 1, 8), broadcast_dims) qm = np.broadcast_to(qm.reshape(1, 8, 1, 8), broadcast_dims) dct_coefficients = dct_coefficients.reshape(broadcast_dims) a = np.transpose(t, axes=(0, 2, 3, 1)) b = (qm * dct_coefficients).transpose(0, 2, 1, 3) c = t.transpose(0, 2, 1, 3) z = a @ b @ c z = z.transpose(0, 2, 1, 3) y_cb_cr.append(z.reshape(img_dims)) return np.stack(y_cb_cr, -1).astype(np.float32)
def test_predict(model_class, folder, file_names, load_path, nclasses, TTA): tf.reset_default_graph() img_batch = tf.placeholder(dtype=tf.float32, shape=[len(TTA.keys()),512,512,3]) global_step = tf.get_variable('global_step', dtype=tf.int64, shape=[], initializer=tf.constant_initializer(0), trainable=False) prediction = model_class(img_batch, tf.estimator.ModeKeys.PREDICT, nclasses) prediction = tf.cast(prediction, tf.float64) soft_prediction = tf.nn.softmax(prediction) init_op = tf.group(tf.global_variables_initializer(), \ tf.local_variables_initializer()) saver = tf.train.Saver() soft_predictions = [] names = [] config = tf.ConfigProto() config.gpu_options.allow_growth = True config.gpu_options.per_process_gpu_memory_fraction = 0.9 with tf.Session(config=config) as sess: sess.run(init_op) saver.restore(sess, load_path) step = sess.run(global_step) for name in tqdm(file_names, bar_format='{l_bar}{bar:20}{r_bar}{bar:-20b}'): tmp = jio.read(folder+name) cover = decompress_structure(tmp) images = [] for t in TTA.values(): images.append(t(cover)) images = np.stack(images) names.extend([name]) pred, soft_pred = sess.run([prediction, soft_prediction], feed_dict={img_batch:images}) soft_pred = np.stack(soft_pred).mean(axis=0) soft_predictions.append(soft_pred) return np.stack(soft_predictions), names
def extract_and_save_dct_jpegio(fname, output_dir): # dct_y, dct_cr, dct_cb = compute_dct_fast(fname) image_id = fs.id_from_fname(fname) + ".npz" method = os.path.split(os.path.split(fname)[0])[1] dct_fname = os.path.join(output_dir, method, image_id) jpegStruct = jpio.read(fname) dct_matrix = jpegStruct.coef_arrays quant_tables = jpegStruct.quant_tables # ci0 = jpegStruct.comp_info[0] # ci1 = jpegStruct.comp_info[1] # ci2 = jpegStruct.comp_info[2] qm0 = np.tile(quant_tables[0], (512 // 8, 512 // 8)) qm1 = np.tile(quant_tables[1], (512 // 8, 512 // 8)) np.savez_compressed( dct_fname, dct_y=(dct_matrix[0] * qm0).astype(np.int16), dct_cb=(dct_matrix[1] * qm1).astype(np.int16), dct_cr=(dct_matrix[2] * qm1).astype(np.int16), qm0=quant_tables[0].astype(np.int16), qm1=quant_tables[1].astype(np.int16), ) del jpegStruct
def proc_dct(f): img = jpegio.read(f) acc = [] # lets accumlate matrices per channel for channel in img.coef_arrays: out = get_strides(channel, 8) out = np.transpose(out, (2, 3, 0, 1)).reshape(-1, 64, 64) acc.append(out) return np.concatenate(acc, axis=0)
def calc_qf(p): jpegStruct = jpegio.read(str(p)) if (jpegStruct.quant_tables[0][0, 0] == 2): return 95 elif (jpegStruct.quant_tables[0][0, 0] == 3): return 90 elif (jpegStruct.quant_tables[0][0, 0] == 8): return 75
def calculate_qf(self, image): jpegStruct = jpio.read(image) if (jpegStruct.quant_tables[0][0,0]==2): return 95 elif (jpegStruct.quant_tables[0][0,0]==3): return 90 elif (jpegStruct.quant_tables[0][0,0]==8): return 75
def test_dct_reshape_speed(): test_path = "data/UERD/00001.jpg" jpeg_struct = jpegio.read(test_path) dct_coefficients = jpeg_struct.coef_arrays[0] # Test speeds for _ in tqdm(range(1000), desc="Regular speed"): dct_array_from_matrix(dct_coefficients)
def test_write_huffman_tables(self): """=> Test modifying a single element of Huffman tables. """ for fpath in self.list_fpaths: for i in range(3): # Test 3 times jpeg = jpegio.read(fpath) fpath_no_ext, ext = os.path.splitext(fpath) fpath_modified = fpath_no_ext + "_modified" + ext ix_hftb = np.random.randint(0, len(jpeg.ac_huff_tables)) ac_hftb = jpeg.ac_huff_tables[ix_hftb] counts = ac_hftb["counts"] symbols = ac_hftb["symbols"] ix_counts = np.random.randint(0, counts.size) ix_symbols = np.random.randint(0, symbols.size) val_counts = np.random.randint(counts.min(), counts.max() + 1) val_symbols = np.random.randint(symbols.min(), symbols.max() + 1) print(counts) print(symbols) counts[ix_counts] = val_counts symbols[ix_symbols] = val_symbols print(counts) print(symbols) self.assertTrue(hasattr(jpeg, 'write')) jpeg.write(fpath_modified) jpeg_modified = jpegio.read(fpath_modified) ac_hftb_modified = jpeg.ac_huff_tables[ix_hftb] counts_modified = ac_hftb_modified["counts"] symbols_modified = ac_hftb_modified["symbols"] self.assertEqual(counts[ix_counts], counts_modified[ix_counts]) self.assertEqual(symbols[ix_symbols], symbols_modified[ix_symbols]) del jpeg del jpeg_modified os.remove(fpath_modified)
def gen_valid(BASE_DIR, im_name, pair_constraint=True, priors=[0.25] * 4, classes=['Cover/', 'JMiPOD/', 'JUNIWARD/', 'UERD/']): try: # Dirty trick to fix TF.estimator str encoding im_name = im_name.decode() C = BASE_DIR.decode() classes = [c.decode() for c in classes] except AttributeError: C = BASE_DIR if pair_constraint: class_idx = 0 else: class_idx = np.random.choice([0, 1, 2, 3], p=priors) tmp = jio.read(C + classes[class_idx] + im_name) image = decompress_structure(tmp).astype(np.float32) if pair_constraint: class_idx = np.random.choice([1, 2, 3]) tmp = jio.read(C + classes[class_idx] + im_name) stego = decompress_structure(tmp).astype(np.float32) batch = np.stack([image, stego]) labels = [0, class_idx] else: labels = [class_idx] batch = np.expand_dims(image, 0) rot = random.randint(0, 3) if random.random() < 0.5: return [ np.rot90(batch, rot, axes=[1, 2]), np.array(labels, dtype='uint8') ] else: return [ np.flip(np.rot90(batch, rot, axes=[1, 2]), axis=2), np.array(labels, dtype='uint8') ]
def get_image_quality(image_path): jpeg = jpegio.read(str(image_path)) first_element = jpeg.quant_tables[0][0, 0] if first_element == 2: return 95 elif first_element == 3: return 90 elif first_element == 8: return 75 else: raise Exception(f"Unknown image quality, quant tables: {jpeg.quant_tables}")
def test_compare_coef_block_array_shape(self): """=> Test getting DCT block array shape. """ for fpath in self.list_fpaths: jpeg = jpegio.read(fpath) for c in range(len(jpeg.coef_arrays)): coef_arr = jpeg.coef_arrays[c] blk_shape = jpeg.get_coef_block_array_shape(c) self.assertTrue(int(coef_arr.shape[0] / BS) == blk_shape[0]) self.assertTrue(int(coef_arr.shape[1] / BS) == blk_shape[1])
def is_outlier(name, folder, M, m): jpg = jio.read(os.path.join(folder, name)) for c in range(jpg.image_components): QT = jpg.quant_tables[jpg.comp_info[c].ac_tbl_no] for k in range(8): for l in range(8): coeffs = jpg.coef_arrays[c][k:-1:8, l:-1:8] T = np.round(M[k, l] / QT[k, l]) t = np.round(m[k, l] / QT[k, l]) if (coeffs > T).any(): return name elif (coeffs < t).any(): return name
def __getitem__(self, index: int): kind, image_name, label = self.kinds[index], self.image_names[index], self.labels[index] jpegStruct = jpio.read(f'{DATA_ROOT_PATH}/{kind}/{image_name}') imDecompressYCbCr = JPEGdecompressYCbCr(jpegStruct) image = imDecompressYCbCr/255.0 if self.transforms: sample = {'image': image} sample = self.transforms(**sample) image = sample['image'] target = onehot(4, label) return image, target
def main(): DATA_ROOT_PATH = os.environ.get('DATA_ROOT_PATH') parser = argparse.ArgumentParser("Generates rich models features") arg = parser.add_argument arg('--model', type=str, default='DCTR', help='model name') arg('--folder', type=str, default='Cover/', help='model name') arg('--subset', type=str, default='train', help='split') arg('--output', type=str, default='train/features/', help='model name') arg('--quality-factor', type=int, default=75, help='quality factor') args = parser.parse_args() os.makedirs(args.output, exist_ok=True) if args.model == 'DCTR': f = octave.DCTR elif args.model == 'JRM': f = octave.JRM with open('./IL_' + args.subset + '_' + str(args.quality_factor) + '.p', 'rb') as handle: IL = pickle.load(handle) im_name = IL[0] tmp = jio.read(os.path.join(DATA_ROOT_PATH + 'Cover', im_name)) feature = f(tmp.coef_arrays[0], tmp.quant_tables[0]) dim = feature.shape[1] features = np.zeros((len(IL), dim)) for i, im_name in enumerate( tqdm(IL, bar_format='{l_bar}{bar:20}{r_bar}{bar:-20b}')): tmp = jio.read(os.path.join(DATA_ROOT_PATH + args.folder, im_name)) features[i, :] = f(tmp.coef_arrays[0], tmp.quant_tables[0]) np.save( os.path.join( args.output, 'QF' + str(args.quality_factor) + '_' + args.model + '_' + args.subset + '_features_' + args.folder[:-1]), features)
def __getitem__(self, index: int): image_name = self.image_names[index] # image = cv2.imread(f'{DATA_ROOT_PATH}/Test/{image_name}', cv2.IMREAD_COLOR) # image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB).astype(np.float32) # image /= 255.0 jpegStruct = jpio.read(f'{DATA_ROOT_PATH}/Test/{image_name}') imDecompressYCbCr = JPEGdecompressYCbCr(jpegStruct) image = imDecompressYCbCr / 255.0 sample = {'image': image} sample = self.transforms(**sample) image = sample['image'] return image_name, image
def test_compare_coef_block(self): """=> Test getting DCT block array. """ for fpath in self.list_fpaths: jpeg = jpegio.read(fpath) for c in range(len(jpeg.coef_arrays)): coef_arr = jpeg.coef_arrays[c] nrows_blk, ncols_blk = jpeg.get_coef_block_array_shape(c) for i in range(nrows_blk): for j in range(ncols_blk): coef_blk = jpeg.get_coef_block(c, i, j) self.assertTrue( np.array_equal( coef_arr[BS * i:BS * (i + 1), BS * j:BS * (j + 1)], coef_blk))
def get_qf_dicts(folder, names): names_qf = dict() for name in tqdm(names, bar_format='{l_bar}{bar:20}{r_bar}{bar:-20b}'): tmp = jio.read(os.path.join(folder, name)) Q = tmp.quant_tables[0] for qf in [75,90,95]: if (Q == quantization_dict[qf]).all(): q = qf names_qf[name] = q qf_names = defaultdict(list) for key, value in sorted(names_qf.items()): qf_names[value].append(key) return (names_qf, qf_names)
def test_compare_count_nnz_ac(self): """=> Test counting non-zero DCT AC coefficients. """ for fpath in self.list_fpaths: fname = os.path.basename(fpath) dpath_mat = apath( pjoin(os.path.dirname(fpath), os.path.pardir, 'matlab_outputs')) fpath_mat = pjoin(dpath_mat, 'nnz_' + fname + '.mat') if not os.path.isfile(fpath_mat): continue mat = spio.loadmat(fpath_mat) nnz_ac_mat = mat['nnz_ac'][0] jpeg = jpegio.read(fpath) nnz_ac_jpegio = jpeg.count_nnz_ac() self.assertTrue(nnz_ac_mat == nnz_ac_jpegio)
def detect(self, local_img_path): local_quality_factor = 'other' try: # analyze jpeg = jio.read(local_img_path) quant_tables = jpeg.quant_tables # print(local_img_path.split('/')[-1]) if quant_tables[0][0, 0] == 2: local_quality_factor = '2' elif quant_tables[0][0, 0] == 3: local_quality_factor = '1' elif quant_tables[0][0, 0] == 8: local_quality_factor = '0' else: print('error at estimating quality factor') except Exception as e: print('controlled error in quality_factor submodule') print(e) logger.error(str(e), exc_info=True) return local_quality_factor
def __getitem__(self, index: int): image_name = self.image_names[index] if self.decoder == 'NR': tmp = jio.read(f'{self.folder}/{image_name}') image = decompress_structure(tmp).astype(np.float32) image = ycbcr2rgb(image) image /= 255.0 else: image = cv2.imread(f'{self.folder}/{image_name}', cv2.IMREAD_COLOR) image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB).astype(np.float32) image /= 255.0 image = self.func_transforms(image) if self.transforms: sample = {'image': image} sample = self.transforms(**sample) image = sample['image'] return image_name, image
def test_compare_dct_coef(self): """=> Test reading DCT coefficients. """ for fpath in self.list_fpaths: fname = os.path.basename(fpath) dpath_mat = apath( pjoin(os.path.dirname(fpath), os.path.pardir, 'matlab_outputs')) fpath_mat = pjoin(dpath_mat, 'coef_arrays' + fname + '.mat') if not os.path.isfile(fpath_mat): continue mat = spio.loadmat(fpath_mat) coef_arrays_mat = mat['coef_arrays'][0] jpeg = jpegio.read(fpath) for i in range(len(jpeg.coef_arrays)): self.assertEqual(coef_arrays_mat[i].dtype, jpeg.coef_arrays[i].dtype) res = np.array_equal(jpeg.coef_arrays[i], coef_arrays_mat[i]) self.assertTrue(res)