83 lines
4.0 KiB
Python
Executable File
83 lines
4.0 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
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, Distance
|
|
import os
|
|
import random
|
|
|
|
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 getPearsonCorrelationDistance
|
|
|
|
setting = escapeFilePath(IMAGES_FOLDER) + f'_{DENOISER}'
|
|
|
|
imagesFileNames = os.listdir(IMAGES_FOLDER)
|
|
random.seed(0)
|
|
# To not have a bias (chronological for instance) when split to make subgroups.
|
|
random.shuffle(imagesFileNames)
|
|
|
|
numberOfImagesPerSubgroup = len(imagesFileNames) // NUMBER_OF_SUBGROUPS
|
|
|
|
subgroupsIterativeMean = [iterativeMean() for _ in range(NUMBER_OF_SUBGROUPS)]
|
|
distances = []
|
|
|
|
minColor = None
|
|
maxColor = None
|
|
|
|
returnSingleColorChannelImage = lambda singleColorChannelImage, _minColor, _maxColor: singleColorChannelImage
|
|
|
|
for computeExtremes in tqdm(([True] if minColor is None or maxColor is None else []) + [False], 'Compute extremes'):
|
|
rescaleIfNeeded = returnSingleColorChannelImage if computeExtremes else rescaleRawImageForDenoiser
|
|
for subgroupImageIndex in tqdm(range(numberOfImagesPerSubgroup), 'Subgroup image index'):
|
|
for subgroupIndex in tqdm(range(NUMBER_OF_SUBGROUPS), 'Subgroup'):
|
|
imageIndex = (subgroupIndex * NUMBER_OF_SUBGROUPS) + subgroupImageIndex
|
|
imageFileName = imagesFileNames[imageIndex]
|
|
imageFilePath = f'{IMAGES_FOLDER}/{imageFileName}'
|
|
singleColorChannelImages = {color: rescaleIfNeeded(getColorChannel(imageFilePath, color), minColor, maxColor) for color in Color}
|
|
multipleColorsImage = mergeSingleColorChannelImagesAccordingToBayerFilter(singleColorChannelImages)
|
|
|
|
if computeExtremes:
|
|
minColor, maxColor = updateExtremes(multipleColorsImage, minColor, maxColor)
|
|
continue
|
|
|
|
singleColorChannelDenoisedImages = {color: denoise(singleColorChannelImages[color], DENOISER) for color in Color}
|
|
multipleColorsDenoisedImage = mergeSingleColorChannelImagesAccordingToBayerFilter(singleColorChannelDenoisedImages)
|
|
|
|
imagePrnuEstimateNpArray = multipleColorsImage - multipleColorsDenoisedImage
|
|
subgroupIterativeMean = subgroupsIterativeMean[subgroupIndex]
|
|
subgroupIterativeMean.add(imagePrnuEstimateNpArray)
|
|
if subgroupIndex == NUMBER_OF_SUBGROUPS - 1:
|
|
assert NUMBER_OF_SUBGROUPS == 2
|
|
firstImage = subgroupIterativeMean.mean
|
|
secondImage = subgroupsIterativeMean[1 - subgroupIndex].mean
|
|
match DISTANCE:
|
|
case ROOT_MEAN_SQUARE:
|
|
distance = rmsDiffNumpy(firstImage, secondImage)
|
|
case PEARSON_CORRELATION:
|
|
distance = getPearsonCorrelationDistance(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'{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(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()
|