def test_detection(self): nat = np.asarray(Image.open('data/nat-jpg/Nikon_D70s_0_22115.JPG')) ff1 = np.asarray(Image.open('data/ff-jpg/Nikon_D70s_0_22193.JPG')) ff2 = np.asarray(Image.open('data/ff-jpg/Nikon_D70s_1_23220.JPG')) nat = prnu.cut_ctr(nat, (500, 500, 3)) ff1 = prnu.cut_ctr(ff1, (500, 500, 3)) ff2 = prnu.cut_ctr(ff2, (500, 500, 3)) w = prnu.extract_single(nat) k1 = prnu.extract_single(ff1) k2 = prnu.extract_single(ff2) pce1 = [{}] * 4 pce2 = [{}] * 4 for rot_idx in range(4): cc1 = prnu.crosscorr_2d(k1, np.rot90(w, rot_idx)) pce1[rot_idx] = prnu.pce(cc1) cc2 = prnu.crosscorr_2d(k2, np.rot90(w, rot_idx)) pce2[rot_idx] = prnu.pce(cc2) best_pce1 = np.max([p['pce'] for p in pce1]) best_pce2 = np.max([p['pce'] for p in pce2]) self.assertGreater(best_pce1, best_pce2)
def get_PCE_from_single_img(fingerprint,img_path): img = prnu.cut_ctr(np.asarray(Image.open(img_path)), (pix_size, pix_size, 3)) detected_fingerprint = prnu.extract_single(img) cc2d = prnu.crosscorr_2d(fingerprint, detected_fingerprint) PCE = prnu.pce(cc2d)['pce'] print(PCE) return PCE
def test_pce(self): im = np.asarray(Image.open('data/prnu1.jpg'))[:500, :400] w_all = prnu.extract_single(im) y_os, x_os = 5, 8 w_cut = w_all[y_os:, x_os:] cc1 = prnu.crosscorr_2d(w_cut, w_all) cc2 = prnu.crosscorr_2d(w_all, w_cut) pce1 = prnu.pce(cc1) pce2 = prnu.pce(cc2) self.assertSequenceEqual( pce1['peak'], (im.shape[0] - y_os - 1, im.shape[1] - x_os - 1)) self.assertTrue(np.allclose(pce1['pce'], 134611.58644973233)) self.assertSequenceEqual(pce2['peak'], (y_os - 1, x_os - 1)) self.assertTrue(np.allclose(pce2['pce'], 134618.03404934643))
def test_crosscorr2d(self): im = np.asarray(Image.open('data/prnu1.jpg'))[:1000, :800] w_all = prnu.extract_single(im) y_os, x_os = 300, 150 w_cut = w_all[y_os:, x_os:] cc = prnu.crosscorr_2d(w_cut, w_all) max_idx = np.argmax(cc.flatten()) max_y, max_x = np.unravel_index(max_idx, cc.shape) peak_y = cc.shape[0] - 1 - max_y peak_x = cc.shape[1] - 1 - max_x peak_height = cc[max_y, max_x] self.assertSequenceEqual((peak_y, peak_x), (y_os, x_os)) self.assertTrue(np.allclose(peak_height, 666995.0))
def main(): """ Main example script. Load a subset of flatfield and natural images from Dresden. For each device compute the fingerprint from all the flatfield images. For each natural image compute the noise residual. Check the detection performance obtained with cross-correlation and PCE :return: """ ff_dirlist = np.array(sorted(glob('test/data/ff-jpg/*.JPG'))) ff_device = np.array( [os.path.split(i)[1].rsplit('_', 1)[0] for i in ff_dirlist]) nat_dirlist = np.array(sorted(glob('test/data/nat-jpg/*.JPG'))) nat_device = np.array( [os.path.split(i)[1].rsplit('_', 1)[0] for i in nat_dirlist]) print('Computing fingerprints') fingerprint_device = sorted(np.unique(ff_device)) k = [] for device in fingerprint_device: imgs = [] for img_path in ff_dirlist[ff_device == device]: im = Image.open(img_path) im_arr = np.asarray(im) if im_arr.dtype != np.uint8: print('Error while reading image: {}'.format(img_path)) continue if im_arr.ndim != 3: print('Image is not RGB: {}'.format(img_path)) continue im_cut = prnu.cut_ctr(im_arr, (512, 512, 3)) imgs += [im_cut] k += [prnu.extract_multiple_aligned(imgs, processes=cpu_count())] k = np.stack(k, 0) print('Computing residuals') imgs = [] for img_path in nat_dirlist: imgs += [prnu.cut_ctr(np.asarray(Image.open(img_path)), (512, 512, 3))] pool = Pool(cpu_count()) w = pool.map(prnu.extract_single, imgs) pool.close() w = np.stack(w, 0) # Computing Ground Truth gt = prnu.gt(fingerprint_device, nat_device) print('Computing cross correlation') cc_aligned_rot = prnu.aligned_cc(k, w)['cc'] print('Computing statistics cross correlation') stats_cc = prnu.stats(cc_aligned_rot, gt) print('Computing PCE') pce_rot = np.zeros((len(fingerprint_device), len(nat_device))) for fingerprint_idx, fingerprint_k in enumerate(k): for natural_idx, natural_w in enumerate(w): cc2d = prnu.crosscorr_2d(fingerprint_k, natural_w) pce_rot[fingerprint_idx, natural_idx] = prnu.pce(cc2d)['pce'] print('Computing statistics on PCE') stats_pce = prnu.stats(pce_rot, gt) print('AUC on CC {:.2f}, expected {:.2f}'.format(stats_cc['auc'], 0.98)) print('AUC on PCE {:.2f}, expected {:.2f}'.format(stats_pce['auc'], 0.81))