Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update-to-0.16.0 #87

Merged
merged 7 commits into from
Dec 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
[![Build Status](https://github.com/clEsperanto/clesperantoj_prototype/actions/workflows/build.yml/badge.svg)](https://github.com/clEsperanto/clesperantoj_prototype/actions/workflows/build.yml)


[![Build Status](https://github.com/clEsperanto/clesperantoj_prototype/actions/workflows/build.yaml/badge.svg)](https://github.com/clEsperanto/clesperantoj_prototype/actions/workflows/build.yaml)
[![GitHub stars](https://img.shields.io/github/stars/clEsperanto/clesperantoj_prototype?style=social)](https://github.com/clEsperanto/clesperantoj_prototype)
[![GitHub forks](https://img.shields.io/github/forks/clEsperanto/clesperantoj_prototype?style=social)](https://github.com/clEsperanto/clesperantoj_prototype)
[![Image.sc Forum](https://img.shields.io/badge/dynamic/json.svg?label=forum&url=https%3A%2F%2Fforum.image.sc%2Ftags%2Fclesperanto.json&query=%24.topic_list.tags.0.topic_count&colorB=green&&suffix=%20topics&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAABPklEQVR42m3SyyqFURTA8Y2BER0TDyExZ+aSPIKUlPIITFzKeQWXwhBlQrmFgUzMMFLKZeguBu5y+//17dP3nc5vuPdee6299gohUYYaDGOyyACq4JmQVoFujOMR77hNfOAGM+hBOQqB9TjHD36xhAa04RCuuXeKOvwHVWIKL9jCK2bRiV284QgL8MwEjAneeo9VNOEaBhzALGtoRy02cIcWhE34jj5YxgW+E5Z4iTPkMYpPLCNY3hdOYEfNbKYdmNngZ1jyEzw7h7AIb3fRTQ95OAZ6yQpGYHMMtOTgouktYwxuXsHgWLLl+4x++Kx1FJrjLTagA77bTPvYgw1rRqY56e+w7GNYsqX6JfPwi7aR+Y5SA+BXtKIRfkfJAYgj14tpOF6+I46c4/cAM3UhM3JxyKsxiOIhH0IO6SH/A1Kb1WBeUjbkAAAAAElFTkSuQmCC)](https://forum.image.sc/tag/clesperanto)

# clEsperantoJ

clEsperantoJ is the Java package of [clEsperanto] - a multi-language framework for GPU-accelerated image processing. It relies on a familly of [OpenCL kernels] originated from [CLIJ]. This package is developped in Java and C++ wrapped using JavaCPP, and uses the C++ [CLIc] library as a processing backend.
clEsperantoJ is the Java library of [clEsperanto] - a multi-language framework for GPU-accelerated image processing.
It relies on a familly of [OpenCL kernels] originated from [CLIJ], and rely on the C++ [CLIc] library as a processing backend.

## How to Build from source

Expand Down
123 changes: 66 additions & 57 deletions native/clesperantoj/include/kernelj.hpp

Large diffs are not rendered by default.

136 changes: 78 additions & 58 deletions native/clesperantoj/src/tier1j.cpp

Large diffs are not rendered by default.

54 changes: 37 additions & 17 deletions native/clesperantoj/src/tier2j.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ ArrayJ Tier2::add_images(DeviceJ * device, ArrayJ * src0, ArrayJ * src1, ArrayJ
return ArrayJ{cle::tier2::add_images_func(device->get(), src0->get(), src1->get(), dst == nullptr ? nullptr : dst->get())};
}

ArrayJ Tier2::bottom_hat_box(DeviceJ * device, ArrayJ * src, ArrayJ * dst, int radius_x, int radius_y, int radius_z)
ArrayJ Tier2::bottom_hat_box(DeviceJ * device, ArrayJ * src, ArrayJ * dst, float radius_x, float radius_y, float radius_z)
{
return ArrayJ{cle::tier2::bottom_hat_box_func(device->get(), src->get(), dst == nullptr ? nullptr : dst->get(), radius_x, radius_y, radius_z)};
}
Expand All @@ -40,14 +40,24 @@ ArrayJ Tier2::closing_box(DeviceJ * device, ArrayJ * src, ArrayJ * dst, int radi
return ArrayJ{cle::tier2::closing_box_func(device->get(), src->get(), dst == nullptr ? nullptr : dst->get(), radius_x, radius_y, radius_z)};
}

ArrayJ Tier2::closing_sphere(DeviceJ * device, ArrayJ * src, ArrayJ * dst, int radius_x, int radius_y, int radius_z)
ArrayJ Tier2::closing_sphere(DeviceJ * device, ArrayJ * src, ArrayJ * dst, float radius_x, float radius_y, float radius_z)
{
return ArrayJ{cle::tier2::closing_sphere_func(device->get(), src->get(), dst == nullptr ? nullptr : dst->get(), radius_x, radius_y, radius_z)};
}

ArrayJ Tier2::closing(DeviceJ * device, ArrayJ * src, ArrayJ * dst, int radius_x, int radius_y, int radius_z, std::string connectivity)
ArrayJ Tier2::grayscale_closing(DeviceJ * device, ArrayJ * src, ArrayJ * dst, float radius_x, float radius_y, float radius_z, std::string connectivity)
{
return ArrayJ{cle::tier2::closing_func(device->get(), src->get(), dst == nullptr ? nullptr : dst->get(), radius_x, radius_y, radius_z, connectivity)};
return ArrayJ{cle::tier2::grayscale_closing_func(device->get(), src->get(), dst == nullptr ? nullptr : dst->get(), radius_x, radius_y, radius_z, connectivity)};
}

ArrayJ Tier2::closing(DeviceJ * device, ArrayJ * src, ArrayJ * footprint, ArrayJ * dst)
{
return ArrayJ{cle::tier2::closing_func(device->get(), src->get(), footprint->get(), dst == nullptr ? nullptr : dst->get())};
}

ArrayJ Tier2::binary_closing(DeviceJ * device, ArrayJ * src, ArrayJ * dst, float radius_x, float radius_y, float radius_z, std::string connectivity)
{
return ArrayJ{cle::tier2::binary_closing_func(device->get(), src->get(), dst == nullptr ? nullptr : dst->get(), radius_x, radius_y, radius_z, connectivity)};
}

ArrayJ Tier2::concatenate_along_x(DeviceJ * device, ArrayJ * src0, ArrayJ * src1, ArrayJ * dst)
Expand All @@ -65,9 +75,9 @@ ArrayJ Tier2::concatenate_along_z(DeviceJ * device, ArrayJ * src0, ArrayJ * src1
return ArrayJ{cle::tier2::concatenate_along_z_func(device->get(), src0->get(), src1->get(), dst == nullptr ? nullptr : dst->get())};
}

ArrayJ Tier2::count_touching_neighbors(DeviceJ * device, ArrayJ * src, ArrayJ * dst, bool ignore_background)
ArrayJ Tier2::count_touching_neighbors(DeviceJ * device, ArrayJ * touch_matrix, ArrayJ * touching_neighbors_count_destination, bool ignore_background)
{
return ArrayJ{cle::tier2::count_touching_neighbors_func(device->get(), src->get(), dst == nullptr ? nullptr : dst->get(), ignore_background)};
return ArrayJ{cle::tier2::count_touching_neighbors_func(device->get(), touch_matrix->get(), touching_neighbors_count_destination == nullptr ? nullptr : touching_neighbors_count_destination->get(), ignore_background)};
}

ArrayJ Tier2::crop_border(DeviceJ * device, ArrayJ * src, ArrayJ * dst, int border_size)
Expand All @@ -85,22 +95,22 @@ ArrayJ Tier2::degrees_to_radians(DeviceJ * device, ArrayJ * src, ArrayJ * dst)
return ArrayJ{cle::tier2::degrees_to_radians_func(device->get(), src->get(), dst == nullptr ? nullptr : dst->get())};
}

ArrayJ Tier2::detect_maxima_box(DeviceJ * device, ArrayJ * src, ArrayJ * dst, int radius_x, int radius_y, int radius_z)
ArrayJ Tier2::detect_maxima_box(DeviceJ * device, ArrayJ * src, ArrayJ * dst, float radius_x, float radius_y, float radius_z)
{
return ArrayJ{cle::tier2::detect_maxima_box_func(device->get(), src->get(), dst == nullptr ? nullptr : dst->get(), radius_x, radius_y, radius_z)};
}

ArrayJ Tier2::detect_maxima(DeviceJ * device, ArrayJ * src, ArrayJ * dst, int radius_x, int radius_y, int radius_z, std::string connectivity)
ArrayJ Tier2::detect_maxima(DeviceJ * device, ArrayJ * src, ArrayJ * dst, float radius_x, float radius_y, float radius_z, std::string connectivity)
{
return ArrayJ{cle::tier2::detect_maxima_func(device->get(), src->get(), dst == nullptr ? nullptr : dst->get(), radius_x, radius_y, radius_z, connectivity)};
}

ArrayJ Tier2::detect_minima_box(DeviceJ * device, ArrayJ * src, ArrayJ * dst, int radius_x, int radius_y, int radius_z)
ArrayJ Tier2::detect_minima_box(DeviceJ * device, ArrayJ * src, ArrayJ * dst, float radius_x, float radius_y, float radius_z)
{
return ArrayJ{cle::tier2::detect_minima_box_func(device->get(), src->get(), dst == nullptr ? nullptr : dst->get(), radius_x, radius_y, radius_z)};
}

ArrayJ Tier2::detect_minima(DeviceJ * device, ArrayJ * src, ArrayJ * dst, int radius_x, int radius_y, int radius_z, std::string connectivity)
ArrayJ Tier2::detect_minima(DeviceJ * device, ArrayJ * src, ArrayJ * dst, float radius_x, float radius_y, float radius_z, std::string connectivity)
{
return ArrayJ{cle::tier2::detect_minima_func(device->get(), src->get(), dst == nullptr ? nullptr : dst->get(), radius_x, radius_y, radius_z, connectivity)};
}
Expand Down Expand Up @@ -145,7 +155,7 @@ float Tier2::minimum_of_masked_pixels(DeviceJ * device, ArrayJ * src, ArrayJ * m
return cle::tier2::minimum_of_masked_pixels_func(device->get(), src->get(), mask->get());
}

ArrayJ Tier2::opening_box(DeviceJ * device, ArrayJ * src, ArrayJ * dst, int radius_x, int radius_y, int radius_z)
ArrayJ Tier2::opening_box(DeviceJ * device, ArrayJ * src, ArrayJ * dst, float radius_x, float radius_y, float radius_z)
{
return ArrayJ{cle::tier2::opening_box_func(device->get(), src->get(), dst == nullptr ? nullptr : dst->get(), radius_x, radius_y, radius_z)};
}
Expand All @@ -155,9 +165,19 @@ ArrayJ Tier2::opening_sphere(DeviceJ * device, ArrayJ * src, ArrayJ * dst, float
return ArrayJ{cle::tier2::opening_sphere_func(device->get(), src->get(), dst == nullptr ? nullptr : dst->get(), radius_x, radius_y, radius_z)};
}

ArrayJ Tier2::opening(DeviceJ * device, ArrayJ * src, ArrayJ * dst, float radius_x, float radius_y, float radius_z, std::string connectivity)
ArrayJ Tier2::grayscale_opening(DeviceJ * device, ArrayJ * src, ArrayJ * dst, float radius_x, float radius_y, float radius_z, std::string connectivity)
{
return ArrayJ{cle::tier2::grayscale_opening_func(device->get(), src->get(), dst == nullptr ? nullptr : dst->get(), radius_x, radius_y, radius_z, connectivity)};
}

ArrayJ Tier2::opening(DeviceJ * device, ArrayJ * src, ArrayJ * footprint, ArrayJ * dst)
{
return ArrayJ{cle::tier2::opening_func(device->get(), src->get(), footprint->get(), dst == nullptr ? nullptr : dst->get())};
}

ArrayJ Tier2::binary_opening(DeviceJ * device, ArrayJ * src, ArrayJ * dst, float radius_x, float radius_y, float radius_z, std::string connectivity)
{
return ArrayJ{cle::tier2::opening_func(device->get(), src->get(), dst == nullptr ? nullptr : dst->get(), radius_x, radius_y, radius_z, connectivity)};
return ArrayJ{cle::tier2::binary_opening_func(device->get(), src->get(), dst == nullptr ? nullptr : dst->get(), radius_x, radius_y, radius_z, connectivity)};
}

ArrayJ Tier2::radians_to_degrees(DeviceJ * device, ArrayJ * src, ArrayJ * dst)
Expand Down Expand Up @@ -185,17 +205,17 @@ ArrayJ Tier2::squared_difference(DeviceJ * device, ArrayJ * src0, ArrayJ * src1,
return ArrayJ{cle::tier2::squared_difference_func(device->get(), src0->get(), src1->get(), dst == nullptr ? nullptr : dst->get())};
}

ArrayJ Tier2::standard_deviation_box(DeviceJ * device, ArrayJ * src, ArrayJ * dst, int radius_x, int radius_y, int radius_z)
ArrayJ Tier2::standard_deviation_box(DeviceJ * device, ArrayJ * src, ArrayJ * dst, float radius_x, float radius_y, float radius_z)
{
return ArrayJ{cle::tier2::standard_deviation_box_func(device->get(), src->get(), dst == nullptr ? nullptr : dst->get(), radius_x, radius_y, radius_z)};
}

ArrayJ Tier2::standard_deviation_sphere(DeviceJ * device, ArrayJ * src, ArrayJ * dst, int radius_x, int radius_y, int radius_z)
ArrayJ Tier2::standard_deviation_sphere(DeviceJ * device, ArrayJ * src, ArrayJ * dst, float radius_x, float radius_y, float radius_z)
{
return ArrayJ{cle::tier2::standard_deviation_sphere_func(device->get(), src->get(), dst == nullptr ? nullptr : dst->get(), radius_x, radius_y, radius_z)};
}

ArrayJ Tier2::standard_deviation(DeviceJ * device, ArrayJ * src, ArrayJ * dst, int radius_x, int radius_y, int radius_z, std::string connectivity)
ArrayJ Tier2::standard_deviation(DeviceJ * device, ArrayJ * src, ArrayJ * dst, float radius_x, float radius_y, float radius_z, std::string connectivity)
{
return ArrayJ{cle::tier2::standard_deviation_func(device->get(), src->get(), dst == nullptr ? nullptr : dst->get(), radius_x, radius_y, radius_z, connectivity)};
}
Expand Down Expand Up @@ -225,7 +245,7 @@ float Tier2::sum_of_all_pixels(DeviceJ * device, ArrayJ * src)
return cle::tier2::sum_of_all_pixels_func(device->get(), src == nullptr ? nullptr : src->get());
}

ArrayJ Tier2::top_hat_box(DeviceJ * device, ArrayJ * src, ArrayJ * dst, int radius_x, int radius_y, int radius_z)
ArrayJ Tier2::top_hat_box(DeviceJ * device, ArrayJ * src, ArrayJ * dst, float radius_x, float radius_y, float radius_z)
{
return ArrayJ{cle::tier2::top_hat_box_func(device->get(), src->get(), dst == nullptr ? nullptr : dst->get(), radius_x, radius_y, radius_z)};
}
Expand Down
16 changes: 8 additions & 8 deletions native/clesperantoj/src/tier3j.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,19 @@ ArrayJ Tier3::generate_touch_matrix(DeviceJ * device, ArrayJ * src, ArrayJ * dst
return ArrayJ{cle::tier3::generate_touch_matrix_func(device->get(), src->get(), dst == nullptr ? nullptr : dst->get())};
}

ArrayJ Tier3::histogram(DeviceJ * device, ArrayJ * src, ArrayJ * dst, int nbins, float min, float max)
ArrayJ Tier3::histogram(DeviceJ * device, ArrayJ * src, ArrayJ * dst, int num_bins, float minimum_intensity, float maximum_intensity)
{
return ArrayJ{cle::tier3::histogram_func(device->get(), src->get(), dst == nullptr ? nullptr : dst->get(), nbins, min, max)};
return ArrayJ{cle::tier3::histogram_func(device->get(), src->get(), dst == nullptr ? nullptr : dst->get(), num_bins, minimum_intensity, maximum_intensity)};
}

float Tier3::jaccard_index(DeviceJ * device, ArrayJ * src0, ArrayJ * src1)
{
return cle::tier3::jaccard_index_func(device->get(), src0->get(), src1->get());
}

ArrayJ Tier3::labelled_spots_to_pointlist(DeviceJ * device, ArrayJ * src, ArrayJ * dst)
ArrayJ Tier3::labelled_spots_to_pointlist(DeviceJ * device, ArrayJ * label, ArrayJ * pointlist)
{
return ArrayJ{cle::tier3::labelled_spots_to_pointlist_func(device->get(), src->get(), dst == nullptr ? nullptr : dst->get())};
return ArrayJ{cle::tier3::labelled_spots_to_pointlist_func(device->get(), label->get(), pointlist == nullptr ? nullptr : pointlist->get())};
}

std::vector<float> Tier3::maximum_position(DeviceJ * device, ArrayJ * src)
Expand All @@ -90,13 +90,13 @@ ArrayJ Tier3::morphological_chan_vese(DeviceJ * device, ArrayJ * src, ArrayJ * d
return ArrayJ{cle::tier3::morphological_chan_vese_func(device->get(), src->get(), dst == nullptr ? nullptr : dst->get(), num_iter, smoothing, lambda1, lambda2)};
}

std::unordered_map<std::string, std::vector<float>> Tier3::statistics_of_labelled_pixels(DeviceJ * device, ArrayJ * label, ArrayJ * intensity)
std::unordered_map<std::string, std::vector<float>> Tier3::statistics_of_labelled_pixels(DeviceJ * device, ArrayJ * intensity, ArrayJ * label)
{
return cle::tier3::statistics_of_labelled_pixels_func(device->get(), label->get(), intensity == nullptr ? nullptr : intensity->get());
return cle::tier3::statistics_of_labelled_pixels_func(device->get(), intensity == nullptr ? nullptr : intensity->get(), label == nullptr ? nullptr : label->get());
}

std::unordered_map<std::string, std::vector<float>> Tier3::statistics_of_background_and_labelled_pixels(DeviceJ * device, ArrayJ * label, ArrayJ * intensity)
std::unordered_map<std::string, std::vector<float>> Tier3::statistics_of_background_and_labelled_pixels(DeviceJ * device, ArrayJ * intensity, ArrayJ * label)
{
return cle::tier3::statistics_of_background_and_labelled_pixels_func(device->get(), label->get(), intensity == nullptr ? nullptr : intensity->get());
return cle::tier3::statistics_of_background_and_labelled_pixels_func(device->get(), intensity == nullptr ? nullptr : intensity->get(), label == nullptr ? nullptr : label->get());
}

17 changes: 11 additions & 6 deletions native/clesperantoj/src/tier4j.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ ArrayJ Tier4::threshold_otsu(DeviceJ * device, ArrayJ * src, ArrayJ * dst)
return ArrayJ{cle::tier4::threshold_otsu_func(device->get(), src->get(), dst == nullptr ? nullptr : dst->get())};
}

ArrayJ Tier4::mean_intensity_map(DeviceJ * device, ArrayJ * src, ArrayJ * labels, ArrayJ * dst)
{
return ArrayJ{cle::tier4::mean_intensity_map_func(device->get(), src->get(), labels->get(), dst == nullptr ? nullptr : dst->get())};
}

ArrayJ Tier4::pixel_count_map(DeviceJ * device, ArrayJ * src, ArrayJ * dst)
{
return ArrayJ{cle::tier4::pixel_count_map_func(device->get(), src->get(), dst == nullptr ? nullptr : dst->get())};
Expand All @@ -40,9 +45,9 @@ ArrayJ Tier4::label_pixel_count_map(DeviceJ * device, ArrayJ * src, ArrayJ * dst
return ArrayJ{cle::tier4::label_pixel_count_map_func(device->get(), src->get(), dst == nullptr ? nullptr : dst->get())};
}

ArrayJ Tier4::centroids_of_labels(DeviceJ * device, ArrayJ * src, ArrayJ * dst, bool withBG)
ArrayJ Tier4::centroids_of_labels(DeviceJ * device, ArrayJ * label_image, ArrayJ * centroids_coordinates, bool include_background)
{
return ArrayJ{cle::tier4::centroids_of_labels_func(device->get(), src->get(), dst == nullptr ? nullptr : dst->get(), withBG)};
return ArrayJ{cle::tier4::centroids_of_labels_func(device->get(), label_image->get(), centroids_coordinates->get(), include_background)};
}

ArrayJ Tier4::remove_labels_with_map_values_out_of_range(DeviceJ * device, ArrayJ * src, ArrayJ * values, ArrayJ * dst, float min_value, float max_value)
Expand All @@ -55,14 +60,14 @@ ArrayJ Tier4::remove_labels_with_map_values_within_range(DeviceJ * device, Array
return ArrayJ{cle::tier4::remove_labels_with_map_values_within_range_func(device->get(), src->get(), values->get(), dst == nullptr ? nullptr : dst->get(), min_value, max_value)};
}

ArrayJ Tier4::exclude_labels_with_map_values_out_of_range(DeviceJ * device, ArrayJ * src, ArrayJ * values, ArrayJ * dst, float min_value_range, float max_value_range)
ArrayJ Tier4::exclude_labels_with_map_values_out_of_range(DeviceJ * device, ArrayJ * values_map, ArrayJ * label_map_input, ArrayJ * dst, float minimum_value_range, float maximum_value_range)
{
return ArrayJ{cle::tier4::exclude_labels_with_map_values_out_of_range_func(device->get(), src->get(), values->get(), dst == nullptr ? nullptr : dst->get(), min_value_range, max_value_range)};
return ArrayJ{cle::tier4::exclude_labels_with_map_values_out_of_range_func(device->get(), values_map->get(), label_map_input->get(), dst == nullptr ? nullptr : dst->get(), minimum_value_range, maximum_value_range)};
}

ArrayJ Tier4::exclude_labels_with_map_values_within_range(DeviceJ * device, ArrayJ * src, ArrayJ * values, ArrayJ * dst, float min_value_range, float max_value_range)
ArrayJ Tier4::exclude_labels_with_map_values_within_range(DeviceJ * device, ArrayJ * values_map, ArrayJ * label_map_input, ArrayJ * dst, float minimum_value_range, float maximum_value_range)
{
return ArrayJ{cle::tier4::exclude_labels_with_map_values_within_range_func(device->get(), src->get(), values->get(), dst == nullptr ? nullptr : dst->get(), min_value_range, max_value_range)};
return ArrayJ{cle::tier4::exclude_labels_with_map_values_within_range_func(device->get(), values_map->get(), label_map_input->get(), dst == nullptr ? nullptr : dst->get(), minimum_value_range, maximum_value_range)};
}

ArrayJ Tier4::extension_ratio_map(DeviceJ * device, ArrayJ * src, ArrayJ * dst)
Expand Down
4 changes: 2 additions & 2 deletions native/clesperantoj/src/tier6j.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ ArrayJ Tier6::masked_voronoi_labeling(DeviceJ * device, ArrayJ * src, ArrayJ * m
return ArrayJ{cle::tier6::masked_voronoi_labeling_func(device->get(), src->get(), mask->get(), dst == nullptr ? nullptr : dst->get())};
}

ArrayJ Tier6::voronoi_labeling(DeviceJ * device, ArrayJ * src, ArrayJ * dst)
ArrayJ Tier6::voronoi_labeling(DeviceJ * device, ArrayJ * input_binary, ArrayJ * output_labels)
{
return ArrayJ{cle::tier6::voronoi_labeling_func(device->get(), src->get(), dst == nullptr ? nullptr : dst->get())};
return ArrayJ{cle::tier6::voronoi_labeling_func(device->get(), input_binary->get(), output_labels == nullptr ? nullptr : output_labels->get())};
}

ArrayJ Tier6::remove_small_labels(DeviceJ * device, ArrayJ * src, ArrayJ * dst, float minimum_size)
Expand Down
Loading
Loading