atom-predict/msunet/.ipynb_checkpoints/Infer-checkpoint.ipynb

601 lines
16 KiB
Plaintext
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "f8d96fcf",
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"import cv2\n",
"import json\n",
"import glob\n",
"import shutil\n",
"from labelme import utils\n",
"import seaborn as sns\n",
"import numpy as np\n",
"import pandas as pd\n",
"import matplotlib.pyplot as plt\n",
"\n",
"from tqdm import tqdm\n",
"from PIL import ImageEnhance\n",
"from PIL import Image\n",
"from skimage.feature import peak_local_max\n",
"\n",
"from core.e2e import get_metrics"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "8537a10b-d7a7-4e0b-a27b-8448eb409bd8",
"metadata": {},
"outputs": [],
"source": [
"data_base_path = '/home/andrewtal/Workspace/metrials/v15_Final/data/infer'\n",
"\n",
"slide_path = os.path.join(data_base_path, 'slide')\n",
"slide_gt_path = os.path.join(data_base_path, 'slide_gt')\n",
"slide_gt3_path = os.path.join(data_base_path, 'slide_gt3')\n",
"slide_pred_path = os.path.join(data_base_path, 'slide_pred')\n",
"slide_pden_path = os.path.join(data_base_path, 'slide_pred_den')\n",
"slide_vis_path = os.path.join(data_base_path, 'slide_vis')\n",
"patch_path = os.path.join(data_base_path, 'patch')\n",
"\n",
"os.makedirs(slide_path, exist_ok=True)\n",
"os.makedirs(slide_gt_path, exist_ok=True)\n",
"os.makedirs(slide_gt3_path, exist_ok=True)\n",
"os.makedirs(slide_pred_path, exist_ok=True)\n",
"os.makedirs(slide_pden_path, exist_ok=True)\n",
"os.makedirs(slide_vis_path, exist_ok=True)\n",
"os.makedirs(patch_path, exist_ok=True)"
]
},
{
"cell_type": "markdown",
"id": "c935b002",
"metadata": {},
"source": [
"# UTILS"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "13205b6d",
"metadata": {},
"outputs": [],
"source": [
"def norm_0_1(mask):\n",
" x_min = np.min(mask)\n",
" x_max = np.max(mask)\n",
" \n",
" new_mask = (mask-x_min)/(x_max-x_min)\n",
" \n",
" return new_mask\n",
"\n",
"def get_dotsmap(den_map, min_dis=8, thres=0.3):\n",
" \n",
" if np.max(den_map) < thres:\n",
" return []\n",
" \n",
" den_map = norm_0_1(den_map)\n",
" \n",
" x_y = peak_local_max(\n",
" den_map, \n",
" min_distance = min_dis,\n",
" threshold_abs = thres,\n",
" )\n",
" \n",
" dots_map = np.zeros(den_map.shape)\n",
" dots_map[x_y[:, 0].tolist(), x_y[:, 1].tolist()] = 1\n",
" \n",
" return dots_map"
]
},
{
"cell_type": "markdown",
"id": "0856aa9b-6972-4202-a81d-69a54526830d",
"metadata": {
"tags": []
},
"source": [
"# 中心点检测"
]
},
{
"cell_type": "markdown",
"id": "d6d03146",
"metadata": {
"tags": []
},
"source": [
"## 数据裁剪 (模型预测级别)\n",
"单张图像大小为1024, 1024预测模型输入大小为256256"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "3bd836ac",
"metadata": {},
"outputs": [],
"source": [
"def generate_one(img_path):\n",
" img = np.array(Image.open(img_path))\n",
" \n",
" input_size = 2048\n",
" patch_size = 256\n",
" roi_size = 128\n",
" margin = int((patch_size - roi_size) / 2)\n",
"\n",
" assert(img.shape == (input_size, input_size))\n",
"\n",
" for hs in range(0, input_size, roi_size):\n",
" for ws in range(0, input_size, roi_size):\n",
" # hs\n",
" if hs - margin < 0:\n",
" phs = 0\n",
" elif hs + roi_size + margin > input_size:\n",
" phs = input_size - patch_size\n",
" else:\n",
" phs = hs - margin\n",
"\n",
" phe = phs + patch_size\n",
"\n",
" # ws\n",
" if ws - margin < 0:\n",
" pws = 0\n",
" elif ws + roi_size + margin > input_size:\n",
" pws = input_size - patch_size\n",
" else:\n",
" pws = ws - margin\n",
"\n",
" pwe = pws + patch_size\n",
"\n",
" Image.fromarray(img[phs:phe, pws:pwe]).save(\n",
" img_path.replace('/slide/', '/patch/').replace(\n",
" '.jpg', '_{}_{}_{}_{}.jpg'.format(int(hs), int(ws), int(phs), int(pws))\n",
" )\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "89329db5",
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"text/plain": [
"3"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"img_list = glob.glob(os.path.join(slide_path, '*.jpg'), recursive=True); len(img_list)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "0dab5bc1",
"metadata": {},
"outputs": [],
"source": [
"for item in img_list:\n",
" generate_one(item)"
]
},
{
"cell_type": "markdown",
"id": "00cc16e2",
"metadata": {},
"source": [
"## 预测 Patch 结果"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "2b5abb65",
"metadata": {},
"outputs": [],
"source": [
"# python inference.py"
]
},
{
"cell_type": "markdown",
"id": "d2e061e2-0985-4d77-8944-4f4e6b10523b",
"metadata": {},
"source": [
"# GT"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "713377ef-70e3-4231-9da1-9127e216c870",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"json_list = glob.glob(os.path.join(slide_path, '*.json'), recursive=True); len(json_list)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "4ef0ff20-9c9c-4d60-ad35-630875053495",
"metadata": {},
"outputs": [],
"source": [
"for json_path in json_list:\n",
" base_name = json_path.split('/')[-1].split('.')[0]\n",
" with open(json_path) as f:\n",
" j_data = json.load(f)\n",
"\n",
" y = np.array(np.array([item['label'] for item in j_data['shapes']]) != 'Norm', np.uint8) + 1\n",
" p = np.array([item['points'][0][::-1] for item in j_data['shapes']], np.int32)\n",
"\n",
" m = np.zeros((2048, 2048))\n",
" m[p[:, 0], p[:, 1]] = y\n",
" m = np.array(m, np.uint8)\n",
"\n",
" Image.fromarray(m).save('{}/{}.png'.format(slide_gt_path, base_name))"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "840d713e-0c26-4fe5-a5d5-edb15dad4b11",
"metadata": {},
"outputs": [],
"source": [
"data_dict = {\n",
" 'Norm': 1,\n",
" 'LineSV': 2,\n",
" 'SV': 3\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "c597a743-9932-49d0-a56f-5053e7a47306",
"metadata": {},
"outputs": [],
"source": [
"for json_path in json_list:\n",
" base_name = json_path.split('/')[-1].split('.')[0]\n",
" with open(json_path) as f:\n",
" j_data = json.load(f)\n",
"\n",
" y = np.array([data_dict[item['label']] for item in j_data['shapes']], np.uint8)\n",
" p = np.array([item['points'][0][::-1] for item in j_data['shapes']], np.int32)\n",
"\n",
" m = np.zeros((2048, 2048))\n",
" m[p[:, 0], p[:, 1]] = y\n",
" m = np.array(m, np.uint8)\n",
"\n",
" Image.fromarray(m).save('{}/{}.png'.format(slide_gt3_path, base_name))"
]
},
{
"cell_type": "markdown",
"id": "3ec0e255",
"metadata": {},
"source": [
"## 重整预测结果"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "cd6b5cff-4b9b-465f-b7bc-ee1c218eb6d9",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 8/8 [02:22<00:00, 17.82s/it]\n"
]
}
],
"source": [
"pds = []\n",
"for i in tqdm(range(8)):\n",
" with open('./infer_patch_{}.json'.format(str(i))) as f:\n",
" data = json.load(f)\n",
" \n",
" imgs = np.array(data['img_path'])\n",
" pds += [np.array(data['pred'])]"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "84b86d4e-2670-40f4-859f-1d123e9367b4",
"metadata": {},
"outputs": [],
"source": [
"slide_pred_path = os.path.join(data_base_path, 'slide_pred_{}'.format(n))\n",
"os.makedirs(slide_pred_path, exist_ok=True)"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "5575c5ca-fa26-446f-9c8d-bd8af40b3bd7",
"metadata": {},
"outputs": [],
"source": [
"pds_m = np.mean(np.array(pds), axis=0)"
]
},
{
"cell_type": "markdown",
"id": "609b1b74-0949-4ed5-a5ce-da491d08758f",
"metadata": {},
"source": [
"# Save Results"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "96cee923",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([0.99319904, 0.98927185, 0.99120423])"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"imgs_name = np.array([item.split('/')[-1].split('_')[0] for item in imgs])\n",
"imgs_name_sets = set(imgs_name)\n",
"\n",
"input_size = 2048\n",
"roi_size = 128\n",
"\n",
"for name in imgs_name_sets:\n",
" idx = imgs_name == name\n",
"\n",
" imgs_temp = imgs[idx]\n",
" pds_temp = pds_m[idx]\n",
"\n",
" den_map = np.zeros((input_size, input_size), np.float32)\n",
"\n",
" for i, item in enumerate(imgs_temp):\n",
" hs, ws, phs, pws = item.split('/')[-1].split('.')[0].split('_')[-4:]\n",
" hs = int(hs)\n",
" ws = int(ws)\n",
" phs = int(phs)\n",
" pws = int(pws)\n",
"\n",
" den_map[hs:hs+roi_size, ws:ws+roi_size] = pds_temp[i][hs-phs:hs-phs+roi_size, ws-pws:ws-pws+roi_size]\n",
"\n",
" np.save('{}/{}.npy'.format(slide_pden_path, name), den_map)\n",
" dots_map = get_dotsmap(den_map, min_dis=8, thres=0.3)\n",
"\n",
" Image.fromarray(dots_map).convert('L').save(\n",
" os.path.join(slide_pred_path, '{}.png'.format(name))\n",
" )\n",
"\n",
"base_names = ['5', '10', '15']\n",
"results = []\n",
"for base_name in base_names:\n",
" gt = cv2.imread('{}/{}.png'.format(slide_gt_path, base_name), 0)\n",
" pred = cv2.imread('{}/{}.png'.format(slide_pred_path, base_name), 0)\n",
" results += [get_metrics(gt, pred, 0.5)]\n",
"\n",
"np.mean(results, axis=0)"
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "85cd28c5-dd54-42cf-a85b-79426a5e4121",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[(0.9941186954197113, 0.9982104509663565, 0.9961603714617376),\n",
" (0.9962653387871243, 0.9989300998573466, 0.997595939809456),\n",
" (0.9892130857648099, 0.9706749956619816, 0.9798563671396042)]"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"results"
]
},
{
"cell_type": "markdown",
"id": "96445c27-9791-45f1-bb35-35d4e078a429",
"metadata": {},
"source": [
"# Plot"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "0d5f03f2-5818-47ca-90af-6ee6cdb7bf88",
"metadata": {},
"outputs": [],
"source": [
"base_names = ['5', '10', '15']"
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "c600f9e3-34e4-412d-8eb0-3b5b5e5f2f75",
"metadata": {},
"outputs": [],
"source": [
"for base_name in base_names:\n",
" img_path = '../../data/slidep/{}.jpg'.format(base_name)\n",
" gt_path = '../../data/infer/slide_gt/{}.png'.format(base_name)\n",
" pd_path = '../../data/infer/slide_pred/{}.png'.format(base_name)\n",
" den_path = '../../data/infer/slide_pred_den/{}.npy'.format(base_name)\n",
"\n",
" img = cv2.imread(img_path, 0)\n",
" gt = cv2.imread(gt_path, 0)\n",
" pd = cv2.imread(pd_path, 0)\n",
" den = np.load(den_path)\n",
"\n",
" plt.figure(figsize=(15, 6))\n",
" plt.subplot(1, 3, 1)\n",
" plt.imshow(img, cmap='gray')\n",
" plt.axis('off')\n",
" plt.title('Ground truth_'+base_name)\n",
" h, w = np.where(gt != 0)\n",
" plt.scatter(w, h, s=4)\n",
"\n",
" plt.subplot(1, 3, 2)\n",
" plt.imshow(den_map)\n",
" plt.axis('off')\n",
" plt.title('Density map_'+base_name)\n",
"\n",
" plt.subplot(1, 3, 3)\n",
" plt.imshow(img, cmap='gray')\n",
" h, w = np.where(pd != 0)\n",
" plt.scatter(w, h, s=4)\n",
" plt.axis('off')\n",
" plt.title('Prediction_'+base_name)\n",
" plt.tight_layout()\n",
"\n",
" plt.savefig('{}/{}.jpg'.format(slide_vis_path, base_name), dpi=200)\n",
" plt.close()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fe34998f-aa2f-4160-804b-a959d96ac272",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "1ab53ed8-3f82-43b4-ac90-9c6fa0cf72c9",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "05b370dd-9582-47c3-be2f-3ab2eee08bb0",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "a7b1b7c9-f329-4407-bd2a-3dc1e7984b7c",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "93a997eb-0d99-40ae-a7c5-7eb84cbbc64f",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "57fc2159-e317-4065-8c5a-8adf0fa48ff6",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "6c651935-2577-4227-93d7-908e05c08716",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "26d2a8e8-c8d0-453a-82d8-02660ebf354f",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "8dac93ed-8fa3-4516-b616-34c583d75b42",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "cmae",
"language": "python",
"name": "cmae"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.16"
}
},
"nbformat": 4,
"nbformat_minor": 5
}