Updating image splitter
This commit is contained in:
@@ -17,7 +17,7 @@ from tifffile import imread, imwrite
|
|||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def get_pseudo_rgb(arr: np.ndarray, gamma: float = 0.3) -> np.ndarray:
|
def get_pseudo_rgb(arr: np.ndarray, gamma: float = 0.5) -> np.ndarray:
|
||||||
"""
|
"""
|
||||||
Convert a grayscale image to a pseudo-RGB image using a gamma correction.
|
Convert a grayscale image to a pseudo-RGB image using a gamma correction.
|
||||||
|
|
||||||
@@ -33,10 +33,11 @@ def get_pseudo_rgb(arr: np.ndarray, gamma: float = 0.3) -> np.ndarray:
|
|||||||
a1 = arr.copy().astype(np.float32)
|
a1 = arr.copy().astype(np.float32)
|
||||||
a1 -= np.percentile(a1, 2)
|
a1 -= np.percentile(a1, 2)
|
||||||
a1[a1 < 0] = 0
|
a1[a1 < 0] = 0
|
||||||
# p999 = np.percentile(a1, 99.9)
|
p999 = np.percentile(a1, 99.9)
|
||||||
# a1[a1 > p999] = p999
|
a1[a1 > p999] = p999
|
||||||
a1 /= a1.max()
|
a1 /= a1.max()
|
||||||
|
|
||||||
|
if 0:
|
||||||
a2 = a1.copy()
|
a2 = a1.copy()
|
||||||
a2 = a2**gamma
|
a2 = a2**gamma
|
||||||
a2 /= a2.max()
|
a2 /= a2.max()
|
||||||
@@ -47,7 +48,7 @@ def get_pseudo_rgb(arr: np.ndarray, gamma: float = 0.3) -> np.ndarray:
|
|||||||
a3 /= a3.max()
|
a3 /= a3.max()
|
||||||
|
|
||||||
return np.stack([a1, np.zeros(a1.shape), np.zeros(a1.shape)], axis=0)
|
return np.stack([a1, np.zeros(a1.shape), np.zeros(a1.shape)], axis=0)
|
||||||
return np.stack([a2, np.zeros(a1.shape), np.zeros(a1.shape)], axis=0)
|
# return np.stack([a2, np.zeros(a1.shape), np.zeros(a1.shape)], axis=0)
|
||||||
# return np.stack([a1, a2, a3], axis=0)
|
# return np.stack([a1, a2, a3], axis=0)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,13 @@ from pathlib import Path
|
|||||||
from tifffile import imread, imwrite
|
from tifffile import imread, imwrite
|
||||||
from shapely.geometry import LineString
|
from shapely.geometry import LineString
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
|
from scipy.ndimage import zoom
|
||||||
|
|
||||||
|
|
||||||
# debug
|
# debug
|
||||||
from src.utils.image import Image
|
from src.utils.image import Image
|
||||||
from show_yolo_seg import draw_annotations
|
from show_yolo_seg import draw_annotations
|
||||||
|
|
||||||
import pylab as plt
|
import pylab as plt
|
||||||
import cv2
|
import cv2
|
||||||
|
|
||||||
@@ -24,13 +27,15 @@ class Label:
|
|||||||
class_id = int(class_id)
|
class_id = int(class_id)
|
||||||
bbox = np.array(coords[:4], dtype=np.float32)
|
bbox = np.array(coords[:4], dtype=np.float32)
|
||||||
polygon = np.array(coords[4:], dtype=np.float32).reshape(-1, 2) if len(coords) > 4 else None
|
polygon = np.array(coords[4:], dtype=np.float32).reshape(-1, 2) if len(coords) > 4 else None
|
||||||
|
if not any(np.isclose(polygon[0], polygon[-1])):
|
||||||
|
polygon = np.vstack([polygon, polygon[0]])
|
||||||
return class_id, bbox, polygon
|
return class_id, bbox, polygon
|
||||||
|
|
||||||
def offset_label(
|
def offset_label(
|
||||||
self,
|
self,
|
||||||
img_w,
|
img_w,
|
||||||
img_h,
|
img_h,
|
||||||
distance: float = 3.0,
|
distance: float = 1.0,
|
||||||
cap_style: int = 2,
|
cap_style: int = 2,
|
||||||
join_style: int = 2,
|
join_style: int = 2,
|
||||||
):
|
):
|
||||||
@@ -64,7 +69,7 @@ class Label:
|
|||||||
line = LineString(pts)
|
line = LineString(pts)
|
||||||
# Buffer distance in pixels
|
# Buffer distance in pixels
|
||||||
buffered = line.buffer(distance=distance, cap_style=cap_style, join_style=join_style)
|
buffered = line.buffer(distance=distance, cap_style=cap_style, join_style=join_style)
|
||||||
self.polygon = np.array(buffered.exterior.coords, dtype=np.float32)
|
self.polygon = np.array(buffered.exterior.coords, dtype=np.float32) / (img_w, img_h)
|
||||||
xmn, ymn = self.polygon.min(axis=0)
|
xmn, ymn = self.polygon.min(axis=0)
|
||||||
xmx, ymx = self.polygon.max(axis=0)
|
xmx, ymx = self.polygon.max(axis=0)
|
||||||
xc = (xmn + xmx) / 2
|
xc = (xmn + xmx) / 2
|
||||||
@@ -158,6 +163,10 @@ class ImageSplitter:
|
|||||||
self.image = imread(image_path)
|
self.image = imread(image_path)
|
||||||
self.image_path = image_path
|
self.image_path = image_path
|
||||||
self.label_path = label_path
|
self.label_path = label_path
|
||||||
|
if not label_path.exists():
|
||||||
|
print(f"Label file {label_path} not found")
|
||||||
|
self.labels = None
|
||||||
|
else:
|
||||||
self.labels = YoloLabelReader(label_path)
|
self.labels = YoloLabelReader(label_path)
|
||||||
|
|
||||||
def split_into_tiles(self, patch_size: tuple = (2, 2)):
|
def split_into_tiles(self, patch_size: tuple = (2, 2)):
|
||||||
@@ -173,8 +182,11 @@ class ImageSplitter:
|
|||||||
tile_reference = f"i{i}j{j}"
|
tile_reference = f"i{i}j{j}"
|
||||||
hrange = (i * hstep / h, (i + 1) * hstep / h)
|
hrange = (i * hstep / h, (i + 1) * hstep / h)
|
||||||
wrange = (j * wstep / w, (j + 1) * wstep / w)
|
wrange = (j * wstep / w, (j + 1) * wstep / w)
|
||||||
labels = deepcopy(self.labels.get_labels(hrange, wrange))
|
|
||||||
tile = self.image[i * hstep : (i + 1) * hstep, j * wstep : (j + 1) * wstep]
|
tile = self.image[i * hstep : (i + 1) * hstep, j * wstep : (j + 1) * wstep]
|
||||||
|
|
||||||
|
labels = None
|
||||||
|
if self.labels is not None:
|
||||||
|
labels = deepcopy(self.labels.get_labels(hrange, wrange))
|
||||||
print(id(labels))
|
print(id(labels))
|
||||||
|
|
||||||
if labels is not None:
|
if labels is not None:
|
||||||
@@ -234,13 +246,14 @@ class ImageSplitter:
|
|||||||
|
|
||||||
# print("tile shape:", tile.shape)
|
# print("tile shape:", tile.shape)
|
||||||
|
|
||||||
yolo_annotation = f"{label.class_id} {x_offset/nx} {y_offset/ny} {h/ny} {w/nx} " + " ".join(
|
yolo_annotation = f"{label.class_id} {x_offset/nx} {y_offset/ny} {h_norm} {w_norm} "
|
||||||
|
print(yolo_annotation)
|
||||||
|
yolo_annotation += " ".join(
|
||||||
[
|
[
|
||||||
f"{(x*self.image.shape[1]-(xc - x_offset))/nx:.6f} {(y*self.image.shape[0]-(yc-y_offset))/ny:.6f}"
|
f"{(x*self.image.shape[1]-(xc - x_offset))/nx:.6f} {(y*self.image.shape[0]-(yc-y_offset))/ny:.6f}"
|
||||||
for x, y in label.polygon
|
for x, y in label.polygon
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
# print(yolo_annotation)
|
|
||||||
new_label = Label(yolo_annotation=yolo_annotation)
|
new_label = Label(yolo_annotation=yolo_annotation)
|
||||||
|
|
||||||
yield tile_reference, tile, [new_label]
|
yield tile_reference, tile, [new_label]
|
||||||
@@ -251,6 +264,7 @@ def main(args):
|
|||||||
if args.output:
|
if args.output:
|
||||||
args.output.mkdir(exist_ok=True, parents=True)
|
args.output.mkdir(exist_ok=True, parents=True)
|
||||||
(args.output / "images").mkdir(exist_ok=True)
|
(args.output / "images").mkdir(exist_ok=True)
|
||||||
|
(args.output / "images-zoomed").mkdir(exist_ok=True)
|
||||||
(args.output / "labels").mkdir(exist_ok=True)
|
(args.output / "labels").mkdir(exist_ok=True)
|
||||||
|
|
||||||
for image_path in (args.input / "images").glob("*.tif"):
|
for image_path in (args.input / "images").glob("*.tif"):
|
||||||
@@ -297,6 +311,11 @@ def main(args):
|
|||||||
|
|
||||||
if args.output:
|
if args.output:
|
||||||
imwrite(args.output / "images" / f"{image_path.stem}_{tile_reference}.tif", tile)
|
imwrite(args.output / "images" / f"{image_path.stem}_{tile_reference}.tif", tile)
|
||||||
|
scale = 5
|
||||||
|
tile_zoomed = zoom(tile, zoom=scale)
|
||||||
|
imwrite(args.output / "images-zoomed" / f"{image_path.stem}_{tile_reference}.tif", tile_zoomed)
|
||||||
|
|
||||||
|
if labels is not None:
|
||||||
with open(args.output / "labels" / f"{image_path.stem}_{tile_reference}.txt", "w") as f:
|
with open(args.output / "labels" / f"{image_path.stem}_{tile_reference}.txt", "w") as f:
|
||||||
for label in labels:
|
for label in labels:
|
||||||
label.offset_label(tile.shape[1], tile.shape[0])
|
label.offset_label(tile.shape[1], tile.shape[0])
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ def draw_annotations(img, labels, alpha=0.4, draw_bbox_for_poly=True):
|
|||||||
cv2.polylines(img, [pts], isClosed=True, color=color, thickness=1)
|
cv2.polylines(img, [pts], isClosed=True, color=color, thickness=1)
|
||||||
# put class text at first point
|
# put class text at first point
|
||||||
x, y = int(pts[0, 0]), int(pts[0, 1]) - 6
|
x, y = int(pts[0, 0]), int(pts[0, 1]) - 6
|
||||||
|
if 0:
|
||||||
cv2.putText(
|
cv2.putText(
|
||||||
img,
|
img,
|
||||||
str(cls),
|
str(cls),
|
||||||
@@ -188,12 +189,32 @@ def main():
|
|||||||
# continue and just show image
|
# continue and just show image
|
||||||
out = draw_annotations(img.copy(), labels, alpha=args.alpha, draw_bbox_for_poly=(not args.no_bbox))
|
out = draw_annotations(img.copy(), labels, alpha=args.alpha, draw_bbox_for_poly=(not args.no_bbox))
|
||||||
|
|
||||||
|
lclass, coords = labels[0]
|
||||||
|
print(lclass, coords)
|
||||||
|
bbox = coords[:4]
|
||||||
|
print("bbox", bbox)
|
||||||
|
bbox = np.array(bbox) * np.array([img.shape[1], img.shape[0], img.shape[1], img.shape[0]])
|
||||||
|
yc, xc, h, w = bbox
|
||||||
|
print("bbox", bbox)
|
||||||
|
polyline = np.array(coords[4:]).reshape(-1, 2) * np.array([img.shape[1], img.shape[0]])
|
||||||
|
print("pl", coords[4:])
|
||||||
|
print("pl", polyline)
|
||||||
|
|
||||||
# Convert BGR -> RGB for matplotlib display
|
# Convert BGR -> RGB for matplotlib display
|
||||||
out_rgb = cv2.cvtColor(out, cv2.COLOR_BGR2RGB)
|
# out_rgb = cv2.cvtColor(out, cv2.COLOR_BGR2RGB)
|
||||||
|
out_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
|
||||||
# out_rgb = Image()
|
# out_rgb = Image()
|
||||||
plt.figure(figsize=(10, 10 * out.shape[0] / out.shape[1]))
|
plt.figure(figsize=(10, 10 * out.shape[0] / out.shape[1]))
|
||||||
plt.imshow(out_rgb)
|
plt.imshow(out_rgb)
|
||||||
plt.axis("off")
|
plt.plot(polyline[:, 0], polyline[:, 1], "y", linewidth=2)
|
||||||
|
plt.plot(
|
||||||
|
[yc - h / 2, yc - h / 2, yc + h / 2, yc + h / 2, yc - h / 2],
|
||||||
|
[xc - w / 2, xc + w / 2, xc + w / 2, xc - w / 2, xc - w / 2],
|
||||||
|
"r",
|
||||||
|
linewidth=2,
|
||||||
|
)
|
||||||
|
|
||||||
|
# plt.axis("off")
|
||||||
plt.title(f"{img_path.name} ({lbl_path.name})")
|
plt.title(f"{img_path.name} ({lbl_path.name})")
|
||||||
plt.show()
|
plt.show()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user