Code » History » Revision 7
Revision 6 (VALECHA Bharat, 01/07/2026 08:57 PM) → Revision 7/9 (VALECHA Bharat, 01/07/2026 09:10 PM)
[[Wiki|Home]] | [[Project Details|Project Details]] | [[Group Members|Group Members]] | [[UML Diagrams|UML Diagrams]] | [[Weekly Progress|Weekly Progress]] | **[[Code|Code]]** | [[Results|Results]] --- > h1. Code *config_reader.py* <pre><code class="python"> #!/usr/bin/env python # -*- coding: utf-8 -*- # ˅ import json import os # ˄ class ConfigReader(object): # ˅ CONFIG_FILENAME = "config.json" # ˄ def __init__(self): self.__config = {} # ˅ self._load_config() # ˄ # ˅ def _load_config(self): """Loads the configuration from the JSON file.""" if not os.path.exists(self.CONFIG_FILENAME): print(f"Warning: {self.CONFIG_FILENAME} not found. Using defaults.") return with open(self.CONFIG_FILENAME, 'r') as f: self.__config = json.load(f) # ˄ def getProjectedImageWidth(self): # ˅ # The physical width of the image projected by ONE projector return float(self.__config.get("projected_image_width", 0)) # ˄ def getDistanceBetweenProjectors(self): # ˅ # The physical distance between the lenses of the two projectors return float(self.__config.get("distance_between_projectors", 0)) # ˄ def getImageWidth(self): # ˅ # The pixel width of the source image file return int(self.__config.get("image_width", 1920)) # ˄ def getImageHeight(self): # ˅ # The pixel height of the source image file return int(self.__config.get("image_height", 1080)) # ˄ def getImageName(self): # ˅ return self.__config.get("image_name", "") # ˄ def getSide(self): # ˅ # 'left' or 'right' return self.__config.get("side", "left").lower() # ˄ def getGamma(self): # ˅ # Usually 2.2 for standard displays return float(self.__config.get("gamma", 2.2)) # ˄ </code></pre> *config.json* <pre><code class="python"> { "image_name": "right.jpg", "image_width": 1920, "image_height": 1080, "projected_image_width": 200, "distance_between_projectors": 150, "gamma": 3, "side": "right" } </code></pre> *graph_gen _IND.py* <pre><code class="python"> import numpy as np import matplotlib.pyplot as plt def generate_individual_graphs(): # Input gradient (0 to 1) x = np.linspace(0, 1, 500) # The three specified Gamma values gamma_values = [0.5, 3, 50] for gamma in gamma_values: plt.figure(figsize=(8, 6)) # 1. Reference Line (Linear - No Correction) # This is the 'Reference Curve'. It shows the output without blending/correction. plt.plot(x, x, 'k--', label='Linear Reference (No Correction)', alpha=0.5) # 2. Gamma Correction Curve # Logic: y = x^(1/gamma) y = np.power(x, 1.0 / gamma) # Plotting the curve plt.plot(x, y, color='blue', linewidth=3, label=f'Gamma Correction (γ={gamma})') # Decoration plt.title(f'Gamma Correction Curve: γ = {gamma}', fontsize=14) plt.xlabel('Input Pixel Intensity (0 to 1)', fontsize=12) plt.ylabel('Corrected Output Intensity', fontsize=12) plt.legend(loc='best') plt.grid(True, alpha=0.3) plt.xlim(0, 1.0) plt.ylim(0, 1.05) # Saving separate files for each gamma filename = f"gamma_curve_{gamma}.png" plt.savefig(filename) print(f"Generated graph: {filename}") # Close plot to start fresh for next gamma plt.close() if __name__ == "__main__": generate_individual_graphs() </code></pre> *graph_gen.py* <pre><code class="python"> import numpy as np import matplotlib.pyplot as plt def plot_gamma_curves(): # Generate input gradient values from 0 to 1 x = np.linspace(0, 1, 500) # Defined gamma values for comparison gamma_values = [0.5, 3, 50] plt.figure(figsize=(10, 6)) # Reference Line (Linear - No Correction) plt.plot(x, x, 'k--', label='Linear (No Correction)', alpha=0.5) # Blending logic: y = x^(1/gamma) for gamma in gamma_values: # Formula derived from the provided code y = np.power(x, 1.0 / gamma) # Plotting plt.plot(x, y, linewidth=2.5, label=f'Gamma = {gamma} (Exp: 1/{gamma} ≈ {1.0 / gamma:.2f})') # Graph Formatting plt.title('Gamma Correction Curves Comparison', fontsize=14) plt.xlabel('Input Value (Gradient 0 to 1)', fontsize=12) plt.ylabel('Corrected Output Value', fontsize=12) plt.legend() plt.grid(True, alpha=0.3) plt.ylim(0, 1.05) plt.xlim(0, 1.0) # Save chart output_filename = 'gamma_comparison_graph.png' plt.savefig(output_filename) print(f"Graph successfully saved as: {output_filename}") plt.show() if __name__ == "__main__": plot_gamma_curves() </code></pre> *main_alpha_blender.py* <pre><code class="python"> #!/usr/bin/env python # -*- coding: utf-8 -*- # ˅ import cv2 import numpy as np from config_reader import ConfigReader # ˄ class MainAlphaBlender(object): # ˅ # ˄ def __init__(self): self.__configReader = None # ˅ self.__configReader = ConfigReader() # ˄ # ˅ def run(self): print("--- Starting Alpha Blend Process (Gamma Corrected) ---") # 1. Get Configuration image_name = self.__configReader.getImageName() side = self.__configReader.getSide() proj_width_phys = self.__configReader.getProjectedImageWidth() dist_phys = self.__configReader.getDistanceBetweenProjectors() gamma = self.__configReader.getGamma() # 2. Load Image img = cv2.imread(image_name, cv2.IMREAD_UNCHANGED) if img is None: print(f"Error: Could not load image '{image_name}'") return # Ensure image is BGRA if img.shape[2] == 3: img = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA) height, width = img.shape[:2] # 3. Calculate Overlap if proj_width_phys > 0: overlap_ratio = 1.0 - (dist_phys / proj_width_phys) else: overlap_ratio = 0.0 if overlap_ratio <= 0: print("Warning: No overlap detected.") return overlap_pixels = int(width * overlap_ratio) print(f"Processing '{side}' | Overlap: {overlap_pixels} pixels | Gamma: {gamma}") # 4. Generate Mask # Create a linear ramp from 0 to 1 linear_ramp = np.linspace(0, 1, overlap_pixels) # Determine the base curve direction BEFORE gamma if side == "left": # Left image fades OUT (1 -> 0) on the right side base_curve = 1.0 - linear_ramp elif side == "right": # Right image fades IN (0 -> 1) on the left side base_curve = linear_ramp else: print("Error: Side must be 'left' or 'right'") return # 5. Apply Gamma Correction # This "boosts" the midtones. 50% gray becomes ~73% gray. # This is crucial because 0.73^2.2 (projector gamma) + 0.73^2.2 = ~1.0 Light mask_curve = np.power(base_curve, 1 / gamma) # 6. Apply to Image alpha_channel = img[:, :, 3].astype(float) / 255.0 mask_block = np.tile(mask_curve, (height, 1)) if side == "left": # Apply to the right-most columns alpha_channel[:, width - overlap_pixels:] *= mask_block elif side == "right": # Apply to the left-most columns alpha_channel[:, :overlap_pixels] *= mask_block # 7. Save Output img[:, :, 3] = (alpha_channel * 255).astype(np.uint8) # Optional: Burn transparency into RGB for easier debugging/viewing # (This makes the transparent parts black, ensuring no 'ghosting' if alpha is ignored) for c in range(3): if side == "left": roi = img[:, :, c][:, width - overlap_pixels:] img[:, :, c][:, width - overlap_pixels:] = (roi * mask_block).astype(np.uint8) else: roi = img[:, :, c][:, :overlap_pixels] img[:, :, c][:, :overlap_pixels] = (roi * mask_block).astype(np.uint8) output_name = f"output_{side}.png" cv2.imwrite(output_name, img) print(f"Saved: {output_name}") # ˄ # ˅ if __name__ == "__main__": blender = MainAlphaBlender() blender.run() # ˄ </code></pre> *x_curve.py* <pre><code class="python"> import numpy as np import matplotlib.pyplot as plt def plot_blending_mechanics_unique(): # Setup - Use your specific project values here if you have them overlap_pixels = 256 # Example: Change this to your actual overlap width x_pixels = np.linspace(0, overlap_pixels, 500) x_normalized = np.linspace(0, 1, 500) # 1. Linear Alpha (The "Wrong" Way) alpha_left_lin = 1.0 - x_normalized alpha_right_lin = x_normalized # 2. Gamma Corrected Alpha (Your Solution) gamma = 2.2 # Your specific gamma alpha_left_corr = np.power(alpha_left_lin, 1.0 / gamma) alpha_right_corr = np.power(alpha_right_lin, 1.0 / gamma) plt.figure(figsize=(10, 6)) # Plot Gamma Corrected (Solid Colors) - The "Hero" of the graph plt.plot(x_pixels, alpha_left_corr, 'b-', linewidth=3, label='Left Projector Output') plt.plot(x_pixels, alpha_right_corr, 'r-', linewidth=3, label='Right Projector Output') # Plot Linear (Dashed) - The "Baseline" plt.plot(x_pixels, alpha_left_lin, 'k:', linewidth=1.5, alpha=0.5, label='Linear Reference (No Correction)') plt.plot(x_pixels, alpha_right_lin, 'k:', linewidth=1.5, alpha=0.5) # Unique Touch: Shade the area to show "Light Energy" plt.fill_between(x_pixels, alpha_left_corr, alpha_left_lin, color='blue', alpha=0.1) plt.fill_between(x_pixels, alpha_right_corr, alpha_right_lin, color='red', alpha=0.1) # Annotations specific to your analysis plt.text(overlap_pixels / 2, 0.8, 'Gamma Boost Region\n(Corrects Dark Band)', horizontalalignment='center', fontsize=10, bbox=dict(facecolor='white', alpha=0.8, edgecolor='none')) plt.title(f'Spatial Intensity Distribution (Overlap: {overlap_pixels}px)', fontsize=14, fontweight='bold') plt.xlabel('Pixel Position in Overlap Zone', fontsize=12) plt.ylabel('Projected Light Intensity (0.0 - 1.0)', fontsize=12) plt.legend() plt.grid(True, alpha=0.3) plt.savefig('custom_blending_curve.png', dpi=100) print("Saved: custom_blending_curve.png") if __name__ == "__main__": plot_blending_mechanics_unique() </code></pre>