batoolset 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- batoolset/GUI/__init__.py +0 -0
- batoolset/GUI/list_gui.py +513 -0
- batoolset/GUI/multi_image_display.py +989 -0
- batoolset/GUI/open.py +325 -0
- batoolset/GUI/overlay_hints.py +45 -0
- batoolset/GUI/paint2.py +1345 -0
- batoolset/GUI/scrollablepaint.py +1152 -0
- batoolset/IJ_ROIs/__init__.py +0 -0
- batoolset/IJ_ROIs/tools.py +40 -0
- batoolset/PATH/__init__.py +0 -0
- batoolset/PATH/tools.py +79 -0
- batoolset/SQLite_tools/__init__.py +0 -0
- batoolset/SQLite_tools/tools.py +840 -0
- batoolset/__init__.py +0 -0
- batoolset/binary/__init__.py +0 -0
- batoolset/binary/tools.py +123 -0
- batoolset/binarytools/__init__.py +0 -0
- batoolset/binarytools/cell_center_detector.py +290 -0
- batoolset/clipboard_tools/__init__.py +0 -0
- batoolset/clipboard_tools/tools.py +7 -0
- batoolset/colors/__init__.py +0 -0
- batoolset/colors/colorgen.py +193 -0
- batoolset/colors/tools.py +22 -0
- batoolset/command_line/__init__.py +0 -0
- batoolset/command_line/tools.py +18 -0
- batoolset/dialogs/__init__.py +0 -0
- batoolset/dialogs/opensave.py +228 -0
- batoolset/dicts/__init__.py +0 -0
- batoolset/dicts/tools.py +299 -0
- batoolset/dims/__init__.py +0 -0
- batoolset/dims/tools.py +83 -0
- batoolset/draw/__init__.py +0 -0
- batoolset/draw/shapes/Position.py +183 -0
- batoolset/draw/shapes/__init__.py +0 -0
- batoolset/draw/shapes/automated_alignment_drawing_refactored.py +346 -0
- batoolset/draw/shapes/circle2d.py +99 -0
- batoolset/draw/shapes/compute_optimal_size_all_merged.py +317 -0
- batoolset/draw/shapes/ellipse2d.py +336 -0
- batoolset/draw/shapes/freehand2d.py +235 -0
- batoolset/draw/shapes/group.py +1830 -0
- batoolset/draw/shapes/image2d.py +2469 -0
- batoolset/draw/shapes/line2d.py +575 -0
- batoolset/draw/shapes/point2d.py +257 -0
- batoolset/draw/shapes/polygon2d.py +357 -0
- batoolset/draw/shapes/polyline2d.py +235 -0
- batoolset/draw/shapes/rect2d.py +388 -0
- batoolset/draw/shapes/rectangle2d.py +601 -0
- batoolset/draw/shapes/scalebar.py +304 -0
- batoolset/draw/shapes/serializablefont.py +126 -0
- batoolset/draw/shapes/serializableguiparams.py +10 -0
- batoolset/draw/shapes/square2d.py +103 -0
- batoolset/draw/shapes/textorientation.py +45 -0
- batoolset/draw/shapes/tools.py +467 -0
- batoolset/draw/shapes/transform2D.py +350 -0
- batoolset/draw/shapes/txt2d.py +550 -0
- batoolset/draw/widgets/__init__.py +0 -0
- batoolset/draw/widgets/col.py +343 -0
- batoolset/draw/widgets/image_group.py +248 -0
- batoolset/draw/widgets/image_organizer.py +96 -0
- batoolset/draw/widgets/paint.py +184 -0
- batoolset/draw/widgets/vectorial.py +257 -0
- batoolset/figure/__init__.py +0 -0
- batoolset/figure/alignment.py +814 -0
- batoolset/figure/column.py +1117 -0
- batoolset/figure/fig_tools.py +285 -0
- batoolset/figure/minimal_debugger_scale_etc.py +139 -0
- batoolset/figure/panel.py +697 -0
- batoolset/figure/row.py +852 -0
- batoolset/figure/user_selection.py +287 -0
- batoolset/files/__init__.py +0 -0
- batoolset/files/tools.py +1321 -0
- batoolset/images/__init__.py +0 -0
- batoolset/images/tools.py +81 -0
- batoolset/img.py +5216 -0
- batoolset/linux/__init__.py +0 -0
- batoolset/linux/tools.py +72 -0
- batoolset/lists/__init__.py +0 -0
- batoolset/lists/tools.py +436 -0
- batoolset/luts/__init__.py +0 -0
- batoolset/luts/lut_minimal_test.py +1207 -0
- batoolset/matplolib/__init__.py +0 -0
- batoolset/matplolib/tools.py +44 -0
- batoolset/np_tools/__init__.py +0 -0
- batoolset/np_tools/tools.py +252 -0
- batoolset/np_tools/trash.py +15 -0
- batoolset/pandas_tools/__init__.py +0 -0
- batoolset/pandas_tools/tools.py +880 -0
- batoolset/partials/__init__.py +0 -0
- batoolset/partials/tools.py +83 -0
- batoolset/plot_tools/__init__.py +0 -0
- batoolset/plot_tools/tools.py +70 -0
- batoolset/pyqt/__init__.py +0 -0
- batoolset/pyqt/tools.py +691 -0
- batoolset/re_tools/__init__.py +0 -0
- batoolset/re_tools/tools.py +35 -0
- batoolset/serialization/__init__.py +0 -0
- batoolset/serialization/tools.py +1192 -0
- batoolset/sets/__init__.py +0 -0
- batoolset/sets/tools.py +109 -0
- batoolset/settings/__init__.py +0 -0
- batoolset/settings/global_settings.py +134 -0
- batoolset/strings/__init__.py +0 -0
- batoolset/strings/tools.py +225 -0
- batoolset/ta/__init__.py +0 -0
- batoolset/ta/database/__init__.py +0 -0
- batoolset/ta/database/advanced_sql_plotter.py +1170 -0
- batoolset/ta/database/my_qt_table.py +79 -0
- batoolset/ta/database/preview_and_edit_sqlite_db.py +405 -0
- batoolset/ta/database/sql.py +2141 -0
- batoolset/ta/database/sql_column_name_dialog.py +122 -0
- batoolset/ta/measurements/TAmeasures.py +2226 -0
- batoolset/ta/measurements/__init__.py +0 -0
- batoolset/ta/measurements/measurements3D/__init__.py +0 -0
- batoolset/ta/measurements/measurements3D/get_point_on_surface_if_centroid_is_bad.py +175 -0
- batoolset/ta/measurements/measurements3D/height_map_to_projection.py +82 -0
- batoolset/ta/measurements/measurements3D/measures3D.py +208 -0
- batoolset/ta/measurements/measurements3D/triangulate.py +331 -0
- batoolset/ta/measurements/nematic.py +562 -0
- batoolset/ta/measurements/nematic_measurements.py +107 -0
- batoolset/ta/segmentation/__init__.py +0 -0
- batoolset/ta/segmentation/neo_wshed.py +314 -0
- batoolset/ta/selections/__init__.py +0 -0
- batoolset/ta/selections/selection.py +329 -0
- batoolset/ta/tracking/__init__.py +0 -0
- batoolset/ta/tracking/last_tracking_based_on_matching_or_on_translation_from_mermaid_warp.py +653 -0
- batoolset/ta/tracking/local_to_track_correspondance.py +138 -0
- batoolset/ta/tracking/rapid_detection_of_vertices.py +517 -0
- batoolset/ta/tracking/registration.py +108 -0
- batoolset/ta/tracking/swap_detector_and_fixer.py +296 -0
- batoolset/ta/tracking/track_correction.py +238 -0
- batoolset/ta/tracking/tracking_error_detector_and_fixer.py +3099 -0
- batoolset/ta/tracking/tracking_yet_another_approach_pyramidal_registration_n_neo_swapping_correction.py +725 -0
- batoolset/ta/utils/TA_tools.py +43 -0
- batoolset/ta/utils/__init__.py +0 -0
- batoolset/ta/utils/rps_tools.py +1783 -0
- batoolset/tests/__init__.py +0 -0
- batoolset/tests/rps_tools.py +51 -0
- batoolset/tests/tools.py +10 -0
- batoolset/tools/__init__.py +0 -0
- batoolset/tools/early_stopper_class.py +9 -0
- batoolset/tools/guided_data_recoverer.py +110 -0
- batoolset/tools/logger.py +100 -0
- batoolset/tools/mytimer.py +31 -0
- batoolset/tools/prompt_color.py +160 -0
- batoolset/tools/qthandler.py +118 -0
- batoolset/uitools/__init__.py +0 -0
- batoolset/uitools/blinker.py +56 -0
- batoolset/unsafe/__init__.py +0 -0
- batoolset/unsafe/tools.py +115 -0
- batoolset/utils/__init__.py +0 -0
- batoolset/utils/commontools.py +158 -0
- batoolset/utils/loadlist.py +728 -0
- batoolset/version.py +10 -0
- batoolset/xml/__init__.py +0 -0
- batoolset/xml/tools.py +65 -0
- batoolset/zip_tools/__init__.py +0 -0
- batoolset/zip_tools/tools.py +76 -0
- batoolset-0.1.0.dist-info/LICENSE +24 -0
- batoolset-0.1.0.dist-info/METADATA +45 -0
- batoolset-0.1.0.dist-info/RECORD +162 -0
- batoolset-0.1.0.dist-info/WHEEL +5 -0
- batoolset-0.1.0.dist-info/top_level.txt +1 -0
batoolset/__init__.py
ADDED
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# this will contain a set of binary tools
|
|
2
|
+
from skimage.measure import label, regionprops
|
|
3
|
+
from skimage.draw import ellipse
|
|
4
|
+
import numpy as np
|
|
5
|
+
import matplotlib.pyplot as plt
|
|
6
|
+
from skimage import data, filters
|
|
7
|
+
from skimage.filters.thresholding import threshold_otsu
|
|
8
|
+
|
|
9
|
+
def ellipsoidify_dots(binary_dots):
|
|
10
|
+
"""
|
|
11
|
+
Replaces all 2D dots detected by an equivalent ellipse using bbox radius to draw the dot.
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
binary_dots (ndarray): An image that contains dots (typically obtained through binarization of an image).
|
|
15
|
+
|
|
16
|
+
Returns:
|
|
17
|
+
ndarray: The modified image with dots replaced by ellipses.
|
|
18
|
+
|
|
19
|
+
Examples:
|
|
20
|
+
>>> binary_dots = np.array([[0, 0, 0, 0],
|
|
21
|
+
... [0, 1, 0, 0],
|
|
22
|
+
... [0, 0, 0, 0]])
|
|
23
|
+
>>> result = ellipsoidify_dots(binary_dots)
|
|
24
|
+
>>> print(result)
|
|
25
|
+
[[0 0 0 0]
|
|
26
|
+
[0 1 0 0]
|
|
27
|
+
[0 0 0 0]]
|
|
28
|
+
"""
|
|
29
|
+
# Check if the image is 3D
|
|
30
|
+
if len(binary_dots.shape) == 3:
|
|
31
|
+
# If image is 3D, loop over all images and apply ellipsoidify_dots to each channel
|
|
32
|
+
for iii, img_2D in enumerate(binary_dots):
|
|
33
|
+
binary_dots[iii] = ellipsoidify_dots(img_2D)
|
|
34
|
+
return binary_dots
|
|
35
|
+
|
|
36
|
+
# Label the dots in the binary image
|
|
37
|
+
lab_dots = label(binary_dots, connectivity=None, background=0)
|
|
38
|
+
rps_dots = regionprops(lab_dots)
|
|
39
|
+
|
|
40
|
+
# Iterate over each labeled region (dot)
|
|
41
|
+
for region in rps_dots:
|
|
42
|
+
centroid = region.centroid
|
|
43
|
+
bbox = region.bbox
|
|
44
|
+
# Draw an ellipse that fits the dot
|
|
45
|
+
rr, cc = ellipse(centroid[0], centroid[1], r_radius=abs(bbox[0] - bbox[2]) / 2,
|
|
46
|
+
c_radius=abs(bbox[1] - bbox[3]) / 2, shape=binary_dots.shape)
|
|
47
|
+
binary_dots[rr, cc] = binary_dots.max()
|
|
48
|
+
|
|
49
|
+
return binary_dots
|
|
50
|
+
# should also work for 3D even though the 3D version is not super elegant
|
|
51
|
+
|
|
52
|
+
def tst_all_auto_thresholds(img):
|
|
53
|
+
# Apply all thresholding methods and display results
|
|
54
|
+
fig, ax = filters.try_all_threshold(img, figsize=(8, 5), verbose=False)
|
|
55
|
+
|
|
56
|
+
# Show plot
|
|
57
|
+
plt.show()
|
|
58
|
+
|
|
59
|
+
def yen_thresholding(img,return_threshold=False):
|
|
60
|
+
# Apply Yen thresholding method
|
|
61
|
+
thresh = filters.threshold_yen(img)
|
|
62
|
+
if return_threshold:
|
|
63
|
+
return thresh
|
|
64
|
+
# Apply threshold to image
|
|
65
|
+
return apply_threshold(img, thresh)
|
|
66
|
+
|
|
67
|
+
def triangle_threshold(img, return_threshold=False):
|
|
68
|
+
# Apply triangle thresholding method
|
|
69
|
+
thresh = filters.threshold_triangle(img)
|
|
70
|
+
if return_threshold:
|
|
71
|
+
return thresh
|
|
72
|
+
# Apply threshold to image
|
|
73
|
+
return apply_threshold(img, thresh)
|
|
74
|
+
|
|
75
|
+
def isodata_threshold(img, return_threshold=False):
|
|
76
|
+
# Apply triangle thresholding method
|
|
77
|
+
thresh = filters.threshold_isodata(img)
|
|
78
|
+
# thresh = threshold_otsu(img)
|
|
79
|
+
if return_threshold:
|
|
80
|
+
return thresh
|
|
81
|
+
# Apply threshold to image
|
|
82
|
+
return apply_threshold(img, thresh)
|
|
83
|
+
|
|
84
|
+
def otsu_threshold(img, return_threshold=False):
|
|
85
|
+
# Apply triangle thresholding method
|
|
86
|
+
# thresh = filters.otsu_threshold(img)
|
|
87
|
+
thresh = threshold_otsu(img)
|
|
88
|
+
if return_threshold:
|
|
89
|
+
return thresh
|
|
90
|
+
# Apply threshold to image
|
|
91
|
+
return apply_threshold(img, thresh)
|
|
92
|
+
|
|
93
|
+
def mean_threshold(img, return_threshold=False):
|
|
94
|
+
# Apply triangle thresholding method
|
|
95
|
+
thresh = filters.threshold_mean(img)
|
|
96
|
+
if return_threshold:
|
|
97
|
+
return thresh
|
|
98
|
+
# Apply threshold to image
|
|
99
|
+
return apply_threshold(img, thresh)
|
|
100
|
+
|
|
101
|
+
def apply_threshold(img, threshold):
|
|
102
|
+
# Apply threshold to image
|
|
103
|
+
binary = img > threshold
|
|
104
|
+
return binary
|
|
105
|
+
|
|
106
|
+
def smart_threshold_above(img,max_fraction, increment=0.01):
|
|
107
|
+
norm = np.copy(img)
|
|
108
|
+
factor = norm.max()
|
|
109
|
+
norm= norm/norm.max()
|
|
110
|
+
# for vvv in range(0,1,increment):
|
|
111
|
+
threshold = 1.
|
|
112
|
+
while threshold-increment>0.:
|
|
113
|
+
if np.count_nonzero(norm>=threshold)/img.size >= max_fraction:
|
|
114
|
+
return threshold*factor
|
|
115
|
+
threshold-=increment
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
if __name__ == '__main__':
|
|
119
|
+
from batoolset.img import Img
|
|
120
|
+
img =Img('/E/Sample_images/cells_escaping_silencing_test_count/Apotome/MAX_IP-ApoTome-01.tif')
|
|
121
|
+
# img =Img('/E/Sample_images/cells_escaping_silencing_test_count/R1-14,5kb T2A DsRed X2 TgA/R1-14,5kb T2A DsRed X2 TgA 0004/wing_deep.tif')
|
|
122
|
+
# img =Img('/E/Sample_images/cells_escaping_silencing_test_count/HT 14,5kbT2ADsRed/A5 No Wari 14,5T2A DsRed X1 Female 0001/wing_deep.tif')
|
|
123
|
+
print(smart_threshold_above(img, 0.36))
|
|
File without changes
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
import math
|
|
2
|
+
from skimage.measure import label, regionprops
|
|
3
|
+
from timeit import default_timer as timer
|
|
4
|
+
import numpy as np
|
|
5
|
+
import matplotlib.pyplot as plt
|
|
6
|
+
|
|
7
|
+
def add_2d_border(image2d):
|
|
8
|
+
"""
|
|
9
|
+
Adds a border to a 2D image.
|
|
10
|
+
|
|
11
|
+
Args:
|
|
12
|
+
image2d (ndarray): The 2D image to which the border will be added.
|
|
13
|
+
|
|
14
|
+
Returns:
|
|
15
|
+
ndarray: The image with the added border.
|
|
16
|
+
|
|
17
|
+
Examples:
|
|
18
|
+
>>> image2d = np.array([[1, 2, 3],
|
|
19
|
+
... [4, 5, 6],
|
|
20
|
+
... [7, 8, 9]])
|
|
21
|
+
>>> result = add_2d_border(image2d)
|
|
22
|
+
>>> print(result)
|
|
23
|
+
[[0 0 0]
|
|
24
|
+
[0 5 0]
|
|
25
|
+
[0 0 0]]
|
|
26
|
+
"""
|
|
27
|
+
# Define the region where the border will be inserted
|
|
28
|
+
insertHere = (slice(1, image2d.shape[0] - 1), slice(1, image2d.shape[1] - 1))
|
|
29
|
+
|
|
30
|
+
# Create an array filled with zeros to hold the image with the border
|
|
31
|
+
cells_with_borders = np.zeros_like(image2d)
|
|
32
|
+
cells_with_borders.fill(0)
|
|
33
|
+
|
|
34
|
+
# Copy the interior of the image to the array with the border
|
|
35
|
+
cells_with_borders[insertHere] = image2d[insertHere]
|
|
36
|
+
|
|
37
|
+
# Update the original image with the image containing the border
|
|
38
|
+
image2d = cells_with_borders
|
|
39
|
+
|
|
40
|
+
return image2d
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def create_horizontal_gradient(cells):
|
|
44
|
+
"""
|
|
45
|
+
Creates a horizontal gradient based on the cell IDs in a 2D array.
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
cells (ndarray): The 2D array containing cell IDs.
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
ndarray: The horizontal gradient array.
|
|
52
|
+
|
|
53
|
+
# Examples:
|
|
54
|
+
# >>> cells = np.array([[0, 0, 0],
|
|
55
|
+
# ... [1, 1, 0],
|
|
56
|
+
# ... [2, 2, 0]])
|
|
57
|
+
# >>> result = create_horizontal_gradient(cells)
|
|
58
|
+
# >>> print(result)
|
|
59
|
+
# [[0 0 0]
|
|
60
|
+
# [0 1 0]
|
|
61
|
+
# [0 0 0]]
|
|
62
|
+
|
|
63
|
+
"""
|
|
64
|
+
# Add a border to the cells array
|
|
65
|
+
cells = add_2d_border(cells)
|
|
66
|
+
|
|
67
|
+
# Create an array of zeros with the same shape as cells to hold the horizontal gradient
|
|
68
|
+
horiz_gradient = np.zeros_like(cells)
|
|
69
|
+
|
|
70
|
+
# Iterate over the rows and columns of the cells array
|
|
71
|
+
for j in range(0, cells.shape[-2], 1):
|
|
72
|
+
counter = 1
|
|
73
|
+
last_id = 0
|
|
74
|
+
|
|
75
|
+
for i in range(0, cells.shape[-1], 1):
|
|
76
|
+
# Check the current cell ID and compare it with the previous cell ID
|
|
77
|
+
|
|
78
|
+
current_cell_id = cells[j][i]
|
|
79
|
+
|
|
80
|
+
if current_cell_id != 0 and current_cell_id != last_id:
|
|
81
|
+
last_id = current_cell_id
|
|
82
|
+
|
|
83
|
+
if current_cell_id == 0 and last_id != 0:
|
|
84
|
+
last_id = 0
|
|
85
|
+
# Divide the counter by 2
|
|
86
|
+
half_counter = int(counter / 2.)
|
|
87
|
+
counter = 1 # Restart the counter
|
|
88
|
+
|
|
89
|
+
# Found a new cell edge, go backwards to create the gradient
|
|
90
|
+
reverse_counter = 1
|
|
91
|
+
for ii in range(0, -half_counter + 1, -1):
|
|
92
|
+
horiz_gradient[j][i + ii] = reverse_counter
|
|
93
|
+
reverse_counter += 1
|
|
94
|
+
|
|
95
|
+
if current_cell_id != 0 and current_cell_id == last_id:
|
|
96
|
+
horiz_gradient[j][i] = counter
|
|
97
|
+
counter += 1
|
|
98
|
+
|
|
99
|
+
return horiz_gradient
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def create_vertical_gradient(cells):
|
|
103
|
+
"""
|
|
104
|
+
Creates a vertical gradient based on the cell IDs in a 2D array.
|
|
105
|
+
|
|
106
|
+
Args:
|
|
107
|
+
cells (ndarray): The 2D array containing cell IDs.
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
ndarray: The vertical gradient array.
|
|
111
|
+
|
|
112
|
+
# Examples:
|
|
113
|
+
# >>> cells = np.array([[0, 0, 0],
|
|
114
|
+
# ... [1, 1, 0],
|
|
115
|
+
# ... [2, 2, 0]])
|
|
116
|
+
# >>> result = create_vertical_gradient(cells)
|
|
117
|
+
# >>> print(result)
|
|
118
|
+
# [[0 0 0]
|
|
119
|
+
# [0 1 0]
|
|
120
|
+
# [0 0 0]]
|
|
121
|
+
"""
|
|
122
|
+
# Add a border to the cells array
|
|
123
|
+
cells = add_2d_border(cells)
|
|
124
|
+
|
|
125
|
+
# Create an array of zeros with the same shape as cells to hold the vertical gradient
|
|
126
|
+
vertical_gradient = np.zeros_like(cells)
|
|
127
|
+
|
|
128
|
+
# Iterate over the columns and rows of the cells array
|
|
129
|
+
for i in range(0, cells.shape[-1], 1):
|
|
130
|
+
counter = 1
|
|
131
|
+
last_id = 0
|
|
132
|
+
|
|
133
|
+
for j in range(0, cells.shape[-2], 1):
|
|
134
|
+
current_cell_id = cells[j][i]
|
|
135
|
+
|
|
136
|
+
if current_cell_id != 0 and current_cell_id != last_id:
|
|
137
|
+
last_id = current_cell_id
|
|
138
|
+
|
|
139
|
+
if current_cell_id == 0 and last_id != 0:
|
|
140
|
+
last_id = 0
|
|
141
|
+
# Divide the counter by 2
|
|
142
|
+
half_counter = int(counter / 2.)
|
|
143
|
+
counter = 1 # Restart the counter
|
|
144
|
+
|
|
145
|
+
# Found a new cell edge, go backwards to create the gradient
|
|
146
|
+
reverse_counter = 1
|
|
147
|
+
for jj in range(0, -half_counter + 1, -1):
|
|
148
|
+
vertical_gradient[j + jj][i] = reverse_counter
|
|
149
|
+
reverse_counter += 1
|
|
150
|
+
|
|
151
|
+
if current_cell_id != 0 and current_cell_id == last_id:
|
|
152
|
+
vertical_gradient[j][i] = counter
|
|
153
|
+
counter += 1
|
|
154
|
+
|
|
155
|
+
return vertical_gradient
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def get_seeds(cells, one_seed_per_cell=True):
|
|
159
|
+
"""
|
|
160
|
+
Obtain seeds for watershed segmentation based on cell gradients.
|
|
161
|
+
|
|
162
|
+
Args:
|
|
163
|
+
cells (ndarray): The 2D array containing cell IDs.
|
|
164
|
+
one_seed_per_cell (bool): Whether to ensure only one seed per cell. Default is True.
|
|
165
|
+
|
|
166
|
+
Returns:
|
|
167
|
+
tuple: A tuple containing the combined gradients array and the seeds array.
|
|
168
|
+
|
|
169
|
+
# Examples:
|
|
170
|
+
# >>> cells = np.array([[0, 0, 0],
|
|
171
|
+
# ... [1, 1, 0],
|
|
172
|
+
# ... [2, 2, 0]])
|
|
173
|
+
# >>> result = get_seeds(cells)
|
|
174
|
+
# >>> combined_gradients, seeds = result
|
|
175
|
+
# >>> print(combined_gradients)
|
|
176
|
+
# [[0 0 0]
|
|
177
|
+
# [1 2 0]
|
|
178
|
+
# [1 2 0]]
|
|
179
|
+
# >>> print(seeds)
|
|
180
|
+
# [[0 0 0]
|
|
181
|
+
# [0 2 0]
|
|
182
|
+
# [0 0 0]]
|
|
183
|
+
"""
|
|
184
|
+
# Create horizontal and vertical gradients
|
|
185
|
+
horiz_gradient = create_horizontal_gradient(cells)
|
|
186
|
+
vertical_gradient = create_vertical_gradient(cells)
|
|
187
|
+
|
|
188
|
+
# Perform further processing on gradients to obtain combined gradients and seeds
|
|
189
|
+
combined_gradients_ready_for_wshed, seeds = _get_seeds(cells, horiz_gradient, vertical_gradient)
|
|
190
|
+
|
|
191
|
+
# If one_seed_per_cell is True, ensure only one seed per cell
|
|
192
|
+
if one_seed_per_cell:
|
|
193
|
+
new_seeds = label(seeds.astype(np.uint8), connectivity=1, background=0)
|
|
194
|
+
props_seeds = regionprops(new_seeds)
|
|
195
|
+
|
|
196
|
+
extra_seeds_to_remove = []
|
|
197
|
+
|
|
198
|
+
for region in regionprops(cells):
|
|
199
|
+
cells_found = []
|
|
200
|
+
for coordinates in region.coords:
|
|
201
|
+
cells_found.append(new_seeds[coordinates[0], coordinates[1]])
|
|
202
|
+
cells_found = list(dict.fromkeys(cells_found))
|
|
203
|
+
if 0 in cells_found:
|
|
204
|
+
cells_found.remove(0)
|
|
205
|
+
if len(cells_found) > 1:
|
|
206
|
+
max_area = 0
|
|
207
|
+
for cell in cells_found:
|
|
208
|
+
region = props_seeds[cell - 1]
|
|
209
|
+
max_area = max(max_area, region.area)
|
|
210
|
+
|
|
211
|
+
for cell in cells_found:
|
|
212
|
+
if not props_seeds[cell - 1].area == max_area:
|
|
213
|
+
extra_seeds_to_remove.append(cell)
|
|
214
|
+
|
|
215
|
+
for region in props_seeds:
|
|
216
|
+
if region.label in extra_seeds_to_remove:
|
|
217
|
+
for coordinates in region.coords:
|
|
218
|
+
seeds[coordinates[0], coordinates[1]] = 0
|
|
219
|
+
|
|
220
|
+
return combined_gradients_ready_for_wshed, seeds
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
def _get_seeds(cells, horiz_gradient, vertical_gradient):
|
|
225
|
+
"""
|
|
226
|
+
Obtain seeds based on combined gradients for watershed segmentation.
|
|
227
|
+
|
|
228
|
+
Args:
|
|
229
|
+
cells (ndarray): The 2D array containing cell IDs.
|
|
230
|
+
horiz_gradient (ndarray): The 2D array representing the horizontal gradient.
|
|
231
|
+
vertical_gradient (ndarray): The 2D array representing the vertical gradient.
|
|
232
|
+
|
|
233
|
+
Returns:
|
|
234
|
+
tuple: A tuple containing the combined gradients array and the highest pixel values array.
|
|
235
|
+
|
|
236
|
+
# Examples:
|
|
237
|
+
# >>> cells = np.array([[0, 0, 0],
|
|
238
|
+
# ... [1, 1, 0],
|
|
239
|
+
# ... [2, 2, 0]])
|
|
240
|
+
# >>> horiz_gradient = np.array([[0, 0, 0],
|
|
241
|
+
# ... [1, 2, 0],
|
|
242
|
+
# ... [1, 2, 0]])
|
|
243
|
+
# >>> vertical_gradient = np.array([[0, 0, 0],
|
|
244
|
+
# ... [0, 1, 0],
|
|
245
|
+
# ... [0, 1, 0]])
|
|
246
|
+
# >>> result = _get_seeds(cells, horiz_gradient, vertical_gradient)
|
|
247
|
+
# >>> combined_gradients, highest_pixels = result
|
|
248
|
+
# >>> print(combined_gradients)
|
|
249
|
+
# [[0 0 0]
|
|
250
|
+
# [1 3 0]
|
|
251
|
+
# [1 3 0]]
|
|
252
|
+
# >>> print(highest_pixels)
|
|
253
|
+
# [[ 0 0 0]
|
|
254
|
+
# [ 0 255 0]
|
|
255
|
+
# [ 0 255 0]]
|
|
256
|
+
"""
|
|
257
|
+
# Combine gradients
|
|
258
|
+
combined_gradients_ready_for_wshed = horiz_gradient + vertical_gradient
|
|
259
|
+
|
|
260
|
+
# Create array for highest pixel values
|
|
261
|
+
highest_pixels = np.zeros_like(cells)
|
|
262
|
+
|
|
263
|
+
# Iterate over labeled regions in cells with intensity_image set to combined_gradients_ready_for_wshed
|
|
264
|
+
for region in regionprops(cells, intensity_image=combined_gradients_ready_for_wshed):
|
|
265
|
+
max_val = 0
|
|
266
|
+
|
|
267
|
+
# Scale seed by cell size using the square root of the region's area
|
|
268
|
+
factor = math.sqrt(region.area) * 30 / 100
|
|
269
|
+
|
|
270
|
+
# Find the maximum value in the intensity image
|
|
271
|
+
for j in range(0, region.intensity_image.shape[-2], 1):
|
|
272
|
+
for i in range(0, region.intensity_image.shape[-1], 1):
|
|
273
|
+
if region.intensity_image[j, i] >= max_val:
|
|
274
|
+
max_val = region.intensity_image[j, i]
|
|
275
|
+
|
|
276
|
+
# Set the region's image to False
|
|
277
|
+
region.image.fill(False)
|
|
278
|
+
|
|
279
|
+
# Set pixels in the region's image to True where the intensity exceeds (max_val - factor)
|
|
280
|
+
region.image[region.intensity_image >= (max_val - factor)] = True
|
|
281
|
+
|
|
282
|
+
# Update the highest_pixels array with the region's coordinates
|
|
283
|
+
for coordinates in region.coords:
|
|
284
|
+
highest_pixels[coordinates[0], coordinates[1]] = 255
|
|
285
|
+
|
|
286
|
+
return combined_gradients_ready_for_wshed, highest_pixels
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
if __name__ == '__main__':
|
|
290
|
+
start = timer()
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# can be used to generate pseudo random or random colors
|
|
2
|
+
|
|
3
|
+
import random
|
|
4
|
+
# need seed it or reset seed
|
|
5
|
+
import sys
|
|
6
|
+
|
|
7
|
+
def get_forbidden_colors():
|
|
8
|
+
"""
|
|
9
|
+
Retrieves a list of forbidden colors represented in RGB format.
|
|
10
|
+
|
|
11
|
+
Returns:
|
|
12
|
+
list: A list of forbidden colors in RGB format.
|
|
13
|
+
|
|
14
|
+
Examples:
|
|
15
|
+
>>> get_forbidden_colors()
|
|
16
|
+
[(0, 0, 0), (255, 255, 255)]
|
|
17
|
+
"""
|
|
18
|
+
# Define the forbidden colors using RGB values
|
|
19
|
+
forbidden_colors = [(0, 0, 0), (255, 255, 255)]
|
|
20
|
+
|
|
21
|
+
return forbidden_colors
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def get_forbidden_colors_int24():
|
|
25
|
+
"""
|
|
26
|
+
Retrieves a list of forbidden colors represented in 24-bit integer format.
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
list: A list of forbidden colors in 24-bit integer format.
|
|
30
|
+
|
|
31
|
+
Examples:
|
|
32
|
+
>>> get_forbidden_colors_int24()
|
|
33
|
+
[0, 16777215]
|
|
34
|
+
"""
|
|
35
|
+
# Define the forbidden colors using 24-bit integer values
|
|
36
|
+
forbidden_colors = [0, 0xFFFFFF]
|
|
37
|
+
|
|
38
|
+
return forbidden_colors
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def r_g_b_to_rgb(r, g, b):
|
|
42
|
+
"""
|
|
43
|
+
Converts individual RGB color components to a combined RGB value.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
r (int): The red color component (0-255).
|
|
47
|
+
g (int): The green color component (0-255).
|
|
48
|
+
b (int): The blue color component (0-255).
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
int: The combined RGB value.
|
|
52
|
+
|
|
53
|
+
Examples:
|
|
54
|
+
>>> r_g_b_to_rgb(255, 0, 0)
|
|
55
|
+
16711680
|
|
56
|
+
>>> r_g_b_to_rgb(0, 255, 0)
|
|
57
|
+
65280
|
|
58
|
+
>>> r_g_b_to_rgb(0, 0, 255)
|
|
59
|
+
255
|
|
60
|
+
"""
|
|
61
|
+
RGB = (r << 16) + (g << 8) + b
|
|
62
|
+
return RGB
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def r_g_b_from_rgb(rgb):
|
|
67
|
+
"""
|
|
68
|
+
Extracts individual RGB color components from a combined RGB value.
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
rgb (int): The combined RGB value.
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
tuple: A tuple containing the red, green, and blue color components.
|
|
75
|
+
|
|
76
|
+
Examples:
|
|
77
|
+
>>> r_g_b_from_rgb(16711680)
|
|
78
|
+
(255, 0, 0)
|
|
79
|
+
>>> r_g_b_from_rgb(65280)
|
|
80
|
+
(0, 255, 0)
|
|
81
|
+
>>> r_g_b_from_rgb(255)
|
|
82
|
+
(0, 0, 255)
|
|
83
|
+
"""
|
|
84
|
+
b = rgb & 255
|
|
85
|
+
g = (rgb >> 8) & 255
|
|
86
|
+
r = (rgb >> 16) & 255
|
|
87
|
+
return r, g, b
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
# self calling stack --> maybe not a good idea ....
|
|
91
|
+
def get_unique_random_color_int24(forbidden_colors=None, seed_random=None, assign_new_col_to_forbidden=False):
|
|
92
|
+
"""
|
|
93
|
+
Generates a unique random color represented in a 24-bit integer format.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
forbidden_colors (list, optional): A list of forbidden colors in RGB format. Defaults to None.
|
|
97
|
+
seed_random (int, optional): An integer value to seed the random number generator. Defaults to None.
|
|
98
|
+
assign_new_col_to_forbidden (bool, optional): Specifies whether to assign the new color to the forbidden colors list. Defaults to False.
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
int: A unique random color represented as a 24-bit integer.
|
|
102
|
+
|
|
103
|
+
Examples:
|
|
104
|
+
>>> get_unique_random_color_int24(forbidden_colors=[16777215])!=16777215
|
|
105
|
+
True
|
|
106
|
+
"""
|
|
107
|
+
if seed_random is not None:
|
|
108
|
+
random.seed(seed_random)
|
|
109
|
+
|
|
110
|
+
color = random.getrandbits(24)
|
|
111
|
+
|
|
112
|
+
if forbidden_colors is not None:
|
|
113
|
+
if color in forbidden_colors:
|
|
114
|
+
while color in forbidden_colors:
|
|
115
|
+
color = random.getrandbits(24)
|
|
116
|
+
|
|
117
|
+
if assign_new_col_to_forbidden:
|
|
118
|
+
forbidden_colors.append(color)
|
|
119
|
+
|
|
120
|
+
return color
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
# if I seed the random then it will work to generate random colors
|
|
124
|
+
def get_unique_random_color(forbidden_colors=None, seed_random=None, assign_new_col_to_forbidden=False):
|
|
125
|
+
"""
|
|
126
|
+
Generates a unique random color represented in RGB format.
|
|
127
|
+
|
|
128
|
+
Args:
|
|
129
|
+
forbidden_colors (list, optional): A list of forbidden colors in RGB format. Defaults to None.
|
|
130
|
+
seed_random (int, optional): An integer value to seed the random number generator. Defaults to None.
|
|
131
|
+
assign_new_col_to_forbidden (bool, optional): Specifies whether to assign the new color to the forbidden colors list. Defaults to False.
|
|
132
|
+
|
|
133
|
+
Returns:
|
|
134
|
+
tuple: A unique random color represented as an RGB tuple.
|
|
135
|
+
|
|
136
|
+
Examples:
|
|
137
|
+
>>> get_unique_random_color(forbidden_colors=[(255, 255, 255)]) != (255,255,255)
|
|
138
|
+
True
|
|
139
|
+
"""
|
|
140
|
+
if seed_random is not None:
|
|
141
|
+
random.seed(seed_random)
|
|
142
|
+
|
|
143
|
+
r = random.getrandbits(8)
|
|
144
|
+
g = random.getrandbits(8)
|
|
145
|
+
b = random.getrandbits(8)
|
|
146
|
+
color = (r, g, b)
|
|
147
|
+
|
|
148
|
+
if forbidden_colors is not None:
|
|
149
|
+
if color in forbidden_colors:
|
|
150
|
+
while color in forbidden_colors:
|
|
151
|
+
color = get_unique_random_color(forbidden_colors=forbidden_colors)
|
|
152
|
+
|
|
153
|
+
if assign_new_col_to_forbidden:
|
|
154
|
+
forbidden_colors.append(color)
|
|
155
|
+
|
|
156
|
+
return color
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
if __name__ == '__main__':
|
|
160
|
+
|
|
161
|
+
if True:
|
|
162
|
+
random.seed(10)
|
|
163
|
+
r = random.getrandbits(8)
|
|
164
|
+
b = random.getrandbits(8)
|
|
165
|
+
g = random.getrandbits(8)
|
|
166
|
+
|
|
167
|
+
color = r_g_b_to_rgb(r, g, b)
|
|
168
|
+
|
|
169
|
+
print(color, random.getrandbits(24), random.getrandbits(32))
|
|
170
|
+
|
|
171
|
+
forbidden = get_forbidden_colors_int24()
|
|
172
|
+
|
|
173
|
+
color = get_unique_random_color_int24(forbidden)
|
|
174
|
+
print(color)
|
|
175
|
+
|
|
176
|
+
sys.exit(0)
|
|
177
|
+
|
|
178
|
+
print(r_g_b_to_rgb(255, 255, 255))
|
|
179
|
+
print(r_g_b_from_rgb(r_g_b_to_rgb(255, 255, 255)))
|
|
180
|
+
|
|
181
|
+
# ça marche et ça doit donner la meme chose qu'en java et c'est bcp plus facile à coder...
|
|
182
|
+
forbidden_colors = get_forbidden_colors()
|
|
183
|
+
print(forbidden_colors)
|
|
184
|
+
forbidden_colors.append((216, 194, 98))
|
|
185
|
+
forbidden_colors.append((227, 10, 107))
|
|
186
|
+
|
|
187
|
+
for i in range(100):
|
|
188
|
+
if i == 0:
|
|
189
|
+
color = get_unique_random_color(forbidden_colors=forbidden_colors, seed_random=0)
|
|
190
|
+
else:
|
|
191
|
+
color = get_unique_random_color(forbidden_colors=forbidden_colors)
|
|
192
|
+
forbidden_colors.append(color)
|
|
193
|
+
print(i, '-->', color)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
def int_to_argb_hex(value, has_alpha=False, auto_rint=True):
|
|
2
|
+
if auto_rint and not isinstance(value, int):
|
|
3
|
+
value = int(round(value))
|
|
4
|
+
alpha = (value >> 24) & 0xFF
|
|
5
|
+
red = (value >> 16) & 0xFF
|
|
6
|
+
green = (value >> 8) & 0xFF
|
|
7
|
+
blue = value & 0xFF
|
|
8
|
+
|
|
9
|
+
if has_alpha:
|
|
10
|
+
argb_hex = f"{alpha:02X}{red:02X}{green:02X}{blue:02X}"
|
|
11
|
+
else:
|
|
12
|
+
argb_hex = f"{red:02X}{green:02X}{blue:02X}"
|
|
13
|
+
return argb_hex
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
if __name__ == '__main__':
|
|
17
|
+
# Example usage:
|
|
18
|
+
integer_value = 0xFFAABBCC # Replace this with your integer value
|
|
19
|
+
integer_value = 255 # Replace this with your integer value
|
|
20
|
+
integer_value = 255.9 # Replace this with your integer value
|
|
21
|
+
argb_hex_value = int_to_argb_hex(integer_value)
|
|
22
|
+
print(f"ARGB Hex Value: #{argb_hex_value}")
|
|
File without changes
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import shlex
|
|
2
|
+
|
|
3
|
+
def join_command(command):
|
|
4
|
+
command_string = shlex.join(command)
|
|
5
|
+
return command_string
|
|
6
|
+
|
|
7
|
+
if __name__ == '__main__':
|
|
8
|
+
command = [
|
|
9
|
+
'/home/aigouy/UCSC_tools/blastn',
|
|
10
|
+
'-task', 'blastn',
|
|
11
|
+
'-query', '/tmp/tmp4a97pceg.fasta',
|
|
12
|
+
'-db', '/F/blast_outputs/25kb/D_suzukii_real_25kb_for_blast.fasta',
|
|
13
|
+
'-evalue', '50',
|
|
14
|
+
'-num_threads', '4',
|
|
15
|
+
'-outfmt', '5',
|
|
16
|
+
'-out', '/F/blast_outputs/subsets/D_suzukii_real_25kb_for_blast_F1a-b.xml'
|
|
17
|
+
]
|
|
18
|
+
print(join_command(command))
|
|
File without changes
|