Skip to content
Snippets Groups Projects
Commit 24983eb3 authored by Tamino Huxohl's avatar Tamino Huxohl
Browse files

add script to extract perfusion values from polar maps

parent 404b8d0f
No related branches found
No related tags found
No related merge requests found
from dataclasses import dataclass
from typing import Tuple
import cv2 as cv
import numpy as np
import pytesseract
@dataclass
class PolarMapSegment:
id: int
rect: Tuple[int, int, int, int]
name: str
location: str
# see https://www.ahajournals.org/doi/full/10.1161/hc0402.102975
SEGMENTS = [
PolarMapSegment( id=1, location="basal", name="anterior", rect=( 14, 190, 41, 217)),
PolarMapSegment( id=2, location="basal", name="anteroseptal", rect=(101, 36, 128, 63)),
PolarMapSegment( id=3, location="basal", name="inferoseptal", rect=(277, 36, 304, 63)),
PolarMapSegment( id=4, location="basal", name="inferior", rect=(365, 190, 392, 217)),
PolarMapSegment( id=5, location="basal", name="inferolateral", rect=(277, 341, 304, 370)),
PolarMapSegment( id=6, location="basal", name="anterolateral", rect=(101, 340, 128, 367)),
PolarMapSegment( id=7, location="mid", name="anterior", rect=( 64, 190, 91, 217)),
PolarMapSegment( id=8, location="mid", name="anteroseptal", rect=(128, 80, 155, 107)),
PolarMapSegment( id=9, location="mid", name="inferoseptal", rect=(251, 80, 278, 107)),
PolarMapSegment(id=10, location="mid", name="inferior", rect=(313, 188, 340, 215)),
PolarMapSegment(id=11, location="mid", name="inferolateral", rect=(251, 298, 278, 325)),
PolarMapSegment(id=12, location="mid", name="anterolateral", rect=(128, 298, 155, 325)),
PolarMapSegment(id=13, location="apical", name="anterior", rect=(115, 190, 142, 217)),
PolarMapSegment(id=14, location="apical", name="septal", rect=(190, 113, 217, 140)),
PolarMapSegment(id=15, location="apical", name="inferior", rect=(265, 188, 292, 215)),
PolarMapSegment(id=16, location="apical", name="lateral", rect=(190, 265, 217, 292)),
PolarMapSegment(id=17, location="apex", name="apex", rect=(190, 190, 217, 217)),
]
hsv_green_lower = np.array([40, 100, 100])
hsv_green_upper = np.array([80, 255, 255])
if __name__ == "__main__":
import argparse
import os
import pandas as pd
from mu_map.data.prepare_polar_maps import headers
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
parser.add_argument(
"--polar_map_dir", type=str, required=True, help="directory where files are output to"
)
parser.add_argument(
"--images_dir",
type=str,
default="images",
help="directory under <out_dir> where images of polar maps are stored",
)
parser.add_argument(
"--csv",
type=str,
default="polar_maps.csv",
help="file unter <out_dir> where meta information is stored",
)
parser.add_argument(
"--perfusion_csv",
type=str,
default="perfusion.csv",
help="csv file output by this script under polar_map_dir",
)
parser.add_argument(
"--number_res",
type=int,
default=128,
help="numbers cutouts are rescaled to this resolution for better number recognition",
)
args = parser.parse_args()
args.images_dir = os.path.join(args.polar_map_dir, args.images_dir)
args.csv = os.path.join(args.polar_map_dir, args.csv)
args.perfusion_csv = os.path.join(args.polar_map_dir, args.perfusion_csv)
data = pd.read_csv(args.csv)
rows = []
for i in range(len(data)):
row = data.iloc[i]
_id = row[headers.id]
_file = os.path.join(args.images_dir, row[headers.file])
polar_map = cv.imread(_file)
for segment in SEGMENTS:
# extract number segment
top, left, bottom, right = segment.rect
img_number = polar_map[top:bottom, left:right]
# process segment for improved automatic number detection
img_number = cv.resize(img_number, (args.number_res, args.number_res))
img_number = cv.cvtColor(img_number, cv.COLOR_BGR2HSV)
img_number = cv.inRange(img_number, hsv_green_lower, hsv_green_upper)
img_number = cv.morphologyEx(img_number, cv.MORPH_CLOSE, np.ones((4, 4), np.uint8))
img_number = cv.morphologyEx(img_number, cv.MORPH_OPEN, np.ones((2, 2), np.uint8))
_, img_number = cv.threshold(img_number, 0, 255, cv.THRESH_BINARY_INV)
# try to recognize number
str_number = pytesseract.image_to_string(img_number, config="-c tessedit_char_whitelist=[1,2,3,4,5,6,7,8,9,0] --psm 7")
str_number = str_number.strip()
# prepare image for visualization
_polar_map = polar_map.copy()
_polar_map = cv.rectangle(_polar_map, (left, top), (right, bottom), (255, 255, 255), 1)
_polar_map = cv.resize(_polar_map, (512, 512))
img_number = img_number.repeat(3).reshape((*img_number.shape, 3))
img_number = cv.resize(img_number, (512, 512))
space_h = np.full((512, 10, 3), 239, np.uint8)
cv.imshow("Polar Map - Segment", np.hstack((_polar_map, space_h, img_number)))
cv.waitKey(50)
while True:
_input = input(f"Number is {str_number} (y/other): ")
try:
if _input == "y":
number = int(str_number)
break
elif _input == "q":
exit(0)
else:
number = int(_input)
break
except ValueError:
print(f"Cannot parse {_input} as a number. Please enter a valid number.")
_value = pd.Series({f"segment_{segment.id}": number})
row = pd.concat([row, _value])
rows.append(row)
pd.DataFrame(rows).to_csv(args.perfusion_csv)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment