TuringsSolutions commited on
Commit
83b86f7
Β·
verified Β·
1 Parent(s): 4e9e766

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +107 -33
app.py CHANGED
@@ -1,9 +1,11 @@
1
  import gradio as gr
2
  import os, math, tempfile
3
  import numpy as np
4
- from PIL import Image
5
 
6
- # --- FLC v1.3 Logic Engine (The "Secret Sauce") ---
 
 
7
  PHI = (1.0 + 5.0**0.5) / 2.0
8
 
9
  def fibonacci_sequence(n):
@@ -46,7 +48,9 @@ def idct_ortho_1d(X):
46
  V[N+1:] = np.conj(c[1:][::-1])
47
  return np.fft.ifft(V).real[:N]
48
 
 
49
  def hologram_spectrum_image(zints):
 
50
  z = zints[:262144]; v = np.tanh(z / 32.0)
51
  theta = (2 * math.pi / (PHI**2)) * np.arange(v.size) + 2.0 * math.pi * (v * 0.25)
52
  r = 1.0 + 0.35 * np.abs(v)
@@ -58,6 +62,7 @@ def hologram_spectrum_image(zints):
58
  return (mag * 255).astype(np.uint8)
59
 
60
  def bytes_to_fib_spiral_image(data):
 
61
  arr = np.frombuffer(data, dtype=np.uint8)[:262144]
62
  fibs = [1, 1]
63
  while sum(s*s for s in fibs) < arr.size: fibs.append(fibs[-1] + fibs[-2])
@@ -80,72 +85,141 @@ def bytes_to_fib_spiral_image(data):
80
  idx += take
81
  return img
82
 
83
- # --- Main Demo Logic ---
84
- def run_demo(input_file, fidelity):
85
- with open(input_file.name, "rb") as f:
86
- raw_data = f.read()
 
 
 
 
87
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  orig_size = len(raw_data)
89
- q_settings = {"High Compression": 6, "Balanced": 12, "Near-Lossless": 24}
 
 
90
  n_bands = q_settings[fidelity]
91
- step = 0.08 if fidelity == "High Compression" else (0.005 if fidelity == "Balanced" else 0.0001)
 
92
 
93
- # Process Data
 
94
  x = (np.frombuffer(raw_data, dtype=np.uint8).astype(float) - 127.5) / 127.5
95
  block_len = 1024
96
- X = np.pad(x, (0, (-x.size) % block_len)).reshape(-1, block_len)
 
97
 
 
98
  C = np.array([dct_ortho_1d(b) for b in X])
 
99
  bnds = fibonacci_frequency_boundaries(block_len, n_bands)
 
100
  Q = np.zeros_like(C, dtype=np.int32)
101
  for bi in range(len(bnds)-1):
102
  Q[:, bnds[bi]:bnds[bi+1]] = np.round(C[:, bnds[bi]:bnds[bi+1]] / (step * (PHI**bi)))
103
 
104
- # Estimate Compressed size (Simulated)
105
- # Using 1.2 as a conservative overhead for Fibonacci entropy coding
106
- compressed_size = int(np.count_nonzero(Q) * 1.2)
107
- ratio = compressed_size / orig_size
108
 
109
- # Generate Progressive Reconstruction GIF
110
  frames = []
 
 
 
111
  for t in range(1, n_bands + 1):
 
112
  Q_p = np.zeros_like(Q)
113
  for bi in range(t): Q_p[:, bnds[bi]:bnds[bi+1]] = Q[:, bnds[bi]:bnds[bi+1]]
 
 
114
  C_p = np.zeros_like(Q_p, dtype=float)
115
  for bi in range(len(bnds)-1):
116
  C_p[:, bnds[bi]:bnds[bi+1]] = Q_p[:, bnds[bi]:bnds[bi+1]] * (step * (PHI**bi))
117
 
118
- recon = np.clip((np.array([idct_ortho_1d(B) for B in C_p]).flatten()[:orig_size] * 127.5) + 127.5, 0, 255).astype(np.uint8)
 
119
 
120
- h_img = Image.fromarray(hologram_spectrum_image(Q_p.flatten())).resize((256, 256))
121
- s_img = Image.fromarray(bytes_to_fib_spiral_image(recon.tobytes())).resize((256, 256))
 
 
 
 
122
 
 
123
  frame = Image.new("RGB", (512, 280), (15, 15, 25))
124
  frame.paste(h_img, (0, 12)); frame.paste(s_img, (256, 12))
125
  frames.append(frame)
126
 
 
127
  gif_path = tempfile.mktemp(suffix=".gif")
128
- frames[0].save(gif_path, save_all=True, append_images=frames[1:], duration=150, loop=0)
129
 
130
- stats = f"Original: {orig_size} bytes\nCompressed: ~{compressed_size} bytes\nRatio: {ratio:.2%}"
131
- return gif_path, stats
 
 
 
 
 
 
 
 
 
 
 
 
132
 
133
- # --- Gradio UI Layout ---
134
- with gr.Blocks(title="FLC v1.3 | Unified Fibonacci Demo") as demo:
 
 
 
135
  gr.Markdown("# πŸŒ€ Fibonacci Lattice Compression (FLC)")
136
- gr.Markdown("Transforming binary data into spectral holograms using the Golden Ratio.")
137
 
138
  with gr.Row():
139
- with gr.Column():
140
- file_input = gr.File(label="Upload File (Image/Data)")
141
- radio_input = gr.Radio(["High Compression", "Balanced", "Near-Lossless"], value="Balanced", label="Fidelity Tier")
142
- run_btn = gr.Button("πŸš€ Execute Holographic Unzip")
143
-
144
- with gr.Column():
145
- gif_output = gr.Image(label="Progressive Reconstruction Sequence")
146
- stats_output = gr.Textbox(label="Compression Metrics", interactive=False)
 
 
 
 
 
 
 
 
 
 
 
 
147
 
148
- run_btn.click(fn=run_demo, inputs=[file_input, radio_input], outputs=[gif_output, stats_output])
 
 
 
 
 
149
 
150
  if __name__ == "__main__":
151
  demo.launch()
 
1
  import gradio as gr
2
  import os, math, tempfile
3
  import numpy as np
4
+ from PIL import Image, UnidentifiedImageError
5
 
6
+ # ==========================================
7
+ # FLC v1.3 Logic Engine (The "Secret Sauce")
8
+ # ==========================================
9
  PHI = (1.0 + 5.0**0.5) / 2.0
10
 
11
  def fibonacci_sequence(n):
 
48
  V[N+1:] = np.conj(c[1:][::-1])
49
  return np.fft.ifft(V).real[:N]
50
 
51
+ # --- Visualization Helpers ---
52
  def hologram_spectrum_image(zints):
53
+ # Visualizes the frequency domain data as a 2D spectrum
54
  z = zints[:262144]; v = np.tanh(z / 32.0)
55
  theta = (2 * math.pi / (PHI**2)) * np.arange(v.size) + 2.0 * math.pi * (v * 0.25)
56
  r = 1.0 + 0.35 * np.abs(v)
 
62
  return (mag * 255).astype(np.uint8)
63
 
64
  def bytes_to_fib_spiral_image(data):
65
+ # Visualizes linear data arranged on a Fibonacci spiral tiling
66
  arr = np.frombuffer(data, dtype=np.uint8)[:262144]
67
  fibs = [1, 1]
68
  while sum(s*s for s in fibs) < arr.size: fibs.append(fibs[-1] + fibs[-2])
 
85
  idx += take
86
  return img
87
 
88
+ # ==========================================
89
+ # Main Processing Logic
90
+ # ==========================================
91
+ def run_demo(input_file_wrapper, fidelity):
92
+ # Determine input type and prepare data
93
+ is_image = False
94
+ orig_pil = None
95
+ img_dims = None
96
 
97
+ try:
98
+ # Try opening as an image
99
+ orig_pil = Image.open(input_file_wrapper.name).convert('L') # Convert to grayscale for core engine
100
+ # Resize large images for demo performance constraint
101
+ orig_pil.thumbnail((512, 512))
102
+ img_dims = orig_pil.size # (width, height)
103
+ raw_data = np.array(orig_pil).tobytes()
104
+ is_image = True
105
+ except (UnidentifiedImageError, OSError):
106
+ # Fallback for non-image binary data
107
+ with open(input_file_wrapper.name, "rb") as f:
108
+ raw_data = f.read()
109
+
110
  orig_size = len(raw_data)
111
+
112
+ # FLC Parameters based on user selection
113
+ q_settings = {"High Compression (Lossy)": 6, "Balanced": 12, "Near-Lossless": 24}
114
  n_bands = q_settings[fidelity]
115
+ # Aggressive steps for lower tiers to show visual difference
116
+ step = 0.15 if fidelity == "High Compression (Lossy)" else (0.01 if fidelity == "Balanced" else 0.0001)
117
 
118
+ # --- Step 1: Transform & Quantize (Compression Simulation) ---
119
+ # Normalize data to range [-1, 1]
120
  x = (np.frombuffer(raw_data, dtype=np.uint8).astype(float) - 127.5) / 127.5
121
  block_len = 1024
122
+ pad_len = (-x.size) % block_len
123
+ X = np.pad(x, (0, pad_len)).reshape(-1, block_len)
124
 
125
+ # Forward DCT
126
  C = np.array([dct_ortho_1d(b) for b in X])
127
+ # Determine Fibonacci bands
128
  bnds = fibonacci_frequency_boundaries(block_len, n_bands)
129
+ # Quantize using Phi-scaling
130
  Q = np.zeros_like(C, dtype=np.int32)
131
  for bi in range(len(bnds)-1):
132
  Q[:, bnds[bi]:bnds[bi+1]] = np.round(C[:, bnds[bi]:bnds[bi+1]] / (step * (PHI**bi)))
133
 
134
+ # Simulated compressed size estimate (entropy estimate)
135
+ compressed_size_est = int(np.count_nonzero(Q) * 1.5) + 512 # base overhead
136
+ ratio = compressed_size_est / orig_size
 
