From f0db61efe2a632b366bbb677df73ae9040aaa29e Mon Sep 17 00:00:00 2001 From: Benjamin Loison Date: Fri, 29 Mar 2024 13:47:27 +0100 Subject: [PATCH] Make single figure to compare multiple `splitNXN` values --- .../noise_free_test_images/estimate_prnu.py | 95 ++++++++++++------- 1 file changed, 62 insertions(+), 33 deletions(-) diff --git a/datasets/noise_free_test_images/estimate_prnu.py b/datasets/noise_free_test_images/estimate_prnu.py index 91e492c..b378696 100644 --- a/datasets/noise_free_test_images/estimate_prnu.py +++ b/datasets/noise_free_test_images/estimate_prnu.py @@ -25,47 +25,76 @@ datasetPath = 'no_noise_images' # In addition to the range difference, note that the distribution in the first set of images was a Gaussian and here is very different and specific. PRNU_FACTOR = 0.01 NOISE_FACTOR = 0.1 -SPLIT_N_X_N = 1 - -IMAGE_SIZE_SHAPE = [dimension // SPLIT_N_X_N for dimension in (704, 469)] np.random.seed(0) -#prnuNpArray = 255 * randomGaussianImage(scale = PRNU_FACTOR, size = IMAGE_SIZE_SHAPE) -prnuNpArray = getPrnuShownAsSuch(IMAGE_SIZE_SHAPE, 255) * PRNU_FACTOR +SPLIT_N_X_N_S = [1, 2, 4] -def isIn256Range(x): - return 0 <= x and x <= 255 +# len(SPLIT_N_X_N_S) +fig, axes = plt.subplots(2, 4) +fig.suptitle('PRNU estimation with different number of images having Gaussian noise and Gaussian noised PRNU') -imagesPrnuEstimateNpArray = [] +for splitNXNIndex, splitNXN in enumerate(SPLIT_N_X_N_S): + IMAGE_SIZE_SHAPE = [dimension // splitNXN for dimension in (704, 469)] -for imageName in os.listdir(datasetPath): - if imageName.endswith('.png'): - imagePath = f'{datasetPath}/{imageName}' - imageWithoutPrnuPil = Image.open(imagePath).convert('F') - imageWithoutPrnuNpArray = np.array(imageWithoutPrnuPil) + #prnuNpArray = 255 * randomGaussianImage(scale = PRNU_FACTOR, size = IMAGE_SIZE_SHAPE) + prnuNpArray = getPrnuShownAsSuch(IMAGE_SIZE_SHAPE, 255) * PRNU_FACTOR - m = IMAGE_SIZE_SHAPE[1] - n = IMAGE_SIZE_SHAPE[0] + def isIn256Range(x): + return 0 <= x and x <= 255 - imageWithoutPrnuNpArrayTiles = [imageWithoutPrnuNpArray[x : x + m, y : y + n] for x in range(0, imageWithoutPrnuNpArray.shape[0], m) for y in range(0, imageWithoutPrnuNpArray.shape[1], n)] - for imageWithoutPrnuNpArrayTile in imageWithoutPrnuNpArrayTiles: - #print(imageWithoutPrnuNpArrayTile.shape, tuple(IMAGE_SIZE_SHAPE[::-1])) - #if imageWithoutPrnuNpArrayTile.shape != tuple(IMAGE_SIZE_SHAPE[::-1]): - # continue - imageNoise = randomGaussianImage(scale = 255 * NOISE_FACTOR, size = imageWithoutPrnuNpArrayTile.shape) - imageWithPrnuNpArray = imageWithoutPrnuNpArrayTile + prnuNpArray + imageNoise - #assert all([isIn256Range(extreme) for extreme in [imageWithPrnuNpArray.max(), imageWithPrnuNpArray.min()]]), 'Adding the PRNU resulted in out of 256 bounds image' - imageWithPrnuPil = toPilImage(imageWithPrnuNpArray) - #imagePrnuEstimatePil = contextAdaptiveInterpolator(imageWithPrnuPil.load(), imageWithPrnuPil) - #imagePrnuEstimateNpArray = np.array(imagePrnuEstimatePil) - imagePrnuEstimateNpArray = imageWithPrnuNpArray - denoise_tv_chambolle(imageWithPrnuNpArray, weight=0.2, channel_axis=-1) + imagesPrnuEstimateNpArray = [] + isFirstImage = True - imagesPrnuEstimateNpArray += [imagePrnuEstimateNpArray] + for imageName in os.listdir(datasetPath): + if imageName.endswith('.png'): + imagePath = f'{datasetPath}/{imageName}' + imageWithoutPrnuPil = Image.open(imagePath).convert('F') + imageWithoutPrnuNpArray = np.array(imageWithoutPrnuPil) -cameraPrnuEstimateNpArray = np.array(imagesPrnuEstimateNpArray).mean(axis = 0) -rms = rmsDiffNumpy(cameraPrnuEstimateNpArray, prnuNpArray, True) -title = f'Camera PRNU estimate\nRMS with actual one: {rmsDiffNumpy(cameraPrnuEstimateNpArray, prnuNpArray):.4f} (normalized RMS: {rmsDiffNumpy(cameraPrnuEstimateNpArray, prnuNpArray, True):.4f})' -#showImageWithMatplotlib(cameraPrnuEstimateNpArray, title) + m = IMAGE_SIZE_SHAPE[1] + n = IMAGE_SIZE_SHAPE[0] -showImageWithMatplotlib(cameraPrnuEstimateNpArray, title, 'gray') \ No newline at end of file + imageWithoutPrnuNpArrayTiles = [imageWithoutPrnuNpArray[x : x + m, y : y + n] for x in range(0, imageWithoutPrnuNpArray.shape[0], m) for y in range(0, imageWithoutPrnuNpArray.shape[1], n)] + for imageWithoutPrnuNpArrayTile in imageWithoutPrnuNpArrayTiles: + #print(imageWithoutPrnuNpArrayTile.shape, tuple(IMAGE_SIZE_SHAPE[::-1])) + #if imageWithoutPrnuNpArrayTile.shape != tuple(IMAGE_SIZE_SHAPE[::-1]): + # continue + imageNoise = randomGaussianImage(scale = 255 * NOISE_FACTOR, size = imageWithoutPrnuNpArrayTile.shape) + imageWithPrnuNpArray = imageWithoutPrnuNpArrayTile + prnuNpArray + imageNoise + + if splitNXNIndex == 0 and isFirstImage: + axis = axes[0] + + axis[0].set_title('First image without noise') + axis[0].imshow(imageWithoutPrnuNpArrayTile) + + axis[1].set_title('Actual Gaussian noised (G.n.) PRNU') + axis[1].imshow(prnuNpArray) + + axis[2].set_title('F. image with G.n.') + axis[2].imshow(imageWithoutPrnuNpArray + imageNoise) + + axis[3].set_title('F. image with G.n. and PRNU') + axis[3].imshow(imageWithoutPrnuNpArray + prnuNpArray + imageNoise) + isFirstImage = False + + #assert all([isIn256Range(extreme) for extreme in [imageWithPrnuNpArray.max(), imageWithPrnuNpArray.min()]]), 'Adding the PRNU resulted in out of 256 bounds image' + imageWithPrnuPil = toPilImage(imageWithPrnuNpArray) + #imagePrnuEstimatePil = contextAdaptiveInterpolator(imageWithPrnuPil.load(), imageWithPrnuPil) + #imagePrnuEstimateNpArray = np.array(imagePrnuEstimatePil) + imagePrnuEstimateNpArray = imageWithPrnuNpArray - denoise_tv_chambolle(imageWithPrnuNpArray, weight=0.2, channel_axis=-1) + + imagesPrnuEstimateNpArray += [imagePrnuEstimateNpArray] + + cameraPrnuEstimateNpArray = np.array(imagesPrnuEstimateNpArray).mean(axis = 0) + rms = rmsDiffNumpy(cameraPrnuEstimateNpArray, prnuNpArray, True) + title = f'RMS with actual PRNU: {rmsDiffNumpy(cameraPrnuEstimateNpArray, prnuNpArray):.4f}\n(normalized RMS: {rmsDiffNumpy(cameraPrnuEstimateNpArray, prnuNpArray, True):.4f})' + axis = axes[1] + axis[splitNXNIndex].set_title(f'Number of images: {len(imagesPrnuEstimateNpArray)}\n{title}') + axis[splitNXNIndex].imshow(cameraPrnuEstimateNpArray) + +axes[1][3].axis('off') + +plt.tight_layout() +plt.show() \ No newline at end of file