Updating tiff image patch

This commit is contained in:
2026-01-02 12:44:06 +02:00
parent d25101de2d
commit e98d287b8a
3 changed files with 26 additions and 26 deletions

View File

@@ -82,12 +82,12 @@ include-package-data = true
"src.database" = ["*.sql"] "src.database" = ["*.sql"]
[tool.black] [tool.black]
line-length = 88 line-length = 120
target-version = ['py38', 'py39', 'py310', 'py311'] target-version = ['py38', 'py39', 'py310', 'py311']
include = '\.pyi?$' include = '\.pyi?$'
[tool.pylint.messages_control] [tool.pylint.messages_control]
max-line-length = 88 max-line-length = 120
[tool.mypy] [tool.mypy]
python_version = "3.8" python_version = "3.8"

View File

@@ -45,9 +45,7 @@ def apply_ultralytics_16bit_tiff_patches(*, force: bool = False) -> None:
_original_imread = ul_patches.imread _original_imread = ul_patches.imread
def tifffile_imread( def tifffile_imread(filename: str, flags: int = cv2.IMREAD_COLOR, pseudo_rgb: bool = True) -> Optional[np.ndarray]:
filename: str, flags: int = cv2.IMREAD_COLOR, pseudo_rgb: bool = True
) -> Optional[np.ndarray]:
"""Replacement for [`ultralytics.utils.patches.imread()`](venv/lib/python3.12/site-packages/ultralytics/utils/patches.py:20). """Replacement for [`ultralytics.utils.patches.imread()`](venv/lib/python3.12/site-packages/ultralytics/utils/patches.py:20).
- For `.tif/.tiff`, uses `tifffile.imread()` and preserves dtype (e.g. uint16). - For `.tif/.tiff`, uses `tifffile.imread()` and preserves dtype (e.g. uint16).
@@ -65,19 +63,17 @@ def apply_ultralytics_16bit_tiff_patches(*, force: bool = False) -> None:
# - (C, H, W) -> (H, W, C) (heuristic) # - (C, H, W) -> (H, W, C) (heuristic)
if arr is None: if arr is None:
return None return None
if ( if arr.ndim == 3 and arr.shape[0] in (1, 3, 4) and arr.shape[0] < arr.shape[1]:
arr.ndim == 3
and arr.shape[0] in (1, 3, 4)
and arr.shape[0] < arr.shape[1]
):
arr = np.transpose(arr, (1, 2, 0)) arr = np.transpose(arr, (1, 2, 0))
if arr.ndim == 2: if arr.ndim == 2:
arr = arr[..., None] arr = arr[..., None]
# Ensure contiguous array for downstream OpenCV ops. # Ensure contiguous array for downstream OpenCV ops.
# logger.info(f"Loading with monkey-patched imread: {filename}") # logger.info(f"Loading with monkey-patched imread: {filename}")
arr *= 2**8 - 1 arr = arr.astype(np.float32)
arr = arr.astype(np.uint8) arr /= arr.max()
arr *= 2**16 - 1
arr = arr.astype(np.uint16)
return np.ascontiguousarray(arr) return np.ascontiguousarray(arr)
# logger.info(f"Loading with original imread: {filename}") # logger.info(f"Loading with original imread: {filename}")
@@ -142,21 +138,14 @@ def apply_ultralytics_16bit_tiff_patches(*, force: bool = False) -> None:
imgs = batch["img"] imgs = batch["img"]
sz = ( sz = (
random.randrange( random.randrange(int(self.args.imgsz * 0.5), int(self.args.imgsz * 1.5 + self.stride))
int(self.args.imgsz * 0.5), int(self.args.imgsz * 1.5 + self.stride)
)
// self.stride // self.stride
* self.stride * self.stride
) )
sf = sz / max(imgs.shape[2:]) sf = sz / max(imgs.shape[2:])
if sf != 1: if sf != 1:
ns = [ ns = [math.ceil(x * sf / self.stride) * self.stride for x in imgs.shape[2:]]
math.ceil(x * sf / self.stride) * self.stride imgs = nn.functional.interpolate(imgs, size=ns, mode="bilinear", align_corners=False)
for x in imgs.shape[2:]
]
imgs = nn.functional.interpolate(
imgs, size=ns, mode="bilinear", align_corners=False
)
batch["img"] = imgs batch["img"] = imgs
return batch return batch
@@ -164,6 +153,4 @@ def apply_ultralytics_16bit_tiff_patches(*, force: bool = False) -> None:
detect_train.DetectionTrainer.preprocess_batch = preprocess_batch_16bit detect_train.DetectionTrainer.preprocess_batch = preprocess_batch_16bit
# Tag function to make it easier to detect patch state. # Tag function to make it easier to detect patch state.
setattr( setattr(detect_train.DetectionTrainer.preprocess_batch, "_ultralytics_16bit_patch", True)
detect_train.DetectionTrainer.preprocess_batch, "_ultralytics_16bit_patch", True
)

View File

@@ -17,6 +17,7 @@ import matplotlib.pyplot as plt
import argparse import argparse
from pathlib import Path from pathlib import Path
import random import random
from shapely.geometry import LineString
from src.utils.image import Image from src.utils.image import Image
@@ -75,7 +76,12 @@ def draw_annotations(img, labels, alpha=0.4, draw_bbox_for_poly=True):
# img: BGR numpy array # img: BGR numpy array
overlay = img.copy() overlay = img.copy()
h, w = img.shape[:2] h, w = img.shape[:2]
for cls, coords in labels: for line in labels:
if isinstance(line, str):
cls, coords = parse_label_line(line)
if isinstance(line, tuple):
cls, coords = line
if not coords: if not coords:
continue continue
# polygon case (>=6 coordinates) # polygon case (>=6 coordinates)
@@ -83,9 +89,16 @@ def draw_annotations(img, labels, alpha=0.4, draw_bbox_for_poly=True):
color = random_color_for_class(cls) color = random_color_for_class(cls)
x1, y1, x2, y2 = yolo_bbox_to_xyxy(coords[:4], w, h) x1, y1, x2, y2 = yolo_bbox_to_xyxy(coords[:4], w, h)
print(x1, y1, x2, y2)
cv2.rectangle(img, (x1, y1), (x2, y2), color, 1) cv2.rectangle(img, (x1, y1), (x2, y2), color, 1)
pts = poly_to_pts(coords[4:], w, h) pts = poly_to_pts(coords[4:], w, h)
line = LineString(pts)
# Buffer distance in pixels
buffered = line.buffer(3, cap_style=2, join_style=2)
coords = np.array(buffered.exterior.coords, dtype=np.int32)
cv2.fillPoly(overlay, [coords], color=(255, 255, 255))
# fill on overlay # fill on overlay
cv2.fillPoly(overlay, [pts], color) cv2.fillPoly(overlay, [pts], color)
# outline on base image # outline on base image