bioimage-cpp 0.2.0__tar.gz → 0.3.0__tar.gz

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.
Files changed (286) hide show
  1. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/MIGRATION_GUIDE.md +25 -0
  2. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/PKG-INFO +1 -1
  3. bioimage_cpp-0.3.0/include/bioimage_cpp/run_length.hxx +48 -0
  4. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bindings/utils.cxx +45 -0
  5. bioimage_cpp-0.3.0/src/bioimage_cpp/_version.py +1 -0
  6. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bioimage_cpp/utils.py +52 -0
  7. bioimage_cpp-0.3.0/tests/test_utils_compute_rle.py +101 -0
  8. bioimage_cpp-0.2.0/src/bioimage_cpp/_version.py +0 -1
  9. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/.github/workflows/docs.yml +0 -0
  10. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/.github/workflows/tests.yml +0 -0
  11. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/.github/workflows/wheels.yml +0 -0
  12. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/.gitignore +0 -0
  13. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/AGENTS.md +0 -0
  14. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/CMakeLists.txt +0 -0
  15. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/LICENSE +0 -0
  16. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/README.md +0 -0
  17. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/affinities/check_compute_affinities.py +0 -0
  18. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/affinities/check_compute_embedding_distances.py +0 -0
  19. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/distance/benchmark.py +0 -0
  20. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/distance/check_non_maximum_distance_suppression.py +0 -0
  21. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/filters/PERFORMANCE_NOTES.md +0 -0
  22. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/filters/_bench_utils.py +0 -0
  23. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/filters/benchmark.py +0 -0
  24. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/filters/check_parity.py +0 -0
  25. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/flow/PERFORMANCE_NOTES.md +0 -0
  26. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/flow/_reference_impl.py +0 -0
  27. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/flow/benchmark.py +0 -0
  28. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/flow/check_flow_density.py +0 -0
  29. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/flow/create_test_data.py +0 -0
  30. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/graph/_grid_affinity_compatibility.py +0 -0
  31. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/graph/_rag_compatibility.py +0 -0
  32. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/graph/agglomeration/PERFORMANCE_NOTES.md +0 -0
  33. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/graph/agglomeration/_compatibility.py +0 -0
  34. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/graph/agglomeration/check_edge_weighted.py +0 -0
  35. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/graph/agglomeration/check_gasp.py +0 -0
  36. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/graph/agglomeration/check_mala.py +0 -0
  37. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/graph/agglomeration/check_node_and_edge_weighted.py +0 -0
  38. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/graph/agglomeration/diagnose.py +0 -0
  39. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/graph/check_grid_affinity_edges.py +0 -0
  40. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/graph/check_grid_affinity_lifted_edges.py +0 -0
  41. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/graph/check_rag_2d.py +0 -0
  42. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/graph/check_rag_3d.py +0 -0
  43. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/graph/lifted_multicut/PERFORMANCE_NOTES.md +0 -0
  44. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/graph/lifted_multicut/_compatibility.py +0 -0
  45. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/graph/lifted_multicut/check_fusion_move.py +0 -0
  46. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/graph/lifted_multicut/check_greedy_additive.py +0 -0
  47. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/graph/lifted_multicut/check_kernighan_lin.py +0 -0
  48. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/graph/lifted_multicut/evaluate_solvers.py +0 -0
  49. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/graph/lifted_multicut/repro_lifted_edges_segfault.py +0 -0
  50. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/graph/multicut/PERFORMANCE_NOTES.md +0 -0
  51. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/graph/multicut/_compatibility.py +0 -0
  52. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/graph/multicut/check_chained.py +0 -0
  53. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/graph/multicut/check_decomposer.py +0 -0
  54. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/graph/multicut/check_fusion_move.py +0 -0
  55. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/graph/multicut/check_greedy_additive.py +0 -0
  56. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/graph/multicut/check_greedy_fixation.py +0 -0
  57. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/graph/multicut/check_kernighan_lin.py +0 -0
  58. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/graph/multicut/evaluate_solvers.py +0 -0
  59. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/graph/mutex_watershed/check_mutex_clustering.py +0 -0
  60. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/graph/mutex_watershed/check_semantic_mutex_clustering.py +0 -0
  61. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/label_multiset/benchmark.py +0 -0
  62. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/local_maxima/benchmark.py +0 -0
  63. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/segmentation/PERFORMANCE_NOTES.md +0 -0
  64. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/segmentation/_label_equivalence.py +0 -0
  65. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/segmentation/_mutex_watershed_equivalence.py +0 -0
  66. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/segmentation/_semantic_mws_equivalence.py +0 -0
  67. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/segmentation/_watershed_equivalence.py +0 -0
  68. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/segmentation/_watershed_from_affinities_equivalence.py +0 -0
  69. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/segmentation/check_label_2d.py +0 -0
  70. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/segmentation/check_label_3d.py +0 -0
  71. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/segmentation/check_mutex_watershed_2d.py +0 -0
  72. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/segmentation/check_mutex_watershed_3d.py +0 -0
  73. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/segmentation/check_relabel_sequential.py +0 -0
  74. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/segmentation/check_semantic_mutex_watershed_2d.py +0 -0
  75. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/segmentation/check_semantic_mutex_watershed_3d.py +0 -0
  76. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/segmentation/check_watershed_2d.py +0 -0
  77. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/segmentation/check_watershed_3d.py +0 -0
  78. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/segmentation/check_watershed_from_affinities_2d.py +0 -0
  79. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/segmentation/check_watershed_from_affinities_3d.py +0 -0
  80. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/transformation/PERFORMANCE_NOTES.md +0 -0
  81. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/transformation/check_affine.py +0 -0
  82. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/utils/_mesh_smoothing_reference.py +0 -0
  83. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/development/utils/benchmark_mesh_smoothing.py +0 -0
  84. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/examples/segmentation/_lifted_problem.py +0 -0
  85. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/examples/segmentation/lifted_multicut_from_affinities.py +0 -0
  86. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/examples/segmentation/multicut_from_affinities.py +0 -0
  87. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/examples/segmentation/mutex_watershed.py +0 -0
  88. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/examples/segmentation/serialize_grid_lifted_problem.py +0 -0
  89. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/examples/segmentation/serialize_lifted_problem.py +0 -0
  90. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/examples/segmentation/watershed.py +0 -0
  91. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/affinities/compute_affinities.hxx +0 -0
  92. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/affinities/compute_embedding_distances.hxx +0 -0
  93. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/array_view.hxx +0 -0
  94. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/blocking.hxx +0 -0
  95. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/detail/edge_hash.hxx +0 -0
  96. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/detail/grid.hxx +0 -0
  97. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/detail/indexed_heap.hxx +0 -0
  98. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/detail/mutex_storage.hxx +0 -0
  99. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/detail/profile.hxx +0 -0
  100. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/detail/relabel.hxx +0 -0
  101. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/detail/semantic_labels.hxx +0 -0
  102. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/detail/threading.hxx +0 -0
  103. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/distance_transform.hxx +0 -0
  104. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/filters/convolve.hxx +0 -0
  105. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/filters/eigenvalues.hxx +0 -0
  106. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/filters/gaussian.hxx +0 -0
  107. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/filters/kernel.hxx +0 -0
  108. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/flow/flow_density.hxx +0 -0
  109. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/agglomeration/agglomerative_clustering.hxx +0 -0
  110. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/agglomeration/cluster_policy_base.hxx +0 -0
  111. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/agglomeration/detail.hxx +0 -0
  112. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/agglomeration/edge_weighted.hxx +0 -0
  113. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/agglomeration/gasp.hxx +0 -0
  114. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/agglomeration/mala.hxx +0 -0
  115. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/agglomeration/node_and_edge_weighted.hxx +0 -0
  116. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/agglomeration.hxx +0 -0
  117. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/breadth_first_search.hxx +0 -0
  118. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/connected_components.hxx +0 -0
  119. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/detail/fusion_contract.hxx +0 -0
  120. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/edge_weighted_watershed.hxx +0 -0
  121. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/feature_accumulation.hxx +0 -0
  122. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/grid_edge_projection.hxx +0 -0
  123. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/grid_features.hxx +0 -0
  124. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/grid_graph.hxx +0 -0
  125. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/label_accumulation.hxx +0 -0
  126. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/lifted_from_affinities.hxx +0 -0
  127. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/lifted_multicut/detail.hxx +0 -0
  128. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/lifted_multicut/fusion_move.hxx +0 -0
  129. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/lifted_multicut/greedy_additive.hxx +0 -0
  130. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/lifted_multicut/kernighan_lin.hxx +0 -0
  131. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/lifted_multicut/lifted_from_node_labels.hxx +0 -0
  132. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/lifted_multicut/objective.hxx +0 -0
  133. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/lifted_multicut.hxx +0 -0
  134. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/multicut/detail.hxx +0 -0
  135. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/multicut/fusion_move.hxx +0 -0
  136. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/multicut/greedy_additive.hxx +0 -0
  137. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/multicut/greedy_fixation.hxx +0 -0
  138. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/multicut/kernighan_lin.hxx +0 -0
  139. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/multicut/objective.hxx +0 -0
  140. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/multicut.hxx +0 -0
  141. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/mutex_watershed/clustering.hxx +0 -0
  142. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/mutex_watershed/semantic.hxx +0 -0
  143. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/mutex_watershed.hxx +0 -0
  144. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/node_label_projection.hxx +0 -0
  145. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/proposal_generator.hxx +0 -0
  146. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/proposal_generators/greedy_additive_multicut.hxx +0 -0
  147. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/proposal_generators/watershed.hxx +0 -0
  148. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/rag_coordinates.hxx +0 -0
  149. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/region_adjacency_graph.hxx +0 -0
  150. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/graph/undirected_graph.hxx +0 -0
  151. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/label_multiset/downsample.hxx +0 -0
  152. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/label_multiset/from_labels.hxx +0 -0
  153. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/label_multiset/merger.hxx +0 -0
  154. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/label_multiset/multiset.hxx +0 -0
  155. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/label_multiset/read_subset.hxx +0 -0
  156. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/mesh_smoothing.hxx +0 -0
  157. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/non_maximum_distance_suppression.hxx +0 -0
  158. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/overlap.hxx +0 -0
  159. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/segmentation/connected_components.hxx +0 -0
  160. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/segmentation/mutex_watershed.hxx +0 -0
  161. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/segmentation/relabel_sequential.hxx +0 -0
  162. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/segmentation/semantic_mutex_watershed.hxx +0 -0
  163. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/segmentation/watershed.hxx +0 -0
  164. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/take_dict.hxx +0 -0
  165. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/transformation/affine.hxx +0 -0
  166. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/include/bioimage_cpp/util/union_find.hxx +0 -0
  167. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/pyproject.toml +0 -0
  168. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bindings/affinities.cxx +0 -0
  169. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bindings/affinities.hxx +0 -0
  170. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bindings/blocking.cxx +0 -0
  171. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bindings/blocking.hxx +0 -0
  172. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bindings/distance.cxx +0 -0
  173. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bindings/distance.hxx +0 -0
  174. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bindings/filters.cxx +0 -0
  175. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bindings/filters.hxx +0 -0
  176. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bindings/flow.cxx +0 -0
  177. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bindings/flow.hxx +0 -0
  178. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bindings/graph.cxx +0 -0
  179. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bindings/graph.hxx +0 -0
  180. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bindings/ground_truth.cxx +0 -0
  181. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bindings/ground_truth.hxx +0 -0
  182. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bindings/label_multiset.cxx +0 -0
  183. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bindings/label_multiset.hxx +0 -0
  184. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bindings/module.cxx +0 -0
  185. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bindings/segmentation.cxx +0 -0
  186. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bindings/segmentation.hxx +0 -0
  187. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bindings/transformation.cxx +0 -0
  188. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bindings/transformation.hxx +0 -0
  189. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bindings/util.cxx +0 -0
  190. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bindings/util.hxx +0 -0
  191. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bindings/utils.hxx +0 -0
  192. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bioimage_cpp/__init__.py +0 -0
  193. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bioimage_cpp/_data.py +0 -0
  194. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bioimage_cpp/affinities/__init__.py +0 -0
  195. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bioimage_cpp/affinities/compute_affinities.py +0 -0
  196. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bioimage_cpp/affinities/compute_embedding_distances.py +0 -0
  197. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bioimage_cpp/distance/__init__.py +0 -0
  198. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bioimage_cpp/distance/_distance.py +0 -0
  199. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bioimage_cpp/filters/__init__.py +0 -0
  200. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bioimage_cpp/filters/_filters.py +0 -0
  201. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bioimage_cpp/flow/__init__.py +0 -0
  202. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bioimage_cpp/flow/_flow.py +0 -0
  203. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bioimage_cpp/graph/__init__.py +0 -0
  204. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bioimage_cpp/graph/_external.py +0 -0
  205. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bioimage_cpp/graph/_shared.py +0 -0
  206. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bioimage_cpp/graph/agglomeration.py +0 -0
  207. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bioimage_cpp/graph/features/__init__.py +0 -0
  208. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bioimage_cpp/graph/lifted_multicut/__init__.py +0 -0
  209. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bioimage_cpp/graph/multicut/__init__.py +0 -0
  210. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bioimage_cpp/graph/mutex_watershed.py +0 -0
  211. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bioimage_cpp/label_multiset/__init__.py +0 -0
  212. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bioimage_cpp/segmentation/__init__.py +0 -0
  213. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bioimage_cpp/segmentation/label.py +0 -0
  214. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bioimage_cpp/segmentation/mutex_watershed.py +0 -0
  215. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bioimage_cpp/segmentation/relabel_sequential.py +0 -0
  216. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bioimage_cpp/segmentation/watershed.py +0 -0
  217. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bioimage_cpp/transformation/__init__.py +0 -0
  218. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/bioimage_cpp/transformation/_transformation.py +0 -0
  219. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/cpp/segmentation/mutex_watershed.cxx +0 -0
  220. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/cpp/segmentation/semantic_mutex_watershed.cxx +0 -0
  221. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/src/cpp/take_dict.cxx +0 -0
  222. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/affinities/test_compute_affinities.py +0 -0
  223. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/affinities/test_compute_embedding_distances.py +0 -0
  224. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/distance/test_distance_transform.py +0 -0
  225. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/distance/test_non_maximum_distance_suppression.py +0 -0
  226. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/agglomeration/__init__.py +0 -0
  227. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/agglomeration/_helpers.py +0 -0
  228. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/agglomeration/test_edge_weighted.py +0 -0
  229. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/agglomeration/test_gasp.py +0 -0
  230. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/agglomeration/test_mala.py +0 -0
  231. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/agglomeration/test_node_and_edge_weighted.py +0 -0
  232. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/lifted_multicut/__init__.py +0 -0
  233. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/lifted_multicut/_helpers.py +0 -0
  234. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/lifted_multicut/conftest.py +0 -0
  235. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/lifted_multicut/test_external_problem.py +0 -0
  236. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/lifted_multicut/test_fusion_move.py +0 -0
  237. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/lifted_multicut/test_greedy_additive.py +0 -0
  238. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/lifted_multicut/test_kernighan_lin.py +0 -0
  239. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/lifted_multicut/test_lifted_edges_from_node_labels.py +0 -0
  240. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/lifted_multicut/test_objective.py +0 -0
  241. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/multicut/__init__.py +0 -0
  242. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/multicut/_helpers.py +0 -0
  243. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/multicut/conftest.py +0 -0
  244. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/multicut/test_chain_decomposer.py +0 -0
  245. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/multicut/test_external_problem.py +0 -0
  246. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/multicut/test_fusion_move.py +0 -0
  247. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/multicut/test_greedy_additive.py +0 -0
  248. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/multicut/test_greedy_fixation.py +0 -0
  249. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/multicut/test_kernighan_lin.py +0 -0
  250. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/multicut/test_objective.py +0 -0
  251. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/multicut/test_proposal_generators.py +0 -0
  252. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/test_breadth_first_search.py +0 -0
  253. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/test_connected_components.py +0 -0
  254. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/test_edge_weighted_watershed.py +0 -0
  255. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/test_grid_affinity_multicut_integration.py +0 -0
  256. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/test_grid_features.py +0 -0
  257. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/test_grid_graph.py +0 -0
  258. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/test_mutex_watershed_graph.py +0 -0
  259. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/test_node_label_projection.py +0 -0
  260. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/test_rag_accumulate_labels.py +0 -0
  261. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/test_rag_coordinates.py +0 -0
  262. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/test_rag_features.py +0 -0
  263. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/test_rag_lifted_features.py +0 -0
  264. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/test_rag_multicut_integration.py +0 -0
  265. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/test_region_adjacency_graph.py +0 -0
  266. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/test_semantic_mutex_watershed_graph.py +0 -0
  267. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/graph/test_undirected_graph.py +0 -0
  268. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/label_multiset/__init__.py +0 -0
  269. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/label_multiset/test_against_nifty.py +0 -0
  270. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/label_multiset/test_downsample.py +0 -0
  271. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/label_multiset/test_merger.py +0 -0
  272. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/label_multiset/test_read_subset.py +0 -0
  273. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/segmentation/test_label.py +0 -0
  274. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/segmentation/test_mutex_watershed.py +0 -0
  275. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/segmentation/test_relabel_sequential.py +0 -0
  276. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/segmentation/test_semantic_mutex_watershed.py +0 -0
  277. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/segmentation/test_watershed.py +0 -0
  278. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/segmentation/test_watershed_from_affinities.py +0 -0
  279. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/test_blocking.py +0 -0
  280. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/test_filters.py +0 -0
  281. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/test_flow.py +0 -0
  282. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/test_ground_truth_overlap.py +0 -0
  283. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/test_transformation.py +0 -0
  284. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/test_util_union_find.py +0 -0
  285. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/test_utils_mesh_smoothing.py +0 -0
  286. {bioimage_cpp-0.2.0 → bioimage_cpp-0.3.0}/tests/test_utils_take_dict.py +0 -0
