#66: Add Distance Enum to choose between ROOT_MEAN_SQUARE and PEARSON_CORRELATION

This commit is contained in:
Benjamin Loison 2024-05-15 19:51:30 +02:00
parent 7ed6ff5adb
commit 6a9900df91
Signed by: Benjamin_Loison
SSH Key Fingerprint: SHA256:BtnEgYTlHdOg1u+RmYcDE0mnfz1rhv5dSbQ2gyxW8B8
3 changed files with 56 additions and 21 deletions

View File

@ -3,15 +3,10 @@
import numpy as np
import matplotlib.pyplot as plt
from tqdm import tqdm
from utils import denoise, iterativeMean, getColorChannel, escapeFilePath, Color, mergeSingleColorChannelImagesAccordingToBayerFilter, rescaleRawImageForDenoiser, updateExtremes, saveNpArray, getColorMeans, getImageCrop, Denoiser
import sys
from utils import denoise, iterativeMean, getColorChannel, escapeFilePath, Color, mergeSingleColorChannelImagesAccordingToBayerFilter, rescaleRawImageForDenoiser, updateExtremes, saveNpArray, getColorMeans, getImageCrop, Denoiser, Distance
import os
import random
sys.path.insert(0, '../../algorithms/distance/')
from rms_diff import rmsDiffNumpy
# Configuration:
DENOISER = Denoiser.MEAN
@ -21,6 +16,17 @@ IMAGES_CAMERAS_FOLDER = {
}
TRAINING_PORTION = 0.5
PREDICT_ONLY_ON_WHOLE_TRAINING_SET = False
DISTANCE = Distance.ROOT_MEAN_SQUARE
# See [Robust_image_source_identification_on_modern_smartphones/issues/22](https://gitea.lemnoslife.com/Benjamin_Loison/Robust_image_source_identification_on_modern_smartphones/issues/22).
match DISTANCE:
case Distance.ROOT_MEAN_SQUARE:
import sys
sys.path.insert(0, '../../algorithms/distance/')
from rms_diff import rmsDiffNumpy
case PEARSON_CORRELATION:
import scipy
from utils import getPearsonCorrelation
setting = ','.join([escapeFilePath(imageCameraFolder) for imageCameraFolder in IMAGES_CAMERAS_FOLDER]) + f'_{DENOISER}'
@ -180,7 +186,11 @@ for computeExtremes in tqdm(([True] if minColor is None or maxColor is None else
multipleColorsImage = getMultipleColorsImage(singleColorChannelImages)
cameraTestingImageNoise = getImagePrnuEstimateNpArray(singleColorChannelImages, multipleColorsImage, camera)
distance = rmsDiffNumpy(cameraTestingImageNoise, camerasIterativeMean[camera].mean)
match DISTANCE:
case ROOT_MEAN_SQUARE:
distance = rmsDiffNumpy(cameraTestingImageNoise, camerasIterativeMean[camera].mean)
case PEARSON_CORRELATION:
distance = getPearsonCorrelation(cameraTestingImagesNoise[actualCamera][cameraTestingImageIndex], camerasIterativeMean[camera].mean)
print(f'{cameraTrainingImageIndex=} {cameraTestingImageIndex=} {camera=} {actualCamera=} {distance=}')
if minimalDistance is None or distance < minimalDistance:
minimalDistance = distance

View File

@ -3,18 +3,24 @@
import numpy as np
import matplotlib.pyplot as plt
from tqdm import tqdm
from utils import denoise, iterativeMean, getColorChannel, escapeFilePath, Color, mergeSingleColorChannelImagesAccordingToBayerFilter, rescaleRawImageForDenoiser, updateExtremes, saveNpArray, Denoiser
import sys
from utils import denoise, iterativeMean, getColorChannel, escapeFilePath, Color, mergeSingleColorChannelImagesAccordingToBayerFilter, rescaleRawImageForDenoiser, updateExtremes, saveNpArray, Denoiser, Distance
import os
import random
sys.path.insert(0, '../../algorithms/distance/')
from rms_diff import rmsDiffNumpy
NUMBER_OF_SUBGROUPS = 2
DENOISER = Denoiser.WAVELET
IMAGES_FOLDER = 'flat-field/NEF'
DISTANCE = Distance.ROOT_MEAN_SQUARE
# See [Robust_image_source_identification_on_modern_smartphones/issues/22](https://gitea.lemnoslife.com/Benjamin_Loison/Robust_image_source_identification_on_modern_smartphones/issues/22).
match DISTANCE:
case Distance.ROOT_MEAN_SQUARE:
import sys
sys.path.insert(0, '../../algorithms/distance/')
from rms_diff import rmsDiffNumpy
case PEARSON_CORRELATION:
import scipy
from utils import getPearsonCorrelation
setting = escapeFilePath(IMAGES_FOLDER) + f'_{DENOISER}'
@ -26,7 +32,7 @@ random.shuffle(imagesFileNames)
numberOfImagesPerSubgroup = len(imagesFileNames) // NUMBER_OF_SUBGROUPS
subgroupsIterativeMean = [iterativeMean() for _ in range(NUMBER_OF_SUBGROUPS)]
rmss = []
distances = []
minColor = None
maxColor = None
@ -55,16 +61,22 @@ for computeExtremes in tqdm(([True] if minColor is None or maxColor is None else
subgroupIterativeMean.add(imagePrnuEstimateNpArray)
if subgroupIndex == NUMBER_OF_SUBGROUPS - 1:
assert NUMBER_OF_SUBGROUPS == 2
rms = rmsDiffNumpy(subgroupIterativeMean.mean, subgroupsIterativeMean[1 - subgroupIndex].mean)
rmss += [rms]
firstImage = subgroupIterativeMean.mean
secondImage = subgroupsIterativeMean[1 - subgroupIndex].mean
match DISTANCE:
case ROOT_MEAN_SQUARE:
distance = rmsDiffNumpy(firstImage, secondImage)
case PEARSON_CORRELATION:
distance = getPearsonCorrelation(firstImage, secondImage)
distances += [distance]
for subgroupIndex in range(NUMBER_OF_SUBGROUPS):
plt.imsave(f'{setting}_estimated_prnu_subgroup_{subgroupIndex}.png', (subgroupsIterativeMean[subgroupIndex].mean))
plt.title(f'RMS between both subgroups estimated PRNUs with {DENOISER} denoiser for a given number of images among them')
plt.title(f'{DISTANCE.getEndUserName()} between both subgroups estimated PRNUs with {DENOISER} denoiser for a given number of images among them')
plt.xlabel('Number of images of each subgroup')
plt.ylabel('RMS between both subgroups estimated PRNUs')
plt.plot(rmss)
saveNpArray(f'{setting}_rmss', rmss)
plt.savefig(f'{setting}_rms_between_estimated_prnu_of_2_subgroups.svg')
plt.ylabel(f'{DISTANCE.getEndUserName()} between both subgroups estimated PRNUs')
plt.plot(distances)
saveNpArray(f'{setting}_{DISTANCE}s', distances)
plt.savefig(f'{setting}_{DISTANCE}_between_estimated_prnu_of_2_subgroups.svg')
#plt.show()

View File

@ -33,6 +33,19 @@ class Denoiser(Enum):
def __str__(self):
return self.name.lower()
class Distance(Enum)
ROOT_MEAN_SQUARE = auto()
PEARSON_CORRELATION = auto()
def __str__(self):
return self.name.lower()
def getEndUserName(self):
return self.name.replace('_', '').title()
def getPearsonCorrelation(firstImage, secondImage):
return abs(scipy.stats.pearsonr(firstImage.flatten(), secondImage.flatten()).statistic - 1)
# Source: https://stackoverflow.com/a/43346070
def getGaussianKernel(size, sigma):
axis = np.linspace(-(size - 1) / 2., (size - 1) / 2., size)