-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
930 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
Binary file not shown.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 41, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"from brightest_path_lib.cost import Cost, Reciprocal\n", | ||
"\n", | ||
"from transonic import boost" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 42, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"@boost\n", | ||
"class FastReciprocal(Cost):\n", | ||
"\n", | ||
" min_intensity: float\n", | ||
" max_intensity: float\n", | ||
" RECIPROCAL_MIN: float\n", | ||
" RECIPROCAL_MAX: float\n", | ||
" _min_step_cost: float\n", | ||
"\n", | ||
" def __init__(self, min_intensity: float, max_intensity: float) -> None:\n", | ||
" super().__init__()\n", | ||
" if min_intensity is None or max_intensity is None:\n", | ||
" raise TypeError\n", | ||
" if min_intensity > max_intensity:\n", | ||
" raise ValueError\n", | ||
" self.min_intensity = min_intensity\n", | ||
" self.max_intensity = max_intensity\n", | ||
" self.RECIPROCAL_MIN = 1E-6\n", | ||
" self.RECIPROCAL_MAX = 255.0\n", | ||
" self._min_step_cost = 1 / self.RECIPROCAL_MAX\n", | ||
" \n", | ||
" @boost\n", | ||
" def cost_of_moving_to(self, intensity_at_new_point: float) -> float:\n", | ||
" if intensity_at_new_point > self.max_intensity:\n", | ||
" raise ValueError\n", | ||
"\n", | ||
" intensity_at_new_point = self.RECIPROCAL_MAX * (intensity_at_new_point - self.min_intensity) / (self.max_intensity - self.min_intensity)\n", | ||
"\n", | ||
" if intensity_at_new_point < self.RECIPROCAL_MIN:\n", | ||
" intensity_at_new_point = self.RECIPROCAL_MIN\n", | ||
" \n", | ||
" return 1.0 / intensity_at_new_point\n", | ||
" \n", | ||
" @boost\n", | ||
" def minimum_step_cost(self) -> float:\n", | ||
" return self._min_step_cost\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 43, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"1.3 µs ± 109 ns per loop (mean ± std. dev. of 7 runs, 45,554 loops each)\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"%%timeit -n45554\n", | ||
"\n", | ||
"fr = FastReciprocal(0, 10000)\n", | ||
"\n", | ||
"fr.cost_of_moving_to(100)\n", | ||
"fr.minimum_step_cost()" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 44, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"1.35 µs ± 147 ns per loop (mean ± std. dev. of 7 runs, 45,554 loops each)\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"%%timeit -n45554\n", | ||
"\n", | ||
"r = Reciprocal(0, 10000)\n", | ||
"\n", | ||
"r.cost_of_moving_to(100)\n", | ||
"r.minimum_step_cost()" | ||
] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "cudmorelab3.8", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3", | ||
"version": "3.8.12" | ||
}, | ||
"orig_nbformat": 4, | ||
"vscode": { | ||
"interpreter": { | ||
"hash": "d10ee8d44f5c0a7cb50271f8411c55c4fd1535f2289c64976b55c3ed75b77fcd" | ||
} | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 2 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
from brightest_path_lib.algorithm import AStarSearch, NBAStarSearch | ||
import numpy as np | ||
import napari | ||
from skimage import data | ||
import tifffile | ||
import time | ||
|
||
|
||
def test_2D_image(): | ||
# testing for 2D | ||
#twoDImage = data.cells3d()[30, 1] # brighter image | ||
# twoDImage = data.cells3d()[30, 0] # darker image | ||
# start_point = np.array([0,192]) | ||
# goal_point = np.array([198,9]) | ||
|
||
#image = tifffile.imread('rr30a_s0_ch2.tif')[30] | ||
start_point = np.array([243, 292]) # (y,x) | ||
goal_point = np.array([128, 711]) # (y,x) | ||
|
||
# astar_search = AStarSearch( | ||
# image, | ||
# start_point, | ||
# goal_point) | ||
# tic = time.perf_counter() | ||
# result = astar_search.search() | ||
# toc = time.perf_counter() | ||
# print(f"result: {result}") | ||
# print(f"Found brightest path in {toc - tic:0.4f} seconds") | ||
# print(f"path size: {len(result)}") | ||
# print(f"Number of nodes viewed: {astar_search.evaluated_nodes}") | ||
two_dim_image = np.array([[ 4496, 5212, 6863, 10113, 7055], | ||
[ 4533, 5146, 7555, 10377, 5768], | ||
[ 4640, 6082, 8452, 10278, 4543], | ||
[ 5210, 6849, 10010, 8677, 3911], | ||
[ 5745, 7845, 11113, 7820, 3551]]) | ||
two_dim_start_point = np.array([0,0]) | ||
two_dim_goal_point = np.array([4,4]) | ||
|
||
three_dim_image = np.array([[[ 4496, 5212, 6863, 10113, 7055], | ||
[ 4533, 5146, 7555, 10377, 5768], | ||
[ 4640, 6082, 8452, 10278, 4543], | ||
[ 5210, 6849, 10010, 8677, 3911], | ||
[ 5745, 7845, 11113, 7820, 3551]], | ||
|
||
[[ 8868, 6923, 5690, 6781, 5738], | ||
[ 7113, 5501, 5216, 4789, 5501], | ||
[ 5833, 7160, 5928, 5596, 5406], | ||
[ 6402, 6259, 5501, 4458, 6449], | ||
[ 6117, 6022, 7160, 7113, 7066]]]) | ||
three_dim_start_point = np.array([0,0,0]) | ||
three_dim_goal_point = np.array([0,4,4]) | ||
|
||
# nbastar_search = NBAStarSearch( | ||
# image, | ||
# start_point, | ||
# goal_point) | ||
# nbastar_search = NBAStarSearch( | ||
# two_dim_image, | ||
# two_dim_start_point, | ||
# two_dim_goal_point) | ||
three_dim_image = (three_dim_image/np.max(three_dim_image) * 255).astype(np.uint8) | ||
nbastar_search = NBAStarSearch( | ||
three_dim_image, | ||
three_dim_start_point, | ||
three_dim_goal_point) | ||
tic = time.perf_counter() | ||
result = nbastar_search.search() | ||
toc = time.perf_counter() | ||
print(f"result: {result}") | ||
print(f"Found brightest path in {toc - tic:0.4f} seconds") | ||
print(f"path size: {len(result)}") | ||
print(f"Number of nodes viewed: {nbastar_search.evaluated_nodes}") | ||
|
||
# viewer = napari.Viewer() | ||
# # viewer.add_image(twoDImage[:100, :250], colormap='magma') | ||
# viewer.add_image(image) | ||
# viewer.add_points(np.array([start_point, goal_point]), size=10, edge_width=1, face_color="red", edge_color="red") | ||
# viewer.add_points(result, size=10, edge_width=1, face_color="green", edge_color="green") | ||
# napari.run() | ||
|
||
def test_3D_image(): | ||
image = tifffile.imread('rr30a_s0_ch2.tif') | ||
start_point = np.array([30, 243, 292]) # (z,y,x) | ||
goal_point = np.array([30, 221, 434]) # (z,y,x) | ||
|
||
astar_search = AStarSearch( | ||
image, | ||
start_point, | ||
goal_point | ||
) | ||
|
||
tic = time.perf_counter() | ||
result = astar_search.search() | ||
toc = time.perf_counter() | ||
print(f"Found brightest path in {toc - tic:0.4f} seconds") | ||
print(f"path size: {len(result)}") | ||
|
||
# nbastar_search = NBAStarSearch( | ||
# image, | ||
# start_point, | ||
# goal_point | ||
# ) | ||
# tic = time.perf_counter() | ||
# result = nbastar_search.search() | ||
# toc = time.perf_counter() | ||
# print(f"Found brightest path in {toc - tic:0.4f} seconds") | ||
# print(f"path size: {len(result)}") | ||
|
||
viewer = napari.Viewer() | ||
viewer.add_image(image) | ||
viewer.add_points([start_point, goal_point], size=10, edge_width=1, face_color="red", edge_color="red") | ||
viewer.add_points(result, size=10, edge_width=1, face_color="green", edge_color="green") | ||
napari.run() | ||
|
||
if __name__ == "__main__": | ||
test_2D_image() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
from queue import Empty, Queue | ||
from threading import Thread | ||
import tifffile | ||
import time | ||
from typing import List | ||
|
||
from brightest_path_lib.algorithm import AStarSearch, NBAStarSearch | ||
|
||
from skimage import data | ||
import numpy as np | ||
import matplotlib.pyplot as plt | ||
|
||
|
||
class AStarThread(Thread): | ||
def __init__(self, | ||
image : np.ndarray, | ||
start_point : np.ndarray, | ||
goal_point : np.ndarray, | ||
queue = None): | ||
super().__init__(daemon=True) | ||
self.queue = queue | ||
self.search_algorithm = AStarSearch(image, start_point=start_point, goal_point=goal_point, open_nodes=queue) | ||
|
||
def cancel(self): | ||
self.search_algorithm.is_canceled = True | ||
|
||
def run(self): | ||
""" | ||
run A* tracing algorithm | ||
""" | ||
print("Searching...") | ||
tic = time.perf_counter() | ||
self.search_algorithm.search() | ||
toc = time.perf_counter() | ||
print(f"Found brightest path in {toc - tic:0.4f} seconds") | ||
print(f"path size: {len(self.search_algorithm.result)}") | ||
print(f"Number of nodes viewed: {self.search_algorithm.evaluated_nodes}") | ||
print("Done") | ||
|
||
|
||
class NBAStarThread(Thread): | ||
def __init__(self, | ||
image : np.ndarray, | ||
start_point : np.ndarray, | ||
goal_point : np.ndarray, | ||
queue = None): | ||
super().__init__(daemon=True) | ||
self.queue = queue | ||
self.search_algorithm = NBAStarSearch(image, start_point=start_point, goal_point=goal_point, open_nodes=queue) | ||
|
||
def cancel(self): | ||
self.search_algorithm.is_canceled = True | ||
|
||
def run(self): | ||
""" | ||
run NBA* tracing algorithm | ||
""" | ||
print("Searching...") | ||
tic = time.perf_counter() | ||
self.search_algorithm.search() | ||
toc = time.perf_counter() | ||
print(f"Found brightest path in {toc - tic:0.4f} seconds") | ||
print(f"path size: {len(self.search_algorithm.result)}") | ||
print(f"Number of nodes viewed: {self.search_algorithm.evaluated_nodes}") | ||
print("Done") | ||
|
||
|
||
def _plot_image(image: np.ndarray, start: np.ndarray, end: np.ndarray): | ||
plt.imshow(image, cmap='gray') | ||
plt.plot(start[1], start[0],'og') | ||
plt.plot(end[1], end[0], 'or') | ||
plt.pause(0.001) | ||
|
||
|
||
def _plot_points(points: List[np.ndarray], color, size, alpha=1.0): | ||
"""Plot points | ||
Args: | ||
points: [(y,x)] | ||
""" | ||
yPlot = [point[0] for point in points] | ||
xPlot = [point[1] for point in points] | ||
|
||
plt.scatter(xPlot, yPlot, c=color, s=size, alpha=alpha) | ||
plt.pause(0.0001) | ||
|
||
|
||
def plot_brightest_path(): | ||
# image = data.cells3d()[30, 0] | ||
# start_point = np.array([0,192]) # [y, x] | ||
# goal_point = np.array([198,9]) | ||
|
||
image = tifffile.imread('/Users/vasudhajha/Documents/mapmanager/brightest-path-lib/brightest_path_lib/a-star-image.tif') | ||
start_point = np.array([188, 71]) # (y,x) | ||
goal_point = np.array([116, 415]) | ||
#goal_point = np.array([128, 628]) | ||
|
||
_plot_image(image, start_point, goal_point) | ||
|
||
queue = Queue() | ||
|
||
# search_thread = AStarThread(image, start_point, goal_point, queue) | ||
search_thread = NBAStarThread(image, start_point, goal_point, queue) | ||
search_thread.start() # start the thread, internally Python calls tt.run() | ||
|
||
_updateInterval = 100 # wait for this number of results and update plot | ||
plotItems = [] | ||
while search_thread.is_alive() or not queue.empty(): # polling the queue | ||
# if search_thread.search_algorithm.found_path: | ||
# break | ||
|
||
try: | ||
item = queue.get(False) | ||
# update a matplotlib/pyqtgraph/napari interface | ||
plotItems.append(item) | ||
if len(plotItems) > _updateInterval: | ||
_plot_points(plotItems, 'c', 8, 0.3) | ||
plotItems = [] | ||
|
||
except Empty: | ||
# Handle empty queue here | ||
pass | ||
|
||
|
||
if search_thread.search_algorithm.found_path: | ||
plt.clf() | ||
|
||
_plot_image(image, start_point, goal_point) | ||
|
||
_plot_points(search_thread.search_algorithm.result, 'y', 4, 0.5) | ||
|
||
|
||
# keep the plot up | ||
plt.show() | ||
|
||
if __name__ == "__main__": | ||
plot_brightest_path() |
Oops, something went wrong.