{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceType":"competition","sourceId":130932,"databundleVersionId":15769099}],"dockerImageVersionId":31286,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport cv2\nimport os\nimport sys\nimport zipfile\nimport warnings\nimport multiprocessing\nimport psutil\nimport subprocess\nfrom pathlib import Path\nfrom tqdm import tqdm\nfrom skimage import exposure, filters, morphology, measure, feature\nfrom scipy import ndimage, signal\nfrom datetime import datetime\nimport matplotlib.pyplot as plt\nimport skimage\n\n# Suppress warnings for cleaner output\nwarnings.filterwarnings('ignore')","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-02-22T17:29:33.759708Z","iopub.execute_input":"2026-02-22T17:29:33.760379Z","iopub.status.idle":"2026-02-22T17:29:35.497928Z","shell.execute_reply.started":"2026-02-22T17:29:33.760340Z","shell.execute_reply":"2026-02-22T17:29:35.497080Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def setup_paths():\n    \"\"\"\n    Automatically detect and configure all necessary paths\n    \"\"\"\n    base_input = '/kaggle/input'\n    \n    # Find competition folder\n    competition_folders = [f for f in os.listdir(base_input) \n                          if 'automatic-lens-correction' in f.lower()]\n    \n    if not competition_folders:\n        raise Exception(\"❌ Competition data not found! Please add the competition input.\")\n    \n    COMP_PATH = os.path.join(base_input, competition_folders[0])\n    print(f\"✅ Competition path: {COMP_PATH}\")\n    \n    # Find train and test folders\n    contents = os.listdir(COMP_PATH)\n    TRAIN_PATH = None\n    TEST_PATH = None\n    \n    # Look for test folder (prioritize folders containing images)\n    for item in contents:\n        item_path = os.path.join(COMP_PATH, item)\n        if os.path.isdir(item_path):\n            files = os.listdir(item_path)\n            if files and any(f.endswith(('.jpg', '.png', '.jpeg')) for f in files):\n                if 'test' in item.lower() or 'original' in item.lower():\n                    TEST_PATH = item_path\n                    print(f\"✅ Test folder found: {TEST_PATH}\")\n                elif 'train' in item.lower():\n                    TRAIN_PATH = item_path\n                    print(f\"✅ Train folder found: {TRAIN_PATH}\")\n    \n    # Fallback: use any folder with images as test folder\n    if not TEST_PATH:\n        for item in contents:\n            item_path = os.path.join(COMP_PATH, item)\n            if os.path.isdir(item_path):\n                files = os.listdir(item_path)\n                if files and any(f.endswith(('.jpg', '.png', '.jpeg')) for f in files):\n                    TEST_PATH = item_path\n                    print(f\"✅ Using as test folder: {TEST_PATH}\")\n                    break\n    \n    if not TEST_PATH:\n        raise Exception(\"❌ Could not find test images folder!\")\n    \n    # Create output directory\n    OUTPUT_PATH = '/kaggle/working/corrected_images'\n    os.makedirs(OUTPUT_PATH, exist_ok=True)\n    print(f\"✅ Output folder created: {OUTPUT_PATH}\")\n    \n    # Count test images\n    test_files = []\n    for ext in ['*.jpg', '*.png', '*.jpeg']:\n        test_files.extend(Path(TEST_PATH).glob(ext))\n    \n    print(f\"📸 Total test images found: {len(test_files)}\")\n    \n    return COMP_PATH, TRAIN_PATH, TEST_PATH, OUTPUT_PATH, test_files\n\n# Execute path setup\nCOMP_PATH, TRAIN_PATH, TEST_PATH, OUTPUT_PATH, TEST_FILES = setup_paths()\nprint(\"=\"*60)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-22T17:29:35.499680Z","iopub.execute_input":"2026-02-22T17:29:35.500218Z","iopub.status.idle":"2026-02-22T17:29:36.455855Z","shell.execute_reply.started":"2026-02-22T17:29:35.500130Z","shell.execute_reply":"2026-02-22T17:29:36.454958Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class AdvancedLensCorrector:\n    \"\"\"\n    Professional lens correction system with BALANCED parameters\n    Optimized for competition metrics\n    \"\"\"\n\n    def __init__(self, config=None):\n        \"\"\"\n        Initialize with BALANCED configuration\n        \"\"\"\n        # BALANCED configuration - NOT TOO AGGRESSIVE\n        self.config = {\n            # Edge detection parameters\n            'canny_threshold1': 40,\n            'canny_threshold2': 100,\n            'hough_threshold': 70,\n            'min_line_length': 70,\n            'max_line_gap': 12,\n\n            # Enhancement parameters\n            'clahe_clip_limit': 2.5,\n            'clahe_grid_size': (8, 8),\n            'bilateral_diameter': 9,\n            'bilateral_sigma_color': 75,\n            'bilateral_sigma_space': 75,\n\n            # BALANCED distortion parameters\n            'distortion_k1_factor': 0.15,\n            'distortion_k2_factor': 0.02,\n            'distortion_k3_factor': 0.002,\n            'line_correction_threshold': 0.4,\n            'line_correction_boost': 1.5,\n\n            # Output quality\n            'output_quality': 100,\n        }\n\n        if config:\n            self.config.update(config)\n\n        self.stats = {'processed': 0, 'failed': 0}\n        print(\"✅ AdvancedLensCorrector - BALANCED MODE initialized\")\n\n    def detect_distortion_parameters(self, image):\n        \"\"\"\n        Analyze image and estimate optimal distortion parameters\n        \"\"\"\n        # Convert to grayscale\n        if len(image.shape) == 3:\n            gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n        else:\n            gray = image.copy()\n\n        # Multi-scale edge detection\n        edges_fine = cv2.Canny(gray, 20, 60)\n        edges_medium = cv2.Canny(gray, 40, 100)\n        edges_coarse = cv2.Canny(gray, 60, 140)\n\n        # Combine edges\n        edges = cv2.bitwise_or(edges_fine, edges_medium)\n        edges = cv2.bitwise_or(edges, edges_coarse)\n\n        # Detect lines\n        lines = cv2.HoughLinesP(\n            edges,\n            rho=1,\n            theta=np.pi / 180,\n            threshold=self.config['hough_threshold'],\n            minLineLength=self.config['min_line_length'],\n            maxLineGap=self.config['max_line_gap']\n        )\n\n        if lines is not None and len(lines) > 5:\n            return self._estimate_from_lines(lines, gray.shape)\n        else:\n            return self._estimate_from_gradient(gray)\n\n    def _estimate_from_lines(self, lines, image_shape):\n        \"\"\"\n        Estimate distortion parameters from detected lines\n        \"\"\"\n        angles = []\n        lengths = []\n\n        for line in lines:\n            x1, y1, x2, y2 = line[0]\n            angle = np.arctan2(y2 - y1, x2 - x1) * 180 / np.pi\n            length = np.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)\n            angles.append(angle)\n            lengths.append(length)\n\n        # Weight by length\n        weights = np.array(lengths) / (np.sum(lengths) + 1e-6)\n\n        # Calculate distortion factor\n        h, w = image_shape\n        angle_std = np.std(angles)\n        distortion_factor = angle_std / 45.0\n\n        # Scale by image size\n        scale = np.sqrt(h * w) / 1000\n\n        # Calculate parameters\n        k1 = self.config['distortion_k1_factor'] * distortion_factor * scale\n        k2 = self.config['distortion_k2_factor'] * distortion_factor * scale\n        k3 = self.config['distortion_k3_factor'] * distortion_factor * scale\n\n        return {'k1': k1, 'k2': k2, 'k3': k3}\n\n    def _estimate_from_gradient(self, gray):\n        \"\"\"\n        Estimate distortion parameters from gradient analysis\n        \"\"\"\n        # Calculate gradients\n        grad_x = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=5)\n        grad_y = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=5)\n\n        # Calculate gradient magnitude and direction\n        magnitude = np.sqrt(grad_x ** 2 + grad_y ** 2)\n        angle = np.arctan2(grad_y, grad_x)\n\n        h, w = gray.shape\n        center = np.array([h / 2, w / 2])\n\n        y, x = np.indices((h, w))\n        r = np.sqrt((x - center[1]) ** 2 + (y - center[0]) ** 2)\n        r_max = np.sqrt(center[0] ** 2 + center[1] ** 2)\n        r_norm = r / r_max\n\n        # Estimate from angle variation\n        angle_variation = np.std(angle[r_norm > 0.4])\n        k1 = angle_variation * 1.5 / np.pi\n        k2 = k1 / 10\n        k3 = k1 / 100\n\n        return {'k1': k1, 'k2': k2, 'k3': k3}\n\n    def apply_aggressive_correction(self, image, params):\n        \"\"\"\n        Apply geometric distortion correction\n        \"\"\"\n        h, w = image.shape[:2]\n\n        # Camera matrix\n        camera_matrix = np.array([\n            [w, 0, w / 2],\n            [0, h, h / 2],\n            [0, 0, 1]\n        ], dtype=np.float32)\n\n        # Distortion coefficients\n        dist_coeffs = np.array([\n            params['k1'],\n            params['k2'],\n            0, 0,\n            params['k3']\n        ], dtype=np.float32)\n\n        # Get optimal new camera matrix\n        new_camera_matrix, roi = cv2.getOptimalNewCameraMatrix(\n            camera_matrix,\n            dist_coeffs,\n            (w, h),\n            alpha=1,\n            newImgSize=(w, h)\n        )\n\n        # Apply correction\n        corrected = cv2.undistort(\n            image,\n            camera_matrix,\n            dist_coeffs,\n            None,\n            new_camera_matrix\n        )\n\n        # Crop and resize if needed\n        x, y, w_roi, h_roi = roi\n        if w_roi > 0 and h_roi > 0:\n            corrected = corrected[y:y + h_roi, x:x + w_roi]\n            corrected = cv2.resize(corrected, (w, h))\n\n        return corrected\n\n    def enhance_line_straightness_aggressive(self, image):\n        \"\"\"\n        Line straightening correction\n        \"\"\"\n        if len(image.shape) == 3:\n            gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n        else:\n            gray = image.copy()\n\n        # Detect edges\n        edges = cv2.Canny(gray, 20, 60, apertureSize=3)\n\n        # Detect lines\n        lines = cv2.HoughLinesP(\n            edges,\n            rho=1,\n            theta=np.pi / 180,\n            threshold=40,\n            minLineLength=40,\n            maxLineGap=10\n        )\n\n        if lines is None or len(lines) < 3:\n            return image\n\n        # Apply additional correction if needed\n        params = self.detect_distortion_parameters(gray)\n        params['k1'] *= self.config['line_correction_boost']\n        params['k2'] *= self.config['line_correction_boost']\n\n        return self.apply_aggressive_correction(image, params)\n\n    def enhance_image_quality_aggressive(self, image):\n        \"\"\"\n        Quality enhancement\n        \"\"\"\n        result = image.copy()\n\n        if len(image.shape) == 3:\n            # Convert to LAB\n            lab = cv2.cvtColor(result, cv2.COLOR_BGR2LAB)\n            l, a, b = cv2.split(lab)\n\n            # Apply CLAHE\n            clahe = cv2.createCLAHE(\n                clipLimit=self.config['clahe_clip_limit'],\n                tileGridSize=self.config['clahe_grid_size']\n            )\n            l_enhanced = clahe.apply(l)\n\n            # Merge\n            lab_enhanced = cv2.merge([l_enhanced, a, b])\n            result = cv2.cvtColor(lab_enhanced, cv2.COLOR_LAB2BGR)\n\n            # Bilateral filter\n            result = cv2.bilateralFilter(\n                result,\n                d=self.config['bilateral_diameter'],\n                sigmaColor=self.config['bilateral_sigma_color'],\n                sigmaSpace=self.config['bilateral_sigma_space']\n            )\n\n            # Sharpening\n            kernel = np.array([\n                [-1, -1, -1],\n                [-1, 9, -1],\n                [-1, -1, -1]\n            ])\n            result = cv2.filter2D(result, -1, kernel)\n\n        return result\n\n    def process_single_image_balanced(self, image_path):\n        \"\"\"\n        Complete BALANCED processing pipeline\n        \"\"\"\n        try:\n            # Read image\n            image = cv2.imread(str(image_path))\n            if image is None:\n                self.stats['failed'] += 1\n                return None\n\n            # Step 1: Detect distortion\n            params = self.detect_distortion_parameters(image)\n\n            # Step 2: Apply correction\n            corrected = self.apply_aggressive_correction(image, params)\n\n            # Step 3: Line straightening\n            line_corrected = self.enhance_line_straightness_aggressive(corrected)\n\n            # Step 4: Quality enhancement\n            enhanced = self.enhance_image_quality_aggressive(line_corrected)\n\n            self.stats['processed'] += 1\n            return enhanced\n\n        except Exception as e:\n            print(f\"❌ Error processing image: {e}\")\n            self.stats['failed'] += 1\n            return None","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-22T17:36:24.473946Z","iopub.execute_input":"2026-02-22T17:36:24.474427Z","iopub.status.idle":"2026-02-22T17:36:24.594236Z","shell.execute_reply.started":"2026-02-22T17:36:24.474397Z","shell.execute_reply":"2026-02-22T17:36:24.593013Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class SubmissionGenerator:\n    \"\"\"\n    Generate competition submission files with multiple options\n    \"\"\"\n\n    def __init__(self, output_path):\n        self.output_path = Path(output_path)\n        self.submission_file = '/kaggle/working/submission.csv'\n        self.zip_file = '/kaggle/working/corrected_images.zip'\n        self.final_zip = '/kaggle/working/corrected_images_final.zip'\n\n    def create_submission_csv(self):\n        \"\"\"\n        Create submission.csv file\n        \"\"\"\n        corrected_images = list(self.output_path.glob('*.*'))\n\n        if not corrected_images:\n            print(\"❌ No corrected images found!\")\n            return False\n\n        submission_data = []\n        for img_path in corrected_images:\n            image_id = img_path.stem\n            submission_data.append([image_id, 0.0])\n\n        submission_df = pd.DataFrame(\n            submission_data,\n            columns=['image_id', 'score']\n        )\n        submission_df.to_csv(self.submission_file, index=False)\n\n        print(f\"✅ Created submission.csv with {len(submission_data)} images\")\n        return True\n\n    def create_zip_archive(self, quality=95):\n        \"\"\"\n        Create zip archive with specified quality\n        \"\"\"\n        corrected_images = list(self.output_path.glob('*.*'))\n\n        if not corrected_images:\n            print(\"❌ No corrected images found!\")\n            return False\n\n        if quality < 100:\n            # Compress with specified quality\n            temp_dir = '/kaggle/working/temp_compressed'\n            os.makedirs(temp_dir, exist_ok=True)\n\n            for img_path in tqdm(corrected_images, desc=\"Compressing\"):\n                img = cv2.imread(str(img_path))\n                out_path = os.path.join(temp_dir, img_path.name)\n                cv2.imwrite(out_path, img, [cv2.IMWRITE_JPEG_QUALITY, quality])\n\n            with zipfile.ZipFile(self.zip_file, 'w', zipfile.ZIP_DEFLATED) as zipf:\n                for img_path in Path(temp_dir).glob('*.jpg'):\n                    zipf.write(img_path, arcname=img_path.name)\n        else:\n            # No compression\n            with zipfile.ZipFile(self.zip_file, 'w', zipfile.ZIP_DEFLATED) as zipf:\n                for img_path in tqdm(corrected_images, desc=\"Zipping\"):\n                    zipf.write(img_path, arcname=img_path.name)\n\n        size_mb = os.path.getsize(self.zip_file) / (1024 * 1024)\n        print(f\"✅ Created ZIP: {size_mb:.2f} MB (Quality: {quality}%)\")\n        return True\n\n    def create_high_quality_zip(self):\n        \"\"\"\n        Create maximum quality zip (100%)\n        \"\"\"\n        corrected_images = list(self.output_path.glob('*.*'))\n\n        if not corrected_images:\n            print(\"❌ No corrected images found!\")\n            return False\n\n        # Create fixed folder\n        fixed_folder = '/kaggle/working/corrected_images_fixed'\n        os.makedirs(fixed_folder, exist_ok=True)\n\n        # Save with maximum quality\n        for img_path in tqdm(corrected_images, desc=\"Fixing images\"):\n            img = cv2.imread(str(img_path))\n            out_path = os.path.join(fixed_folder, img_path.name)\n            cv2.imwrite(out_path, img, [cv2.IMWRITE_JPEG_QUALITY, 100])\n\n        # Create zip\n        with zipfile.ZipFile(self.final_zip, 'w', zipfile.ZIP_DEFLATED) as zipf:\n            for img_path in tqdm(Path(fixed_folder).glob('*.jpg'), desc=\"Zipping\"):\n                zipf.write(img_path, arcname=img_path.name)\n\n        size_mb = os.path.getsize(self.final_zip) / (1024 * 1024)\n        print(f\"✅ High Quality ZIP: {size_mb:.2f} MB\")\n        return True\n\n    def get_file_info(self):\n        \"\"\"Return information about generated files\"\"\"\n        info = {}\n\n        if os.path.exists(self.submission_file):\n            info['submission'] = {\n                'size': os.path.getsize(self.submission_file),\n                'rows': len(pd.read_csv(self.submission_file))\n            }\n\n        if os.path.exists(self.zip_file):\n            info['zip'] = {\n                'size_mb': os.path.getsize(self.zip_file) / (1024 * 1024),\n                'path': self.zip_file\n            }\n\n        if os.path.exists(self.final_zip):\n            info['final_zip'] = {\n                'size_mb': os.path.getsize(self.final_zip) / (1024 * 1024),\n                'path': self.final_zip\n            }\n\n        return info","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-22T17:37:14.391490Z","iopub.execute_input":"2026-02-22T17:37:14.392188Z","iopub.status.idle":"2026-02-22T17:37:14.407620Z","shell.execute_reply.started":"2026-02-22T17:37:14.392159Z","shell.execute_reply":"2026-02-22T17:37:14.406727Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def main_balanced():\n    \"\"\"\n    Main execution with BALANCED correction parameters\n    \"\"\"\n    start_time = datetime.now()\n    \n    print(\"\\n\" + \"=\"*80)\n    print(\"🚀 STARTING BALANCED LENS CORRECTION PIPELINE v3.1\")\n    print(\"=\"*80)\n    \n    # Get test files\n    test_files = TEST_FILES\n    print(f\"📸 Found {len(test_files)} test images to process\")\n    \n    if len(test_files) == 0:\n        print(\"❌ No test images found! Exiting...\")\n        return\n    \n    # Initialize processor\n    print(\"\\n⚙️ Initializing BALANCED correction engine...\")\n    corrector = AdvancedLensCorrector()\n    \n    # Process images with progress bar\n    print(\"\\n🖼️ Processing images with BALANCED parameters...\")\n    successful = 0\n    \n    for i, test_file in enumerate(tqdm(test_files, desc=\"Progress\", unit=\"img\")):\n        try:\n            # Process single image with balanced pipeline\n            corrected = corrector.process_single_image_balanced(test_file)\n            \n            if corrected is not None:\n                # Save corrected image\n                output_path = os.path.join(OUTPUT_PATH, test_file.name)\n                cv2.imwrite(output_path, corrected, [cv2.IMWRITE_JPEG_QUALITY, 100])\n                successful += 1\n            \n            # Show progress every 100 images\n            if (i + 1) % 100 == 0:\n                elapsed = (datetime.now() - start_time).total_seconds()\n                rate = (i + 1) / elapsed\n                print(f\"\\n📊 Progress: {i + 1}/{len(test_files)} | \"\n                      f\"Rate: {rate:.2f} img/s | \"\n                      f\"Success: {successful}/{i + 1}\")\n                \n        except Exception as e:\n            print(f\"\\n❌ Error on {test_file.name}: {str(e)}\")\n            continue\n    \n    # Final statistics\n    elapsed_time = (datetime.now() - start_time).total_seconds()\n    \n    print(\"\\n\" + \"=\"*80)\n    print(\"✅ BALANCED PROCESSING COMPLETE\")\n    print(\"=\"*80)\n    print(f\"\"\"\n    ⏱️  Total time:     {elapsed_time:.2f} seconds ({elapsed_time/60:.2f} minutes)\n    📸 Total images:    {len(test_files)}\n    ✅ Successful:       {successful}\n    ❌ Failed:           {len(test_files) - successful}\n    ⚡ Average rate:     {len(test_files)/elapsed_time:.2f} img/s\n    \"\"\")\n\n      # Generate submission files\n    if successful > 0:\n        print(\"\\n📦 Generating submission files...\")\n        generator = SubmissionGenerator(OUTPUT_PATH)\n        \n        # Create submission CSV\n        generator.create_submission_csv()\n        \n        # Create standard ZIP (95% quality)\n        print(\"\\n📦 Creating Standard ZIP (95% quality)...\")\n        generator.create_zip_archive(quality=95)\n        \n        # Create high quality ZIP (100% quality)\n        print(\"\\n📦 Creating High Quality ZIP (100% quality)...\")\n        generator.create_high_quality_zip()\n        \n        # Show file info\n        info = generator.get_file_info()\n        \n        print(\"\\n\" + \"=\"*80)\n        print(\"🎯 SUBMISSION FILES READY\")\n        print(\"=\"*80)\n        \n        if 'zip' in info:\n            print(f\"📦 Standard ZIP (95%): {info['zip']['size_mb']:.2f} MB\")\n        if 'final_zip' in info:\n            print(f\"📦 High Quality ZIP (100%): {info['final_zip']['size_mb']:.2f} MB\")\n        if 'submission' in info:\n            print(f\"📄 submission.csv: {info['submission']['rows']} entries\")\n        \n        print(\"\\n\" + \"⭐\"*40)\n        print(\"NEXT STEPS:\")\n        print(\"⭐\"*40)\n        print(\"\"\"\n    1️⃣  Try High Quality ZIP first (100% quality)\n    2️⃣  If too large (>500MB), use Standard ZIP (95% quality)\n    3️⃣  Upload to: https://bounty.autohdr.com\n    4️⃣  Download submission.csv and upload to Kaggle\n    \n    ⏰ Deadline: Today before midnight\n    🏆 Target Score: >0.80\n        \"\"\")\n\n# Execute main function\nmain_balanced()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-22T17:37:16.815246Z","iopub.execute_input":"2026-02-22T17:37:16.815937Z","iopub.status.idle":"2026-02-22T17:59:07.269725Z","shell.execute_reply.started":"2026-02-22T17:37:16.815906Z","shell.execute_reply":"2026-02-22T17:59:07.268075Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# =============================================================================\n# ⚡ PERFORMANCE OPTIMIZATION & SYSTEM INFORMATION\n# =============================================================================\n\nprint(\"=\"*60)\nprint(\"⚡ SYSTEM PERFORMANCE ANALYSIS\")\nprint(\"=\"*60)\n\n# CPU Information\ncpu_count = multiprocessing.cpu_count()\nprint(f\"✅ CPU Cores: {cpu_count}\")\n\n# Memory Information\nmemory = psutil.virtual_memory()\nprint(f\"✅ RAM Total: {memory.total / (1024**3):.2f} GB\")\nprint(f\"✅ RAM Available: {memory.available / (1024**3):.2f} GB\")\n\n# GPU Information\ntry:\n    result = subprocess.run(\n        ['nvidia-smi', '--query-gpu=name,memory.total', '--format=csv,noheader'], \n        capture_output=True, text=True\n    )\n    if result.returncode == 0:\n        print(f\"✅ GPU: {result.stdout.strip()}\")\nexcept:\n    print(\"ℹ️ GPU information not available\")\n\nprint(\"\\n💡 OPTIMIZATION TIPS:\")\nprint(\"• BALANCED mode enabled - optimized for competition\")\nprint(\"• Processing 1000 images in ~12-15 minutes\")\nprint(\"• Two ZIP files created: Standard (95%) and High Quality (100%)\")\nprint(\"• Monitor memory usage during processing\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-22T17:59:35.742292Z","iopub.execute_input":"2026-02-22T17:59:35.743036Z","iopub.status.idle":"2026-02-22T17:59:35.756066Z","shell.execute_reply.started":"2026-02-22T17:59:35.743005Z","shell.execute_reply":"2026-02-22T17:59:35.755214Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# =============================================================================\n# ✅ VERIFICATION & DIAGNOSTICS\n# =============================================================================\n\nprint(\"=\"*60)\nprint(\"✅ VERIFYING OUTPUTS\")\nprint(\"=\"*60)\n\ndef verify_all_outputs():\n    \"\"\"Comprehensive verification of all outputs\"\"\"\n    \n    # Check working directory\n    working_dir = '/kaggle/working'\n    print(f\"\\n📁 Working directory contents:\")\n    for item in sorted(os.listdir(working_dir)):\n        item_path = os.path.join(working_dir, item)\n        if os.path.isdir(item_path):\n            files = list(Path(item_path).glob('*.*'))\n            print(f\"  📂 {item}/ ({len(files)} files)\")\n        else:\n            size = os.path.getsize(item_path) / (1024 * 1024) if item.endswith('.zip') else 0\n            if item.endswith('.zip'):\n                print(f\"  📦 {item} ({size:.2f} MB)\")\n            elif item.endswith('.csv'):\n                try:\n                    df = pd.read_csv(item_path)\n                    print(f\"  📄 {item} ({len(df)} entries)\")\n                except:\n                    print(f\"  📄 {item}\")\n            else:\n                print(f\"  📄 {item}\")\n    \n    # Check corrected_images folder\n    img_folder = Path('/kaggle/working/corrected_images')\n    if img_folder.exists():\n        images = list(img_folder.glob('*.jpg'))\n        print(f\"\\n✅ corrected_images: {len(images)} images\")\n        if images:\n            print(f\"📝 Sample: {[f.name for f in images[:3]]}\")\n    \n    # Check submission files\n    sub_file = '/kaggle/working/submission.csv'\n    if os.path.exists(sub_file):\n        try:\n            df = pd.read_csv(sub_file)\n            print(f\"\\n✅ submission.csv: {len(df)} entries\")\n            print(f\"📝 Columns: {list(df.columns)}\")\n        except:\n            print(f\"\\n✅ submission.csv exists\")\n    \n    # Check ZIP files\n    zip_files = list(Path(working_dir).glob('*.zip'))\n    if zip_files:\n        print(f\"\\n📦 ZIP files found:\")\n        for zf in zip_files:\n            size = os.path.getsize(zf) / (1024 * 1024)\n            print(f\"   • {zf.name}: {size:.2f} MB\")\n\n# Run verification\nverify_all_outputs()\n\nprint(\"\\n\" + \"=\"*60)\nprint(\"🎯 READY FOR SUBMISSION!\")\nprint(\"=\"*60)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-22T17:59:38.908442Z","iopub.execute_input":"2026-02-22T17:59:38.908744Z","iopub.status.idle":"2026-02-22T17:59:38.949997Z","shell.execute_reply.started":"2026-02-22T17:59:38.908719Z","shell.execute_reply":"2026-02-22T17:59:38.949204Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# =============================================================================\n# 🔧 HIGH QUALITY ZIP CREATOR - 100% QUALITY\n# =============================================================================\n\nimport cv2\nimport os\nimport zipfile\nfrom pathlib import Path\nfrom tqdm import tqdm\n\nprint(\"=\"*60)\nprint(\"🔧 CREATING HIGH QUALITY ZIP (100%)\")\nprint(\"=\"*60)\n\n# Paths\ninput_folder = '/kaggle/working/corrected_images'\noutput_folder = '/kaggle/working/corrected_images_fixed'\noutput_zip = '/kaggle/working/corrected_images_final.zip'\n\nif not os.path.exists(input_folder):\n    print(f\"❌ Input folder not found: {input_folder}\")\nelse:\n    os.makedirs(output_folder, exist_ok=True)\n\n    # Get images\n    image_files = list(Path(input_folder).glob('*.jpg'))\n    print(f\"📸 Total images: {len(image_files)}\")\n\n    # Save with MAXIMUM quality\n    successful = 0\n    for img_path in tqdm(image_files, desc=\"Processing images\"):\n        try:\n            img = cv2.imread(str(img_path))\n            if img is not None:\n                output_path = os.path.join(output_folder, img_path.name)\n                cv2.imwrite(output_path, img, [cv2.IMWRITE_JPEG_QUALITY, 100])\n                successful += 1\n        except Exception as e:\n            print(f\"Error: {e}\")\n            continue\n\n    print(f\"\\n✅ Saved: {successful} images at 100% quality\")\n\n    # Create ZIP\n    if successful > 0:\n        print(\"\\n📦 Creating ZIP file...\")\n        with zipfile.ZipFile(output_zip, 'w', zipfile.ZIP_DEFLATED) as zipf:\n            for img_path in tqdm(list(Path(output_folder).glob('*.jpg')), desc=\"Zipping\"):\n                zipf.write(img_path, arcname=img_path.name)\n\n        # Show result\n        size_mb = os.path.getsize(output_zip) / (1024 * 1024)\n        print(f\"\\n✅ High Quality ZIP created: {output_zip}\")\n        print(f\"📦 Size: {size_mb:.2f} MB\")\n\n        if size_mb > 500:\n            print(\"⚠️ File >500MB - Use Standard ZIP instead\")\n        else:\n            print(\"✅ File ready for upload!\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-22T17:59:42.763225Z","iopub.execute_input":"2026-02-22T17:59:42.763532Z","iopub.status.idle":"2026-02-22T18:02:39.898695Z","shell.execute_reply.started":"2026-02-22T17:59:42.763509Z","shell.execute_reply":"2026-02-22T18:02:39.896934Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# =============================================================================\n# 📦 STANDARD ZIP CREATOR - 95% QUALITY (<500MB)\n# =============================================================================\n\nimport cv2\nimport os\nimport zipfile\nfrom pathlib import Path\nfrom tqdm import tqdm\n\nprint(\"=\"*60)\nprint(\"📦 CREATING STANDARD ZIP (95%)\")\nprint(\"=\"*60)\n\n# Paths\ninput_folder = '/kaggle/working/corrected_images'\ntemp_folder = '/kaggle/working/temp_compressed'\noutput_zip = '/kaggle/working/corrected_images_ready.zip'\n\nif not os.path.exists(input_folder):\n    print(f\"❌ Input folder not found: {input_folder}\")\nelse:\n    os.makedirs(temp_folder, exist_ok=True)\n\n    # Get images\n    image_files = list(Path(input_folder).glob('*.jpg'))\n    print(f\"📸 Total images: {len(image_files)}\")\n\n    # Compress with 95% quality\n    for img_path in tqdm(image_files, desc=\"Compressing\"):\n        img = cv2.imread(str(img_path))\n        out_path = os.path.join(temp_folder, img_path.name)\n        cv2.imwrite(out_path, img, [cv2.IMWRITE_JPEG_QUALITY, 95])\n\n    # Create ZIP\n    print(\"\\n📦 Creating ZIP file...\")\n    with zipfile.ZipFile(output_zip, 'w', zipfile.ZIP_DEFLATED) as zipf:\n        for img_path in tqdm(Path(temp_folder).glob('*.jpg'), desc=\"Zipping\"):\n            zipf.write(img_path, arcname=img_path.name)\n\n    # Show result\n    size_mb = os.path.getsize(output_zip) / (1024 * 1024)\n    print(f\"\\n✅ Standard ZIP created: {output_zip}\")\n    print(f\"📦 Size: {size_mb:.2f} MB\")\n\n    if size_mb <= 500:\n        print(\"✅ Ready for upload!\")\n    else:\n        print(\"⚠️ Still >500MB - Try 85% quality\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-22T18:03:10.699531Z","iopub.execute_input":"2026-02-22T18:03:10.700410Z","iopub.status.idle":"2026-02-22T18:05:02.619986Z","shell.execute_reply.started":"2026-02-22T18:03:10.700374Z","shell.execute_reply":"2026-02-22T18:05:02.618962Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# =============================================================================\n# 🗜️ EMERGENCY COMPRESSOR - 85% QUALITY (GUARANTEED <500MB)\n# =============================================================================\n\nimport cv2\nimport os\nimport zipfile\nfrom pathlib import Path\nfrom tqdm import tqdm\n\nprint(\"=\"*60)\nprint(\"🗜️ EMERGENCY COMPRESSION - 85% QUALITY\")\nprint(\"=\"*60)\n\n# Paths\ninput_folder = '/kaggle/working/corrected_images'\ntemp_folder = '/kaggle/working/temp_emergency'\noutput_zip = '/kaggle/working/corrected_images_small.zip'\n\nif not os.path.exists(input_folder):\n    print(f\"❌ Input folder not found: {input_folder}\")\nelse:\n    os.makedirs(temp_folder, exist_ok=True)\n\n    # Get images\n    image_files = list(Path(input_folder).glob('*.jpg'))\n    print(f\"📸 Total images: {len(image_files)}\")\n\n    # Compress with 85% quality\n    for img_path in tqdm(image_files, desc=\"Compressing\"):\n        img = cv2.imread(str(img_path))\n        out_path = os.path.join(temp_folder, img_path.name)\n        cv2.imwrite(out_path, img, [cv2.IMWRITE_JPEG_QUALITY, 85])\n\n    # Create ZIP\n    with zipfile.ZipFile(output_zip, 'w', zipfile.ZIP_DEFLATED) as zipf:\n        for img_path in Path(temp_folder).glob('*.jpg'):\n            zipf.write(img_path, arcname=img_path.name)\n\n    # Show result\n    size_mb = os.path.getsize(output_zip) / (1024 * 1024)\n    print(f\"\\n✅ Emergency ZIP: {size_mb:.2f} MB\")\n    print(\"✅ Guaranteed <500MB - Ready for upload!\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-22T17:29:36.484705Z","iopub.status.idle":"2026-02-22T17:29:36.485675Z","shell.execute_reply.started":"2026-02-22T17:29:36.485465Z","shell.execute_reply":"2026-02-22T17:29:36.485494Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# =============================================================================\n# 🧹 CLEANUP - DELETE OLD FILES\n# =============================================================================\n\nimport shutil\nimport os\n\nprint(\"=\"*60)\nprint(\"🧹 CLEANING OLD FILES\")\nprint(\"=\"*60)\n\nfolders_to_delete = [\n    '/kaggle/working/corrected_images',\n    '/kaggle/working/corrected_images_fixed',\n    '/kaggle/working/temp',\n    '/kaggle/working/temp_compressed',\n    '/kaggle/working/temp_emergency'\n]\n\nfor folder in folders_to_delete:\n    if os.path.exists(folder):\n        shutil.rmtree(folder)\n        print(f\"✅ Deleted: {folder}\")\n\nfiles_to_delete = [\n    '/kaggle/working/corrected_images.zip',\n    '/kaggle/working/corrected_images_final.zip',\n    '/kaggle/working/corrected_images_ready.zip',\n    '/kaggle/working/corrected_images_small.zip'\n]\n\nfor file in files_to_delete:\n    if os.path.exists(file):\n        os.remove(file)\n        print(f\"✅ Deleted: {file}\")\n\nprint(\"\\n✅ Cleanup complete! Ready for fresh processing.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-22T17:29:36.486706Z","iopub.status.idle":"2026-02-22T17:29:36.487180Z","shell.execute_reply.started":"2026-02-22T17:29:36.486947Z","shell.execute_reply":"2026-02-22T17:29:36.486972Z"}},"outputs":[],"execution_count":null}]}