{"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":"import os\nimport glob\nimport numpy as np\nimport pandas as pd\nimport cv2\nimport tensorflow as tf\nfrom tensorflow.keras.models import Model, load_model\nfrom tensorflow.keras.layers import Input, Conv2D, MaxPooling2D, Flatten, Dense\nfrom tensorflow.keras.optimizers import Adam\n\nTRAIN_DIR = '/kaggle/input/physionet-ecg-image-digitization/train'\nTEST_DIR = '/kaggle/input/physionet-ecg-image-digitization/test'\nTRAIN_CSV = '/kaggle/input/physionet-ecg-image-digitization/train.csv'\nSAMPLE_SUB = '/kaggle/input/physionet-ecg-image-digitization/sample_submission.parquet'\n\nIMG_WIDTH, IMG_HEIGHT = 224, 224\n\ntrain_df = pd.read_csv(TRAIN_CSV)\ntrain_patient_csvs = glob.glob(os.path.join(TRAIN_DIR, '*/*.csv'))\ntrain_data_dict = {}\n\nfor csv_path in train_patient_csvs:\n    pid = os.path.basename(csv_path).split('.')[0]\n    train_data_dict[pid] = pd.read_csv(csv_path)\n\ntrain_images = glob.glob(os.path.join(TRAIN_DIR, '*/*.png'))\ntrain_images_dict = {}\nfor img_path in train_images:\n    pid = os.path.basename(os.path.dirname(img_path))\n    if pid not in train_images_dict:\n        train_images_dict[pid] = []\n    train_images_dict[pid].append(img_path)\n\ndef preprocess_signal(signal, length=500):\n    if len(signal) < length:\n        signal = np.pad(signal, (0, length - len(signal)), 'constant')\n    else:\n        signal = signal[:length]\n    return signal\n\ndef preprocess_image(img_path):\n    img = cv2.imread(img_path)\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)\n    img = cv2.resize(img, (IMG_WIDTH, IMG_HEIGHT))\n    img = img / 255.0\n    img = np.expand_dims(img, axis=-1)\n    return img\n\nX_images = []\ny_signals = []\nnum_samples = 200\ncount = 0\n\nfor pid in train_images_dict.keys():\n    signal_df = train_data_dict[pid]\n    signal = signal_df['I'].values\n    signal_proc = preprocess_signal(signal, length=500)\n    for img_path in train_images_dict[pid]:\n        if count >= num_samples:\n            break\n        img_proc = preprocess_image(img_path)\n        X_images.append(img_proc)\n        y_signals.append(signal_proc)\n        count += 1\n    if count >= num_samples:\n        break\n\nX_images = np.array(X_images, dtype=np.float32)\ny_signals = np.array(y_signals, dtype=np.float32)\n\ninput_img = Input(shape=(IMG_WIDTH, IMG_HEIGHT, 1))\nx = Conv2D(16, (3,3), activation='relu', padding='same')(input_img)\nx = MaxPooling2D((2,2))(x)\nx = Conv2D(32, (3,3), activation='relu', padding='same')(x)\nx = MaxPooling2D((2,2))(x)\nx = Flatten()(x)\nx = Dense(256, activation='relu')(x)\noutput = Dense(500, activation='linear')(x)\n\nmodel = Model(inputs=input_img, outputs=output)\nmodel.compile(optimizer=Adam(0.001), loss='mse')\nmodel.fit(X_images, y_signals, epochs=5, batch_size=16, verbose=1)\n\nmodel.save('/kaggle/working/ecg_digitizer_model.h5')\n\n\nsample_sub = pd.read_parquet(SAMPLE_SUB)\nsubmission = sample_sub.copy()\n\n\ntest_images = sorted(glob.glob(os.path.join(TEST_DIR, '*.png')))\n\ndef load_test_images(img_list):\n    imgs = []\n    ids = []\n    for path in img_list:\n        img = preprocess_image(path)\n        imgs.append(img)\n        ids.append(os.path.basename(path).split('.')[0])\n    return np.array(imgs, dtype=np.float32), ids\n\nX_test, test_ids = load_test_images(test_images)\n\n# Predict ECG signal from test images\npredictions = model.predict(X_test, verbose=1)\n\n# Build submission dataframe\nsub_rows = []\nfor pid, pred in zip(test_ids, predictions):\n    for i, val in enumerate(pred):\n        sub_rows.append({\"Id\": pid, \"Sample\": i, \"Value\": val})\n\nsubmission = pd.DataFrame(sub_rows)\nsubmission.to_csv(\"/kaggle/working/submission.csv\", index=False)\nprint(\"submission.csv created successfully\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-24T19:13:56.544834Z","iopub.execute_input":"2025-10-24T19:13:56.545177Z"}},"outputs":[],"execution_count":null}]}