3 Commits

View File

@@ -14,7 +14,7 @@ from tqdm import tqdm
IMAGE_SIZE = 64
NUMBER_OF_PHONES = 1#0
NUMBER_OF_IMAGES_PER_PHONE = 100
NUMBER_OF_IMAGES_PER_PHONE = 10_000
# Compared to images being 1.
PRNU_FACTOR = 0.1
@@ -25,7 +25,7 @@ def randomImage(scale):
imagesWithoutPrnu = [[randomImage(scale = 1) for _ in range(NUMBER_OF_IMAGES_PER_PHONE)] for phoneIndex in range(NUMBER_OF_PHONES)]
prnus = [randomImage(scale = PRNU_FACTOR) for _ in range(NUMBER_OF_PHONES)]
prnus = [np.array(Image.open('prnu.png').convert('F')) * PRNU_FACTOR / 255]
imagesWithPrnu = [[imageWithoutPrnu + prnus[phoneIndex] for imageWithoutPrnu in imagesWithoutPrnu[phoneIndex]] for phoneIndex in range(NUMBER_OF_PHONES)]
@@ -43,32 +43,55 @@ def showImageWithMatplotlib(npArray):
plt.imshow(npArray)
plt.show()
fig, axs = plt.subplots(1, 4)
NUMBER_OF_ROWS = 5
NUMBER_OF_COLUMNS = 3
fig, axes = plt.subplots(NUMBER_OF_ROWS, NUMBER_OF_COLUMNS)
fig.suptitle('Single PRNU estimation with images being Gaussian noise')
prnusPil = [toPilImage(prnu) for prnu in prnus]
#showImageWithMatplotlib(prnus[0])
axs[0].set_title('Actual PRNU')
axs[0].imshow(prnus[0])
MAIN_AXIS_ROW_INDEX = 1
mainAxis = axes[MAIN_AXIS_ROW_INDEX]
mainAxis[0].set_title('Actual PRNU')
mainAxis[0].imshow(prnus[0])
axs[1].set_title('Image without PRNU')
axs[1].imshow(imagesWithPrnu[0][0])
mainAxis[1].set_title('First image without PRNU')
mainAxis[1].imshow(imagesWithoutPrnu[0][0])
imagesWithPrnuPil = [[toPilImage(imageWithPrnu) for imageWithPrnu in imagesWithPrnu[phoneIndex]] for phoneIndex in range(NUMBER_OF_PHONES)]
#showImageWithMatplotlib(imagesWithPrnu[0][0])
axs[2].set_title(f'First image with PRNU\nRMS with image without PRNU: {round(rmsDiffNumpy(imagesWithPrnu[0][0], imagesWithoutPrnu[0][0]), 4)}')
axs[2].imshow(imagesWithPrnu[0][0])
assert NUMBER_OF_IMAGES_PER_PHONE >= 10 ** (NUMBER_OF_ROWS - 1), 'Try to use more images than generated!'
imagesWithPrnuPil0Mean = np.array(imagesWithPrnuPil[0]).mean(axis = 0)
#showImageWithMatplotlib(imagesWithPrnuPil0Mean)
axs[3].set_title(f'Mean of images with PRNU\ni.e. estimated PRNU\nRMS with actual PRNU: {round(rmsDiffNumpy(imagesWithPrnuPil0Mean, prnus[0]), 4)}')
axs[3].imshow(imagesWithPrnuPil0Mean)
for rowIndex, numberOfImages in enumerate([10 ** power for power in range(NUMBER_OF_ROWS)]):
imagesWithPrnuPil0Mean = np.array(imagesWithPrnu[0][:numberOfImages]).mean(axis = 0)
title = (f'Mean of first $N$ images with PRNU\ni.e. estimated PRNU\nRMS with actual PRNU\n\n' if rowIndex == 0 else '') + f'$N$ = {numberOfImages:,}, $RMS$ = {round(rmsDiffNumpy(imagesWithPrnuPil0Mean, prnus[0]), 4)}'
axes[rowIndex][2].set_title(title)
axes[rowIndex][2].imshow(imagesWithPrnuPil0Mean)
for columnIndex in range(NUMBER_OF_COLUMNS):
for axisIndex in range(NUMBER_OF_ROWS):
if axisIndex != MAIN_AXIS_ROW_INDEX:
axes[axisIndex][columnIndex].axis('off')
plt.tight_layout()
plt.show()
##
def toFileName(title):
return title.lower().replace(' ', '_').replace(',', '_')
for title, image in zip(['Actual PRNU', 'First image without PRNU'], [prnus[0], imagesWithoutPrnu[0][0]]):
plt.title(title)
plt.imshow(image)
plt.savefig(title.lower().replace(' ', '_') + '.svg')
for numberOfImages in [10 ** power for power in range(NUMBER_OF_ROWS)]:
title = 'First image with PRNU' if numberOfImages == 1 else f'Mean of first {numberOfImages:,} images with PRNU'
image = np.array(imagesWithPrnu[0][:numberOfImages]).mean(axis = 0)
plt.title(f'{title}\ni.e. estimated PRNU\nRMS with actual PRNU = {round(rmsDiffNumpy(image, prnus[0]), 4)}')
plt.imshow(image)
plt.savefig(f'{toFileName(title)}.svg')
##
# Compute CAI of phone images.
caiImages = [[contextAdaptiveInterpolator(image.load(), image) for image in imagesWithPrnuPil[phoneIndex]] for phoneIndex in tqdm(range(NUMBER_OF_PHONES))]
#caiImages[0][0].show()