Базовый коммит
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
from typing import NamedTuple
|
||||
import os
|
||||
import torch
|
||||
import numpy as np
|
||||
import pydicom
|
||||
from service.structs import PredictorInput, TagError, MetaTags
|
||||
|
||||
|
||||
class InputImage(NamedTuple):
|
||||
img: np.ndarray
|
||||
ww: int
|
||||
wc: int
|
||||
uid: str
|
||||
color_inversion: bool
|
||||
|
||||
|
||||
def _get_ww_wc(study_ww, study_wc):
|
||||
if type(study_ww) is pydicom.valuerep.DSfloat:
|
||||
return int(study_ww), int(study_wc)
|
||||
return int(study_ww[0]), int(study_wc[0])
|
||||
|
||||
|
||||
def _is_color_inverted(study):
|
||||
return study.PhotometricInterpretation == "MONOCHROME1"
|
||||
|
||||
|
||||
def _prep_img(img_pack: InputImage) -> torch.Tensor:
|
||||
img = img_pack.img.astype(np.float32)
|
||||
lower_bound = img_pack.wc - 0.5 * img_pack.ww
|
||||
upper_bound = img_pack.wc + 0.5 * img_pack.ww
|
||||
img = np.clip(img, lower_bound, upper_bound)
|
||||
img = ((img - lower_bound) / img_pack.ww) * 255
|
||||
img = img.astype(np.uint8)
|
||||
if img_pack.color_inversion:
|
||||
img = 255 - img
|
||||
return torch.from_numpy(img[None, ...])
|
||||
|
||||
|
||||
def _check_required_tags(study: pydicom.FileDataset, pathology: str):
|
||||
invalid_tags = []
|
||||
if not (hasattr(study, "PhotometricInterpretation") and
|
||||
study.PhotometricInterpretation in ("MONOCHROME1", "MONOCHROME2")):
|
||||
invalid_tags.append("PhotometricInterpretation")
|
||||
if pathology in ("shoulder", "wrist"):
|
||||
if not (hasattr(study, "PixelSpacing") or
|
||||
hasattr(study, "ImagerPixelSpacing")):
|
||||
invalid_tags.append("PixelSpacing/ImagerPixelSpacing")
|
||||
for tag in ("WindowWidth", "WindowCenter"):
|
||||
if not hasattr(study, tag) or getattr(study, tag) == "":
|
||||
invalid_tags.append(tag)
|
||||
if len(invalid_tags) == 1:
|
||||
raise TagError(f"DICOM тег {invalid_tags[0]} не заполнен, "\
|
||||
"либо имеет некорректное значение")
|
||||
elif len(invalid_tags) > 1:
|
||||
raise TagError(f"DICOM теги {", ".join(invalid_tags)} не заполнены, "\
|
||||
"либо имеют некорректные значения")
|
||||
|
||||
|
||||
def _get_meta_tags(study: pydicom.FileDataset):
|
||||
return MetaTags(study.StudyInstanceUID, study.SeriesInstanceUID,
|
||||
getattr(study, "PatientID", None),
|
||||
getattr(study, "AccessionNumber", None),
|
||||
getattr(study, "IssuerOfPatientID", None),
|
||||
getattr(study, "FillerOrderNumberImagingServiceRequest",
|
||||
None))
|
||||
|
||||
|
||||
def _get_px_size(study: pydicom.FileDataset):
|
||||
if hasattr(study, "PixelSpacing"):
|
||||
return study.PixelSpacing
|
||||
if hasattr(study, "ImagerPixelSpacing"):
|
||||
return study.ImagerPixelSpacing
|
||||
return None, None
|
||||
|
||||
|
||||
def prep_imgs(pathology: str, study_path: str) -> tuple[MetaTags, PredictorInput]:
|
||||
instance = pydicom.dcmread(study_path, force=True)
|
||||
_check_required_tags(instance, pathology)
|
||||
meta_tags = _get_meta_tags(instance)
|
||||
ww, wc = _get_ww_wc(instance.WindowWidth, instance.WindowCenter)
|
||||
clr_inverted = _is_color_inverted(instance)
|
||||
img = InputImage(instance.pixel_array, ww, wc, meta_tags.study_iuid, clr_inverted)
|
||||
pred_input = PredictorInput(meta_tags.study_iuid, _prep_img(img),
|
||||
getattr(instance, "ImageLaterality", None),
|
||||
*_get_px_size(instance))
|
||||
return meta_tags, pred_input
|
||||
Reference in New Issue
Block a user