2026-05-03-22-02-15 调整预览分界线绘制

This commit is contained in:
2026-05-03 22:09:19 +08:00
parent e431830d15
commit 525c2c1dda
6 changed files with 299 additions and 18 deletions

View File

@@ -123,14 +123,21 @@ 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()
def cutoff_line_y(panel, image_depth, coordinates_cutoff=DEFAULT_COORDINATES_CUTOFF):
crop_height = int(image_depth * 0.72)
if crop_height <= 0:
return panel
return None
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 None
return line_y
def draw_cutoff_line(panel, image_depth, coordinates_cutoff=DEFAULT_COORDINATES_CUTOFF):
panel = panel.copy()
line_y = cutoff_line_y(panel, image_depth, coordinates_cutoff)
if line_y is None:
return panel
draw = ImageDraw.Draw(panel)
@@ -141,6 +148,57 @@ def draw_cutoff_line(panel, image_depth, coordinates_cutoff=DEFAULT_COORDINATES_
return panel
def draw_deformed_cutoff_line(panel, image_depth, angle_degrees, coordinates_cutoff=DEFAULT_COORDINATES_CUTOFF):
panel = panel.copy()
line_y = cutoff_line_y(panel, image_depth, coordinates_cutoff)
if line_y is None:
return panel
theta = np.deg2rad(float(angle_degrees))
cos_t = np.cos(theta)
sin_t = np.sin(theta)
pivot_x = int(panel.width * 0.55)
pivot_y = int(panel.height * 0.62)
points = []
for x in (-panel.width * 0.08, panel.width * 1.08):
dx = x - pivot_x
dy = line_y - pivot_y
points.append((
pivot_x + cos_t * dx - sin_t * dy,
pivot_y + sin_t * dx + cos_t * dy,
))
draw = ImageDraw.Draw(panel)
shadow = (0, 0, 0)
line_color = (255, 215, 60)
draw.line(points, fill=shadow, width=6)
draw.line(points, fill=line_color, width=3)
return panel
def preview_deform_with_cutoff_line(
image,
image_depth,
angle_degrees,
mode="soft_transition",
transition_width=90,
gaussian_sigma=3,
show_cutoff_line=True,
coordinates_cutoff=DEFAULT_COORDINATES_CUTOFF,
):
preview = preview_deform_2d(
image,
angle_degrees,
mode,
transition_width=transition_width,
gaussian_sigma=gaussian_sigma,
)
if not show_cutoff_line:
return preview
return draw_deformed_cutoff_line(preview, image_depth, angle_degrees, coordinates_cutoff)
def fit_image(image, width, height):
scale = min(width / image.width, height / image.height)
resized = image.resize(
@@ -464,18 +522,34 @@ def make_four_state_preview(state_images, output_dir, angle_degrees, coordinates
screenshot_dir = output_dir / "process_screenshots"
reset_folder(screenshot_dir)
original_panel = sitk_sagittal_panel(state_images["original"], coordinates_cutoff)
image_depth = state_images["original"].GetSize()[2]
original_panel = sitk_sagittal_panel(state_images["original"])
original_display = (
draw_cutoff_line(original_panel, image_depth, coordinates_cutoff)
if coordinates_cutoff is not None
else original_panel
)
preview_panels = {
"original": original_panel,
"hard_boundary": preview_deform_2d(original_panel, angle_degrees, "hard_boundary"),
"gaussian_smooth": preview_deform_2d(
"original": original_display,
"hard_boundary": preview_deform_with_cutoff_line(
original_panel,
image_depth,
angle_degrees,
"hard_boundary",
show_cutoff_line=coordinates_cutoff is not None,
coordinates_cutoff=coordinates_cutoff or DEFAULT_COORDINATES_CUTOFF,
),
"gaussian_smooth": preview_deform_with_cutoff_line(
original_panel,
image_depth,
angle_degrees,
"gaussian_smooth",
transition_width,
show_cutoff_line=coordinates_cutoff is not None,
coordinates_cutoff=coordinates_cutoff or DEFAULT_COORDINATES_CUTOFF,
),
"soft_transition": preview_deform_2d(
original_panel,
original_display,
angle_degrees,
"soft_transition",
transition_width,