From 1c77de040712e8d13b324bc9ac24de4dc4f89430 Mon Sep 17 00:00:00 2001
From: Christian <s224389@dtu.dk>
Date: Wed, 15 Jan 2025 13:23:29 +0100
Subject: [PATCH] Bug fixes and added ability to use 'centerline' method
 instead

---
 GUI_draft.py |  4 +--
 live_wire.py | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 90 insertions(+), 4 deletions(-)

diff --git a/GUI_draft.py b/GUI_draft.py
index fb0231c..a28f30f 100644
--- a/GUI_draft.py
+++ b/GUI_draft.py
@@ -100,7 +100,7 @@ class ImageGraphicsView(QGraphicsView):
         self.editor_mode = False
         self.dot_radius = 4
         self.path_radius = 1
-        self.radius_something = 3  # cost-lowering radius
+        self.radius_cost_image = 2  # cost-lowering radius
         self._img_w = 0
         self._img_h = 0
 
@@ -198,7 +198,7 @@ class ImageGraphicsView(QGraphicsView):
             return
         for i, (ax, ay) in enumerate(self.anchor_points):
             if self.point_items[i].is_removable():
-                self._lower_cost_in_circle(ax, ay, self.radius_something)
+                self._lower_cost_in_circle(ax, ay, self.radius_cost_image)
 
     def _lower_cost_in_circle(self, x_f, y_f, radius):
         """Set cost_image row,col in circle of radius -> global min."""
diff --git a/live_wire.py b/live_wire.py
index 9b49d97..e42f7d5 100644
--- a/live_wire.py
+++ b/live_wire.py
@@ -6,9 +6,10 @@ from skimage import exposure
 from skimage.filters import gaussian
 from skimage.feature import canny
 from skimage.graph import route_through_array
+from scipy.signal import convolve2d
 
-#### Helper functions ####
-
+'''
+### Canny Edge cost image
 def compute_cost_image(path, sigma=3):
 
     ### Load image
@@ -28,6 +29,49 @@ def compute_cost_image(path, sigma=3):
 
     return cost_img
 
+def find_path(cost_image, points):
+
+    if len(points) != 2:
+        raise ValueError("Points should be a list of 2 points: seed and target.")
+    
+    seed_rc, target_rc = points
+
+    path_rc, cost = route_through_array(
+        cost_image, 
+        start=seed_rc, 
+        end=target_rc, 
+        fully_connected=True
+    )
+
+    return path_rc
+'''
+
+### Disk live wire cost image
+def compute_cost_image(path, sigma=3, disk_size=15):
+
+    ### Load image
+    image = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
+
+    # Apply histogram equalization
+    image_contrasted = exposure.equalize_adapthist(image, clip_limit=0.01)
+
+    # Apply smoothing
+    smoothed_img = gaussian(image_contrasted, sigma=sigma)
+
+    # Apply Canny edge detection
+    canny_img = canny(smoothed_img)
+
+    # Do disk thing
+    binary_img = canny_img
+    k_size = 17
+    kernel = circle_edge_kernel(k_size=disk_size)
+    convolved = convolve2d(binary_img, kernel, mode='same', boundary='fill')
+
+    # Create cost image
+    cost_img = (convolved.max() - convolved)**4  # Invert edges: higher cost where edges are stronger
+
+    return cost_img
+
 
 def find_path(cost_image, points):
 
@@ -46,8 +90,50 @@ def find_path(cost_image, points):
     return path_rc
 
 
+def circle_edge_kernel(k_size=5, radius=None):
+    """
+    Create a k_size x k_size array whose values increase linearly
+    from 0 at the center to 1 at the circle boundary (radius).
+
+    Parameters
+    ----------
+    k_size : int
+        The size (width and height) of the kernel array.
+    radius : float, optional
+        The circle's radius. By default, set to (k_size-1)/2.
+
+    Returns
+    -------
+    kernel : 2D numpy array of shape (k_size, k_size)
+        The circle-edge-weighted kernel.
+    """
+    if radius is None:
+        # By default, let the radius be half the kernel size
+        radius = (k_size - 1) / 2
+
+    # Create an empty kernel
+    kernel = np.zeros((k_size, k_size), dtype=float)
+
+    # Coordinates of the center
+    center = radius  # same as (k_size-1)/2 if radius is default
+
+    # Fill the kernel
+    for y in range(k_size):
+        for x in range(k_size):
+            dist = np.sqrt((x - center)**2 + (y - center)**2)
+            if dist <= radius:
+                # Weight = distance / radius => 0 at center, 1 at boundary
+                kernel[y, x] = dist / radius
+
+    return kernel
+
+
+
+
+
 
 
+# Other functions 
 def downscale(img, points, scale_percent):
     """
     Downsample `img` to `scale_percent` size and scale the given points accordingly.
-- 
GitLab