draw deformation cutoff line in previews
This commit is contained in:
@@ -119,6 +119,28 @@ def crop_head_neck(image):
|
|||||||
return image.crop((left, top, right, bottom))
|
return image.crop((left, top, right, bottom))
|
||||||
|
|
||||||
|
|
||||||
|
def cutoff_center_z(coordinates_cutoff):
|
||||||
|
return float(np.mean([point[0] for point in coordinates_cutoff]))
|
||||||
|
|
||||||
|
|
||||||
|
def draw_cutoff_line(panel, image_depth, coordinates_cutoff=DEFAULT_COORDINATES_CUTOFF):
|
||||||
|
panel = panel.copy()
|
||||||
|
crop_height = int(image_depth * 0.72)
|
||||||
|
if crop_height <= 0:
|
||||||
|
return panel
|
||||||
|
|
||||||
|
line_y = int(round((image_depth - 1 - cutoff_center_z(coordinates_cutoff)) * panel.height / crop_height))
|
||||||
|
if line_y < 0 or line_y >= panel.height:
|
||||||
|
return panel
|
||||||
|
|
||||||
|
draw = ImageDraw.Draw(panel)
|
||||||
|
shadow = (0, 0, 0)
|
||||||
|
line_color = (255, 215, 60)
|
||||||
|
draw.line((0, line_y, panel.width, line_y), fill=shadow, width=6)
|
||||||
|
draw.line((0, line_y, panel.width, line_y), fill=line_color, width=3)
|
||||||
|
return panel
|
||||||
|
|
||||||
|
|
||||||
def fit_image(image, width, height):
|
def fit_image(image, width, height):
|
||||||
scale = min(width / image.width, height / image.height)
|
scale = min(width / image.width, height / image.height)
|
||||||
resized = image.resize(
|
resized = image.resize(
|
||||||
@@ -333,12 +355,18 @@ def run_deformation(input_dir, output_dir, angle_degrees, transition_width, prog
|
|||||||
output_paths["legacy_soft"] = legacy_soft_dir
|
output_paths["legacy_soft"] = legacy_soft_dir
|
||||||
|
|
||||||
progress("正在生成四状态过程对比图...")
|
progress("正在生成四状态过程对比图...")
|
||||||
preview_paths = make_four_state_preview(state_images, Path(output_dir), angle_degrees)
|
preview_paths = make_four_state_preview(
|
||||||
|
state_images,
|
||||||
|
Path(output_dir),
|
||||||
|
angle_degrees,
|
||||||
|
vol_info.coordinates_cutoff,
|
||||||
|
)
|
||||||
make_output_preview_from_images(
|
make_output_preview_from_images(
|
||||||
state_images["original"],
|
state_images["original"],
|
||||||
state_images["soft_transition"],
|
state_images["soft_transition"],
|
||||||
Path(output_dir),
|
Path(output_dir),
|
||||||
angle_degrees,
|
angle_degrees,
|
||||||
|
vol_info.coordinates_cutoff,
|
||||||
)
|
)
|
||||||
return output_paths, preview_paths
|
return output_paths, preview_paths
|
||||||
|
|
||||||
@@ -375,14 +403,17 @@ def make_output_preview(original_dir, deformed_dicom_dir, output_dir, angle_degr
|
|||||||
return preview_path
|
return preview_path
|
||||||
|
|
||||||
|
|
||||||
def sitk_sagittal_panel(image):
|
def sitk_sagittal_panel(image, coordinates_cutoff=None):
|
||||||
volume = sitk.GetArrayFromImage(image)[::-1]
|
volume = sitk.GetArrayFromImage(image)[::-1]
|
||||||
return crop_head_neck(sagittal_mip(volume))
|
panel = crop_head_neck(sagittal_mip(volume))
|
||||||
|
if coordinates_cutoff is not None:
|
||||||
|
panel = draw_cutoff_line(panel, volume.shape[0], coordinates_cutoff)
|
||||||
|
return panel
|
||||||
|
|
||||||
|
|
||||||
def make_output_preview_from_images(original_image, deformed_image, output_dir, angle_degrees):
|
def make_output_preview_from_images(original_image, deformed_image, output_dir, angle_degrees, coordinates_cutoff=None):
|
||||||
before = sitk_sagittal_panel(original_image)
|
before = sitk_sagittal_panel(original_image, coordinates_cutoff)
|
||||||
after = sitk_sagittal_panel(deformed_image)
|
after = sitk_sagittal_panel(deformed_image, coordinates_cutoff)
|
||||||
|
|
||||||
slide = Image.new("RGB", (2560, 1440), (0, 0, 0))
|
slide = Image.new("RGB", (2560, 1440), (0, 0, 0))
|
||||||
draw = ImageDraw.Draw(slide)
|
draw = ImageDraw.Draw(slide)
|
||||||
@@ -408,14 +439,14 @@ def make_output_preview_from_images(original_image, deformed_image, output_dir,
|
|||||||
return preview_path
|
return preview_path
|
||||||
|
|
||||||
|
|
||||||
def make_four_state_preview(state_images, output_dir, angle_degrees):
|
def make_four_state_preview(state_images, output_dir, angle_degrees, coordinates_cutoff=None):
|
||||||
output_dir = Path(output_dir)
|
output_dir = Path(output_dir)
|
||||||
screenshot_dir = output_dir / "process_screenshots"
|
screenshot_dir = output_dir / "process_screenshots"
|
||||||
reset_folder(screenshot_dir)
|
reset_folder(screenshot_dir)
|
||||||
|
|
||||||
panels = []
|
panels = []
|
||||||
for state_key, label, _ in STATE_LABELS:
|
for state_key, label, _ in STATE_LABELS:
|
||||||
panel = sitk_sagittal_panel(state_images[state_key])
|
panel = sitk_sagittal_panel(state_images[state_key], coordinates_cutoff)
|
||||||
panel_path = screenshot_dir / f"{state_key}.png"
|
panel_path = screenshot_dir / f"{state_key}.png"
|
||||||
panel.save(panel_path, quality=95)
|
panel.save(panel_path, quality=95)
|
||||||
panels.append((label, panel))
|
panels.append((label, panel))
|
||||||
@@ -573,6 +604,7 @@ class HeadExtensionApp:
|
|||||||
self.status.set("正在读取 DICOM 生成预览...")
|
self.status.set("正在读取 DICOM 生成预览...")
|
||||||
self.cached_volume = load_dicom_volume(self.input_dir.get())
|
self.cached_volume = load_dicom_volume(self.input_dir.get())
|
||||||
before = crop_head_neck(sagittal_mip(self.cached_volume))
|
before = crop_head_neck(sagittal_mip(self.cached_volume))
|
||||||
|
before = draw_cutoff_line(before, self.cached_volume.shape[0])
|
||||||
after = preview_deform_2d(before, float(self.angle.get()))
|
after = preview_deform_2d(before, float(self.angle.get()))
|
||||||
|
|
||||||
canvas = Image.new("RGB", (1120, 610), (0, 0, 0))
|
canvas = Image.new("RGB", (1120, 610), (0, 0, 0))
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ from head_extension_app import (
|
|||||||
APP_DIR,
|
APP_DIR,
|
||||||
crop_head_neck,
|
crop_head_neck,
|
||||||
ct_window,
|
ct_window,
|
||||||
|
draw_cutoff_line,
|
||||||
fit_image,
|
fit_image,
|
||||||
load_dicom_volume,
|
load_dicom_volume,
|
||||||
preview_deform_2d,
|
preview_deform_2d,
|
||||||
@@ -549,6 +550,7 @@ def start_job(kind, worker, owner=None, params=None, remember_user_task=True):
|
|||||||
def make_preview(input_dir, angle_degrees):
|
def make_preview(input_dir, angle_degrees):
|
||||||
volume = load_dicom_volume(input_dir)
|
volume = load_dicom_volume(input_dir)
|
||||||
before = crop_head_neck(sagittal_mip(volume))
|
before = crop_head_neck(sagittal_mip(volume))
|
||||||
|
before = draw_cutoff_line(before, volume.shape[0])
|
||||||
after = preview_deform_2d(before, float(angle_degrees))
|
after = preview_deform_2d(before, float(angle_degrees))
|
||||||
|
|
||||||
canvas = BytesIO()
|
canvas = BytesIO()
|
||||||
|
|||||||
Reference in New Issue
Block a user