@@ -770,6 +770,31 @@ Notes:
770
770
  - Every value in the input must be present in the mapping.
771
771
  - Non-contiguous inputs are copied before entering C++.
772
772
 
773
+ ### Run-Length Encoding
774
+
775
+ `nifty.tools.computeRLE` computes the COCO-style binary run-length encoding of an
776
+ array. Use `bic.utils.compute_rle`:
777
+
778
+ ```python
779
+ import nifty.tools as nt
780
+
781
+ mask = np.array([[0, 0, 1], [1, 1, 0], [0, 1, 1]], dtype=np.uint8)
782
+
783
+ rle = nt.computeRLE(mask) # nifty: Python list [2, 3, 2, 2]
784
+ rle = bic.utils.compute_rle(mask) # bioimage-cpp: np.int64 array([2, 3, 2, 2])
785
+ ```
786
+
787
+ Notes:
788
+
789
+ - The array is flattened in **C-order** and interpreted as binary
790
+ (zero vs. nonzero). Counts always start with a run of zeros and then
791
+ alternate; a leading `0` is emitted when the first element is nonzero.
792
+ - Supported input dtypes are `bool`, `uint8`, `uint16`, `uint32`, `uint64`,
793
+ `int32`, and `int64`.
794
+ - **Behavioral difference:** nifty returns a Python `list`; `bioimage-cpp`
795
+ returns a 1-D NumPy `int64` array.
796
+ - Non-contiguous inputs are copied before entering C++.
797
+
773
798
  ### Edge-Weighted Watershed
