Skip to content
Snippets Groups Projects
Commit fd71c9a4 authored by Christian's avatar Christian
Browse files

Added method using sato and kernel for centerline extraction

parent 14451d92
No related branches found
No related tags found
1 merge request!3Live wire to be implemented into GUI
import time
import cv2
import numpy as np
import matplotlib.pyplot as plt
from skimage.morphology import skeletonize
from skimage.filters import gaussian, sato
from skimage.feature import canny
from skimage.graph import route_through_array
#### Helper functions ####
def load_image(path, type):
"""
Load an image in either gray or color mode (then convert color to gray).
"""
if type == 'gray':
img = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
if img is None:
raise FileNotFoundError(f"Could not read {path}")
elif type == 'color':
img = cv2.imread(path, cv2.IMREAD_COLOR)
if img is None:
raise FileNotFoundError(f"Could not read {path}")
else:
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
else:
raise ValueError("type must be 'gray' or 'color'")
return img
def downscale(img, points, scale_percent):
"""
Downsample `img` to `scale_percent` size and scale the given points accordingly.
Returns (downsampled_img, (scaled_seed, scaled_target)).
"""
if scale_percent == 100:
return img, (tuple(points[0]), tuple(points[1]))
else:
# Compute new dimensions
width = int(img.shape[1] * scale_percent / 100)
height = int(img.shape[0] * scale_percent / 100)
new_dimensions = (width, height)
# Downsample
downsampled_img = cv2.resize(img, new_dimensions, interpolation=cv2.INTER_AREA)
# Scaling factors
scale_x = width / img.shape[1]
scale_y = height / img.shape[0]
# Scale the points (x, y)
seed_xy = tuple(points[0])
target_xy = tuple(points[1])
scaled_seed_xy = (int(seed_xy[0] * scale_x), int(seed_xy[1] * scale_y))
scaled_target_xy = (int(target_xy[0] * scale_x), int(target_xy[1] * scale_y))
return downsampled_img, (scaled_seed_xy, scaled_target_xy)
## NO LONGER INVERSE (NOT 1/...)
def compute_cost(image, sigma=1.0, epsilon=1e-1):
"""
Smooth the image, run Canny edge detection, then invert the edge map into a cost image.
"""
smoothed_img = gaussian(image, sigma=sigma)
canny_img = sato(smoothed_img)
canny_thresh = canny_img > 0.08
skeleton = skeletonize(canny_thresh)
cost_img = 1 /(skeleton + epsilon) # Invert edges: higher cost where edges are stronger
return cost_img, skeleton
def backtrack_pixels_on_image(img_color, path_coords, bgr_color=(0, 0, 255)):
"""
Color the path on the (already converted BGR) image in the specified color.
`path_coords` should be a list of (row, col) or (y, x).
"""
for (row, col) in path_coords:
img_color[row, col] = bgr_color
return img_color
#### Main Script ####
def main():
# Define input parameters
image_path = './tests/slice_60_volQ.png'
image_type = 'gray' # 'gray' or 'color'
downscale_factor = 100 # % of original size
points_path = './tests/LiveWireEndPoints.npy'
# Load image
image = load_image(image_path, image_type)
# Load seed and target points
points = np.int0(np.round(np.load(points_path))) # shape: (2, 2), i.e. [[x_seed, y_seed], [x_target, y_target]]
# Downscale image and points
scaled_image, scaled_points = downscale(image, points, downscale_factor)
seed, target = scaled_points # Each is (x, y)
# Convert to row,col for scikit-image (which uses (row, col) = (y, x))
seed_rc = (seed[1], seed[0])
target_rc = (target[1], target[0])
# Compute cost image
cost_image, canny_img = compute_cost(scaled_image)
# Find path using route_through_array
# route_through_array expects: route_through_array(image, start, end, fully_connected=True/False)
start_time = time.time()
path_rc, cost = route_through_array(
cost_image,
start=seed_rc,
end=target_rc,
fully_connected=True
)
end_time = time.time()
print(f"Elapsed time for pathfinding: {end_time - start_time:.3f} seconds")
# Convert single-channel image to BGR for coloring
color_img = cv2.cvtColor(scaled_image, cv2.COLOR_GRAY2BGR)
# Draw path. `path_rc` is a list of (row, col).
# If you want to mark it in red, do (0,0,255) because OpenCV uses BGR format.
color_img = backtrack_pixels_on_image(color_img, path_rc, bgr_color=(0, 0, 255))
# Display results
plt.figure(figsize=(20, 8))
plt.subplot(1, 2, 1)
plt.title("Canny Edges")
plt.imshow(canny_img, cmap='gray')
plt.subplot(1, 2, 2)
plt.title("Path from Seed to Target")
# Convert BGR->RGB for pyplot
plt.imshow(color_img[..., ::-1])
plt.show()
if __name__ == "__main__":
main()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment