WIP: Getting PRNU by averaging on fake dataset

This commit is contained in:
Benjamin Loison 2024-03-25 17:45:01 +01:00
parent 72e37a252a
commit 8575da5b1d
Signed by: Benjamin_Loison
SSH Key Fingerprint: SHA256:BtnEgYTlHdOg1u+RmYcDE0mnfz1rhv5dSbQ2gyxW8B8
3 changed files with 22 additions and 18 deletions

View File

@ -19,11 +19,11 @@ def contextAdaptiveInterpolator(I, IImage, showProgress = False):
# Accelerate computation. See #15.
for m in range(1, IImage.size[0] - 1):
for n in range(1, IImage.size[1] - 1):
e = I[m, n + 1]
e = I[m , n + 1]
se = I[m + 1, n + 1]
s = I[m + 1, n]
s = I[m + 1, n]
sw = I[m + 1, n - 1]
w = I[m, n - 1]
w = I[m , n - 1]
nw = I[m - 1, n - 1]
no = I[m - 1, n]
ne = I[m - 1, n + 1]

View File

@ -5,7 +5,6 @@ def wienerFilter(r, rImage, Q, sigma_0, showProgress):
h_wImage = Image.new('L', (rImage.size[0], rImage.size[1]))
h_wImagePixels = h_wImage.load()
# Wiener filter.
def h_w(hImage, h, i, j):
# Equation (7)
return h[i, j] * sigma(hImage, h, i, j) / (sigma(hImage, h, i, j) + sigma_0 ** 2)

View File

@ -13,41 +13,45 @@ from context_adaptive_interpolator import contextAdaptiveInterpolator
from tqdm import tqdm
IMAGE_SIZE = 64
NUMBER_OF_PHONES = 10
NUMBER_OF_PHONES = 1#0
NUMBER_OF_IMAGES_PER_PHONE = 100
# Compared to images.
# Compared to images being 1.
PRNU_FACTOR = 0.1
# Generate PRNUs and images of phones.
# Is such `np.maximum` probabilistically correct with our theoretical method? See #19.
def randomImage(scale):
return np.maximum(np.random.normal(loc = 0, scale = scale, size = (IMAGE_SIZE, IMAGE_SIZE)), 0)
return np.random.normal(loc = 0, scale = scale, size = (IMAGE_SIZE, IMAGE_SIZE))
prnus = [randomImage(scale = PRNU_FACTOR) for _ in range(NUMBER_OF_PHONES)]
images = [[randomImage(scale = 1) + prnus[phoneIndex] for _ in range(NUMBER_OF_IMAGES_PER_PHONE)] for phoneIndex in range(NUMBER_OF_PHONES)]
# How to simplify?
allImages = np.max([np.max(prnus) + np.max(images)])
def toPilImage(npArray):
npArray = (255 * npArray / np.max(allImages)).round()
return Image.fromarray(np.uint8(npArray))
return Image.fromarray(npArray)
prnus = [toPilImage(prnu) for prnu in prnus]
#prnus[0].show()
def showImage(npArray):
npArray -= npArray.min()
npArray = (npArray / npArray.max()) * 255
Image.fromarray(npArray).show()
images = [[toPilImage(image) for image in images[phoneIndex]] for phoneIndex in range(NUMBER_OF_PHONES)]
#images[0][0].show()
prnusPil = [toPilImage(prnu) for prnu in prnus]
#showImage(prnus[0])
imagesPil = [[toPilImage(image) for image in images[phoneIndex]] for phoneIndex in range(NUMBER_OF_PHONES)]
#showImage(images[0][0])
# Compute CAI of phone images.
caiImages = [[contextAdaptiveInterpolator(image.load(), image) for image in images[phoneIndex]] for phoneIndex in tqdm(range(NUMBER_OF_PHONES))]
caiImages = [[contextAdaptiveInterpolator(image.load(), image) for image in imagesPil[phoneIndex]] for phoneIndex in tqdm(range(NUMBER_OF_PHONES))]
#caiImages[0][0].show()
# Guess the phone by consider the one reaching the lowest RMS difference between the estimated PRNU and the actual one.
def getPhoneIndexByNearestPrnu(estimatedPrnu):
nearestPrnuRmsDiff = None
nearestPrnuPhoneIndex = None
for phoneIndex, prnu in enumerate(prnus):
for phoneIndex, prnu in enumerate(prnusPil):
prnuRmsDiff = rmsdiff(estimatedPrnu, prnu)
if nearestPrnuRmsDiff is None or prnuRmsDiff < nearestPrnuRmsDiff:
nearestPrnuRmsDiff = prnuRmsDiff
@ -58,15 +62,16 @@ def getPhoneIndexByNearestPrnu(estimatedPrnu):
# What about CAI on `phoneImagesMean`? See https://gitea.lemnoslife.com/Benjamin_Loison/Robust_image_source_identification_on_modern_smartphones/issues/9#issuecomment-1369.
correctGuessesByMeanImages = 0
correctGuessesByMeanCAIImages = 0
# Maybe make sense only because Gaussian images here.
correctGuessesByCAIImagesMean = 0
for phoneIndex in range(NUMBER_OF_PHONES):
phoneImages = images[phoneIndex]
phoneImages = imagesPil[phoneIndex]
phoneCaiImages = caiImages[phoneIndex]
phoneImagesMean = toPilImage(np.array(phoneImages).mean(axis = 0))
caiImagesMean = toPilImage(np.array(phoneCaiImages).mean(axis = 0))
caiOverPhoneImagesMean = contextAdaptiveInterpolator(phoneImagesMean.load(), phoneImagesMean)
phonePrnu = prnus[phoneIndex]
phonePrnu = prnusPil[phoneIndex]
print('RMS diff with mean image =', rmsdiff(phoneImagesMean, phonePrnu))
print('RMS diff with mean CAI images =', rmsdiff(caiImagesMean, phonePrnu))
print('RMS diff with CAI images mean =', rmsdiff(caiOverPhoneImagesMean, phonePrnu))