774
799
 
775
800
  Nifty:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: bioimage-cpp
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: Dependency-light C++ bioimage analysis algorithms with Python bindings
5
5
  Author: bioimage-cpp contributors
6
6
  License: MIT
@@ -0,0 +1,48 @@
1
+ #pragma once
2
+
3
+ #include "bioimage_cpp/array_view.hxx"
4
+
5
+ #include <cstdint>
6
+ #include <numeric>
7
+ #include <vector>
8
+
9
+ namespace bioimage_cpp {
10
+
11
+ // Compute the COCO-style binary run-length encoding of `mask`.
12
+ //
13
+ // The array is treated as a flat C-order buffer and interpreted as binary
14
+ // (zero vs. nonzero). The returned run lengths always start with a run of
15
+ // zeros and then alternate (zeros, ones, zeros, ...). If the first element is
16
+ // nonzero a leading 0 is emitted. An empty input yields an empty result.
17
+ template <class T>
18
+ std::vector<std::int64_t> compute_rle(const ConstArrayView<T> &mask) {
19
+ const auto n = std::accumulate(
20
+ mask.shape.begin(),
21
+ mask.shape.end(),
22
+ std::ptrdiff_t{1},
23
+ [](const std::ptrdiff_t a, const std::ptrdiff_t b) { return a * b; }
24
+ );
25
+
26
+ std::vector<std::int64_t> counts;
27
+ if (n <= 0) {
28
+ return counts;
29
+ }
30
+
31
+ bool current_value = false; // runs start with zeros
32
+ std::int64_t run_length = 0;
33
+ for (std::ptrdiff_t i = 0; i < n; ++i) {
34
+ const bool value = mask.data[i] != T{0};
35
+ if (value == current_value) {
36
+ ++run_length;
37
+ } else {
38
+ counts.push_back(run_length);
39
+ current_value = value;
40
+ run_length = 1;
41
+ }
42
+ }
43
+ counts.push_back(run_length);
44
+
45
+ return counts;
46
+ }
47
+
48
+ } // namespace bioimage_cpp
@@ -2,12 +2,14 @@
2
2
 