137
 
138
+ # --- Step 2: Progressive Reconstruction (Animation) ---
139
  frames = []
140
+ final_recon_data = None
141
+
142
+ # Iterate through bands to create progressive frames
143
  for t in range(1, n_bands + 1):
144
+ # Partial quantization buffer
145
  Q_p = np.zeros_like(Q)
146
  for bi in range(t): Q_p[:, bnds[bi]:bnds[bi+1]] = Q[:, bnds[bi]:bnds[bi+1]]
147
+
148
+ # Dequantize back to coefficients
149
  C_p = np.zeros_like(Q_p, dtype=float)
150
  for bi in range(len(bnds)-1):
151
  C_p[:, bnds[bi]:bnds[bi+1]] = Q_p[:, bnds[bi]:bnds[bi+1]] * (step * (PHI**bi))
152
 
153
+ # Inverse DCT and denormalize
154
+ recon_1d = np.clip((np.array([idct_ortho_1d(B) for B in C_p]).flatten()[:orig_size] * 127.5) + 127.5, 0, 255).astype(np.uint8)
155
 
156
+ if t == n_bands:
157
+ final_recon_data = recon_1d
158
+
159
+ # Create visualization frames
160
+ h_img = Image.fromarray(hologram_spectrum_image(Q_p.flatten())).resize((256, 256)).convert("RGB")
161
+ s_img = Image.fromarray(bytes_to_fib_spiral_image(recon_1d.tobytes())).resize((256, 256)).convert("RGB")
162
 
163
+ # Combine into one frame
164
  frame = Image.new("RGB", (512, 280), (15, 15, 25))
165
  frame.paste(h_img, (0, 12)); frame.paste(s_img, (256, 12))
166
  frames.append(frame)
167
 
168
+ # Save animation
169
  gif_path = tempfile.mktemp(suffix=".gif")
170
+ frames[0].save(gif_path, save_all=True, append_images=frames[1:], duration=120, loop=0)
171
 
172
+ stats = f"Original Size: {orig_size:,} bytes\nSimulated Compressed Size: ~{compressed_size_est:,} bytes\ncompression Ratio: {ratio:.2%}"
173
+
174
+ # --- Step 3: Prepare Final Comparison Images ---
175
+ recon_pil = None
176
+ if is_image and final_recon_data is not None:
177
+ # Reshape 1D reconstructed data back to 2D image dimensions
178
+ recon_pil = Image.fromarray(final_recon_data.reshape((img_dims[1], img_dims[0])))
179
+
180
+ # Return results based on input type
181
+ if is_image:
182
+ return gif_path, stats, orig_pil, recon_pil
183
+ else:
184
+ # If not an image, return None for image image components so they don't display weirdly
185
+ return gif_path, stats, None, None
186
 
187
+
188
+ # ==========================================
189
+ # Gradio UI Layout
190
+ # ==========================================
191
+ with gr.Blocks(title="FLC v1.3 | Unified Fibonacci Demo", theme=gr.themes.Soft(primary_hue="amber", neutral_hue="slate")) as demo:
192
  gr.Markdown("# πŸŒ€ Fibonacci Lattice Compression (FLC)")
193
+ gr.Markdown("Upload an image to see the **Golden Ratio** compress data and reconstruct it progressively.")
194
 
195
  with gr.Row():
196
+ with gr.Column(scale=1):
197
+ with gr.Group():
198
+ file_input = gr.File(label="1. Upload Input (Image recommended)", file_count="single")
199
+ radio_input = gr.Radio(["High Compression (Lossy)", "Balanced", "Near-Lossless"], value="Balanced", label="2. Select Fidelity Tier")
200
+ run_btn = gr.Button("πŸš€ Run Holographic Compression", variant="primary")
201
+
202
+ stats_output = gr.Textbox(label="Compression Metrics", interactive=False, lines=4)
203
+
204
+ with gr.Column(scale=2):
205
+ gr.Markdown("### 🎞️ Progressive Reconstruction Animation")
206
+ gr.Markdown("_Left: Frequency Hologram filling up. Right: Data organizing into Fibonacci Spiral._")
207
+ gif_output = gr.Image(label="Animation Sequence", show_label=False)
208
+
209
+ gr.Markdown("---")
210
+ gr.Markdown("### πŸ” Visual Verification: Original vs. Reconstructed")
211
+ gr.Markdown("_Determine if the 'Secret Sauce' maintained enough quality at the chosen compression tier._")
212
+
213
+ with gr.Row():
214
+ orig_image_output = gr.Image(label="Original Input (Grayscale)", type="pil", interactive=False)
215
+ recon_image_output = gr.Image(label="Final Decompressed Result", type="pil", interactive=False)
216
 
217
+ # Define the action
218
+ run_btn.click(
219
+ fn=run_demo,
220
+ inputs=[file_input, radio_input],
221
+ outputs=[gif_output, stats_output, orig_image_output, recon_image_output]
222
+ )
223
 
224
  if __name__ == "__main__":
225
  demo.launch()