Mattral commited on
Commit
2ce4737
·
verified ·
1 Parent(s): 3dbe3cb

Create localRun_NoStramlit.py

Browse files
Files changed (1) hide show
  1. localRun_NoStramlit.py +139 -0
localRun_NoStramlit.py ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import cv2
3
+ import matplotlib.pyplot as plt
4
+ from mpl_toolkits.mplot3d import Axes3D
5
+ import os
6
+ import csv
7
+
8
+ # 1. Function to apply Fast Fourier Transform to a colored image (separate for each channel)
9
+ def apply_fft(image):
10
+ """Apply Fast Fourier Transform to a colored image (separate for each channel)"""
11
+ fft_channels = []
12
+ for channel in cv2.split(image): # Split the image into its color channels (B, G, R)
13
+ fft = np.fft.fft2(channel)
14
+ fft_shifted = np.fft.fftshift(fft) # Shift the zero frequency to the center
15
+ fft_channels.append(fft_shifted)
16
+ return fft_channels
17
+
18
+ # 2. Function to display frequency components of each color channel in interactive 3D plots using Matplotlib
19
+ def show_frequency_components_3d(fft_channels, title='Frequency Components'):
20
+ """Display the magnitude and phase of the FFT for each channel (R, G, B) in 3D with Matplotlib"""
21
+
22
+ channel_names = ['Blue Channel', 'Green Channel', 'Red Channel']
23
+
24
+ # Create a figure for 3D plotting
25
+ fig = plt.figure(figsize=(18, 6))
26
+
27
+ # Loop through each channel's FFT data
28
+ for i, fft_data in enumerate(fft_channels):
29
+ magnitude = np.abs(fft_data) # Magnitude spectrum
30
+ phase = np.angle(fft_data) # Phase spectrum
31
+
32
+ # Generate grid for the 3D plot (x, y grid of frequencies)
33
+ rows, cols = magnitude.shape
34
+ x = np.linspace(-cols // 2, cols // 2, cols)
35
+ y = np.linspace(-rows // 2, rows // 2, rows)
36
+ X, Y = np.meshgrid(x, y)
37
+
38
+ # Create a subplot for each channel's magnitude and phase
39
+ ax = fig.add_subplot(1, 6, 2 * i + 1, projection='3d')
40
+ ax.set_title(f'{channel_names[i]} - Magnitude')
41
+ ax.plot_surface(X, Y, magnitude, cmap='viridis', edgecolor='none')
42
+
43
+ ax = fig.add_subplot(1, 6, 2 * i + 2, projection='3d')
44
+ ax.set_title(f'{channel_names[i]} - Phase')
45
+ ax.plot_surface(X, Y, phase, cmap='inferno', edgecolor='none')
46
+
47
+ plt.suptitle(title, fontsize=16)
48
+ plt.tight_layout()
49
+ plt.show()
50
+
51
+ # 3. Function to apply percentage-based filtering to the FFT (for each channel)
52
+ def filter_fft_percentage(fft_channels, percentage):
53
+ """Apply percentage-based filtering, keeping the highest-magnitude frequency components"""
54
+ filtered_fft = []
55
+ for fft_data in fft_channels:
56
+ magnitude = np.abs(fft_data)
57
+ flat_mag = magnitude.flatten()
58
+ sorted_mag = np.sort(flat_mag)[::-1] # Sort magnitudes in descending order
59
+
60
+ # Determine the threshold for the given percentage
61
+ num_elements_to_keep = int(len(sorted_mag) * percentage / 100)
62
+ threshold = sorted_mag[num_elements_to_keep - 1] if num_elements_to_keep > 0 else 0
63
+
64
+ # Create a mask to keep only the top frequencies
65
+ mask = magnitude >= threshold
66
+ filtered_fft.append(fft_data * mask) # Apply mask to the FFT data
67
+ return filtered_fft
68
+
69
+ # 4. Function to apply inverse Fourier transform to reconstruct the color image
70
+ def inverse_fft(filtered_fft):
71
+ """Apply inverse Fourier transform to reconstruct the image from filtered FFT"""
72
+ reconstructed_channels = []
73
+ for fft_data in filtered_fft:
74
+ fft_ishift = np.fft.ifftshift(fft_data) # Reverse FFT shift
75
+ img_reconstructed = np.fft.ifft2(fft_ishift) # Apply inverse FFT
76
+ img_reconstructed = np.abs(img_reconstructed) # Get the magnitude of the result
77
+
78
+ # Normalize and convert to uint8 for image format
79
+ img_normalized = cv2.normalize(img_reconstructed, None, 0, 255, cv2.NORM_MINMAX)
80
+ reconstructed_channels.append(img_normalized.astype(np.uint8))
81
+
82
+ # Merge the channels back into a color image (BGR format)
83
+ return cv2.merge(reconstructed_channels)
84
+
85
+ # 5. Main function to process images in batches
86
+ def process_images():
87
+ """Main function to process images, apply FFT, and filter results"""
88
+ # Create directories if they don't exist
89
+ os.makedirs('Modified', exist_ok=True)
90
+
91
+ # Ask user for the percentage of top frequencies to keep
92
+ percentage = float(input("Enter the percentage of highest-magnitude frequencies to keep (0-100): "))
93
+ print(f"Applying percentage-based filtering: Keeping top {percentage}% of frequencies.")
94
+
95
+ # Create CSV logging file
96
+ with open('fft_features.csv', 'w', newline='') as csvfile:
97
+ csv_writer = csv.writer(csvfile)
98
+ csv_writer.writerow(['Image', 'Max Magnitude', 'Mean Magnitude', 'Non-zero Count'])
99
+
100
+ # Process each image in the 'original' folder
101
+ image_filenames = [filename for filename in os.listdir('original')
102
+ if filename.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.tiff'))]
103
+
104
+ # Process all images
105
+ for i, filename in enumerate(image_filenames):
106
+ # Read image (colored)
107
+ img_path = os.path.join('original', filename)
108
+ img = cv2.imread(img_path)
109
+
110
+ # Apply FFT to each channel (RGB)
111
+ fft_channels = apply_fft(img)
112
+
113
+ # Apply percentage-based filtering
114
+ filtered_fft = filter_fft_percentage(fft_channels, percentage)
115
+
116
+ # Reconstruct the image using inverse FFT
117
+ reconstructed = inverse_fft(filtered_fft)
118
+
119
+ # Show frequency components (filtered FFT) as interactive 3D plots using Matplotlib
120
+ show_frequency_components_3d(filtered_fft, f'Filtered FFT - {filename}')
121
+
122
+ # Log FFT features for the first channel (R)
123
+ magnitude = np.abs(filtered_fft[0]) # Just checking the first channel's magnitude
124
+ non_zero = magnitude > 0
125
+ csv_writer.writerow([
126
+ filename,
127
+ np.max(magnitude),
128
+ np.mean(magnitude[non_zero]) if np.any(non_zero) else 0,
129
+ np.count_nonzero(non_zero)
130
+ ])
131
+
132
+ # Save reconstructed image
133
+ cv2.imwrite(os.path.join('Modified', filename), reconstructed)
134
+
135
+ print("Processing completed successfully!")
136
+
137
+ # Run the main function
138
+ if __name__ == "__main__":
139
+ process_images()