3
3
  #include "bioimage_cpp/array_view.hxx"
4
4
  #include "bioimage_cpp/mesh_smoothing.hxx"
5
+ #include "bioimage_cpp/run_length.hxx"
5
6
  #include "bioimage_cpp/take_dict.hxx"
6
7
 
7
8
  #include <nanobind/ndarray.h>
8
9
  #include <nanobind/stl/pair.h>
9
10
  #include <nanobind/stl/string.h>
10
11
 
12
+ #include <algorithm>
11
13
  #include <cstddef>
12
14
  #include <cstdint>
13
15
  #include <memory>
@@ -151,6 +153,35 @@ std::pair<OutputArray<V>, OutputArray<V>> smooth_mesh_t(
151
153
  return {std::move(out_verts), std::move(out_normals)};
152
154
  }
153
155
 
156
+ template <class T>
157
+ OutputArray<std::int64_t> compute_rle_t(InputArray<T> mask) {
158
+ std::vector<std::ptrdiff_t> view_shape(mask.ndim());
159
+ for (std::size_t axis = 0; axis < mask.ndim(); ++axis) {
160
+ view_shape[axis] = static_cast<std::ptrdiff_t>(mask.shape(axis));
161
+ }
162
+
163
+ ConstArrayView<T> input{
164
+ mask.data(),
165
+ view_shape,
166
+ {},
167
+ };
168
+
169
+ std::vector<std::int64_t> counts;
170
+ {
171
+ nb::gil_scoped_release release;
172
+ counts = compute_rle<T>(input);
173
+ }
174
+
175
+ auto *data = new std::int64_t[counts.size()];
176
+ std::copy(counts.begin(), counts.end(), data);
177
+ nb::capsule owner(data, [](void *p) noexcept {
178
+ delete[] static_cast<std::int64_t *>(p);
179
+ });
180
+
181
+ std::size_t shape[1] = {counts.size()};
182
+ return OutputArray<std::int64_t>(data, 1, shape, owner);
183
+ }
184
+
154
185
  } // namespace
