Remove manually in the Fourier domain periodic patterns #70

Open
opened 2024-05-10 01:15:09 +02:00 by Benjamin_Loison · 8 comments

image

Notice dotted horizontal lines on mean_rafael_230424_mean_multiple_colors.png (source: issues/59#issuecomment-1721).

help(fftpack.fft2)
Help on function fft2 in module scipy.fftpack._basic:

fft2(x, shape=None, axes=(-2, -1), overwrite_x=False)
    2-D discrete Fourier transform.
    
    Return the 2-D discrete Fourier transform of the 2-D argument
    `x`.
    
    See Also
    --------
    fftn : for detailed information.
    
    Examples
    --------
    >>> import numpy as np
    >>> from scipy.fftpack import fft2, ifft2
    >>> y = np.mgrid[:5, :5][0]
    >>> y
    array([[0, 0, 0, 0, 0],
           [1, 1, 1, 1, 1],
           [2, 2, 2, 2, 2],
           [3, 3, 3, 3, 3],
           [4, 4, 4, 4, 4]])
    >>> np.allclose(y, ifft2(fft2(y)))
    True
help(fftpack.fftshift)
Help on _ArrayFunctionDispatcher in module numpy.fft:

fftshift(x, axes=None)
    Shift the zero-frequency component to the center of the spectrum.
    
    This function swaps half-spaces for all axes listed (defaults to all).
    Note that ``y[0]`` is the Nyquist component only if ``len(x)`` is even.
    
    Parameters
    ----------
    x : array_like
        Input array.
    axes : int or shape tuple, optional
        Axes over which to shift.  Default is None, which shifts all axes.
    
    Returns
    -------
    y : ndarray
        The shifted array.
    
    See Also
    --------
    ifftshift : The inverse of `fftshift`.
    
    Examples
    --------
    >>> freqs = np.fft.fftfreq(10, 0.1)
    >>> freqs
    array([ 0.,  1.,  2., ..., -3., -2., -1.])
    >>> np.fft.fftshift(freqs)
    array([-5., -4., -3., -2., -1.,  0.,  1.,  2.,  3.,  4.])
    
    Shift the zero-frequency component only along the second axis:
    
    >>> freqs = np.fft.fftfreq(9, d=1./9).reshape(3, 3)
    >>> freqs
    array([[ 0.,  1.,  2.],
           [ 3.,  4., -4.],
           [-3., -2., -1.]])
    >>> np.fft.fftshift(freqs, axes=(1,))
    array([[ 2.,  0.,  1.],
           [-4.,  3.,  4.],
           [-1., -3., -2.]])

where is it otherwise?

Related to #69.

![image](/attachments/dc9136a6-2284-4d22-a33c-af047a00da90) Notice dotted horizontal lines on [mean_rafael_230424_mean_multiple_colors.png](https://gitea.lemnoslife.com/Benjamin_Loison/Robust_image_source_identification_on_modern_smartphones/attachments/73552659-6d11-44de-937c-5714fc5aa3d8) (source: [issues/59#issuecomment-1721](https://gitea.lemnoslife.com/Benjamin_Loison/Robust_image_source_identification_on_modern_smartphones/issues/59#issuecomment-1721)). ```python help(fftpack.fft2) ``` ``` Help on function fft2 in module scipy.fftpack._basic: fft2(x, shape=None, axes=(-2, -1), overwrite_x=False) 2-D discrete Fourier transform. Return the 2-D discrete Fourier transform of the 2-D argument `x`. See Also -------- fftn : for detailed information. Examples -------- >>> import numpy as np >>> from scipy.fftpack import fft2, ifft2 >>> y = np.mgrid[:5, :5][0] >>> y array([[0, 0, 0, 0, 0], [1, 1, 1, 1, 1], [2, 2, 2, 2, 2], [3, 3, 3, 3, 3], [4, 4, 4, 4, 4]]) >>> np.allclose(y, ifft2(fft2(y))) True ``` ```python help(fftpack.fftshift) ``` ``` Help on _ArrayFunctionDispatcher in module numpy.fft: fftshift(x, axes=None) Shift the zero-frequency component to the center of the spectrum. This function swaps half-spaces for all axes listed (defaults to all). Note that ``y[0]`` is the Nyquist component only if ``len(x)`` is even. Parameters ---------- x : array_like Input array. axes : int or shape tuple, optional Axes over which to shift. Default is None, which shifts all axes. Returns ------- y : ndarray The shifted array. See Also -------- ifftshift : The inverse of `fftshift`. Examples -------- >>> freqs = np.fft.fftfreq(10, 0.1) >>> freqs array([ 0., 1., 2., ..., -3., -2., -1.]) >>> np.fft.fftshift(freqs) array([-5., -4., -3., -2., -1., 0., 1., 2., 3., 4.]) Shift the zero-frequency component only along the second axis: >>> freqs = np.fft.fftfreq(9, d=1./9).reshape(3, 3) >>> freqs array([[ 0., 1., 2.], [ 3., 4., -4.], [-3., -2., -1.]]) >>> np.fft.fftshift(freqs, axes=(1,)) array([[ 2., 0., 1.], [-4., 3., 4.], [-1., -3., -2.]]) ``` where is it otherwise? Related to #69.
293 KiB
Benjamin_Loison added the
enhancement
medium priority
medium
labels 2024-05-10 01:15:24 +02:00
Author
Owner

ifft1

Why other vertical lines? Around x = 4520 for instance. These lines are precisely at 1/4 and 3/4 of the width.

Why circles also at extremities of axes and corners?

![ifft1](/attachments/7325addc-da2a-4a0c-bc7d-a21d8a22b72d) Why other vertical lines? Around x = 4520 for instance. These lines are precisely at 1/4 and 3/4 of the width. Why circles also at extremities of axes and corners?
Author
Owner

On vertical axis:

image

produces:

ifft2

The very center pixel seems to result in a constant everywhere.

On vertical axis: ![image](/attachments/9972dbf3-4d8d-4aeb-81b2-bef1ec3e42fd) produces: ![ifft2](/attachments/62fa1e78-b6bf-4a1e-b81b-db91abff2554) The very center pixel seems to result in a constant everywhere.
Author
Owner
height, width = fft1.shape
for x in range(width):
    fft1[height // 2, x] = np.median(fft1[:, x])

Figure_1

the median is not correct enough, should inpaint indeed.

Related to Improve_websites_thanks_to_open_source/issues/457.

```python height, width = fft1.shape for x in range(width): fft1[height // 2, x] = np.median(fft1[:, x]) ``` ![Figure_1](/attachments/35fd9381-0047-4f77-99fb-d7ea7127facc) the median is not correct enough, should inpaint indeed. Related to [Improve_websites_thanks_to_open_source/issues/457](https://codeberg.org/Benjamin_Loison/Improve_websites_thanks_to_open_source/issues/457).
Author
Owner

Figure_1

Original FFT:

ifft1

![Figure_1](/attachments/97ff088d-36f7-43fd-8c1a-34eebd1575ce) Original FFT: ![ifft1](/attachments/cab70494-4425-449d-b55f-c5a8400b0527)
Author
Owner

I was about to say that I am surprised that the background of the FFT looks having similar values to everything else but we are in logarithmic scale so the colors differ linearly while the actual values differ logarithmitically. I am still a bit surprised that some parts are not so near 0 such that the color looks far different but maybe it is because the estimated PRNU is not a perfect image, hence the FFT puts significant coefficients everywhere to accurately be equivalent to this not perfect image.

I was about to say that I am surprised that the background of the FFT looks having similar values to everything else but we are in logarithmic scale so the colors differ linearly while the actual values differ logarithmitically. I am still a bit surprised that some parts are not so near 0 such that the color looks far different but maybe it is because the estimated PRNU is not a perfect image, hence the FFT puts significant coefficients everywhere to accurately be equivalent to this not perfect image.
Author
Owner

To summarize based on Google Doc Minutes:

PRNU estimation:

image

PRNU estimation in Fourier domain:

image

PRNU estimation in Fourier domain with attenuated periodic patterns:

image

image

PRNU estimation with attenuated periodic patterns:

image

Difference between both PRNU estimations:

image

It seems that as wanted the periodic patterns were removed:

image

image

To summarize based on Google Doc Minutes: PRNU estimation: ![image](/attachments/1fa272ae-8278-460c-8fa2-5f8bad5f3e34) PRNU estimation in Fourier domain: ![image](/attachments/f3438ea9-2ddd-4f94-8749-a60a33313398) PRNU estimation in Fourier domain with attenuated periodic patterns: ![image](/attachments/fde7ebc5-79f9-4691-8152-aa9b751b0938) ![image](/attachments/2d1a106c-46ca-4a60-8249-b2f1e7f70f04) PRNU estimation with attenuated periodic patterns: ![image](/attachments/8cc4e21e-122f-4cc7-9463-e37ffdf9d1e3) Difference between both PRNU estimations: ![image](/attachments/afd92fab-18e7-4e39-981f-20a43c6f110f) It seems that as wanted the periodic patterns were removed: ![image](/attachments/1d5e80e7-74b2-471d-81bf-c86bbfda6e67) ![image](/attachments/98e4bae4-c668-48e5-9179-5098d409e144)
Author
Owner

Verify with a simple algorithm the pense of dots the earliest in the data pipeline to ensure that it is not an added artifact.

Do removing means of columns and lines, as proposed in Determining Image Origin and Integrity Using
Sensor Noise (by Mo Chen, Jessica Fridrich, Miroslav Goljan, and Jan Lukáš), gives as good results as inpainting axes in the Fourier domain?

Verify with a simple algorithm the pense of dots the earliest in the data pipeline to ensure that it is not an added artifact. Do removing means of columns and lines, as proposed in Determining Image Origin and Integrity Using Sensor Noise (by Mo Chen, Jessica Fridrich, Miroslav Goljan, and Jan Lukáš), gives as good results as inpainting axes in the Fourier domain?
Author
Owner

be83fcf154/datasets/raise/fft/verify_dots.py seems to show randomness...

https://gitea.lemnoslife.com/Benjamin_Loison/Robust_image_source_identification_on_modern_smartphones/src/commit/be83fcf154ba144045e296f2f0e6d0d8deb58ca4/datasets/raise/fft/verify_dots.py seems to show randomness...
Sign in to join this conversation.
No description provided.