{"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"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"from pathlib import Path\nfrom collections import defaultdict\nimport numpy as np\nimport pandas as pd\nimport cv2\nimport matplotlib.pyplot as plt\nimport torch\nimport torch.nn.functional as F","metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","papermill":{"duration":4.211159,"end_time":"2023-10-18T08:58:07.859102","exception":false,"start_time":"2023-10-18T08:58:03.647943","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-10-19T00:18:25.665316Z","iopub.execute_input":"2023-10-19T00:18:25.666048Z","iopub.status.idle":"2023-10-19T00:18:29.475502Z","shell.execute_reply.started":"2023-10-19T00:18:25.666012Z","shell.execute_reply":"2023-10-19T00:18:29.474544Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! wget https://dl.fbaipublicfiles.com/sscd-copy-detection/sscd_disc_mixup.torchscript.pt","metadata":{"papermill":{"duration":7.638849,"end_time":"2023-10-18T08:58:15.500979","exception":false,"start_time":"2023-10-18T08:58:07.86213","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-10-19T00:18:29.477069Z","iopub.execute_input":"2023-10-19T00:18:29.477428Z","iopub.status.idle":"2023-10-19T00:18:31.093699Z","shell.execute_reply.started":"2023-10-19T00:18:29.477405Z","shell.execute_reply":"2023-10-19T00:18:31.092559Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = \"cuda\" if torch.cuda.is_available() else \"cpu\"\nimg_size = 128\nmax_slice_num = 128","metadata":{"papermill":{"duration":0.077551,"end_time":"2023-10-18T08:58:15.581758","exception":false,"start_time":"2023-10-18T08:58:15.504207","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-10-19T00:18:31.09532Z","iopub.execute_input":"2023-10-19T00:18:31.095687Z","iopub.status.idle":"2023-10-19T00:18:31.123649Z","shell.execute_reply.started":"2023-10-19T00:18:31.095651Z","shell.execute_reply":"2023-10-19T00:18:31.122769Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = torch.jit.load(\"sscd_disc_mixup.torchscript.pt\").eval().to(device)","metadata":{"papermill":{"duration":3.488725,"end_time":"2023-10-18T08:58:19.073819","exception":false,"start_time":"2023-10-18T08:58:15.585094","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-10-19T00:18:31.125884Z","iopub.execute_input":"2023-10-19T00:18:31.126479Z","iopub.status.idle":"2023-10-19T00:18:34.615559Z","shell.execute_reply.started":"2023-10-19T00:18:31.126451Z","shell.execute_reply":"2023-10-19T00:18:34.614545Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"patient_id_to_series_ids = defaultdict(set)\n\nfor img_path in Path(\"/kaggle/input/rsna-abdominal-trauma-detection-png-pt1\").glob(\"*.png\"):\n    patient_id, series_id = img_path.stem.split(\"_\")[:2]\n    patient_id_to_series_ids[patient_id].add(series_id)","metadata":{"papermill":{"duration":11.433265,"end_time":"2023-10-18T08:58:30.511071","exception":false,"start_time":"2023-10-18T08:58:19.077806","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-10-19T00:18:34.617058Z","iopub.execute_input":"2023-10-19T00:18:34.617624Z","iopub.status.idle":"2023-10-19T00:18:46.592841Z","shell.execute_reply.started":"2023-10-19T00:18:34.61759Z","shell.execute_reply":"2023-10-19T00:18:46.59209Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"@torch.no_grad()\ndef get_embeddings(series_id):\n    img_paths = sorted(Path(\"/kaggle/input/rsna-abdominal-trauma-detection-png-pt1\").glob(f\"*_{series_id}_*.png\"))\n    \n    if len(img_paths) > max_slice_num:\n        indices = np.round(np.linspace(0, len(img_paths) - 1, max_slice_num)).astype(int)\n        img_paths = np.array(img_paths)[indices]\n    \n    imgs = []\n    \n    for img_path in img_paths:\n        img = cv2.imread(str(img_path), 0)\n        imgs.append(torch.from_numpy(img))\n    \n    imgs = torch.stack(imgs, dim=0)\n    d, h, w = imgs.shape\n    x = imgs.reshape(d, 1, h, w)\n    x = F.interpolate(x, (img_size, img_size), mode=\"bilinear\")\n    x = x.expand(d, 3, img_size, img_size)\n    x = (x - 128.0) / 64\n    x = x.to(device)\n    x = model(x)\n    return imgs, x","metadata":{"papermill":{"duration":0.013562,"end_time":"2023-10-18T08:58:30.528176","exception":false,"start_time":"2023-10-18T08:58:30.514614","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-10-19T00:18:46.593839Z","iopub.execute_input":"2023-10-19T00:18:46.594088Z","iopub.status.idle":"2023-10-19T00:18:46.600946Z","shell.execute_reply.started":"2023-10-19T00:18:46.594068Z","shell.execute_reply":"2023-10-19T00:18:46.600157Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i, series_ids in enumerate(patient_id_to_series_ids.values()):\n    if len(series_ids) < 2:\n        continue\n    \n    series_id0, series_id1 = series_ids\n    imgs0, embeddings0 = get_embeddings(series_id0)\n    imgs1, embeddings1 = get_embeddings(series_id1)\n    sim = (embeddings0 @ embeddings1.T).cpu().numpy()\n    h, w = sim.shape\n    img = np.zeros((h, w), dtype=np.uint8)\n\n    if w > h:\n        img[range(h), sim.argmax(axis=1)] = 1\n    else:\n        img[sim.argmax(axis=0), range(w)] = 1\n\n    img = img * (sim > 0.5).astype(np.uint8)\n    lines = cv2.HoughLines(img, 1, np.pi / 180, 10)\n    rho, theta = lines[0, 0]\n    a = np.cos(theta)\n    b = np.sin(theta)\n    \n    def get_y(x):\n        return (rho - a * x) / b\n    \n    xs = np.arange(0, w, 1)\n    ys = get_y(xs).astype(int)\n    valid = (ys >= 0) & (ys < h)\n    xs = xs[valid]\n    ys = ys[valid]\n    imgs0 = imgs0[ys]\n    imgs1 = imgs1[xs]\n    img = cv2.line(img, (xs[0], ys[0]), (xs[-1], ys[-1]), 2, 1)\n    \n    fig, axs = plt.subplots(3, 2, figsize=(10, 8))\n    axs[0, 0].set_title(\"similarity matrix\")\n    axs[0, 0].imshow(sim)\n    axs[0, 1].set_title(\"hough transformation result\")\n    axs[0, 1].imshow(img)\n    axs[1, 0].set_title(f\"series_id: {series_id0}\")\n    axs[1, 0].imshow(imgs0[:, :, imgs0.shape[-1] // 2])\n    axs[1, 1].set_title(f\"series_id: {series_id1}\")\n    axs[1, 1].imshow(imgs1[:, :, imgs1.shape[-1] // 2])\n    axs[2, 0].imshow(imgs0[imgs0.shape[0] // 2])\n    axs[2, 1].imshow(imgs1[imgs1.shape[0] // 2])\n    plt.tight_layout()\n    plt.show()\n    \n    if i >= 50:\n        break","metadata":{"papermill":{"duration":176.868754,"end_time":"2023-10-18T09:01:27.399761","exception":false,"start_time":"2023-10-18T08:58:30.531007","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-10-19T00:18:46.601981Z","iopub.execute_input":"2023-10-19T00:18:46.60224Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"papermill":{"duration":0.130131,"end_time":"2023-10-18T09:01:27.673795","exception":false,"start_time":"2023-10-18T09:01:27.543664","status":"completed"},"tags":[]},"execution_count":null,"outputs":[]}]}