155
186
 
156
187
  void bind_utils(nb::module_ &m) {
@@ -202,6 +233,20 @@ void bind_utils(nb::module_ &m) {
202
233
  nb::arg("n_threads"),
203
234
  "Laplacian smoothing of a triangular mesh with float64 vertices and normals."
204
235
  );
236
+ m.def("_compute_rle_bool", &compute_rle_t<bool>, nb::arg("mask"),
237
+ "COCO-style binary run-length encoding of a contiguous bool array.");
238
+ m.def("_compute_rle_uint8", &compute_rle_t<std::uint8_t>, nb::arg("mask"),
239
+ "COCO-style binary run-length encoding of a contiguous uint8 array.");
240
+ m.def("_compute_rle_uint16", &compute_rle_t<std::uint16_t>, nb::arg("mask"),
241
+ "COCO-style binary run-length encoding of a contiguous uint16 array.");
242
+ m.def("_compute_rle_uint32", &compute_rle_t<std::uint32_t>, nb::arg("mask"),
243
+ "COCO-style binary run-length encoding of a contiguous uint32 array.");
244
+ m.def("_compute_rle_uint64", &compute_rle_t<std::uint64_t>, nb::arg("mask"),
245
+ "COCO-style binary run-length encoding of a contiguous uint64 array.");
246
+ m.def("_compute_rle_int32", &compute_rle_t<std::int32_t>, nb::arg("mask"),
247
+ "COCO-style binary run-length encoding of a contiguous int32 array.");
248
+ m.def("_compute_rle_int64", &compute_rle_t<std::int64_t>, nb::arg("mask"),
249
+ "COCO-style binary run-length encoding of a contiguous int64 array.");
205
250
  }
