diff --git a/clic/include/statistics.hpp b/clic/include/statistics.hpp index 3b036dc81..a8d2365a5 100644 --- a/clic/include/statistics.hpp +++ b/clic/include/statistics.hpp @@ -14,8 +14,7 @@ using StatisticsMap = std::unordered_map>; auto compute_statistics_per_labels(const Device::Pointer & device, const Array::Pointer & label, - const Array::Pointer & intensity, - size_t offset) -> StatisticsMap; + const Array::Pointer & intensity) -> StatisticsMap; auto _statistics_per_label(const Device::Pointer & device, diff --git a/clic/include/tier1.hpp b/clic/include/tier1.hpp index 91aec19f4..80caf34c3 100644 --- a/clic/include/tier1.hpp +++ b/clic/include/tier1.hpp @@ -2059,6 +2059,47 @@ replace_value_func(const Device::Pointer & device, float scalar0, float scalar1) -> Array::Pointer; +/** + * @name replace_intensity + * @brief Replaces a specific intensity in an image with a given new value. + * + * @param device Device to perform the operation on. [const Device::Pointer &] + * @param src Input image to process. [const Array::Pointer &] + * @param dst Output result image. [Array::Pointer ( = None )] + * @param scalar0 Old value. [float ( = 0 )] + * @param scalar1 New value. [float ( = 1 )] + * @return Array::Pointer + * @see https://clij.github.io/clij2-docs/reference_replaceIntensity + * @deprecated This function is deprecated. Consider using replace_value() instead. + */ +auto +replace_intensity_func(const Device::Pointer & device, + const Array::Pointer & src, + Array::Pointer dst, + float scalar0, + float scalar1) -> Array::Pointer; + +/** + * @name replace_intensities + * @brief Replaces integer intensities specified in a vector image. The values are passed as a vector of values. + * The vector index represents the old intensity and the value at that position represents the new intensity.s + * + * @param device Device to perform the operation on. [const Device::Pointer &] + * @param src0 Input image to process. [const Array::Pointer &] + * @param src1 List of intensities to replace, as a vector of values. [const Array::Pointer &] + * @param dst Output result image. [Array::Pointer ( = None )] + * @return Array::Pointer + * + * @note 'bia-bob-suggestion' + * @see https://clij.github.io/clij2-docs/reference_replaceIntensities + * @deprecated This function is deprecated. Consider using replace_values() instead. + */ +auto +replace_intensities_func(const Device::Pointer & device, + const Array::Pointer & src0, + const Array::Pointer & src1, + Array::Pointer dst) -> Array::Pointer; + /** * @name maximum_sphere * @brief Computes the local maximum of a pixels spherical neighborhood. The spheres size is specified by its halfwidth, diff --git a/clic/include/tier2.hpp b/clic/include/tier2.hpp index b2b7cfb9f..8ded3e38a 100644 --- a/clic/include/tier2.hpp +++ b/clic/include/tier2.hpp @@ -895,6 +895,46 @@ subtract_images_func(const Device::Pointer & device, const Array::Pointer & src1, Array::Pointer dst) -> Array::Pointer; +/** + * @name sub_stack + * @brief Crop a volume into a new volume, along the z-axis. + * + * @param device Device to perform the operation on. [const Device::Pointer &] + * @param src Input image. [const Array::Pointer &] + * @param dst Output image. [Array::Pointer ( = None )] + * @param start_z Start z coordinate of the crop. [int ( = 0 )] + * @param end_z End z coordinate of the crop. [int ( = 0 )] + * @return Array::Pointer + * + * @note 'transform', 'in assistant' + * @see https://clij.github.io/clij2-docs/reference_subStack + */ +auto +sub_stack_func(const Device::Pointer & device, const Array::Pointer & src, Array::Pointer dst, int start_z, int end_z) + -> Array::Pointer; + +/** + * @name reduce_stack + * @brief Reduces the number of z-slices in a stack by a given factor. With the offset you have control which slices + * stays: with a factor 3 and offset 0, slices 0,3,6, etc. are kept. with a factor 4 and offset 1, slices 1,5,9, etc. + * are kept. + * + * @param device Device to perform the operation on. [const Device::Pointer &] + * @param src Input image. [const Array::Pointer &] + * @param dst Output image. [Array::Pointer ( = None )] + * @param reduction_factor Reduction factor. [int ( = 2 )] + * @param offset Offset. [int ( = 0 )] + * @return Array::Pointer + * + * @note 'transform', 'in assistant' + * @see https://clij.github.io/clij2-docs/reference_reduceStack + */ +auto +reduce_stack_func(const Device::Pointer & device, + const Array::Pointer & src, + Array::Pointer dst, + int reduction_factor, + int offset) -> Array::Pointer; /** * @name sum_of_all_pixels diff --git a/clic/include/tier3.hpp b/clic/include/tier3.hpp index 423d8ca68..a4540172c 100644 --- a/clic/include/tier3.hpp +++ b/clic/include/tier3.hpp @@ -368,16 +368,36 @@ morphological_chan_vese_func(const Device::Pointer & device, * The intensity image is optional and set to 0 if not provided. * * @param device Device to perform the operation on. [const Device::Pointer &] - * @param src Label image to compute the statistics. [const Array::Pointer &]] + * @param label Label image to compute the statistics. [const Array::Pointer &]] * @param intensity Intensity image. [Array::Pointer ( = None )] - * @param withBG Include the background label in the statistics. [bool ( = False )] * @return StatisticsMap + * + * @see https://clij.github.io/clij2-docs/reference_statisticsOfLabelledPixels */ auto statistics_of_labelled_pixels_func(const Device::Pointer & device, - const Array::Pointer & src, - Array::Pointer intensity, - bool withBG) -> StatisticsMap; + const Array::Pointer & label, + Array::Pointer intensity) -> StatisticsMap; + +/** + * @name statistics_of_background_and_labelled_pixels + * @brief Compute, for the background and labels, the bounding box, area (in pixels/voxels), minimum intensity, + * maximum intensity, average intensity, standard deviation of the intensity, and some shape descriptors of + * labelled objects in a label image and its corresponding intensity image. + * + * The intensity image is optional and set to 0 if not provided. + * + * @param device Device to perform the operation on. [const Device::Pointer &] + * @param label Label image to compute the statistics. [const Array::Pointer &]] + * @param intensity Intensity image. [Array::Pointer ( = None )] + * @return StatisticsMap + * + * @see https://clij.github.io/clij2-docs/reference_statisticsOfBackgroundAndLabelledPixels + */ +auto +statistics_of_background_and_labelled_pixels_func(const Device::Pointer & device, + const Array::Pointer & label, + const Array::Pointer & intensity) -> StatisticsMap; } // namespace cle::tier3 diff --git a/clic/include/tier4.hpp b/clic/include/tier4.hpp index 2e56f308a..c174a5dd3 100644 --- a/clic/include/tier4.hpp +++ b/clic/include/tier4.hpp @@ -105,25 +105,162 @@ threshold_otsu_func(const Device::Pointer & device, const Array::Pointer & src, /** - * @name filter_label_by_size - * @brief Filter labelled objects outside of the min/max size range value. + * @name label_pixel_count_map + * @brief Takes a label map, determines the number of pixels per label and replaces every label with the that number. + * This results in a parametric image expressing area or volume. + * + * @param device Device to perform the operation on. [const Device::Pointer &] + * @param src Label image to measure [const Array::Pointer &] + * @param dst Parametric image computed[Array::Pointer ( = None )] + * @return Array::Pointer + * + * @note 'label measurement', 'map', 'in assistant' + * @see https://clij.github.io/clij2-docs/reference_pixelCountMap + */ +auto +label_pixel_count_map_func(const Device::Pointer & device, + const Array::Pointer & src, + Array::Pointer dst) -> Array::Pointer; + + +/** + * @name centroids_of_labels + * @brief Determines the centroids of all labels in a label image or image stack. + * It writes the resulting coordinates in point list image of dimensions n * d + * where n is the number of labels and d=3 the dimensionality (x,y,z) of the original image. + * + * @param device Device to perform the operation on. [const Device::Pointer &] + * @param src Label image where the centroids will be determined from. [const Array::Pointer &] + * @param dst Output image where the centroids will be written to. [Array::Pointer ( = None )] + * @param withBG Determines if the background label should be included. [bool ( = False )] + * @return Array::Pointer + * + * @note 'bia-bob-suggestion' + * @see https://clij.github.io/clij2-docs/reference_centroidsOfLabels + */ +auto +centroids_of_labels_func(const Device::Pointer & device, const Array::Pointer & src, Array::Pointer dst, bool withBG) + -> Array::Pointer; + + +/** + * @name remove_labels_with_values_out_of_range + * @brief Remove labels with values outside a given value range based on a vector of values + * associated with the labels. + * + * @param device Device to perform the operation on. [const Device::Pointer &] + * @param src Input image where labels will be filtered. [const Array::Pointer &] + * @param values Vector of values associated with the labels. [const Array::Pointer &] + * @param dst Output image where labels will be written to. [Array::Pointer ( = None )] + * @param min_value Minimum value to keep. [float ( = 0 )] + * @param max_value Maximum value to keep. [float ( = 100 )] + * @return Array::Pointer + * + * @note 'label processing', 'combine' + * @see https://clij.github.io/clij2-docs/reference_excludeLabelsWithValuesOutOfRange + */ +auto +remove_labels_with_values_out_of_range_func(const Device::Pointer & device, + const Array::Pointer & src, + const Array::Pointer & values, + Array::Pointer dst, + float min_value, + float max_value) -> Array::Pointer; + +/** + * @name remove_labels_with_values_within_range + * @brief Remove labels with values inside a given value range based on a vector of values + * associated with the labels. + * + * @param device Device to perform the operation on. [const Device::Pointer &] + * @param src Input image where labels will be filtered. [const Array::Pointer &] + * @param values Vector of values associated with the labels. [const Array::Pointer &] + * @param dst Output image where labels will be written to. [Array::Pointer ( = None )] + * @param min_value Minimum value to keep. [float ( = 0 )] + * @param max_value Maximum value to keep. [float ( = 100 )] + * @return Array::Pointer + * + * @note 'label processing', 'combine' + * @see https://clij.github.io/clij2-docs/reference_excludeLabelsWithValuesWithinRange + */ +auto +remove_labels_with_values_within_range_func(const Device::Pointer & device, + const Array::Pointer & src, + const Array::Pointer & values, + Array::Pointer dst, + float min_value, + float max_value) -> Array::Pointer; + +/** + * @name exclude_labels_with_values_out_of_range + * @brief Exclude labels with values outside a given value range based on a vector of values + * associated with the labels. + * + * @param device Device to perform the operation on. [const Device::Pointer &] + * @param src Input image where labels will be filtered. [const Array::Pointer &] + * @param values Vector of values associated with the labels. [const Array::Pointer &] + * @param dst Output image where labels will be written to. [Array::Pointer ( = None )] + * @param min_value_range Minimum value to keep. [float ( = 0 )] + * @param max_value_range Maximum value to keep. [float ( = 100 )] + * @return Array::Pointer + * + * @note 'label processing', 'combine' + * @see https://clij.github.io/clij2-docs/reference_excludeLabelsWithValuesOutOfRange + * @deprecated This function is deprecated. Use remove_labels_with_values_out_of_range_func instead. + */ +auto +exclude_labels_with_values_out_of_range_func(const Device::Pointer & device, + const Array::Pointer & src, + const Array::Pointer & values, + Array::Pointer dst, + float min_value_range, + float max_value_range) -> Array::Pointer; + +/** + * @name exclude_labels_with_values_within_range + * @brief Exclude labels with values inside a given value range based on a vector of values + * associated with the labels. + * + * @param device Device to perform the operation on. [const Device::Pointer &] + * @param src Input image where labels will be filtered. [const Array::Pointer &] + * @param values Vector of values associated with the labels. [const Array::Pointer &] + * @param dst Output image where labels will be written to. [Array::Pointer ( = None )] + * @param min_value_range Minimum value to keep. [float ( = 0 )] + * @param max_value_range Maximum value to keep. [float ( = 100 )] + * @return Array::Pointer + * + * @note 'label processing', 'combine' + * @see https://clij.github.io/clij2-docs/reference_excludeLabelsWithValuesWithinRange + * @deprecated This function is deprecated. Use remove_labels_with_values_within_range_func instead. + */ +auto +exclude_labels_with_values_within_range_func(const Device::Pointer & device, + const Array::Pointer & src, + const Array::Pointer & values, + Array::Pointer dst, + float min_value_range, + float max_value_range) -> Array::Pointer; + +/** + * @name extension_ratio_map + * @brief Determines the ratio of the extension for every label in a label map and returns it as + * a parametric map. + * + * The extension ration is defined as the maximum distance of any pixel in the label to the label's centroid divided by + * the average distance of all pixels in the label to the centroid. * * @param device Device to perform the operation on. [const Device::Pointer &] * @param src Input label image. [const Array::Pointer &] - * @param dst Output label image. [Array::Pointer ( = None )] - * @param min_size Minimum size of labels to keep. [float ( = 0 )] - * @param max_size Maximum size of labels to keep. [float ( = 100 )] + * @param dst Output parametric image. [Array::Pointer ( = None )] * @return Array::Pointer * - * @note 'label processing', 'in assistant' - * @see https://clij.github.io/clij2-docs/reference_excludeLabelsOutsideSizeRange + * @note 'label processing', 'in assistant', 'map' + * @see https://clij.github.io/clij2-docs/reference_extensionRatioMap */ auto -filter_label_by_size_func(const Device::Pointer & device, - const Array::Pointer & src, - Array::Pointer dst, - float min_size, - float max_size) -> Array::Pointer; +extension_ratio_map_func(const Device::Pointer & device, + const Array::Pointer & src, + Array::Pointer dst) -> Array::Pointer; } // namespace cle::tier4 diff --git a/clic/include/tier5.hpp b/clic/include/tier5.hpp index 402c2293f..42bd666d0 100644 --- a/clic/include/tier5.hpp +++ b/clic/include/tier5.hpp @@ -89,77 +89,44 @@ connected_component_labeling_func(const Device::Pointer & device, Array::Pointer dst, const std::string & connectivity) -> Array::Pointer; -/** - * @name remove_small_labels - * @brief Removes labelled objects small than a given size (in pixels) from a label map. - * - * @param device Device to perform the operation on. [const Device::Pointer &] - * @param src Label image to filter. [const Array::Pointer &] - * @param dst Output label image fitlered. [Array::Pointer ( = None )] - * @param min_size Smallest size object allowed. [float ( = 100 )] - * @return Array::Pointer - * - * @note 'label processing', 'in assistant', 'bia-bob-suggestion' - * @see https://clij.github.io/clij2-docs/reference_excludeLabelsOutsideSizeRange - */ -auto -remove_small_labels_func(const Device::Pointer & device, const Array::Pointer & src, Array::Pointer dst, float min_size) - -> Array::Pointer; - -/** - * @name exclude_small_labels - * @brief Removes labels from a label map which are below a given maximum size. - * - * @param device Device to perform the operation on. [const Device::Pointer &] - * @param src Label image to filter. [const Array::Pointer &] - * @param dst Output label image fitlered. [Array::Pointer ( = None )] - * @param max_size Largest size object to exclude. [float ( = 100 )] - * @return Array::Pointer - * - * @note 'label processing', 'in assistant', 'bia-bob-suggestion' - * @see https://clij.github.io/clij2-docs/reference_excludeLabelsOutsideSizeRange - */ -auto -exclude_small_labels_func(const Device::Pointer & device, - const Array::Pointer & src, - Array::Pointer dst, - float max_size) -> Array::Pointer; /** - * @name remove_large_labels - * @brief Removes labelled objects bigger than a given size (in pixels) from a label map. + * @name reduce_labels_to_centroids + * @brief Take a label map and reduce each label to its centroid. * * @param device Device to perform the operation on. [const Device::Pointer &] - * @param src Label image to filter. [const Array::Pointer &] - * @param dst Output label image fitlered. [Array::Pointer ( = None )] - * @param max_size Biggest size object allowed. [float ( = 100 )] + * @param src Label image to reduce. [const Array::Pointer &] + * @param dst Output label image with centroids. [Array::Pointer ( = None )] * @return Array::Pointer * * @note 'label processing', 'in assistant', 'bia-bob-suggestion' - * @see https://clij.github.io/clij2-docs/reference_excludeLabelsOutsideSizeRange + * @see https://clij.github.io/clij2-docs/reference_reduceLabelsToCentroids */ auto -remove_large_labels_func(const Device::Pointer & device, const Array::Pointer & src, Array::Pointer dst, float max_size) - -> Array::Pointer; +reduce_labels_to_centroids_func(const Device::Pointer & device, + const Array::Pointer & src, + Array::Pointer dst) -> Array::Pointer; /** - * @name exclude_large_labels - * @brief Removes labels from a label map which are higher a given minimum size. + * @name filter_label_by_size + * @brief Filter labelled objects outside of the min/max size range value. * * @param device Device to perform the operation on. [const Device::Pointer &] - * @param src Label image to filter. [const Array::Pointer &] - * @param dst Output label image fitlered. [Array::Pointer ( = None )] - * @param min_size Smallest size object to keep. [float ( = 100 )] + * @param src Input label image. [const Array::Pointer &] + * @param dst Output label image. [Array::Pointer ( = None )] + * @param min_size Minimum size of labels to keep. [float ( = 0 )] + * @param max_size Maximum size of labels to keep. [float ( = 100 )] * @return Array::Pointer * - * @note 'label processing', 'in assistant', 'bia-bob-suggestion' + * @note 'label processing', 'in assistant' * @see https://clij.github.io/clij2-docs/reference_excludeLabelsOutsideSizeRange */ auto -exclude_large_labels_func(const Device::Pointer & device, +filter_label_by_size_func(const Device::Pointer & device, const Array::Pointer & src, Array::Pointer dst, - float min_size) -> Array::Pointer; + float min_size, + float max_size) -> Array::Pointer; } // namespace cle::tier5 diff --git a/clic/include/tier6.hpp b/clic/include/tier6.hpp index e830d9527..bec846225 100644 --- a/clic/include/tier6.hpp +++ b/clic/include/tier6.hpp @@ -115,22 +115,77 @@ voronoi_labeling_func(const Device::Pointer & device, const Array::Pointer & src /** - * @name fill_holes - * @brief Fill holes in labelled objects samller than a given size (in pixels) from a label map. + * @name remove_small_labels + * @brief Removes labelled objects small than a given size (in pixels) from a label map. * * @param device Device to perform the operation on. [const Device::Pointer &] * @param src Label image to filter. [const Array::Pointer &] * @param dst Output label image fitlered. [Array::Pointer ( = None )] - * @param max_size Biggest size holes allowed. [float ( = 100 )] + * @param min_size Smallest size object allowed. [float ( = 100 )] * @return Array::Pointer * * @note 'label processing', 'in assistant', 'bia-bob-suggestion' * @see https://clij.github.io/clij2-docs/reference_excludeLabelsOutsideSizeRange */ auto -fill_holes_func(const Device::Pointer & device, const Array::Pointer & src, Array::Pointer dst, float max_size) +remove_small_labels_func(const Device::Pointer & device, const Array::Pointer & src, Array::Pointer dst, float min_size) -> Array::Pointer; +/** + * @name exclude_small_labels + * @brief Removes labels from a label map which are below a given maximum size. + * + * @param device Device to perform the operation on. [const Device::Pointer &] + * @param src Label image to filter. [const Array::Pointer &] + * @param dst Output label image fitlered. [Array::Pointer ( = None )] + * @param max_size Largest size object to exclude. [float ( = 100 )] + * @return Array::Pointer + * + * @note 'label processing', 'in assistant', 'bia-bob-suggestion' + * @see https://clij.github.io/clij2-docs/reference_excludeLabelsOutsideSizeRange + */ +auto +exclude_small_labels_func(const Device::Pointer & device, + const Array::Pointer & src, + Array::Pointer dst, + float max_size) -> Array::Pointer; + +/** + * @name remove_large_labels + * @brief Removes labelled objects bigger than a given size (in pixels) from a label map. + * + * @param device Device to perform the operation on. [const Device::Pointer &] + * @param src Label image to filter. [const Array::Pointer &] + * @param dst Output label image fitlered. [Array::Pointer ( = None )] + * @param max_size Biggest size object allowed. [float ( = 100 )] + * @return Array::Pointer + * + * @note 'label processing', 'in assistant', 'bia-bob-suggestion' + * @see https://clij.github.io/clij2-docs/reference_excludeLabelsOutsideSizeRange + */ +auto +remove_large_labels_func(const Device::Pointer & device, const Array::Pointer & src, Array::Pointer dst, float max_size) + -> Array::Pointer; + +/** + * @name exclude_large_labels + * @brief Removes labels from a label map which are higher a given minimum size. + * + * @param device Device to perform the operation on. [const Device::Pointer &] + * @param src Label image to filter. [const Array::Pointer &] + * @param dst Output label image fitlered. [Array::Pointer ( = None )] + * @param min_size Smallest size object to keep. [float ( = 100 )] + * @return Array::Pointer + * + * @note 'label processing', 'in assistant', 'bia-bob-suggestion' + * @see https://clij.github.io/clij2-docs/reference_excludeLabelsOutsideSizeRange + */ +auto +exclude_large_labels_func(const Device::Pointer & device, + const Array::Pointer & src, + Array::Pointer dst, + float min_size) -> Array::Pointer; + } // namespace cle::tier6 diff --git a/clic/include/tier7.hpp b/clic/include/tier7.hpp index a9f8aea0a..15079b24a 100644 --- a/clic/include/tier7.hpp +++ b/clic/include/tier7.hpp @@ -272,6 +272,23 @@ voronoi_otsu_labeling_func(const Device::Pointer & device, float outline_sigma) -> Array::Pointer; +/** + * @name fill_holes + * @brief Fill holes in labelled objects samller than a given size (in pixels) from a label map. + * + * @param device Device to perform the operation on. [const Device::Pointer &] + * @param src Label image to filter. [const Array::Pointer &] + * @param dst Output label image fitlered. [Array::Pointer ( = None )] + * @param max_size Biggest size holes allowed. [float ( = 100 )] + * @return Array::Pointer + * + * @note 'label processing', 'in assistant', 'bia-bob-suggestion' + * @see https://clij.github.io/clij2-docs/reference_excludeLabelsOutsideSizeRange + */ +auto +fill_holes_func(const Device::Pointer & device, const Array::Pointer & src, Array::Pointer dst, float max_size) + -> Array::Pointer; + } // namespace cle::tier7 #endif // __INCLUDE_TIER7_HPP diff --git a/clic/src/statistics.cpp b/clic/src/statistics.cpp index d7baf9f5a..067ad00ed 100644 --- a/clic/src/statistics.cpp +++ b/clic/src/statistics.cpp @@ -77,13 +77,12 @@ _std_per_label(const Device::Pointer & device, auto compute_statistics_per_labels(const Device::Pointer & device, const Array::Pointer & label, - const Array::Pointer & intensity, - size_t offset) -> StatisticsMap + const Array::Pointer & intensity) -> StatisticsMap { // initialize variables, output, and constants - // const size_t offset= 0; // skip the bg label with value 0 + const size_t offset = 1; const size_t nb_labels = static_cast(tier2::maximum_of_all_pixels_func(device, label)) + offset; const size_t nb_measurements = nb_labels - offset; const RangeArray origin = { 0, 0, 0 }; diff --git a/clic/src/tier1/replace_value.cpp b/clic/src/tier1/replace_value.cpp deleted file mode 100644 index 5fc464125..000000000 --- a/clic/src/tier1/replace_value.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "tier0.hpp" -#include "tier1.hpp" - -#include "utils.hpp" - -#include "cle_replace_value.h" -#include "cle_replace_values.h" - -namespace cle::tier1 -{ - -auto -replace_value_func(const Device::Pointer & device, - const Array::Pointer & src, - Array::Pointer dst, - float scalar0, - float scalar1) -> Array::Pointer -{ - tier0::create_like(src, dst); - const KernelInfo kernel = { "replace_value", kernel::replace_value }; - const ParameterList params = { { "src", src }, { "dst", dst }, { "scalar0", scalar0 }, { "scalar1", scalar1 } }; - const RangeArray range = { dst->width(), dst->height(), dst->depth() }; - execute(device, kernel, params, range); - return dst; -} - -// resample_func -// touch_matrix_to_mesh_func - -} // namespace cle::tier1 diff --git a/clic/src/tier1/replace_values.cpp b/clic/src/tier1/replace_values.cpp index e6d743c84..0e35cac12 100644 --- a/clic/src/tier1/replace_values.cpp +++ b/clic/src/tier1/replace_values.cpp @@ -3,6 +3,7 @@ #include "utils.hpp" +#include "cle_replace_value.h" #include "cle_replace_values.h" namespace cle::tier1 @@ -22,4 +23,38 @@ replace_values_func(const Device::Pointer & device, return dst; } +auto +replace_value_func(const Device::Pointer & device, + const Array::Pointer & src, + Array::Pointer dst, + float scalar0, + float scalar1) -> Array::Pointer +{ + tier0::create_like(src, dst); + const KernelInfo kernel = { "replace_value", kernel::replace_value }; + const ParameterList params = { { "src", src }, { "dst", dst }, { "scalar0", scalar0 }, { "scalar1", scalar1 } }; + const RangeArray range = { dst->width(), dst->height(), dst->depth() }; + execute(device, kernel, params, range); + return dst; +} + +auto +replace_intensity_func(const Device::Pointer & device, + const Array::Pointer & src, + Array::Pointer dst, + float scalar0, + float scalar1) -> Array::Pointer +{ + return replace_value_func(device, src, dst, scalar0, scalar1); +} + +auto +replace_intensities_func(const Device::Pointer & device, + const Array::Pointer & src0, + const Array::Pointer & src1, + Array::Pointer dst) -> Array::Pointer +{ + return replace_values_func(device, src0, src1, dst); +} + } // namespace cle::tier1 diff --git a/clic/src/tier2/stack_operations.cpp b/clic/src/tier2/stack_operations.cpp new file mode 100644 index 000000000..868b2fb3a --- /dev/null +++ b/clic/src/tier2/stack_operations.cpp @@ -0,0 +1,39 @@ +#include "tier0.hpp" +#include "tier1.hpp" +#include "tier2.hpp" + +#include "utils.hpp" + +namespace cle::tier2 +{ + +auto +sub_stack_func(const Device::Pointer & device, const Array::Pointer & src, Array::Pointer dst, int start_z, int end_z) + -> Array::Pointer +{ + auto nb_slice = end_z - start_z + 1; + nb_slice = nb_slice < 1 ? 1 : nb_slice; + return tier1::crop_func(device, src, dst, 0, 0, start_z, 0, 0, nb_slice); +} + +auto +reduce_stack_func(const Device::Pointer & device, + const Array::Pointer & src, + Array::Pointer dst, + int reduction_factor, + int offset) -> Array::Pointer +{ + reduction_factor = reduction_factor < 1 ? 1 : reduction_factor; + auto num_slice = static_cast(src->depth() / reduction_factor); + + tier0::create_dst(src, dst, src->width(), src->height(), num_slice, src->dtype()); + auto temp_slice = Array::create(src->width(), src->height(), 1, 2, src->dtype(), src->mtype(), device); + for (auto z = 0; z < num_slice; z++) + { + tier1::copy_slice_func(device, src, temp_slice, z * reduction_factor + offset); + tier1::copy_slice_func(device, temp_slice, dst, z); + } + return dst; +} + +} // namespace cle::tier2 diff --git a/clic/src/tier3/statistics_of_labelled_pixels.cpp b/clic/src/tier3/statistics_of_labelled_pixels.cpp index 96b3ec96c..3060ea2d6 100644 --- a/clic/src/tier3/statistics_of_labelled_pixels.cpp +++ b/clic/src/tier3/statistics_of_labelled_pixels.cpp @@ -7,22 +7,32 @@ namespace cle::tier3 auto statistics_of_labelled_pixels_func(const Device::Pointer & device, - const Array::Pointer & src, - Array::Pointer intensity, - bool withBG) -> StatisticsMap + const Array::Pointer & label, + Array::Pointer intensity) -> StatisticsMap { - // create intensity if not set if (intensity == nullptr) { // std::cerr << "Warning: no intensity was provided. Pixels intensity will be set to their label value." << // std::endl; - tier0::create_like(src, intensity, dType::FLOAT); + tier0::create_like(label, intensity, dType::FLOAT); intensity->fill(0); - // tier1::copy_func(device, label, intensity); } - size_t offset = (withBG) ? 0 : 1; - return compute_statistics_per_labels(device, src, intensity, offset); + return compute_statistics_per_labels(device, label, intensity); +} + + +auto +statistics_of_background_and_labelled_pixels_func(const Device::Pointer & device, + const Array::Pointer & label, + const Array::Pointer & intensity) -> StatisticsMap +{ + auto temp = tier1::add_image_and_scalar_func(device, label, nullptr, 1); + auto props = tier3::statistics_of_labelled_pixels_func(device, temp, intensity); + std::vector labels = props["label"]; + std::transform(labels.begin(), labels.end(), labels.begin(), [](float label) { return label - 1; }); + props["label"] = labels; + return props; } diff --git a/clic/src/tier4/centroids_of_labels.cpp b/clic/src/tier4/centroids_of_labels.cpp new file mode 100644 index 000000000..92532d406 --- /dev/null +++ b/clic/src/tier4/centroids_of_labels.cpp @@ -0,0 +1,40 @@ + +#include "tier0.hpp" +#include "tier1.hpp" +#include "tier2.hpp" +#include "tier3.hpp" +#include "tier4.hpp" + +#include "utils.hpp" +#include + +namespace cle::tier4 +{ + +auto +centroids_of_labels_func(const Device::Pointer & device, const Array::Pointer & src, Array::Pointer dst, bool withBG) + -> Array::Pointer +{ + cle::StatisticsMap props; + if (withBG) + { + props = tier3::statistics_of_background_and_labelled_pixels_func(device, src, nullptr); + } + else + { + props = tier3::statistics_of_labelled_pixels_func(device, src, nullptr); + } + auto centroid_x = props["centroid_x"]; + auto centroid_y = props["centroid_y"]; + auto centroid_z = props["centroid_z"]; + auto nb_labels = centroid_x.size(); + + auto res = Array::create(nb_labels, 3, 1, 1, dType::FLOAT, mType::BUFFER, device); + res->writeFrom(centroid_x.data(), { nb_labels, 1, 1 }, { 0, 0, 0 }); + res->writeFrom(centroid_y.data(), { nb_labels, 1, 1 }, { 0, 1, 0 }); + res->writeFrom(centroid_z.data(), { nb_labels, 1, 1 }, { 0, 2, 0 }); + return res; +} + + +} // namespace cle::tier4 diff --git a/clic/src/tier4/filter_label_by_size.cpp b/clic/src/tier4/filter_label_by_size.cpp deleted file mode 100644 index 89a779fe2..000000000 --- a/clic/src/tier4/filter_label_by_size.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include "tier0.hpp" -#include "tier1.hpp" -#include "tier2.hpp" -#include "tier3.hpp" -#include "tier4.hpp" - -#include "utils.hpp" -#include - -namespace cle::tier4 -{ - -auto -filter_label_by_size_func(const Device::Pointer & device, - const Array::Pointer & src, - Array::Pointer dst, - float min_size, - float max_size) -> Array::Pointer -{ - tier0::create_like(src, dst, dType::LABEL); - auto stats = tier3::statistics_of_labelled_pixels_func(device, src, nullptr, true); - - const auto nb_labels = stats["label"].size(); - auto list_of_area = Array::create(nb_labels, 1, 1, 1, dType::FLOAT, mType::BUFFER, device); - list_of_area->writeFrom(stats["area"].data()); - - auto below_min_buffer = tier1::smaller_constant_func(device, list_of_area, nullptr, min_size); - auto above_max_buffer = tier1::greater_constant_func(device, list_of_area, nullptr, max_size); - - auto list_of_labels_to_exclude = Array::create(nb_labels, 1, 1, 1, dType::LABEL, mType::BUFFER, device); - tier1::binary_or_func(device, below_min_buffer, above_max_buffer, list_of_labels_to_exclude); - return tier3::remove_labels_func(device, src, list_of_labels_to_exclude, dst); -} - - -} // namespace cle::tier4 diff --git a/clic/src/tier4/filter_label_by_values.cpp b/clic/src/tier4/filter_label_by_values.cpp new file mode 100644 index 000000000..151139962 --- /dev/null +++ b/clic/src/tier4/filter_label_by_values.cpp @@ -0,0 +1,71 @@ + + + +#include "tier0.hpp" +#include "tier1.hpp" +#include "tier2.hpp" +#include "tier3.hpp" +#include "tier4.hpp" + +#include "utils.hpp" +#include + +namespace cle::tier4 +{ + +auto +remove_labels_with_values_out_of_range_func(const Device::Pointer & device, + const Array::Pointer & src, + const Array::Pointer & values, + Array::Pointer dst, + float min_value, + float max_value) -> Array::Pointer +{ + auto above = tier1::greater_constant_func(device, values, nullptr, max_value); + auto below = tier1::smaller_constant_func(device, values, nullptr, min_value); + auto flaglist = Array::create(values->size(), 1, 1, 1, dType::LABEL, mType::BUFFER, device); + tier1::binary_or_func(device, below, above, flaglist); + return tier3::remove_labels_func(device, src, flaglist, dst); +} + + +auto +remove_labels_with_values_within_range_func(const Device::Pointer & device, + const Array::Pointer & src, + const Array::Pointer & values, + Array::Pointer dst, + float min_value, + float max_value) -> Array::Pointer +{ + auto above = tier1::greater_or_equal_constant_func(device, values, nullptr, max_value); + auto below = tier1::smaller_or_equal_constant_func(device, values, nullptr, max_value); + auto flaglist = Array::create(values->size(), 1, 1, 1, dType::LABEL, mType::BUFFER, device); + tier1::binary_or_func(device, below, above, flaglist); + return tier3::remove_labels_func(device, src, flaglist, dst); +} + + +auto +exclude_labels_with_values_out_of_range_func(const Device::Pointer & device, + const Array::Pointer & src, + const Array::Pointer & values, + Array::Pointer dst, + float min_value_range, + float max_value_range) -> Array::Pointer +{ + return remove_labels_with_values_out_of_range_func(device, src, values, dst, min_value_range, max_value_range); +} + + +auto +exclude_labels_with_values_within_range_func(const Device::Pointer & device, + const Array::Pointer & src, + const Array::Pointer & values, + Array::Pointer dst, + float min_value_range, + float max_value_range) -> Array::Pointer +{ + return remove_labels_with_values_within_range_func(device, src, values, dst, min_value_range, max_value_range); +} + +} // namespace cle::tier4 diff --git a/clic/src/tier4/parametrics_map.cpp b/clic/src/tier4/parametrics_map.cpp new file mode 100644 index 000000000..6004a159a --- /dev/null +++ b/clic/src/tier4/parametrics_map.cpp @@ -0,0 +1,44 @@ + +#include "tier0.hpp" +#include "tier1.hpp" +#include "tier2.hpp" +#include "tier3.hpp" +#include "tier4.hpp" + +#include "utils.hpp" +#include + +namespace cle::tier4 +{ + +auto +label_pixel_count_map_func(const Device::Pointer & device, + const Array::Pointer & src, + Array::Pointer dst) -> Array::Pointer +{ + tier0::create_like(src, dst, dType::FLOAT); + auto props = tier3::statistics_of_background_and_labelled_pixels_func(device, src, nullptr); + + auto values = cle::Array::create(props["area"].size(), 1, 1, 1, dType::FLOAT, mType::BUFFER, device); + values->writeFrom(props["area"].data()); + + tier1::set_column_func(device, values, 0, 0); + return tier1::replace_values_func(device, src, values, dst); +} + +auto +extension_ratio_map_func(const Device::Pointer & device, + const Array::Pointer & src, + Array::Pointer dst) -> Array::Pointer +{ + tier0::create_like(src, dst, dType::FLOAT); + auto props = tier3::statistics_of_background_and_labelled_pixels_func(device, src, nullptr); + auto vector = props["mean_max_distance_to_centroid_ratio"]; + auto values = Array::create(vector.size(), 1, 1, 1, dType::FLOAT, mType::BUFFER, device); + values->writeFrom(vector.data()); + tier1::set_column_func(device, values, 0, 0); + return tier1::replace_values_func(device, src, values, dst); +} + + +} // namespace cle::tier4 diff --git a/clic/src/tier5/filter_label_by_size.cpp b/clic/src/tier5/filter_label_by_size.cpp new file mode 100644 index 000000000..b629d1c19 --- /dev/null +++ b/clic/src/tier5/filter_label_by_size.cpp @@ -0,0 +1,39 @@ +#include "tier0.hpp" +#include "tier1.hpp" +#include "tier2.hpp" +#include "tier3.hpp" +#include "tier4.hpp" +#include "tier5.hpp" + +#include "utils.hpp" +#include + +namespace cle::tier5 +{ + +auto +filter_label_by_size_func(const Device::Pointer & device, + const Array::Pointer & src, + Array::Pointer dst, + float min_size, + float max_size) -> Array::Pointer +{ + tier0::create_like(src, dst, dType::LABEL); + auto stats = tier3::statistics_of_background_and_labelled_pixels_func(device, src, nullptr); + + const auto nb_labels = stats["label"].size(); + auto list_of_area = Array::create(nb_labels, 1, 1, 1, dType::FLOAT, mType::BUFFER, device); + list_of_area->writeFrom(stats["area"].data()); + + return tier4::remove_labels_with_values_out_of_range_func(device, src, list_of_area, dst, min_size, max_size); + + // auto below_min_buffer = tier1::smaller_constant_func(device, list_of_area, nullptr, min_size); + // auto above_max_buffer = tier1::greater_constant_func(device, list_of_area, nullptr, max_size); + + // auto list_of_labels_to_exclude = Array::create(nb_labels, 1, 1, 1, dType::LABEL, mType::BUFFER, device); + // tier1::binary_or_func(device, below_min_buffer, above_max_buffer, list_of_labels_to_exclude); + // return tier3::remove_labels_func(device, src, list_of_labels_to_exclude, dst); +} + + +} // namespace cle::tier5 diff --git a/clic/src/tier5/reduce_labels_to_centroids.cpp b/clic/src/tier5/reduce_labels_to_centroids.cpp new file mode 100644 index 000000000..5d97dc4e4 --- /dev/null +++ b/clic/src/tier5/reduce_labels_to_centroids.cpp @@ -0,0 +1,30 @@ +#include "tier0.hpp" +#include "tier1.hpp" +#include "tier2.hpp" +#include "tier3.hpp" +#include "tier4.hpp" +#include "tier5.hpp" + +#include "utils.hpp" + +namespace cle::tier5 +{ + +auto +reduce_labels_to_centroids_func(const Device::Pointer & device, + const Array::Pointer & src, + Array::Pointer dst) -> Array::Pointer +{ + tier0::create_like(src, dst, dType::LABEL); + dst->fill(0); + + auto pos = tier4::centroids_of_labels_func(device, src, dst, true); + auto label_pos = Array::create(pos->width(), 4, 1, 2, dType::FLOAT, mType::BUFFER, device); + tier1::set_ramp_x_func(device, label_pos); + pos->copyTo(label_pos, { pos->width(), 3, 1 }, { 0, 0, 0 }, { 0, 0, 0 }); + + tier1::set_column_func(device, label_pos, 0, -1); + return tier1::write_values_to_positions_func(device, label_pos, dst); +} + +} // namespace cle::tier5 diff --git a/clic/src/tier5/remove_objects.cpp b/clic/src/tier6/remove_objects.cpp similarity index 76% rename from clic/src/tier5/remove_objects.cpp rename to clic/src/tier6/remove_objects.cpp index 8dcd1e862..766285bb7 100644 --- a/clic/src/tier5/remove_objects.cpp +++ b/clic/src/tier6/remove_objects.cpp @@ -4,25 +4,26 @@ #include "tier3.hpp" #include "tier4.hpp" #include "tier5.hpp" +#include "tier6.hpp" #include "utils.hpp" #include -namespace cle::tier5 +namespace cle::tier6 { auto remove_small_labels_func(const Device::Pointer & device, const Array::Pointer & src, Array::Pointer dst, float min_size) -> Array::Pointer { - return tier4::filter_label_by_size_func(device, src, dst, min_size, std::numeric_limits::max()); + return tier5::filter_label_by_size_func(device, src, dst, min_size, std::numeric_limits::max()); } auto remove_large_labels_func(const Device::Pointer & device, const Array::Pointer & src, Array::Pointer dst, float max_size) -> Array::Pointer { - return tier4::filter_label_by_size_func(device, src, dst, 0, max_size); + return tier5::filter_label_by_size_func(device, src, dst, 0, max_size); } auto @@ -31,7 +32,7 @@ exclude_small_labels_func(const Device::Pointer & device, Array::Pointer dst, float max_size) -> Array::Pointer { - return tier5::remove_small_labels_func(device, src, dst, max_size); + return remove_small_labels_func(device, src, dst, max_size); } auto @@ -40,7 +41,7 @@ exclude_large_labels_func(const Device::Pointer & device, Array::Pointer dst, float min_size) -> Array::Pointer { - return tier5::remove_large_labels_func(device, src, dst, min_size); + return remove_large_labels_func(device, src, dst, min_size); } -} // namespace cle::tier5 +} // namespace cle::tier6 diff --git a/clic/src/tier6/remove_holes.cpp b/clic/src/tier7/fill_holes.cpp similarity index 85% rename from clic/src/tier6/remove_holes.cpp rename to clic/src/tier7/fill_holes.cpp index f39da6a4e..b817e7367 100644 --- a/clic/src/tier6/remove_holes.cpp +++ b/clic/src/tier7/fill_holes.cpp @@ -5,10 +5,11 @@ #include "tier4.hpp" #include "tier5.hpp" #include "tier6.hpp" +#include "tier7.hpp" #include "utils.hpp" -namespace cle::tier6 +namespace cle::tier7 { auto @@ -20,7 +21,7 @@ fill_holes_func(const Device::Pointer & device, const Array::Pointer & src, Arra auto inverted = tier1::binary_not_func(device, binary, nullptr); auto labels = tier5::connected_component_labeling_func(device, inverted, nullptr, "box"); - tier5::remove_small_labels_func(device, labels, dst, max_size); + tier6::remove_small_labels_func(device, labels, dst, max_size); // invert the filtered image tier1::greater_constant_func(device, dst, binary, 0); @@ -29,4 +30,4 @@ fill_holes_func(const Device::Pointer & device, const Array::Pointer & src, Arra } -} // namespace cle::tier6 +} // namespace cle::tier7 diff --git a/tests/tier3/test_label_statistics.cpp b/tests/tier3/test_label_statistics.cpp index b76db440e..03cdcd856 100644 --- a/tests/tier3/test_label_statistics.cpp +++ b/tests/tier3/test_label_statistics.cpp @@ -84,7 +84,7 @@ TEST_P(TestStatisticsOfLabelledPixels, execute2D) gpu_labels->writeFrom(labels.data()); // passing labels also as intensity image to have a simpler test - auto region_props = cle::tier3::statistics_of_labelled_pixels_func(device, gpu_labels, gpu_intensity, false); + auto region_props = cle::tier3::statistics_of_labelled_pixels_func(device, gpu_labels, gpu_intensity); // Test bounding box min/max (x, y, z) std::vector expected_bbox_min_x = { 0, 1, 0 }; @@ -150,7 +150,7 @@ TEST_P(TestStatisticsOfLabelledPixels, execute3D) auto gpu_labels = cle::Array::create(3, 2, 3, 3, cle::dType::FLOAT, cle::mType::BUFFER, device); gpu_labels->writeFrom(labels.data()); - auto region_props = cle::tier3::statistics_of_labelled_pixels_func(device, gpu_labels, gpu_intensity, false); + auto region_props = cle::tier3::statistics_of_labelled_pixels_func(device, gpu_labels, gpu_intensity); // Test bounding box min/max (x, y, z) std::vector expected_bbox_min_x = { 0, 1, 0 }; @@ -235,7 +235,7 @@ TEST_P(TestStatisticsOfLabelledPixels, shape) gpu_labels->writeFrom(labels.data()); // passing labels also as intensity image to have a simpler test - auto region_props = cle::tier3::statistics_of_labelled_pixels_func(device, gpu_labels, gpu_labels, false); + auto region_props = cle::tier3::statistics_of_labelled_pixels_func(device, gpu_labels, gpu_labels); // Test bounding box min/max (x, y, z) std::vector expected_bbox_min_x = { 0 }; @@ -301,7 +301,7 @@ TEST_P(TestStatisticsOfLabelledPixels, standard_deviation) auto gpu_labels = cle::Array::create(3, 3, 1, 3, cle::dType::FLOAT, cle::mType::BUFFER, device); gpu_labels->writeFrom(labels.data()); - auto region_props = cle::tier3::statistics_of_labelled_pixels_func(device, gpu_labels, gpu_image, false); + auto region_props = cle::tier3::statistics_of_labelled_pixels_func(device, gpu_labels, gpu_image); // print_stats_dict(region_props); diff --git a/tests/tier4/test_centroids_of_labels.cpp b/tests/tier4/test_centroids_of_labels.cpp new file mode 100644 index 000000000..ea189bde0 --- /dev/null +++ b/tests/tier4/test_centroids_of_labels.cpp @@ -0,0 +1,51 @@ +#include "cle.hpp" + +#include +#include + +class TestCentroidsOfLabels : public ::testing::TestWithParam +{ +protected: + std::array input = { 1, 1, 2, 0, 3, 3, 1, 1, 2, 0, 3, 3, 0, 0, 0, + 0, 0, 0, 4, 4, 5, 6, 6, 6, 4, 4, 5, 6, 6, 6 }; + + std::array valid = { 2.625, 0.5, 2, 4.5, 0.5, 2, 4, 1.625, 0.5, 0.5, 0.5, + 3.5, 3.5, 3.5, 0, 0, 0, 0, 0, 0, 0 }; +}; + +TEST_P(TestCentroidsOfLabels, execute2d) +{ + + std::string param = GetParam(); + cle::BackendManager::getInstance().setBackend(param); + auto device = cle::BackendManager::getInstance().getBackend().getDevice("", "all"); + device->setWaitToFinish(true); + + auto gpu_input = cle::Array::create(6, 5, 1, 2, cle::dType::LABEL, cle::mType::BUFFER, device); + gpu_input->writeFrom(input.data()); + + auto gpu_output = cle::tier4::centroids_of_labels_func(device, gpu_input, nullptr, true); + + std::vector output(gpu_output->size()); + gpu_output->readTo(output.data()); + for (int i = 0; i < output.size(); i++) + { + EXPECT_EQ(output[i], valid[i]); + } +} + + +std::vector +getParameters() +{ + std::vector parameters; +#if USE_OPENCL + parameters.push_back("opencl"); +#endif +#if USE_CUDA + parameters.push_back("cuda"); +#endif + return parameters; +} + +INSTANTIATE_TEST_SUITE_P(InstantiationName, TestCentroidsOfLabels, ::testing::ValuesIn(getParameters())); diff --git a/tests/tier4/test_label_pixelcount_map.cpp b/tests/tier4/test_label_pixelcount_map.cpp new file mode 100644 index 000000000..1000faf45 --- /dev/null +++ b/tests/tier4/test_label_pixelcount_map.cpp @@ -0,0 +1,51 @@ +#include "cle.hpp" + +#include +#include + +class TestLabelPixelCountMap : public ::testing::TestWithParam +{ +protected: + std::array input = { 1, 1, 2, 0, 3, 3, 1, 1, 2, 0, 3, 3, 0, 0, 0, + 0, 0, 0, 4, 4, 5, 6, 6, 6, 4, 4, 5, 6, 6, 6 }; + + std::array valid = { 4, 4, 2, 0, 4, 4, 4, 4, 2, 0, 4, 4, 0, 0, 0, + 0, 0, 0, 4, 4, 2, 6, 6, 6, 4, 4, 2, 6, 6, 6 }; +}; + +TEST_P(TestLabelPixelCountMap, execute2d) +{ + + std::string param = GetParam(); + cle::BackendManager::getInstance().setBackend(param); + auto device = cle::BackendManager::getInstance().getBackend().getDevice("", "all"); + device->setWaitToFinish(true); + + auto gpu_input = cle::Array::create(6, 5, 1, 2, cle::dType::LABEL, cle::mType::BUFFER, device); + gpu_input->writeFrom(input.data()); + + auto gpu_output = cle::tier4::label_pixel_count_map_func(device, gpu_input, nullptr); + + std::vector output(gpu_output->size()); + gpu_output->readTo(output.data()); + for (int i = 0; i < output.size(); i++) + { + EXPECT_EQ(output[i], valid[i]); + } +} + + +std::vector +getParameters() +{ + std::vector parameters; +#if USE_OPENCL + parameters.push_back("opencl"); +#endif +#if USE_CUDA + parameters.push_back("cuda"); +#endif + return parameters; +} + +INSTANTIATE_TEST_SUITE_P(InstantiationName, TestLabelPixelCountMap, ::testing::ValuesIn(getParameters())); diff --git a/tests/tier4/test_filter_labels_by_size.cpp b/tests/tier5/test_filter_labels_by_size.cpp similarity index 95% rename from tests/tier4/test_filter_labels_by_size.cpp rename to tests/tier5/test_filter_labels_by_size.cpp index c4afc3f79..843c88595 100644 --- a/tests/tier4/test_filter_labels_by_size.cpp +++ b/tests/tier5/test_filter_labels_by_size.cpp @@ -24,7 +24,7 @@ TEST_P(TestFilterLabelsBySize, execute2d) auto gpu_input = cle::Array::create(6, 5, 1, 2, cle::dType::LABEL, cle::mType::BUFFER, device); gpu_input->writeFrom(input.data()); - auto gpu_output = cle::tier4::filter_label_by_size_func(device, gpu_input, nullptr, 4, 5); + auto gpu_output = cle::tier5::filter_label_by_size_func(device, gpu_input, nullptr, 4, 5); std::vector output(gpu_output->size()); gpu_output->readTo(output.data()); diff --git a/tests/tier5/test_reduce_labels_to_centroids.cpp b/tests/tier5/test_reduce_labels_to_centroids.cpp new file mode 100644 index 000000000..3ab68b1ad --- /dev/null +++ b/tests/tier5/test_reduce_labels_to_centroids.cpp @@ -0,0 +1,50 @@ +#include "cle.hpp" + +#include +#include + +class TestReduceLabelToCentroids : public ::testing::TestWithParam +{ +protected: + const std::array input = { + 0, 0, 0, 1, 1, 1, 0, 2, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 3, 3, 3, 4, 4, 4, 3, 3, 3, 4, 4, 4, 3, 3, 3, 4, 4, 4, + }; + const std::array valid = { + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, + }; + std::array output; +}; + +TEST_P(TestReduceLabelToCentroids, executeBox) +{ + std::string param = GetParam(); + cle::BackendManager::getInstance().setBackend(param); + auto device = cle::BackendManager::getInstance().getBackend().getDevice("", "all"); + device->setWaitToFinish(true); + + auto gpu_input = cle::Array::create(6, 6, 1, 3, cle::dType::LABEL, cle::mType::BUFFER, device); + gpu_input->writeFrom(input.data()); + + auto gpu_output = cle::tier5::reduce_labels_to_centroids_func(device, gpu_input, nullptr); + + gpu_output->readTo(output.data()); + for (int i = 0; i < output.size(); i++) + { + EXPECT_EQ(output[i], valid[i]); + } +} + +std::vector +getParameters() +{ + std::vector parameters; +#if USE_OPENCL + parameters.push_back("opencl"); +#endif +#if USE_CUDA + parameters.push_back("cuda"); +#endif + return parameters; +} + +INSTANTIATE_TEST_SUITE_P(InstantiationName, TestReduceLabelToCentroids, ::testing::ValuesIn(getParameters()));