|
@@ -22,27 +22,28 @@ def qimage_from_bgr(img_bgr: np.ndarray) -> QImage:
|
|
|
return QImage(rgb.data, w, h, rgb.strides[0], QImage.Format_RGB888)
|
|
|
|
|
|
|
|
|
-def apply_filtration(src_gray: np.ndarray, rois_for_slice, threshold_brightness: float):
|
|
|
+def apply_filtration(src_gray: np.ndarray, not_norm_gray: np.ndarray, rois_for_slice, threshold_brightness: float):
|
|
|
if src_gray is None:
|
|
|
return None
|
|
|
h, w = src_gray.shape
|
|
|
mask = build_mask_from_rois(rois_for_slice, (h, w))
|
|
|
|
|
|
- masked = src_gray.copy()
|
|
|
+ #masked = src_gray.copy()
|
|
|
+ masked = not_norm_gray.copy()
|
|
|
masked[mask != 255] = 0
|
|
|
|
|
|
thr_val = threshold_brightness * float(masked.max()) if masked.max() > 0 else 0.0
|
|
|
seg = np.zeros_like(src_gray, dtype=np.uint8)
|
|
|
- seg[(mask == 255) & (src_gray >= thr_val)] = 255
|
|
|
+ seg[(mask == 255) & (not_norm_gray >= thr_val)] = 255
|
|
|
|
|
|
- contours, _ = cv2.findContours(seg, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
|
|
|
+ contours, _ = cv2.findContours(seg, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
|
|
|
color = cv2.cvtColor(src_gray, cv2.COLOR_GRAY2BGR)
|
|
|
cv2.drawContours(color, contours, -1, (255, 0, 0), 2)
|
|
|
|
|
|
return QPixmap.fromImage(qimage_from_bgr(color))
|
|
|
|
|
|
|
|
|
-def apply_segmentation(src_gray: np.ndarray, rois_for_slice, threshold_brightness: float,
|
|
|
+def apply_segmentation(src_gray: np.ndarray, not_norm_gray: np.ndarray, rois_for_slice, threshold_brightness: float,
|
|
|
area_rel: float, spacing_xy, z_spacing, volume_by_slice: dict, slice_index: int):
|
|
|
if src_gray is None:
|
|
|
return None, 0.0, 0.0
|
|
@@ -50,18 +51,23 @@ def apply_segmentation(src_gray: np.ndarray, rois_for_slice, threshold_brightnes
|
|
|
h, w = src_gray.shape
|
|
|
mask = build_mask_from_rois(rois_for_slice, (h, w))
|
|
|
|
|
|
- masked = src_gray.copy()
|
|
|
+ #masked = src_gray.copy()
|
|
|
+ masked = not_norm_gray.copy()
|
|
|
masked[mask != 255] = 0
|
|
|
|
|
|
thr_val = threshold_brightness * float(masked.max()) if masked.max() > 0 else 0.0
|
|
|
seg = np.zeros_like(src_gray, dtype=np.uint8)
|
|
|
- seg[(mask == 255) & (src_gray >= thr_val)] = 255
|
|
|
+ seg[(mask == 255) & (not_norm_gray >= thr_val)] = 255
|
|
|
|
|
|
contours, _ = cv2.findContours(seg, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
|
|
|
max_area = max((cv2.contourArea(c) for c in contours), default=0.0)
|
|
|
area_thr = float(area_rel) * max_area
|
|
|
filtered = [c for c in contours if cv2.contourArea(c) > area_thr]
|
|
|
|
|
|
+ # создаём бинарную маску только с filtered контурами для дальнейшего возможного сохранения
|
|
|
+ filtered_mask = np.zeros_like(src_gray, dtype=np.uint8)
|
|
|
+ cv2.drawContours(filtered_mask, filtered, -1, color=255, thickness=cv2.FILLED)
|
|
|
+
|
|
|
spacing_x, spacing_y = spacing_xy
|
|
|
voxel_mm3 = float(spacing_x) * float(spacing_y) * float(z_spacing)
|
|
|
pixel_area_sum = sum(cv2.contourArea(c) for c in filtered)
|
|
@@ -74,25 +80,26 @@ def apply_segmentation(src_gray: np.ndarray, rois_for_slice, threshold_brightnes
|
|
|
cv2.putText(color, f"Slice: {slice_index} Volume (ml): {volume_ml:.3f}",
|
|
|
(10, 22), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 255), 1)
|
|
|
|
|
|
- return QPixmap.fromImage(qimage_from_bgr(color)), volume_ml, total_ml
|
|
|
+ return QPixmap.fromImage(qimage_from_bgr(color)), volume_ml, total_ml, filtered_mask
|
|
|
|
|
|
|
|
|
# НОВОЕ: расчёт только объёма (без рисования, без модификации словарей)
|
|
|
-def compute_volume_ml(src_gray: np.ndarray, rois_for_slice, threshold_brightness: float,
|
|
|
+def compute_volume_ml(src_gray: np.ndarray, not_norm_gray: np.ndarray, rois_for_slice, threshold_brightness: float,
|
|
|
area_rel: float, spacing_xy, z_spacing: float) -> float:
|
|
|
if src_gray is None:
|
|
|
return 0.0
|
|
|
h, w = src_gray.shape
|
|
|
mask = build_mask_from_rois(rois_for_slice, (h, w))
|
|
|
|
|
|
- masked = src_gray.copy()
|
|
|
+ #masked = src_gray.copy()
|
|
|
+ masked = not_norm_gray.copy()
|
|
|
masked[mask != 255] = 0
|
|
|
|
|
|
thr_val = threshold_brightness * float(masked.max()) if masked.max() > 0 else 0.0
|
|
|
seg = np.zeros_like(src_gray, dtype=np.uint8)
|
|
|
- seg[(mask == 255) & (src_gray >= thr_val)] = 255
|
|
|
+ seg[(mask == 255) & (not_norm_gray >= thr_val)] = 255
|
|
|
|
|
|
- contours, _ = cv2.findContours(seg, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
|
|
|
+ contours, _ = cv2.findContours(seg, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
|
|
|
max_area = max((cv2.contourArea(c) for c in contours), default=0.0)
|
|
|
area_thr = float(area_rel) * max_area
|
|
|
filtered = [c for c in contours if cv2.contourArea(c) > area_thr]
|