206
251
 
207
252
  } // namespace bioimage_cpp::bindings
@@ -0,0 +1 @@
1
+ __version__ = "0.3.0"
@@ -24,6 +24,16 @@ _SMOOTH_MESH_BY_DTYPE = {
24
24
  np.dtype("float64"): _core._smooth_mesh_float64,
25
25
  }
26
26
 
27
+ _COMPUTE_RLE_BY_DTYPE = {
28
+ np.dtype("bool"): _core._compute_rle_bool,
29
+ np.dtype("uint8"): _core._compute_rle_uint8,
30
+ np.dtype("uint16"): _core._compute_rle_uint16,
31
+ np.dtype("uint32"): _core._compute_rle_uint32,
32
+ np.dtype("uint64"): _core._compute_rle_uint64,
33
+ np.dtype("int32"): _core._compute_rle_int32,
34
+ np.dtype("int64"): _core._compute_rle_int64,
35
+ }
36
+
27
37
  _COUNT_TABLE_DTYPE = np.dtype([("label", np.uint64), ("count", np.uint64)])
28
38
  _OVERLAP_TABLE_DTYPE = np.dtype(
29
39
  [("label_a", np.uint64), ("label_b", np.uint64), ("count", np.uint64)]
@@ -307,6 +317,47 @@ def take_dict(relabeling: Mapping[Any, Any], to_relabel: np.ndarray) -> np.ndarr
307
317
  raise
308
318
 
309
319
 
320
+ def compute_rle(mask: np.ndarray) -> np.ndarray:
321
+ """Compute the COCO-style binary run-length encoding of an array.
322
+
323
+ The array is flattened in C-order and interpreted as binary (zero vs.
324
+ nonzero). The returned run lengths always start with a run of zeros and then
325
+ alternate (zeros, ones, zeros, ...); if the first element is nonzero a
326
+ leading ``0`` is emitted. An empty array yields an empty result.
327
+
328
+ This is the equivalent of ``nifty.tools.computeRLE``. Unlike nifty, which
329
+ returns a Python list, this returns a NumPy ``int64`` array.
330
+
331
+ Parameters
332
+ ----------
333
+ mask:
334
+ NumPy array with dtype ``bool``, ``uint8``, ``uint16``, ``uint32``,
335
+ ``uint64``, ``int32``, or ``int64``. Non-contiguous inputs are copied to
336
+ a contiguous array before calling the C++ kernel.
337
+
338
+ Returns
339
+ -------
340
+ np.ndarray
341
+ 1-D ``int64`` array of run lengths.
342
+
343
+ Raises
344
+ ------
345
+ TypeError
346
+ If ``mask`` has an unsupported dtype.
347
+ """
348
+ array = np.asarray(mask)
349
+ dtype = array.dtype
350
+ try:
351
+ run = _COMPUTE_RLE_BY_DTYPE[dtype]
352
+ except KeyError as error:
353
+ supported = ", ".join(str(dtype) for dtype in _COMPUTE_RLE_BY_DTYPE)
354
+ raise TypeError(
355
+ f"mask must have one of dtypes ({supported}), got dtype={dtype}"
356
+ ) from error
357
+
358
+ return run(np.ascontiguousarray(array))
359
+
360
+
310
361
  def smooth_mesh(
311
362
  verts: np.ndarray,
312
363
  normals: np.ndarray,
@@ -473,6 +524,7 @@ __all__ = [
473
524
  "BlockWithHalo",
474
525
  "SegmentationOverlap",
475
526
  "UnionFind",
527
+ "compute_rle",
476
528
  "segmentation_overlap",
477
529
  "smooth_mesh",
478
530
  "take_dict",
@@ -0,0 +1,101 @@
1
+ import numpy as np
2
+ import pytest
3
+
4
+ import bioimage_cpp as bic
5
+
6
+ SUPPORTED_DTYPES = [
7
+ np.bool_,
8
+ np.uint8,
9
+ np.uint16,
10
+ np.uint32,
11
+ np.uint64,
12
+ np.int32,
13
+ np.int64,
14
+ ]
15
+
16
+
17
+ def _rle(values, dtype=np.uint8):
18
+ return bic.utils.compute_rle(np.asarray(values, dtype=dtype))
19
+
20
+
21
+ @pytest.mark.parametrize(
22
+ "values, expected",
23
+ [
24
+ ([0, 0, 1, 1, 1, 0, 0, 1, 1], [2, 3, 2, 2]),
25
+ ([1, 1, 0, 1], [0, 2, 1, 1]),
26
+ ([1, 1, 1, 1, 1], [0, 5]),
27
+ ([0, 0, 0, 0], [4]),
28
+ ([1], [0, 1]),
29
+ ([0], [1]),
30
+ ],
31
+ )
32
+ def test_known_cases(values, expected):
33
+ result = _rle(values)
34
+ np.testing.assert_array_equal(result, np.asarray(expected, dtype=np.int64))
35
+
36
+
37
+ def test_empty_input():
38
+ result = _rle([])
39
+ assert result.dtype == np.int64
40
+ assert result.shape == (0,)
41
+
42
+
43
+ def test_output_is_int64_1d():
44
+ result = _rle([0, 1, 1])
45
+ assert result.dtype == np.int64
46
+ assert result.ndim == 1
47
+
48
+
49
+ @pytest.mark.parametrize("dtype", SUPPORTED_DTYPES)
50
+ def test_dtype_variants(dtype):
51
+ mask = np.array([0, 1, 1, 0, 0, 1], dtype=dtype)
52
+ result = bic.utils.compute_rle(mask)
53
+ np.testing.assert_array_equal(result, np.array([1, 2, 2, 1], dtype=np.int64))
54
+
55
+
56
+ def _reference_rle(flat):
57
+ # COCO-style: counts of alternating runs starting with zeros.
58
+ counts = []
59
+ current = 0
60
+ run = 0
61
+ for value in flat:
62
+ binary = int(value != 0)
63
+ if binary == current:
64
+ run += 1
65
+ else:
66
+ counts.append(run)
67
+ current = binary
68
+ run = 1
69
+ counts.append(run)
70
+ return np.asarray(counts, dtype=np.int64)
71
+
72
+
73
+ @pytest.mark.parametrize("shape", [(6, 8), (3, 4, 5)])
74
+ def test_c_order_flatten(shape):
75
+ rng = np.random.default_rng(0)
76
+ mask = (rng.integers(0, 2, size=shape)).astype(np.uint8)
77
+ result = bic.utils.compute_rle(mask)
78
+ expected = _reference_rle(mask.ravel(order="C"))
79
+ np.testing.assert_array_equal(result, expected)
80
+
81
+
82
+ def test_non_contiguous_input():
83
+ rng = np.random.default_rng(1)
84
+ base = (rng.integers(0, 2, size=(5, 6))).astype(np.uint8)
85
+ view = base.T # non-contiguous (Fortran-ordered view)
86
+ assert not view.flags["C_CONTIGUOUS"]
87
+ result = bic.utils.compute_rle(view)
88
+ expected = _reference_rle(np.ascontiguousarray(view).ravel(order="C"))
89
+ np.testing.assert_array_equal(result, expected)
90
+
91
+
92
+ def test_nonzero_values_are_binary():
93
+ # Values other than 0/1 are treated as "set".
94
+ mask = np.array([0, 7, 3, 0], dtype=np.int32)
95
+ result = bic.utils.compute_rle(mask)
96
+ np.testing.assert_array_equal(result, np.array([1, 2, 1], dtype=np.int64))
97
+
98
+
99
+ def test_invalid_dtype_raises():
100
+ with pytest.raises(TypeError):
101
+ bic.utils.compute_rle(np.array([0.0, 1.0], dtype=np.float32))
@@ -1 +0,0 @@
1
- __version__ = "0.2.0"
File without changes
File without changes
File without changes
File without changes