Image resampling replicates and folds original frequencies in the Fourier domain. This creates replicated patterns in the Fourier spectrum in a resampled image. For example, the image below is upsampled from 512 x 512 to 666 x 666. Its spectrum after residual extraction (on the right) shows similar patterns in two local patches separated by 154 = 666 - 512 frequencies along the vertical direction.
A non-parametric statistical a contrario framework is thus proposed to detect such correlations with control of number of false alarms (NFA). Below is the detection result on the above resampled image, where the NFA values at distances 154 and 512 are significantly low. This indicates a strong evidence of resampling.
The proposed method is suitable for identifying images resampled with different anti-aliasing filters, scaling factors, classical linear interpolators, and AI-based nonlinear interpolators, and with post-compression at different levels.
Tested python versions: 3.10.19 (conda) and 3.10.13 (uv)
Use conda to create a virtual environment:
conda create -n ird python=3.10.19
conda activate ird
pip install -r requirements.txtOr use uv to create a virtual environment:
uv venv .venv --python python3.10.13
source .venv/bin/activate
uv pip install -r requirements.txtCompile the TV denoiser in src/filters/CDS_ChambolleTV:
cd src/filters/CDS_ChambolleTV
makeUsage:
detect_one_image.py [-h] [--direction {h,v,both}] [--preproc {rt,tv,dct,phot,none}] [--is_jpeg] [--crop x y w h] [--out_folder OUT_FOLDER] IMAGE_PATHwhere:
direction: Direction for resampling detection.hfor horizontal,vfor vertical, andbothfor both directions.preproc: Preprocessing method:rt: rank transformtv: total variation denoisingdct: DCT denoisingphot: phase-only transformnone: no preprocessing
is_jpeg: Whether the input image is a JPEG compressed image. Applying this flag will suppress the spurious peaks left by JPEG compression.crop: Crop the image to the rectangle defined by (x, y, w, h).out_folder: Folder to save results. By default, results will be saved in theresults/folder.
Examples on PNG images:
# Process detection on an original PNG image without resampling
python detect_one_image.py img/baboon.png --direction h --preproc rt
# Process detection on a PNG image which was upsampled from 512x512 to 666x666
python detect_one_image.py img/baboon_666.png --direction h --preproc rtExamples on JPEG images (--is_jpeg must be flagged):
# Process detection on an original JPEG without resampling
python detect_one_image.py img/pashmina.jpg --is_jpeg --direction h --preproc tv
# Process detection on a JPEG image which was downsampled from 800x800 to 720x720
python detect_one_image.py img/pashmina_720.jpg --is_jpeg --direction h --preproc tv Detection results will be saved in the results/ folder by default.
For uncompressed images, it is recommended to use the rank transform (rt). For JPEG compressed images, using the total variation denoising (tv) as preprocessing filter usually gives slightly better performance.

