commit 9187b1554ae5844e35f8cc9b7502dfd4c52f1de1 Author: Daniel Dolezal Date: Tue May 27 08:52:17 2025 +0200 init commit, add code diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..640ee4c --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.venv/ +fft_parts/ + +*.jpeg +*.png +*.jpg diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..a6d541d --- /dev/null +++ b/requirements.txt @@ -0,0 +1,13 @@ +contourpy==1.3.2 +cycler==0.12.1 +fonttools==4.58.0 +kiwisolver==1.4.8 +matplotlib==3.10.3 +numpy==2.2.6 +packaging==25.0 +pillow==11.2.1 +pip-autoremove==0.10.0 +pyparsing==3.2.3 +python-dateutil==2.9.0.post0 +setuptools==80.8.0 +six==1.17.0 diff --git a/run.py b/run.py new file mode 100644 index 0000000..7ddb615 --- /dev/null +++ b/run.py @@ -0,0 +1,104 @@ +import numpy as np +import cv2 +import matplotlib.pyplot as plt +import os +import gzip + +def split_fft(image): + fshift_channels = [] + magnitude_spectrums = [] + for i in range(3): # Process B, G, R channels separately + channel = image[:, :, i] + f = np.fft.fft2(channel) + fshift = np.fft.fftshift(f) + magnitude_spectrum = 20 * np.log(np.abs(fshift) + 1) + fshift_channels.append(fshift) + magnitude_spectrums.append(magnitude_spectrum) + return fshift_channels, magnitude_spectrums + +def save_fft_parts_compressed(path_prefix, fshift_channels): + for i, fshift in enumerate(fshift_channels): + file_path = f"{path_prefix}_channel_{i}.npz.gz" + with gzip.GzipFile(file_path, 'w') as f: + np.save(f, fshift) + print(f"Saved compressed FFT part: {file_path}") + +def save_magnitude_spectrums_as_images(path_prefix, magnitude_spectrums): + for i, mag in enumerate(magnitude_spectrums): + normalized = cv2.normalize(mag, None, 0, 255, cv2.NORM_MINMAX) + img = normalized.astype(np.uint8) + file_path = f"{path_prefix}_magnitude_{i}.png" + cv2.imwrite(file_path, img) + print(f"Saved magnitude spectrum image: {file_path}") + +def load_fft_parts_compressed(path_prefix): + fshift_channels = [] + for i in range(3): + file_path = f"{path_prefix}_channel_{i}.npz.gz" + with gzip.GzipFile(file_path, 'r') as f: + part = np.load(f) + fshift_channels.append(part) + print(f"Loaded compressed FFT part: {file_path}") + return fshift_channels + +def merge_fft(fshift_channels): + reconstructed_channels = [] + for fshift in fshift_channels: + f_ishift = np.fft.ifftshift(fshift) + img_back = np.fft.ifft2(f_ishift) + img_back = np.abs(img_back) + img_back = np.clip(img_back, 0, 255).astype(np.uint8) + reconstructed_channels.append(img_back) + reconstructed_image = cv2.merge(reconstructed_channels) + return reconstructed_image + +def load_image(path): + if not os.path.exists(path): + raise FileNotFoundError(f"Image file '{path}' not found") + image = cv2.imread(path) + if image is None: + raise ValueError(f"Failed to load image from '{path}'") + return image + +def plot_images(original=None, magnitude_spectrums=None, reconstructed=None): + if original.any(): + plt.figure(figsize=(12, 6)) + plt.subplot(1, 3, 1) + plt.imshow(cv2.cvtColor(original, cv2.COLOR_BGR2RGB)) + plt.title('Original Image') + plt.axis('off') + + if magnitude_spectrums: + plt.subplot(1, 3, 2) + combined_mag = np.stack(magnitude_spectrums, axis=2) + combined_mag = np.clip(combined_mag / np.max(combined_mag), 0, 1) + plt.imshow(combined_mag) + plt.title('Magnitude Spectrum (BGR)') + plt.axis('off') + + if reconstructed.any(): + plt.subplot(1, 3, 3) + plt.imshow(cv2.cvtColor(reconstructed, cv2.COLOR_BGR2RGB)) + plt.title('Reconstructed Image') + plt.axis('off') + + plt.show() + +def main(image_path, fft_prefix): + image = load_image(image_path) + fshift_channels, magnitude_spectrums = split_fft(image) + save_fft_parts_compressed(fft_prefix, fshift_channels) + save_magnitude_spectrums_as_images(fft_prefix, magnitude_spectrums) + + # To test loading and reconstructing: + loaded_fshift_channels = load_fft_parts_compressed(fft_prefix) + reconstructed_image = merge_fft(loaded_fshift_channels) + + plot_images(image, magnitude_spectrums, reconstructed_image) + #plot_images(None, None, reconstructed_image) + +if __name__ == "__main__": + input_image_path = 'your_image.jpg' # Replace with your image path + fft_parts_prefix = 'fft_parts/your_image' # Directory + prefix for saving FFT parts + os.makedirs(os.path.dirname(fft_parts_prefix), exist_ok=True) + main(input_image_path, fft_parts_prefix)