{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":97984,"databundleVersionId":14096757,"sourceType":"competition"}],"dockerImageVersionId":31153,"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,"execution":{"iopub.status.busy":"2025-11-10T15:08:56.114667Z","iopub.execute_input":"2025-11-10T15:08:56.114928Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import cv2\nimport numpy as np\nimport matplotlib.pyplot as plt\n\ndef preprocess_image(image_path):\n    img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)\n    blurred = cv2.GaussianBlur(img, (5, 5), 0)\n    edges = cv2.Canny(blurred, 50, 150)\n    return edges\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def extract_waveform(edges):\n    height, width = edges.shape\n    waveform = []\n    for x in range(width):\n        column = edges[:, x]\n        y_indices = np.where(column > 0)[0]\n        if len(y_indices) > 0:\n            y = np.mean(y_indices)\n        else:\n            y = height / 2  # default if no edge found\n        waveform.append(y)\n    return np.array(waveform)\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def normalize_waveform(waveform):\n    waveform = (waveform - np.min(waveform)) / (np.max(waveform) - np.min(waveform))\n    waveform = 1 - waveform  # invert to match ECG polarity\n    return waveform\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\n\ndef save_submission(waveform, output_path='submission.csv'):\n    df = pd.DataFrame({'voltage': waveform})\n    df.to_csv(output_path, index=False)\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Step 1: Import libraries\nimport cv2\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\n\n# Step 2: Preprocess ECG image\ndef preprocess_image(image_path):\n    img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)\n    blurred = cv2.GaussianBlur(img, (5, 5), 0)\n    edges = cv2.Canny(blurred, 50, 150)\n    return edges\n\n# Step 3: Extract waveform from image\ndef extract_waveform(edges):\n    height, width = edges.shape\n    waveform = []\n    for x in range(width):\n        column = edges[:, x]\n        y_indices = np.where(column > 0)[0]\n        if len(y_indices) > 0:\n            y = np.mean(y_indices)\n        else:\n            y = height / 2  # default if no edge found\n        waveform.append(y)\n    return np.array(waveform)\n\n# Step 4: Normalize waveform\ndef normalize_waveform(waveform):\n    waveform = (waveform - np.min(waveform)) / (np.max(waveform) - np.min(waveform))\n    waveform = 1 - waveform  # invert to match ECG polarity\n    return waveform\n\n# Step 5: Save submission file\ndef save_submission(waveform, output_path='submission.csv'):\n    df = pd.DataFrame({'voltage': waveform})\n    df.to_csv(output_path, index=False)\n\n# Step 6: Run the pipeline\nimage_path = '/kaggle/input/ecg-images/sample_ecg.png'  # Update with your image path\nedges = preprocess_image(image_path)\nwaveform = extract_waveform(edges)\nnormalized_waveform = normalize_waveform(waveform)\nsave_submission(normalized_waveform)\n\n# Optional: Visualize the waveform\nplt.plot(normalized_waveform)\nplt.title('Extracted ECG Time Series')\nplt.xlabel('Time')\nplt.ylabel('Normalized Voltage')\nplt.show()\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport cv2\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\n\n# Step 1: Preprocess ECG image\ndef preprocess_image(image_path):\n    img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)\n    blurred = cv2.GaussianBlur(img, (5, 5), 0)\n    edges = cv2.Canny(blurred, 50, 150)\n    return edges\n\n# Step 2: Extract waveform from image\ndef extract_waveform(edges):\n    height, width = edges.shape\n    waveform = []\n    for x in range(width):\n        column = edges[:, x]\n        y_indices = np.where(column > 0)[0]\n        if len(y_indices) > 0:\n            y = np.mean(y_indices)\n        else:\n            y = height / 2\n        waveform.append(y)\n    return np.array(waveform)\n\n# Step 3: Normalize waveform\ndef normalize_waveform(waveform):\n    waveform = (waveform - np.min(waveform)) / (np.max(waveform) - np.min(waveform))\n    waveform = 1 - waveform\n    return waveform\n\n# Step 4: Process all images and save submission\ndef process_all_images(image_folder, output_path='submission.csv'):\n    submission_data = []\n    for filename in os.listdir(image_folder):\n        if filename.endswith('.png') or filename.endswith('.jpg'):\n            image_id = filename.split('.')[0]\n            image_path = os.path.join(image_folder, filename)\n            edges = preprocess_image(image_path)\n            waveform = extract_waveform(edges)\n            normalized_waveform = normalize_waveform(waveform)\n            submission_data.append({\n                'id': image_id,\n                'voltage_series':\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"![](http://)","metadata":{}},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}