Spaces:
Sleeping
Sleeping
File size: 3,728 Bytes
fc8df74 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | """
Please read the copyright notice located on the readme file (README.md).
"""
import utils.src.Functions as Fu
import cv2 as cv
import numpy as np
def getFingerprint(Images, sigma=3., fromHowMany=-1):
"""
Extracts and averages noise from all images and outputs a camera
fingerprint
Parameters
----------
Images : list
List of color images to process. They have to be from the same camera
and the same size and orientation.
sigma : float32
Standard deviation of the expected noise (PRNU)
Returns
-------
numpy.ndarray('float32')
3D matrix of reference pattern - estimate of PRNU (in the output file)
dict
Dictionary of Linear Pattern data
-------------------------------------------------------------------------
[1] M. Goljan, T. Filler, and J. Fridrich. Large Scale Test of Sensor
Fingerprint Camera Identification. In N.D. Memon and E.J. Delp and P.W.
Wong and J. Dittmann, editors, Proc. of SPIE, Electronic Imaging, Media
Forensics and Security XI, volume 7254, pages % 0I010I12, January 2009.
-------------------------------------------------------------------------
"""
database_size = Images.__len__() if fromHowMany==-1 else fromHowMany; del fromHowMany # Number of the images
if database_size==0: raise ValueError('No images of specified type in the directory.')
### Parameters used in denoising filter
L = 4 # number of decomposition levels
qmf = [ .230377813309, .714846570553, .630880767930, -.027983769417,
-.187034811719, .030841381836, .032883011667, -.010597401785]
qmf /= np.linalg.norm(qmf)
t = 0
ImagesinRP = []
for i in range(database_size):
Fu.SeeProgress(i),
im = Images[i]
X = cv.imread(im);
if np.ndim(X)==3: X = X[:,:,::-1] # BGR to RGB
X = _double255(X)
if t == 0:
M,N,three=X.shape
if three == 1:
continue # only color images will be processed
### Initialize sums
RPsum = np.zeros([M,N,3],dtype='single')
NN = np.zeros([M,N,3],dtype='single') # number of additions to each pixel for RPsum
else:
s = X.shape
if X.ndim != 3:
print('Not a color image - skipped.\n')
continue # only color images will be used
if set([M,N,three]) != set(X.shape):
print('\n Skipping image %(im)s of size %(s1)d x %(s2)d x %(s3)d \n' %{'im':im,'s1':s(1-1),'s2':s(2-1),'s3':s(3-1)})
continue # only same size images will be used
# The image will be the t-th image used for the reference pattern RP
t=t+1 # counter of used images
ImagesinRP.append(im)
for j in range(3):
ImNoise = np.single(Fu.NoiseExtract(X[:,:,j],qmf,sigma,L))
Inten = np.multiply(Fu.IntenScale(X[:,:,j]),\
Fu.Saturation(X[:,:,j])) # zeros for saturated pixels
RPsum[:,:,j] = RPsum[:,:,j] + np.multiply(ImNoise,Inten) # weighted average of ImNoise (weighted by Inten)
NN[:,:,j] = NN[:,:,j] + np.power(Inten,2)
del ImNoise, Inten, X
if t==0: raise ValueError('None of the images was color image in landscape orientation.')
RP = np.divide(RPsum, NN + 1)
# Remove linear pattern and keep its parameters
RP, LP = Fu.ZeroMeanTotal(RP)
return RP, LP, ImagesinRP
### FUNCTIONS ##
def _double255(X):
# In MATLAB: convert to 'double' ranging from 0 to 255
# Here in this Python implementation we convert it to 'single' (np.float32)
X = X.astype(np.single)
return X
|