{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":97984,"databundleVersionId":14096757,"sourceType":"competition"},{"sourceId":622926,"sourceType":"modelInstanceVersion","isSourceIdPinned":true,"modelInstanceId":468633,"modelId":484483}],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# ECG Emergency Classification: AI LifeSaver Adaptation Starter\n\n## Introduction\n\nThis notebook demonstrates how to adapt the **AI LifeSaver** model for ECG image analysis and emergency classification. The PhysioNet ECG Image Digitization competition provides scans and photographs of paper ECG printouts, which need to be processed and analyzed.\n\n### Key Objectives:\n1. **Load and explore** sample ECG images from the competition dataset\n2. **Adapt image processing techniques** from AI LifeSaver for ECG scans\n3. **Classify emergency ECG patterns** (arrhythmia, heart attack risk, etc.)\n4. **Generate automated advice** for detected cardiac conditions\n5. **Support real-world triage** scenarios in emergency medical settings\n\n### Model Adaptation Strategy\n\nThe AI LifeSaver model was originally designed for emergency detection and first aid advice. We'll adapt its computer vision and classification capabilities to:\n- **Process ECG images** (both scanned and photographed paper printouts)\n- **Extract signal features** from digitized ECG waveforms\n- **Identify critical patterns** indicating cardiac emergencies\n- **Provide triage recommendations** based on detected conditions\n\nThis approach bridges the gap between image-based AI emergency detection and specialized cardiac monitoring, enabling faster response in critical situations.","metadata":{}},{"cell_type":"code","source":"# Import necessary libraries\nimport os\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport cv2\nfrom PIL import Image\nimport torch\nimport torchvision.transforms as transforms\nfrom pathlib import Path\n\nprint(\"Libraries imported successfully!\")\nprint(f\"PyTorch version: {torch.__version__}\")\nprint(f\"CUDA available: {torch.cuda.is_available()}\")\n\n# List all available input files\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames[:5]:  # Show first 5 files from each directory\n        print(os.path.join(dirname, filename))","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Delete the default first code cell - it's redundant\n# This cell can be removed during cleanup","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 📸 Section 1: Loading Sample ECG Images\n\nIn this section, we'll load and visualize sample ECG images from the PhysioNet competition dataset. These images may include:\n- **Scanned ECG printouts** (high quality, clear paper scans)\n- **Photographed ECG printouts** (mobile phone captures, varying lighting/angles)\n- **Various ECG lead configurations** (12-lead, single-lead, etc.)","metadata":{}},{"cell_type":"code","source":"# Load sample ECG images from the competition dataset\ndata_dir = Path('/kaggle/input/physionet-ecg-image-digitization')\n\n# Find sample images\nimage_files = []\nif data_dir.exists():\n    for ext in ['*.png', '*.jpg', '*.jpeg']:\n        image_files.extend(list(data_dir.rglob(ext)))\n    print(f\"Found {len(image_files)} ECG image files\")\n    \n    # Display first few sample images\n    sample_count = min(3, len(image_files))\n    if sample_count > 0:\n        fig, axes = plt.subplots(1, sample_count, figsize=(15, 5))\n        if sample_count == 1:\n            axes = [axes]\n        \n        for idx in range(sample_count):\n            img = Image.open(image_files[idx])\n            axes[idx].imshow(img)\n            axes[idx].set_title(f'Sample ECG {idx+1}\\n{image_files[idx].name}')\n            axes[idx].axis('off')\n        \n        plt.tight_layout()\n        plt.show()\n        print(f\"\\nDisplayed {sample_count} sample ECG images\")\n    else:\n        print(\"No images found in the dataset directory\")\nelse:\n    print(\"Dataset directory not found. Using placeholder demonstration.\")","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Placeholder for image preprocessing demonstration\n# This would contain ECG-specific image processing code\nprint(\"Image preprocessing pipeline:\")\nprint(\"1. Perspective correction for photographed ECGs\")\nprint(\"2. Contrast enhancement and noise reduction\")\nprint(\"3. Grid line detection and removal\")\nprint(\"4. ECG waveform extraction\")","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 🔍 Section 2: AI LifeSaver Image Processing Adaptation\n\n### Adapting AI LifeSaver for ECG Image Analysis\n\nThe **AI LifeSaver** model was designed for general emergency scene detection. To adapt it for ECG analysis, we need to modify the image processing pipeline:\n\n#### Key Adaptations:\n\n1. **Preprocessing for Paper ECG Images:**\n   - **Perspective correction** - Handle photographed ECGs with skewed angles\n   - **Contrast enhancement** - Improve visibility of faint ECG traces\n   - **Noise reduction** - Remove paper artifacts and scanner imperfections\n   - **Grid line detection & removal** - Extract clean ECG waveforms from gridded paper\n\n2. **Feature Extraction Modifications:**\n   - Replace general object detection with **specialized ECG waveform detection**\n   - Adapt convolutional layers to recognize **QRS complexes, P waves, T waves**\n   - Focus on **temporal patterns** in waveform sequences rather than spatial object detection\n\n3. **Signal Digitization:**\n   - Convert image pixels to **time-series ECG signal data**\n   - Extract lead-specific information from 12-lead configurations\n   - Normalize amplitudes and time scales\n\n4. **Transfer Learning Strategy:**\n   - Freeze early CNN layers (basic edge/shape detection remains useful)\n   - Fine-tune middle layers for ECG-specific pattern recognition\n   - Retrain classification head for cardiac emergency types","metadata":{}},{"cell_type":"code","source":"# Placeholder for ECG feature extraction\n# This demonstrates adapting AI LifeSaver's feature extraction for ECG signals\nprint(\"ECG Feature Extraction:\")\nprint(\"- QRS complex detection\")\nprint(\"- P-wave and T-wave identification\")\nprint(\"- Heart rate variability analysis\")\nprint(\"- ST-segment elevation/depression measurement\")","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Section 4: Emergency Advice Generation\n# Generate automated triage recommendations based on detected patterns\n\ndef generate_emergency_advice(detected_condition, confidence):\n    advice_database = {\n        \"STEMI\": {\n            \"condition\": \"ST-Elevation Myocardial Infarction\",\n            \"urgency\": \"CRITICAL - CALL 911\",\n            \"action\": \"Immediate emergency medical attention required. Administer aspirin if available.\",\n            \"details\": \"Acute heart attack in progress. Every minute counts for survival.\"\n        },\n        \"VT\": {\n            \"condition\": \"Ventricular Tachycardia\",\n            \"urgency\": \"CRITICAL\",\n            \"action\": \"Seek emergency care immediately. Prepare for possible defibrillation.\",\n            \"details\": \"Life-threatening arrhythmia. Patient may lose consciousness.\"\n        },\n        \"AFib\": {\n            \"condition\": \"Atrial Fibrillation\",\n            \"urgency\": \"URGENT\",\n            \"action\": \"Contact cardiologist within 24 hours. Monitor for stroke symptoms.\",\n            \"details\": \"Irregular rhythm increases stroke risk 5x. Requires anticoagulation evaluation.\"\n        }\n    }\n    \n    if detected_condition in advice_database and confidence > 0.7:\n        return advice_database[detected_condition]\n    return None\n\n# Example demonstration\nprint(\"=\" * 60)\nprint(\"EMERGENCY TRIAGE ADVICE SYSTEM (Simulated Output)\")\nprint(\"=\" * 60)\nadvice = generate_emergency_advice(\"STEMI\", 0.85)\nif advice:\n    print(f\"\\nDetected Condition: {advice['condition']} (85% confidence)\")\n    print(f\"Urgency Level: {advice['urgency']}\")\n    print(f\"Recommended Action: {advice['action']}\")\n    print(f\"Additional Info: {advice['details']}\")\nprint(\"\\n\" + \"=\" * 60)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Placeholder: Load AI LifeSaver pretrained weights\n# In practice, we would load the model from /kaggle/input/ai-lifesaver/\nprint(\"AI LifeSaver model path: /kaggle/input/ai-lifesaver/pytorch/default/1\")\nprint(\"\\nNext steps:\")\nprint(\"1. Load pretrained weights from AI LifeSaver\")\nprint(\"2. Freeze base CNN layers\")\nprint(\"3. Fine-tune on ECG dataset\")\nprint(\"4. Validate performance metrics\")","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"markdown","source":"## ❤️ Section 3: Emergency ECG Pattern Classification Plan\n\n### Key Emergency ECG Types to Detect\n\nOur adapted AI LifeSaver model will focus on identifying critical cardiac patterns that require immediate medical attention:\n\n#### Target Classification Categories:\n\n1. **Arrhythmias:**\n   - Atrial Fibrillation (AFib) - Irregular rhythm, missing P waves\n   - Ventricular Tachycardia (VT) - Rapid ventricular rate\n   - Ventricular Fibrillation (VF) - Chaotic, life-threatening rhythm\n   - Supraventricular Tachycardia (SVT)\n\n2. **Myocardial Infarction (Heart Attack) Indicators:**\n   - ST-Elevation (STEMI) - Raised ST segment indicating acute MI\n   - ST-Depression - Possible ischemia or NSTEMI\n   - T-wave inversions\n   - Pathological Q waves\n\n3. **Conduction Abnormalities:**\n   - Bundle Branch Blocks (LBBB/RBBB)\n   - AV Blocks (1st, 2nd, 3rd degree)\n   - Prolonged QT interval (risk of sudden cardiac death)\n\n4. **Other Critical Patterns:**\n   - Bradycardia (dangerously slow heart rate)\n   - Tachycardia (dangerously fast heart rate)\n   - Premature ventricular contractions (PVCs)\n\n### Classification Approach\nWe'll use a **multi-label classification** architecture that can detect multiple conditions simultaneously, as real-world ECGs often show combined pathologies.","metadata":{}},{"cell_type":"code","source":"# Placeholder: ECG Classification Model (adapted from AI LifeSaver)\nimport torch.nn as nn\n\nclass ECGEmergencyClassifier(nn.Module):\n    def __init__(self, num_classes=10):\n        super(ECGEmergencyClassifier, self).__init__()\n        self.features = nn.Sequential(\n            nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3),\n            nn.ReLU(inplace=True),\n            nn.MaxPool2d(kernel_size=3, stride=2),\n            nn.Conv2d(64, 128, kernel_size=3, padding=1),\n            nn.ReLU(inplace=True),\n        )\n        self.classifier = nn.Sequential(\n            nn.AdaptiveAvgPool2d((1, 1)),\n            nn.Flatten(),\n            nn.Linear(128, 256),\n            nn.ReLU(),\n            nn.Dropout(0.5),\n            nn.Linear(256, num_classes),\n            nn.Sigmoid()  # Multi-label classification\n        )\n    \n    def forward(self, x):\n        x = self.features(x)\n        x = self.classifier(x)\n        return x\n\nmodel = ECGEmergencyClassifier(num_classes=10)\nprint(f\"Model initialized: {sum(p.numel() for p in model.parameters())} parameters\")\nprint(\"\\nTarget classes: AFib, VT, STEMI, BBB, Bradycardia, Tachycardia, QT Prolongation, AV Block, Normal, Other\")","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}