diff --git a/README.md b/README.md index 86c4c3190e703e8ba35ee8e441c7d66aaf4003d0..305c3a0c0db2e441b053ebe12cdc505cf3492b3b 100644 --- a/README.md +++ b/README.md @@ -45,9 +45,12 @@ Run the image processing benchmark: *ii. Please replace `<kernel name>` with name of the kernel which is to be used for* *benchmarking as specifed in `include/ImageProcessing/Kernels.h`.* +*ii. Please replace `<kernelmorph name>` with name of the unsigned int kernel which is to be used for* +*benchmarking as specifed in `include/ImageProcessing/Kernels.h`.* + *iii. Please replace `<Boundary Option>` with `CONSTANT_PADDING` or `REPLICATE_PADDING`.* -Ex. `./image-processing-benchmark ../../benchmarks/ImageProcessing/Images/YuTu.png laplacianKernelAlign CONSTANT_PADDING` +Ex. `./image-processing-benchmark ../../benchmarks/ImageProcessing/Images/YuTu.png random3x3KernelAlign random3x3KernelAlignInt CONSTANT_PADDING` ``` $ cd buddy-benchmark $ mkdir build && cd build @@ -57,7 +60,7 @@ $ cmake -G Ninja .. \ -DEIGEN_DIR=/PATH/TO/EIGEN/SOURCE/CODE \ -DBUDDY_OPT_BUILD_DIR=/PATH/TO/BUDDY-MLIR/BUILD/ $ ninja image-processing-benchmark -$ cd bin && ./image-processing-benchmark <image path> <kernel name> <Boundary Option> +$ cd bin && ./image-processing-benchmark <image path> <kernel name> <kernelmorph name> <Boundary Option> ``` ## Deep Learning Benchmark diff --git a/benchmarks/ImageProcessing/BuddyMorph2D.mlir b/benchmarks/ImageProcessing/BuddyMorph2D.mlir new file mode 100644 index 0000000000000000000000000000000000000000..d1d9b7f7dc71a053a2ae74eb1669edaae3337762 --- /dev/null +++ b/benchmarks/ImageProcessing/BuddyMorph2D.mlir @@ -0,0 +1,103 @@ +//===- BuddyMorph2D.mlir ---------------------------------------------------===// +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//===----------------------------------------------------------------------===// +// +// This file provides Buddy Morpholgical operations. +// +//===----------------------------------------------------------------------===// + +func.func @erosion_2d_constant_padding(%inputImage : memref<?x?xf32>, %kernel : memref<?x?xf32>, %outputImage : memref<?x?xf32>, %copymemref : memref<?x?xf32>, %centerX : index, %centerY : index, %iterations : index, %constantValue: f32) +{ + dip.erosion_2d <CONSTANT_PADDING> %inputImage, %kernel, %outputImage, %copymemref, %centerX, %centerY, %iterations, %constantValue: memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, index, index, index, f32 + return +} + +func.func @erosion_2d_replicate_padding(%inputImage : memref<?x?xf32>, %kernel : memref<?x?xf32>, %outputImage : memref<?x?xf32>, %copymemref : memref<?x?xf32>, %centerX : index, %centerY : index, %iterations : index, %constantValue : f32) +{ + dip.erosion_2d <REPLICATE_PADDING> %inputImage, %kernel, %outputImage, %copymemref, %centerX, %centerY, %iterations, %constantValue : memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, index, index, index, f32 + return +} + +func.func @dilation_2d_constant_padding(%inputImage : memref<?x?xf32>, %kernel : memref<?x?xf32>, %outputImage : memref<?x?xf32>, %copymemref : memref<?x?xf32>, %centerX : index, %centerY : index, %iterations : index, %constantValue: f32) +{ + dip.dilation_2d <CONSTANT_PADDING> %inputImage, %kernel, %outputImage, %copymemref, %centerX, %centerY, %iterations, %constantValue : memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, index, index, index, f32 + return +} + +func.func @dilation_2d_replicate_padding(%inputImage : memref<?x?xf32>, %kernel : memref<?x?xf32>, %outputImage : memref<?x?xf32>, %copymemref : memref<?x?xf32>, %centerX : index, %centerY : index, %iterations : index, %constantValue : f32) +{ + dip.dilation_2d <REPLICATE_PADDING> %inputImage, %kernel, %outputImage, %copymemref, %centerX, %centerY, %iterations, %constantValue : memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, index, index, index, f32 + return +} + +func.func @opening_2d_constant_padding(%inputImage : memref<?x?xf32>, %kernel : memref<?x?xf32>, %outputImage : memref<?x?xf32>, %outputImage1 : memref<?x?xf32>, %copymemref : memref<?x?xf32>, %copymemref1 : memref<?x?xf32>, %centerX : index, %centerY : index, %iterations : index, %constantValue: f32) +{ + dip.opening_2d <CONSTANT_PADDING> %inputImage, %kernel, %outputImage, %outputImage1, %copymemref, %copymemref1, %centerX, %centerY, %iterations, %constantValue : memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, index, index, index, f32 + return +} + +func.func @opening_2d_replicate_padding(%inputImage : memref<?x?xf32>, %kernel : memref<?x?xf32>, %outputImage : memref<?x?xf32>, %outputImage1 : memref<?x?xf32>, %copymemref : memref<?x?xf32>, %copymemref1 : memref<?x?xf32>, %centerX : index, %centerY : index, %iterations : index, %constantValue : f32) +{ + dip.opening_2d <REPLICATE_PADDING> %inputImage, %kernel, %outputImage, %outputImage1, %copymemref, %copymemref1, %centerX, %centerY, %iterations, %constantValue : memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, index, index, index, f32 + return +} + +func.func @closing_2d_constant_padding(%inputImage : memref<?x?xf32>, %kernel : memref<?x?xf32>, %outputImage : memref<?x?xf32>, %outputImage1 : memref<?x?xf32>, %copymemref : memref<?x?xf32>, %copymemref1 : memref<?x?xf32>, %centerX : index, %centerY : index, %iterations : index, %constantValue: f32) +{ + dip.closing_2d <CONSTANT_PADDING> %inputImage, %kernel, %outputImage, %outputImage1, %copymemref, %copymemref1, %centerX, %centerY, %iterations, %constantValue : memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, index, index, index, f32 + return +} + +func.func @closing_2d_replicate_padding(%inputImage : memref<?x?xf32>, %kernel : memref<?x?xf32>, %outputImage : memref<?x?xf32>, %outputImage1 : memref<?x?xf32>, %copymemref : memref<?x?xf32>, %copymemref1 : memref<?x?xf32>, %centerX : index, %centerY : index, %iterations : index, %constantValue : f32) +{ + dip.closing_2d <REPLICATE_PADDING> %inputImage, %kernel, %outputImage, %outputImage1, %copymemref, %copymemref1, %centerX, %centerY, %iterations, %constantValue : memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>,memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, index, index, index, f32 + return +} + +func.func @tophat_2d_constant_padding(%inputImage : memref<?x?xf32>, %kernel : memref<?x?xf32>, %outputImage : memref<?x?xf32>, %outputImage1 : memref<?x?xf32>,%outputImage2 : memref<?x?xf32>, %inputImage1 : memref<?x?xf32>, %copymemref : memref<?x?xf32>, %copymemref1 : memref<?x?xf32>, %centerX : index, %centerY : index, %iterations : index, %constantValue: f32) +{ + dip.tophat_2d <CONSTANT_PADDING> %inputImage, %kernel, %outputImage, %outputImage1, %outputImage2, %inputImage1, %copymemref, %copymemref1, %centerX, %centerY, %iterations, %constantValue : memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, index, index, index, f32 + return +} + +func.func @tophat_2d_replicate_padding(%inputImage : memref<?x?xf32>, %kernel : memref<?x?xf32>, %outputImage : memref<?x?xf32>, %outputImage1 : memref<?x?xf32>, %outputImage2 : memref<?x?xf32>, %inputImage1 : memref<?x?xf32>, %copymemref : memref<?x?xf32>, %copymemref1 : memref<?x?xf32>, %centerX : index, %centerY : index, %iterations : index, %constantValue : f32) +{ + dip.tophat_2d <REPLICATE_PADDING> %inputImage, %kernel, %outputImage, %outputImage1, %outputImage2, %inputImage1, %copymemref, %copymemref1, %centerX, %centerY, %iterations, %constantValue : memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, index, index, index, f32 + return +} + +func.func @bottomhat_2d_constant_padding(%inputImage : memref<?x?xf32>, %kernel : memref<?x?xf32>, %outputImage : memref<?x?xf32>, %outputImage1 : memref<?x?xf32>, %outputImage2 : memref<?x?xf32>, %inputImage1 : memref<?x?xf32>, %copymemref : memref<?x?xf32>, %copymemref1 : memref<?x?xf32>, %centerX : index, %centerY : index, %iterations : index, %constantValue: f32) +{ + dip.bottomhat_2d <CONSTANT_PADDING> %inputImage, %kernel, %outputImage, %outputImage1, %outputImage2, %inputImage1, %copymemref, %copymemref1, %centerX, %centerY, %iterations, %constantValue : memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, index, index, index, f32 + return +} + +func.func @bottomhat_2d_replicate_padding(%inputImage : memref<?x?xf32>, %kernel : memref<?x?xf32>, %outputImage : memref<?x?xf32>, %outputImage1 : memref<?x?xf32>, %outputImage2 : memref<?x?xf32>, %inputImage1 : memref<?x?xf32>, %copymemref : memref<?x?xf32>, %copymemref1 : memref<?x?xf32>, %centerX : index, %centerY : index, %iterations : index, %constantValue : f32) +{ + dip.bottomhat_2d <REPLICATE_PADDING> %inputImage, %kernel, %outputImage, %outputImage1, %outputImage2, %inputImage1, %copymemref, %copymemref1, %centerX, %centerY, %iterations, %constantValue : memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, index, index, index, f32 + return +} + +func.func @morphgrad_2d_constant_padding(%inputImage : memref<?x?xf32>, %kernel : memref<?x?xf32>, %outputImage : memref<?x?xf32>, %outputImage1 : memref<?x?xf32>,%outputImage2 : memref<?x?xf32>, %inputImage1 : memref<?x?xf32>, %copymemref : memref<?x?xf32>, %copymemref1 : memref<?x?xf32>, %centerX : index, %centerY : index,%iterations : index, %constantValue: f32) +{ + dip.morphgrad_2d <CONSTANT_PADDING> %inputImage, %kernel, %outputImage, %outputImage1, %outputImage2, %inputImage1, %copymemref, %copymemref1, %centerX, %centerY, %iterations, %constantValue : memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, index, index,index, f32 + return +} + +func.func @morphgrad_2d_replicate_padding(%inputImage : memref<?x?xf32>, %kernel : memref<?x?xf32>, %outputImage : memref<?x?xf32>, %outputImage1 : memref<?x?xf32>,%outputImage2 : memref<?x?xf32>, %inputImage1 : memref<?x?xf32>, %copymemref : memref<?x?xf32>, %copymemref1 : memref<?x?xf32>, %centerX : index, %centerY : index, %iterations : index, %constantValue : f32) +{ + dip.morphgrad_2d <REPLICATE_PADDING> %inputImage, %kernel, %outputImage, %outputImage1,%outputImage2, %inputImage1, %copymemref, %copymemref1, %centerX, %centerY, %iterations, %constantValue : memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, memref<?x?xf32>, index, index, index, f32 + return +} diff --git a/benchmarks/ImageProcessing/BuddyMorph2DBenchmark.cpp b/benchmarks/ImageProcessing/BuddyMorph2DBenchmark.cpp new file mode 100644 index 0000000000000000000000000000000000000000..62f1d1affc3b3ac1bff53416169c5b0fa570a1ae --- /dev/null +++ b/benchmarks/ImageProcessing/BuddyMorph2DBenchmark.cpp @@ -0,0 +1,832 @@ +//===- BuddyMorph2DBenchmark.cpp -------------------------------------------===// +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//===----------------------------------------------------------------------===// +// +// This file implements the benchmark for Morph2D operation. +// +//===----------------------------------------------------------------------===// + +#include "ImageProcessing/Kernels.h" +#include "Utils/Container.h" +#include <benchmark/benchmark.h> +#include <opencv2/opencv.hpp> + +using namespace cv; +using namespace std; + +// Declare the C interface + +extern "C" { +void _mlir_ciface_erosion_2d_constant_padding( + MemRef<float, 2> inputBuddyMorph2D, MemRef<float, 2> *kernelBuddyMorph2D, + MemRef<float, 2> *outputBuddyErosion2D, + MemRef<float, 2> *copyMemRefErosion2D, unsigned int centerX, + unsigned int centerY, unsigned int iterations, float constantValue); + +void _mlir_ciface_erosion_2d_replicate_padding( + MemRef<float, 2> inputBuddyMorph2D, MemRef<float, 2> *kernelBuddyMorph2D, + MemRef<float, 2> *outputBuddyErosion2D, + MemRef<float, 2> *copyMemRefErosion2D, unsigned int centerX, + unsigned int centerY, unsigned int iterations, float constantValue); + +void _mlir_ciface_dilation_2d_constant_padding( + MemRef<float, 2> inputBuddyMorph2D, MemRef<float, 2> *kernelBuddyMorph2D, + MemRef<float, 2> *outputBuddyDilation2D, + MemRef<float, 2> *copyMemRefDilation2D, unsigned int centerX, + unsigned int centerY, unsigned int iterations, float constantValue); + +void _mlir_ciface_dilation_2d_replicate_padding( + MemRef<float, 2> inputBuddyMorph2D, MemRef<float, 2> *kernelBuddyMorph2D, + MemRef<float, 2> *outputBuddyDilation2D, + MemRef<float, 2> *copyMemRefDilation2D, unsigned int centerX, + unsigned int centerY, unsigned int iterations, float constantValue); + +void _mlir_ciface_opening_2d_constant_padding( + MemRef<float, 2> inputBuddyMorph2D, MemRef<float, 2> *kernelBuddyMorph2D, + MemRef<float, 2> *outputBuddyOpening2D, + MemRef<float, 2> *outputBuddyOpening2D1, + MemRef<float, 2> *copyMemRefOpening2D, + MemRef<float, 2> *copyMemRefOpening2D1, unsigned int centerX, + unsigned int centerY, unsigned int iterations, float constantValue); + +void _mlir_ciface_opening_2d_replicate_padding( + MemRef<float, 2> inputBuddyMorph2D, MemRef<float, 2> *kernelBuddyMorph2D, + MemRef<float, 2> *outputBuddyOpening2D, + MemRef<float, 2> *outputBuuddyOpening2D1, + MemRef<float, 2> *copyMemRefOpening2D, + MemRef<float, 2> *copyMemRefOpening2D1, unsigned int centerX, + unsigned int centerY, unsigned int iterations, float constantValue); + +void _mlir_ciface_closing_2d_constant_padding( + MemRef<float, 2> inputBuddyMorph2D, MemRef<float, 2> *kernelBuddyMorph2D, + MemRef<float, 2> *outputBuddyClosing2D, + MemRef<float, 2> *outputBuddyClosing2D1, + MemRef<float, 2> *copyMemRefClosing2D, + MemRef<float, 2> *copyMemRefClosing2D1, unsigned int centerX, + unsigned int centerY, unsigned int iterations, float constantValue); + +void _mlir_ciface_closing_2d_replicate_padding( + MemRef<float, 2> inputBuddyMorph2D, MemRef<float, 2> *kernelBuddyMorph2D, + MemRef<float, 2> *outputBuddyClosing2D, + MemRef<float, 2> *outputBuuddyClosing2D1, + MemRef<float, 2> *copyMemRefClosing2D, + MemRef<float, 2> *copyMemRefClosing2D1, unsigned int centerX, + unsigned int centerY, unsigned int iterations, float constantValue); + +void _mlir_ciface_tophat_2d_constant_padding( + MemRef<float, 2> inputBuddyMorph2D, MemRef<float, 2> *kernelBuddyMorph2D, + MemRef<float, 2> *outputBuddyTopHat2D, + MemRef<float, 2> *outputBuddyTopHat2D1, + MemRef<float, 2> *outputBuddyTopHat2D2, + MemRef<float, 2> *inputBuddyTopHat2D1, MemRef<float, 2> *copyMemRefTopHat2D, + MemRef<float, 2> *copyMemRefTopHat2D1, unsigned int centerX, + unsigned int centerY, unsigned int iterations, float constantValue); + +void _mlir_ciface_tophat_2d_replicate_padding( + MemRef<float, 2> inputBuddyMorph2D, MemRef<float, 2> *kernelBuddyMorph2D, + MemRef<float, 2> *outputBuddyTopHat2D, + MemRef<float, 2> *outputBuddyTopHat2D1, + MemRef<float, 2> *outputBuddyTopHat2D2, + MemRef<float, 2> *inputBuddyTopHat2D1, MemRef<float, 2> *copyMemRefTopHat2D, + MemRef<float, 2> *copyMemRefTopHat2D1, unsigned int centerX, + unsigned int centerY, unsigned int iterations, float constantValue); + +void _mlir_ciface_bottomhat_2d_constant_padding( + MemRef<float, 2> inputBuddyMorph2D, MemRef<float, 2> *kernelBuddyMorph2D, + MemRef<float, 2> *outputBuddyBottomHat2D, + MemRef<float, 2> *outputBuddyBottomHat2D1, + MemRef<float, 2> *outputBuddyBottomHat2D2, + MemRef<float, 2> *inputBuddyBottomHat2D1, + MemRef<float, 2> *copyMemRefBottomHat2D, + MemRef<float, 2> *copyMemRefBottomHat2D1, unsigned int centerX, + unsigned int centerY, unsigned int iterations, float constantValue); + +void _mlir_ciface_bottomhat_2d_replicate_padding( + MemRef<float, 2> inputBuddyMorph2D, MemRef<float, 2> *kernelBuddyMorph2D, + MemRef<float, 2> *outputBuddyBottomHat2D, + MemRef<float, 2> *outputBuddyBottomHat2D1, + MemRef<float, 2> *outputBuddyBottomHat2D2, + MemRef<float, 2> *inputBuddyBottomHat2D1, + MemRef<float, 2> *copyMemRefBottomHat2D, + MemRef<float, 2> *copyMemRefBottomHat2D1, unsigned int centerX, + unsigned int centerY, unsigned int iterations, float constantValue); + +void _mlir_ciface_morphgrad_2d_constant_padding( + MemRef<float, 2> inputBuddyMorph2D, MemRef<float, 2> *kernelBuddyMorph2D, + MemRef<float, 2> *outputBuddyMorphGrad2D, + MemRef<float, 2> *outputBuddyMorphGrad2D1, + MemRef<float, 2> *outputBuddyMorphGrad2D2, + MemRef<float, 2> *inputBuddyMorphGrad2D1, + MemRef<float, 2> *copyMemRefMorphGrad2D, + MemRef<float, 2> *copyMemRefMorphGrad2D1, unsigned int centerX, + unsigned int centerY, unsigned int iterations, float constantValue); + +void _mlir_ciface_morphgrad_2d_replicate_padding( + MemRef<float, 2> inputBuddyMorph2D, MemRef<float, 2> *kernelBuddyMorph2D, + MemRef<float, 2> *outputBuddyMorphGrad2D, + MemRef<float, 2> *outputBuddyMorphGrad2D1, + MemRef<float, 2> *outputBuddyMorphGrad2D2, + MemRef<float, 2> *inputBuddyMorphGrad2D1, + MemRef<float, 2> *copyMemRefMorphGrad2D, + MemRef<float, 2> *copyMemRefMorphGrad2D1, unsigned int centerX, + unsigned int centerY, unsigned int iterations, float constantValue); +} + +// Declare input image and kernel. +Mat inputImageBuddyMorph2D, kernelBuddyMorph2DMat; + +// Define the kernel size. +int kernelRowsBuddyMorph2D, kernelColsBuddyMorph2D; + +// Define the output size. +int outputRowsBuddyMorph2D, outputColsBuddyMorph2D; + +// Define sizes of input, kernel, and output. +intptr_t sizesInputBuddyMorph2D[2]; +intptr_t sizesKernelBuddyMorph2D[2]; +intptr_t sizesOutputBuddyMorph2D[2]; + +// Declare Boundary Options supported. +enum BoundaryOption { constant_padding, replicate_padding }; + +// Define Boundary option selected. +BoundaryOption BoundaryType1; + +void initializeBuddyMorph2D(char **argv) { + inputImageBuddyMorph2D = imread(argv[1], IMREAD_GRAYSCALE); + kernelBuddyMorph2DMat = + Mat(get<1>(kernelMap[argv[2]]), get<2>(kernelMap[argv[2]]), CV_32FC1, + get<0>(kernelMap[argv[2]])); + + kernelRowsBuddyMorph2D = kernelBuddyMorph2DMat.rows; + kernelColsBuddyMorph2D = kernelBuddyMorph2DMat.cols; + + outputRowsBuddyMorph2D = inputImageBuddyMorph2D.rows; + outputColsBuddyMorph2D = inputImageBuddyMorph2D.cols; + + sizesInputBuddyMorph2D[0] = inputImageBuddyMorph2D.rows; + sizesInputBuddyMorph2D[1] = inputImageBuddyMorph2D.cols; + + sizesKernelBuddyMorph2D[0] = kernelRowsBuddyMorph2D; + sizesKernelBuddyMorph2D[1] = kernelColsBuddyMorph2D; + + sizesOutputBuddyMorph2D[0] = outputRowsBuddyMorph2D; + sizesOutputBuddyMorph2D[1] = outputColsBuddyMorph2D; + + if (static_cast<string>(argv[3]) == "REPLICATE_PADDING") { + BoundaryType1 = replicate_padding; + } else { + BoundaryType1 = constant_padding; + } +} +MemRef<float, 2> inputBuddyMorph2D(inputImageBuddyMorph2D, + sizesInputBuddyMorph2D); +MemRef<float, 2> kernelBuddyMorph2D(kernelBuddyMorph2DMat, + sizesKernelBuddyMorph2D); +static void Buddy_Erosion2D_Constant_Padding(benchmark::State &state) { + // Define the MemRef descriptor for input, kernel, and output. + + MemRef<float, 2> outputBuddyErosion2D(sizesOutputBuddyMorph2D); + MemRef<float, 2> copyMemRefErosion2D(sizesOutputBuddyMorph2D, 256.f); + + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) { + _mlir_ciface_erosion_2d_constant_padding( + inputBuddyMorph2D, &kernelBuddyMorph2D, &outputBuddyErosion2D, + ©MemRefErosion2D, 1 /* Center X */, 1 /* Center Y */, 1, + 0.0f /* Constant Value */); + } + } +} + +static void Buddy_Erosion2D_Replicate_Padding(benchmark::State &state) { + // Define the MemRef descriptor for input, kernel, and output. + MemRef<float, 2> outputBuddyErosion2D(sizesOutputBuddyMorph2D); + MemRef<float, 2> copyMemRefErosion2D(sizesOutputBuddyMorph2D, 256.f); + + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) { + _mlir_ciface_erosion_2d_replicate_padding( + inputBuddyMorph2D, &kernelBuddyMorph2D, &outputBuddyErosion2D, + ©MemRefErosion2D, 1 /* Center X */, 1 /* Center Y */, 1, + 0.0f /* Constant Value */); + } + } +} + +static void Buddy_Dilation2D_Constant_Padding(benchmark::State &state) { + // Define the MemRef descriptor for input, kernel, and output. + MemRef<float, 2> outputBuddyDilation2D(sizesOutputBuddyMorph2D); + MemRef<float, 2> copyMemRefDilation2D(sizesOutputBuddyMorph2D, -1.f); + + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) { + _mlir_ciface_dilation_2d_constant_padding( + inputBuddyMorph2D, &kernelBuddyMorph2D, &outputBuddyDilation2D, + ©MemRefDilation2D, 1 /* Center X */, 1 /* Center Y */, 1, + 0.0f /* Constant Value */); + } + } +} + +static void Buddy_Dilation2D_Replicate_Padding(benchmark::State &state) { + // Define the MemRef descriptor for input, kernel, and output. + MemRef<float, 2> outputBuddyDilation2D(sizesOutputBuddyMorph2D); + MemRef<float, 2> copyMemRefDilation2D(sizesOutputBuddyMorph2D, -1.f); + + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) { + _mlir_ciface_dilation_2d_replicate_padding( + inputBuddyMorph2D, &kernelBuddyMorph2D, &outputBuddyDilation2D, + ©MemRefDilation2D, 1 /* Center X */, 1 /* Center Y */, 1, + 0.0f /* Constant Value */); + } + } +} + +static void Buddy_Opening2D_Constant_Padding(benchmark::State &state) { + // Define the MemRef descriptor for input, kernel, and output. + + MemRef<float, 2> outputBuddyOpening2D(sizesOutputBuddyMorph2D); + MemRef<float, 2> outputBuddyOpening2D1(sizesOutputBuddyMorph2D); + MemRef<float, 2> copyMemRefOpening2D(sizesOutputBuddyMorph2D, -1.f); + MemRef<float, 2> copyMemRefOpening2D1(sizesOutputBuddyMorph2D, 256.f); + + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) { + _mlir_ciface_opening_2d_constant_padding( + inputBuddyMorph2D, &kernelBuddyMorph2D, &outputBuddyOpening2D, + &outputBuddyOpening2D1, ©MemRefOpening2D, ©MemRefOpening2D1, + 1 /* Center X */, 1 /* Center Y */, 1, 0.0f /* Constant Value */); + } + } +} + +static void Buddy_Opening2D_Replicate_Padding(benchmark::State &state) { + // Define the MemRef descriptor for input, kernel, and output. + + MemRef<float, 2> outputBuddyOpening2D(sizesOutputBuddyMorph2D); + MemRef<float, 2> outputBuddyOpening2D1(sizesOutputBuddyMorph2D); + MemRef<float, 2> copyMemRefOpening2D(sizesOutputBuddyMorph2D, -1.f); + MemRef<float, 2> copyMemRefOpening2D1(sizesOutputBuddyMorph2D, 256.f); + + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) { + _mlir_ciface_opening_2d_replicate_padding( + inputBuddyMorph2D, &kernelBuddyMorph2D, &outputBuddyOpening2D, + &outputBuddyOpening2D1, ©MemRefOpening2D, ©MemRefOpening2D1, + 1 /* Center X */, 1 /* Center Y */, 1, 0.0f /* Constant Value */); + } + } +} + +static void Buddy_Closing2D_Constant_Padding(benchmark::State &state) { + // Define the MemRef descriptor for input, kernel, and output. + + MemRef<float, 2> outputBuddyClosing2D(sizesOutputBuddyMorph2D); + MemRef<float, 2> outputBuddyClosing2D1(sizesOutputBuddyMorph2D); + MemRef<float, 2> copyMemRefClosing2D(sizesOutputBuddyMorph2D, -1.f); + MemRef<float, 2> copyMemRefClosing2D1(sizesOutputBuddyMorph2D, 256.f); + + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) { + _mlir_ciface_closing_2d_constant_padding( + inputBuddyMorph2D, &kernelBuddyMorph2D, &outputBuddyClosing2D, + &outputBuddyClosing2D1, ©MemRefClosing2D, ©MemRefClosing2D1, + 1 /* Center X */, 1 /* Center Y */, 1, 0.0f /* Constant Value */); + } + } +} + +static void Buddy_Closing2D_Replicate_Padding(benchmark::State &state) { + // Define the MemRef descriptor for input, kernel, and output. + + MemRef<float, 2> outputBuddyClosing2D(sizesOutputBuddyMorph2D); + MemRef<float, 2> outputBuddyClosing2D1(sizesOutputBuddyMorph2D); + MemRef<float, 2> copyMemRefClosing2D(sizesOutputBuddyMorph2D, -1.f); + MemRef<float, 2> copyMemRefClosing2D1(sizesOutputBuddyMorph2D, 256.f); + + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) { + _mlir_ciface_closing_2d_replicate_padding( + inputBuddyMorph2D, &kernelBuddyMorph2D, &outputBuddyClosing2D, + &outputBuddyClosing2D1, ©MemRefClosing2D, ©MemRefClosing2D1, + 1 /* Center X */, 1 /* Center Y */, 1, 0.0f /* Constant Value */); + } + } +} + +static void Buddy_TopHat2D_Constant_Padding(benchmark::State &state) { + // Define the MemRef descriptor for input, kernel, and output. + + MemRef<float, 2> inputBuddyTopHat2D1(sizesInputBuddyMorph2D); + MemRef<float, 2> outputBuddyTopHat2D(sizesOutputBuddyMorph2D); + MemRef<float, 2> outputBuddyTopHat2D1(sizesOutputBuddyMorph2D); + MemRef<float, 2> outputBuddyTopHat2D2(sizesOutputBuddyMorph2D); + MemRef<float, 2> copyMemRefTopHat2D(sizesOutputBuddyMorph2D, 256.f); + MemRef<float, 2> copyMemRefTopHat2D1(sizesOutputBuddyMorph2D, -1.f); + + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) { + _mlir_ciface_tophat_2d_constant_padding( + inputBuddyMorph2D, &kernelBuddyMorph2D, &outputBuddyTopHat2D, + &outputBuddyTopHat2D1, &outputBuddyTopHat2D2, &inputBuddyTopHat2D1, + ©MemRefTopHat2D, ©MemRefTopHat2D1, 1 /* Center X */, + 1 /* Center Y */, 1, 0.0f /* Constant Value */); + } + } +} + +static void Buddy_TopHat2D_Replicate_Padding(benchmark::State &state) { + // Define the MemRef descriptor for input, kernel, and output. + MemRef<float, 2> inputBuddyTopHat2D1(sizesInputBuddyMorph2D); + MemRef<float, 2> outputBuddyTopHat2D(sizesOutputBuddyMorph2D); + MemRef<float, 2> outputBuddyTopHat2D1(sizesOutputBuddyMorph2D); + MemRef<float, 2> outputBuddyTopHat2D2(sizesOutputBuddyMorph2D); + MemRef<float, 2> copyMemRefTopHat2D(sizesOutputBuddyMorph2D, 256.f); + MemRef<float, 2> copyMemRefTopHat2D1(sizesOutputBuddyMorph2D, -1.f); + + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) { + _mlir_ciface_tophat_2d_replicate_padding( + inputBuddyMorph2D, &kernelBuddyMorph2D, &outputBuddyTopHat2D, + &outputBuddyTopHat2D1, &outputBuddyTopHat2D2, &inputBuddyTopHat2D1, + ©MemRefTopHat2D, ©MemRefTopHat2D1, 1 /* Center X */, + 1 /* Center Y */, 1, 0.0f /* Constant Value */); + } + } +} + +static void Buddy_BottomHat2D_Constant_Padding(benchmark::State &state) { + // Define the MemRef descriptor for input, kernel, and output. + MemRef<float, 2> inputBuddyBottomHat2D1(sizesInputBuddyMorph2D); + MemRef<float, 2> outputBuddyBottomHat2D(sizesOutputBuddyMorph2D); + MemRef<float, 2> outputBuddyBottomHat2D1(sizesOutputBuddyMorph2D); + MemRef<float, 2> outputBuddyBottomHat2D2(sizesOutputBuddyMorph2D); + MemRef<float, 2> copyMemRefBottomHat2D(sizesOutputBuddyMorph2D, 256.f); + MemRef<float, 2> copyMemRefBottomHat2D1(sizesOutputBuddyMorph2D, -1.f); + + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) { + _mlir_ciface_bottomhat_2d_constant_padding( + inputBuddyMorph2D, &kernelBuddyMorph2D, &outputBuddyBottomHat2D, + &outputBuddyBottomHat2D1, &outputBuddyBottomHat2D2, + &inputBuddyBottomHat2D1, ©MemRefBottomHat2D, + ©MemRefBottomHat2D1, 1 /* Center X */, 1 /* Center Y */, 1, + 0.0f /* Constant Value */); + } + } +} + +static void Buddy_BottomHat2D_Replicate_Padding(benchmark::State &state) { + // Define the MemRef descriptor for input, kernel, and output. + MemRef<float, 2> inputBuddyBottomHat2D1(sizesInputBuddyMorph2D); + MemRef<float, 2> outputBuddyBottomHat2D(sizesOutputBuddyMorph2D); + MemRef<float, 2> outputBuddyBottomHat2D1(sizesOutputBuddyMorph2D); + MemRef<float, 2> outputBuddyBottomHat2D2(sizesOutputBuddyMorph2D); + MemRef<float, 2> copyMemRefBottomHat2D(sizesOutputBuddyMorph2D, 256.f); + MemRef<float, 2> copyMemRefBottomHat2D1(sizesOutputBuddyMorph2D, -1.f); + + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) { + _mlir_ciface_bottomhat_2d_replicate_padding( + inputBuddyMorph2D, &kernelBuddyMorph2D, &outputBuddyBottomHat2D, + &outputBuddyBottomHat2D1, &outputBuddyBottomHat2D2, + &inputBuddyBottomHat2D1, ©MemRefBottomHat2D, + ©MemRefBottomHat2D1, 1 /* Center X */, 1 /* Center Y */, 1, + 0.0f /* Constant Value */); + } + } +} + +static void Buddy_MorphGrad2D_Constant_Padding(benchmark::State &state) { + // Define the MemRef descriptor for input, kernel, and output. + MemRef<float, 2> inputBuddyMorphGrad2D1(sizesInputBuddyMorph2D); + MemRef<float, 2> outputBuddyMorphGrad2D(sizesOutputBuddyMorph2D); + MemRef<float, 2> outputBuddyMorphGrad2D1(sizesOutputBuddyMorph2D); + MemRef<float, 2> outputBuddyMorphGrad2D2(sizesOutputBuddyMorph2D); + MemRef<float, 2> copyMemRefMorphGrad2D(sizesOutputBuddyMorph2D, 256.f); + MemRef<float, 2> copyMemRefMorphGrad2D1(sizesOutputBuddyMorph2D, -1.f); + + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) { + _mlir_ciface_morphgrad_2d_constant_padding( + inputBuddyMorph2D, &kernelBuddyMorph2D, &outputBuddyMorphGrad2D, + &outputBuddyMorphGrad2D1, &outputBuddyMorphGrad2D2, + &inputBuddyMorphGrad2D1, ©MemRefMorphGrad2D, + ©MemRefMorphGrad2D1, 1 /* Center X */, 1 /* Center Y */, 1, + 0.0f /* Constant Value */); + } + } +} + +static void Buddy_MorphGrad2D_Replicate_Padding(benchmark::State &state) { + // Define the MemRef descriptor for input, kernel, and output. + MemRef<float, 2> inputBuddyMorphGrad2D1(sizesInputBuddyMorph2D); + MemRef<float, 2> outputBuddyMorphGrad2D(sizesOutputBuddyMorph2D); + MemRef<float, 2> outputBuddyMorphGrad2D1(sizesOutputBuddyMorph2D); + MemRef<float, 2> outputBuddyMorphGrad2D2(sizesOutputBuddyMorph2D); + MemRef<float, 2> copyMemRefMorphGrad2D(sizesOutputBuddyMorph2D, 256.f); + MemRef<float, 2> copyMemRefMorphGrad2D1(sizesOutputBuddyMorph2D, -1.f); + + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) { + _mlir_ciface_morphgrad_2d_replicate_padding( + inputBuddyMorph2D, &kernelBuddyMorph2D, &outputBuddyMorphGrad2D, + &outputBuddyMorphGrad2D1, &outputBuddyMorphGrad2D2, + &inputBuddyMorphGrad2D1, ©MemRefMorphGrad2D, + ©MemRefMorphGrad2D1, 1 /* Center X */, 1 /* Center Y */, 1, + 0.0f /* Constant Value */); + } + } +} + +// Register benchmarking function. +void registerBenchmarkBuddyErosion2D() { + if (BoundaryType1 == replicate_padding) { + BENCHMARK(Buddy_Erosion2D_Replicate_Padding)->Arg(1); + } else { + BENCHMARK(Buddy_Erosion2D_Constant_Padding)->Arg(1); + } +} + +// Register benchmarking function. +void registerBenchmarkBuddyDilation2D() { + if (BoundaryType1 == replicate_padding) { + BENCHMARK(Buddy_Dilation2D_Replicate_Padding)->Arg(1); + } else { + BENCHMARK(Buddy_Dilation2D_Constant_Padding)->Arg(1); + } +} + +// Register benchmarking function. +void registerBenchmarkBuddyOpening2D() { + if (BoundaryType1 == replicate_padding) { + BENCHMARK(Buddy_Opening2D_Replicate_Padding)->Arg(1); + } else { + BENCHMARK(Buddy_Opening2D_Constant_Padding)->Arg(1); + } +} + +// Register benchmarking function. +void registerBenchmarkBuddyClosing2D() { + if (BoundaryType1 == replicate_padding) { + BENCHMARK(Buddy_Closing2D_Replicate_Padding)->Arg(1); + } else { + BENCHMARK(Buddy_Closing2D_Constant_Padding)->Arg(1); + } +} + +// Register benchmarking function. +void registerBenchmarkBuddyTopHat2D() { + if (BoundaryType1 == replicate_padding) { + BENCHMARK(Buddy_TopHat2D_Replicate_Padding)->Arg(1); + } else { + BENCHMARK(Buddy_TopHat2D_Constant_Padding)->Arg(1); + } +} + +// Register benchmarking function. +void registerBenchmarkBuddyBottomHat2D() { + if (BoundaryType1 == replicate_padding) { + BENCHMARK(Buddy_BottomHat2D_Replicate_Padding)->Arg(1); + } else { + BENCHMARK(Buddy_BottomHat2D_Constant_Padding)->Arg(1); + } +} + +// Register benchmarking function. +void registerBenchmarkBuddyMorphGrad2D() { + if (BoundaryType1 == replicate_padding) { + BENCHMARK(Buddy_MorphGrad2D_Replicate_Padding)->Arg(1); + } else { + BENCHMARK(Buddy_MorphGrad2D_Constant_Padding)->Arg(1); + } +} + +// Generate result image. +void generateResultBuddyErosion2D(char **argv) { + // Define the MemRef descriptor for input, kernel, and output. + MemRef<float, 2> input = inputBuddyMorph2D; + MemRef<float, 2> kernel = kernelBuddyMorph2D; + MemRef<float, 2> output(sizesOutputBuddyMorph2D); + MemRef<float, 2> copyMemRef(sizesOutputBuddyMorph2D, 256.f); + // Run the 2D Erosionelation. + if (static_cast<string>(argv[3]) == "REPLICATE_PADDING") { + _mlir_ciface_erosion_2d_replicate_padding( + input, &kernel, &output, ©MemRef, 1 /* Center X */, + 1 /* Center Y */, 1, 0.0f /* Constant Value */); + } else { + _mlir_ciface_erosion_2d_constant_padding( + input, &kernel, &output, ©MemRef, 1 /* Center X */, + 1 /* Center Y */, 1, 0.0f /* Constant Value */); + } + + // Define a cv::Mat with the output of the Erosionelation. + Mat outputImage(outputRowsBuddyMorph2D, outputColsBuddyMorph2D, CV_32FC1, + output.getData()); + + // Choose a PNG compression level + vector<int> compressionParams; + compressionParams.push_back(IMWRITE_PNG_COMPRESSION); + compressionParams.push_back(9); + + // Write output to PNG. + bool result = false; + try { + result = + imwrite("ResultBuddyErosion2D.png", outputImage, compressionParams); + } catch (const cv::Exception &ex) { + fprintf(stderr, "Exception converting image to PNG format: %s\n", + ex.what()); + } + if (result) + cout << "Saved PNG file." << endl; + else + cout << "ERROR: Can't save PNG file." << endl; +} + +// Generate result image. +void generateResultBuddyDilation2D(char **argv) { + // Define the MemRef descriptor for input, kernel, and output. + MemRef<float, 2> input = inputBuddyMorph2D; + MemRef<float, 2> kernel = kernelBuddyMorph2D; + MemRef<float, 2> output(sizesOutputBuddyMorph2D); + MemRef<float, 2> copymemref(sizesOutputBuddyMorph2D, -1.f); + // Run the 2D Dilationelation. + if (static_cast<string>(argv[3]) == "REPLICATE_PADDING") { + _mlir_ciface_dilation_2d_replicate_padding( + input, &kernel, &output, ©memref, 1 /* Center X */, + 1 /* Center Y */, 1, 0.0f /* Constant Value */); + } else { + _mlir_ciface_dilation_2d_constant_padding( + input, &kernel, &output, ©memref, 1 /* Center X */, + 1 /* Center Y */, 1, 0.0f /* Constant Value */); + } + + // Define a cv::Mat with the output of the Dilationelation. + Mat outputImage(outputRowsBuddyMorph2D, outputColsBuddyMorph2D, CV_32FC1, + output.getData()); + + // Choose a PNG compression level + vector<int> compressionParams; + compressionParams.push_back(IMWRITE_PNG_COMPRESSION); + compressionParams.push_back(9); + + // Write output to PNG. + bool result = false; + try { + result = + imwrite("ResultBuddyDilation2D.png", outputImage, compressionParams); + } catch (const cv::Exception &ex) { + fprintf(stderr, "Exception converting image to PNG format: %s\n", + ex.what()); + } + if (result) + cout << "Saved PNG file." << endl; + else + cout << "ERROR: Can't save PNG file." << endl; +} + +// Generate result image. +void generateResultBuddyOpening2D(char **argv) { + // Define the MemRef descriptor for input, kernel, and output. + MemRef<float, 2> input = inputBuddyMorph2D; + MemRef<float, 2> kernel = kernelBuddyMorph2D; + MemRef<float, 2> output(sizesOutputBuddyMorph2D); + MemRef<float, 2> output1(sizesOutputBuddyMorph2D); + MemRef<float, 2> copymemref(sizesOutputBuddyMorph2D, -1.f); + MemRef<float, 2> copymemref1(sizesOutputBuddyMorph2D, 256.f); + // Run the 2D Opening operation + if (static_cast<string>(argv[3]) == "REPLICATE_PADDING") { + _mlir_ciface_opening_2d_replicate_padding( + input, &kernel, &output, &output1, ©memref, ©memref1, + 1 /* Center X */, 1 /* Center Y */, 1, 0.0f /* Constant Value */); + } else { + _mlir_ciface_opening_2d_constant_padding( + input, &kernel, &output, &output1, ©memref, ©memref1, + 1 /* Center X */, 1 /* Center Y */, 1, 0.0f /* Constant Value */); + } + + // Define a cv::Mat with the output of the Opening + Mat outputImage(outputRowsBuddyMorph2D, outputColsBuddyMorph2D, CV_32FC1, + output.getData()); + + // Choose a PNG compression level + vector<int> compressionParams; + compressionParams.push_back(IMWRITE_PNG_COMPRESSION); + compressionParams.push_back(9); + + // Write output to PNG. + bool result = false; + try { + result = + imwrite("ResultBuddyOpening2D.png", outputImage, compressionParams); + } catch (const cv::Exception &ex) { + fprintf(stderr, "Exception converting image to PNG format: %s\n", + ex.what()); + } + if (result) + cout << "Saved PNG file." << endl; + else + cout << "ERROR: Can't save PNG file." << endl; +} + +// Generate result image. +void generateResultBuddyClosing2D(char **argv) { + // Define the MemRef descriptor for input, kernel, and output. + MemRef<float, 2> input = inputBuddyMorph2D; + MemRef<float, 2> kernel = kernelBuddyMorph2D; + MemRef<float, 2> output(sizesOutputBuddyMorph2D); + MemRef<float, 2> output1(sizesOutputBuddyMorph2D); + MemRef<float, 2> copymemref(sizesOutputBuddyMorph2D, -1.f); + MemRef<float, 2> copymemref1(sizesOutputBuddyMorph2D, 256.f); + // Run the 2D Closing operation + if (static_cast<string>(argv[3]) == "REPLICATE_PADDING") { + _mlir_ciface_closing_2d_replicate_padding( + input, &kernel, &output, &output1, ©memref, ©memref1, + 1 /* Center X */, 1 /* Center Y */, 1, 0.0f /* Constant Value */); + } else { + _mlir_ciface_closing_2d_constant_padding( + input, &kernel, &output, &output1, ©memref, ©memref1, + 1 /* Center X */, 1 /* Center Y */, 1, 0.0f /* Constant Value */); + } + + // Define a cv::Mat with the output of the Closing + Mat outputImage(outputRowsBuddyMorph2D, outputColsBuddyMorph2D, CV_32FC1, + output.getData()); + + // Choose a PNG compression level + vector<int> compressionParams; + compressionParams.push_back(IMWRITE_PNG_COMPRESSION); + compressionParams.push_back(9); + + // Write output to PNG. + bool result = false; + try { + result = + imwrite("ResultBuddyClosing2D.png", outputImage, compressionParams); + } catch (const cv::Exception &ex) { + fprintf(stderr, "Exception converting image to PNG format: %s\n", + ex.what()); + } + if (result) + cout << "Saved PNG file." << endl; + else + cout << "ERROR: Can't save PNG file." << endl; +} + +// Generate result image. +void generateResultBuddyTopHat2D(char **argv) { + // Define the MemRef descriptor for input, kernel, and output. + MemRef<float, 2> input = inputBuddyMorph2D; + MemRef<float, 2> kernel = kernelBuddyMorph2D; + MemRef<float, 2> output(sizesOutputBuddyMorph2D); + MemRef<float, 2> output1(sizesOutputBuddyMorph2D); + MemRef<float, 2> output2(sizesOutputBuddyMorph2D); + MemRef<float, 2> input1(sizesOutputBuddyMorph2D); + MemRef<float, 2> copymemref(sizesOutputBuddyMorph2D, 256.f); + MemRef<float, 2> copymemref1(sizesOutputBuddyMorph2D, -1.f); + // Run the 2D TopHat operation + if (static_cast<string>(argv[3]) == "REPLICATE_PADDING") { + _mlir_ciface_tophat_2d_replicate_padding( + input, &kernel, &output, &output1, &output2, &input1, ©memref, + ©memref1, 1 /* Center X */, 1 /* Center Y */, 1, + 0.0f /* Constant Value */); + } else { + _mlir_ciface_tophat_2d_constant_padding( + input, &kernel, &output, &output1, &output2, &input1, ©memref, + ©memref1, 1 /* Center X */, 1 /* Center Y */, 1, + 0.0f /* Constant Value */); + } + + // Define a cv::Mat with the output of the TopHat + Mat outputImage(outputRowsBuddyMorph2D, outputColsBuddyMorph2D, CV_32FC1, + output.getData()); + + // Choose a PNG compression level + vector<int> compressionParams; + compressionParams.push_back(IMWRITE_PNG_COMPRESSION); + compressionParams.push_back(9); + + // Write output to PNG. + bool result = false; + try { + result = imwrite("ResultBuddyTopHat2D.png", outputImage, compressionParams); + } catch (const cv::Exception &ex) { + fprintf(stderr, "Exception converting image to PNG format: %s\n", + ex.what()); + } + if (result) + cout << "Saved PNG file." << endl; + else + cout << "ERROR: Can't save PNG file." << endl; +} + +// Generate result image. +void generateResultBuddyBottomHat2D(char **argv) { + // Define the MemRef descriptor for input, kernel, and output. + MemRef<float, 2> input = inputBuddyMorph2D; + MemRef<float, 2> kernel = kernelBuddyMorph2D; + MemRef<float, 2> output(sizesOutputBuddyMorph2D); + MemRef<float, 2> output1(sizesOutputBuddyMorph2D); + MemRef<float, 2> output2(sizesOutputBuddyMorph2D); + MemRef<float, 2> input1(sizesOutputBuddyMorph2D); + MemRef<float, 2> copymemref(sizesOutputBuddyMorph2D, 256.f); + MemRef<float, 2> copymemref1(sizesOutputBuddyMorph2D, -1.f); + // Run the 2D BottomHat operation + if (static_cast<string>(argv[3]) == "REPLICATE_PADDING") { + _mlir_ciface_bottomhat_2d_replicate_padding( + input, &kernel, &output, &output1, &output2, &input1, ©memref, + ©memref1, 1 /* Center X */, 1 /* Center Y */, 1, + 0.0f /* Constant Value */); + } else { + _mlir_ciface_bottomhat_2d_constant_padding( + input, &kernel, &output, &output1, &output2, &input1, ©memref, + ©memref1, 1 /* Center X */, 1 /* Center Y */, 1, + 0.0f /* Constant Value */); + } + + // Define a cv::Mat with the output of the BottomHat + Mat outputImage(outputRowsBuddyMorph2D, outputColsBuddyMorph2D, CV_32FC1, + output.getData()); + + // Choose a PNG compression level + vector<int> compressionParams; + compressionParams.push_back(IMWRITE_PNG_COMPRESSION); + compressionParams.push_back(9); + + // Write output to PNG. + bool result = false; + try { + result = + imwrite("ResultBuddyBottomHat2D.png", outputImage, compressionParams); + } catch (const cv::Exception &ex) { + fprintf(stderr, "Exception converting image to PNG format: %s\n", + ex.what()); + } + if (result) + cout << "Saved PNG file." << endl; + else + cout << "ERROR: Can't save PNG file." << endl; +} + +// Generate result image. +void generateResultBuddyMorphGrad2D(char **argv) { + // Define the MemRef descriptor for input, kernel, and output. + MemRef<float, 2> input = inputBuddyMorph2D; + MemRef<float, 2> kernel = kernelBuddyMorph2D; + MemRef<float, 2> output(sizesOutputBuddyMorph2D); + MemRef<float, 2> output1(sizesOutputBuddyMorph2D); + MemRef<float, 2> output2(sizesOutputBuddyMorph2D); + MemRef<float, 2> input1(sizesOutputBuddyMorph2D); + MemRef<float, 2> copymemref(sizesOutputBuddyMorph2D, 256.f); + MemRef<float, 2> copymemref1(sizesOutputBuddyMorph2D, -1.f); + // Run the 2D MorphGrad operation + if (static_cast<string>(argv[3]) == "REPLICATE_PADDING") { + _mlir_ciface_morphgrad_2d_replicate_padding( + input, &kernel, &output, &output1, &output2, &input1, ©memref, + ©memref1, 1 /* Center X */, 1 /* Center Y */, 1, + 0.0f /* Constant Value */); + } else { + _mlir_ciface_morphgrad_2d_constant_padding( + input, &kernel, &output, &output1, &output2, &input1, ©memref, + ©memref1, 1 /* Center X */, 1 /* Center Y */, 1, + 0.0f /* Constant Value */); + } + + // Define a cv::Mat with the output of the MorphGrad + Mat outputImage(outputRowsBuddyMorph2D, outputRowsBuddyMorph2D, CV_32FC1, + output.getData()); + + // Choose a PNG compression level + vector<int> compressionParams; + compressionParams.push_back(IMWRITE_PNG_COMPRESSION); + compressionParams.push_back(9); + + // Write output to PNG. + bool result = false; + try { + result = + imwrite("ResultBuddyMorphGrad2D.png", outputImage, compressionParams); + } catch (const cv::Exception &ex) { + fprintf(stderr, "Exception converting image to PNG format: %s\n", + ex.what()); + } + if (result) + cout << "Saved PNG file." << endl; + else + cout << "ERROR: Can't save PNG file." << endl; +} diff --git a/benchmarks/ImageProcessing/CMakeLists.txt b/benchmarks/ImageProcessing/CMakeLists.txt index 5d8125b7a92fb34c5303d49b48bab44f701268d9..286c01bf3498ce0f2034fd8ebede9fc44f8189e8 100644 --- a/benchmarks/ImageProcessing/CMakeLists.txt +++ b/benchmarks/ImageProcessing/CMakeLists.txt @@ -102,6 +102,22 @@ add_custom_command(OUTPUT buddy-corr2d.o add_library(BuddyCorr2D STATIC buddy-corr2d.o) set_target_properties(BuddyCorr2D PROPERTIES LINKER_LANGUAGE CXX) +add_custom_command(OUTPUT buddy-morph2d.o + COMMAND ${BUDDY_OPT_BUILD_DIR}/bin/buddy-opt + ${BUDDY_SOURCE_DIR}/benchmarks/ImageProcessing/BuddyMorph2D.mlir + -lower-dip="DIP-strip-mining=${SPLITING_SIZE}" + -lower-affine -convert-scf-to-cf -convert-vector-to-llvm + --llvm-request-c-wrappers + -convert-memref-to-llvm -convert-func-to-llvm + -reconcile-unrealized-casts | + ${LLVM_MLIR_BINARY_DIR}/mlir-translate --mlir-to-llvmir | + ${LLVM_MLIR_BINARY_DIR}/llc -mtriple=${BUDDY_OPT_TRIPLE} + -mattr=${BUDDY_OPT_ATTR} --filetype=obj + -o ${BUDDY_BINARY_DIR}/../benchmarks/ImageProcessing/buddy-morph2d.o +) +add_library(BuddyMorph2D STATIC buddy-morph2d.o) +set_target_properties(BuddyMorph2D PROPERTIES LINKER_LANGUAGE CXX) + #------------------------------------------------------------------------------- # Image Processing Benchmark Target #------------------------------------------------------------------------------- @@ -113,6 +129,8 @@ add_executable(image-processing-benchmark MLIRConv2DBenchmark.cpp BuddyConv2DBenchmark.cpp BuddyCorr2DBenchmark.cpp + BuddyMorph2DBenchmark.cpp + OpenCVMorph2DBenchmark.cpp ) target_include_directories(image-processing-benchmark @@ -127,6 +145,7 @@ target_link_libraries(image-processing-benchmark MLIRConv2D BuddyConv2D BuddyCorr2D + BuddyMorph2D Container PNGImage ) diff --git a/benchmarks/ImageProcessing/Main.cpp b/benchmarks/ImageProcessing/Main.cpp index 787bd75a2bb38f0ea281efebfc640b677396d4e2..83d949841582cceaf1070de3574e848014e543b6 100644 --- a/benchmarks/ImageProcessing/Main.cpp +++ b/benchmarks/ImageProcessing/Main.cpp @@ -24,27 +24,58 @@ void initializeMLIRConv2D(char **); void initializeBuddyConv2D(char **); void initializeBuddyCorr2D(char **); +void initializeBuddyMorph2D(char **); +void initializeOpenCVMorph2D(char **); void initializeOpenCVFilter2D(char **); void initializeEigenConvolve2D(char **); void generateResultBuddyConv2D(char **); void generateResultBuddyCorr2D(char **); +void generateResultBuddyErosion2D(char **); +void generateResultBuddyOpening2D(char **); +void generateResultBuddyClosing2D(char **); +void generateResultBuddyTopHat2D(char **); +void generateResultBuddyBottomHat2D(char **); +void generateResultBuddyMorphGrad2D(char **); +void generateResultBuddyDilation2D(char **); +void generateResultOpenCVErode2D(); +void generateResultOpenCVDilate2D(); void generateResultOpenCVFilter2D(); +void generateResultOpenCVOpening2D(); +void generateResultOpenCVClosing2D(); +void generateResultOpenCVTopHat2D(); +void generateResultOpenCVBottomHat2D(); +void generateResultOpenCVMorphGrad2D(); void generateResultEigenConvolve2D(); void registerBenchmarkBuddyCorr2D(); +void registerBenchmarkBuddyErosion2D(); +void registerBenchmarkBuddyDilation2D(); +void registerBenchmarkBuddyOpening2D(); +void registerBenchmarkBuddyClosing2D(); +void registerBenchmarkBuddyTopHat2D(); +void registerBenchmarkBuddyBottomHat2D(); +void registerBenchmarkBuddyMorphGrad2D(); +void registerBenchmarkOpenCVErode2D(); +void registerBenchmarkOpenCVDilate2D(); +void registerBenchmarkOpenCVOpening2D(); +void registerBenchmarkOpenCVClosing2D(); +void registerBenchmarkOpenCVTopHat2D(); +void registerBenchmarkOpenCVBottomHat2D(); +void registerBenchmarkOpenCVMorphGrad2D(); void registerBenchmarkOpenCVFilter2D(); // Run benchmarks. int main(int argc, char **argv) { - if (argc != 4) { + if (argc != 5) { throw std::invalid_argument( "Wrong format of command line arguments.\n" "Correct format is ./image-processing-benchmark <image path> <kernel " - "name> <Boundary Option>\n where " + "name> <kernelmorph> <Boundary Option>\n where " "image path provides path of the image to be processed, kernel name " "denotes the name " "of desired kernel as specified in " + "kernelmorph denotes the kernel to be used for morphological operations" "include/ImageProcessing/Kernels.h and Boundary options available " "are CONSTANT_PADDING, REPLICATE_PADDING.\n"); } @@ -52,11 +83,26 @@ int main(int argc, char **argv) { initializeMLIRConv2D(argv); initializeBuddyConv2D(argv); initializeBuddyCorr2D(argv); + initializeBuddyMorph2D(argv); + initializeOpenCVMorph2D(argv); initializeOpenCVFilter2D(argv); initializeEigenConvolve2D(argv); registerBenchmarkBuddyCorr2D(); registerBenchmarkOpenCVFilter2D(); + registerBenchmarkBuddyErosion2D(); + registerBenchmarkBuddyDilation2D(); + registerBenchmarkBuddyOpening2D(); + registerBenchmarkBuddyClosing2D(); + registerBenchmarkBuddyTopHat2D(); + registerBenchmarkBuddyBottomHat2D(); + registerBenchmarkOpenCVErode2D(); + registerBenchmarkOpenCVOpening2D(); + registerBenchmarkOpenCVClosing2D(); + registerBenchmarkOpenCVTopHat2D(); + registerBenchmarkOpenCVBottomHat2D(); + registerBenchmarkOpenCVMorphGrad2D(); + registerBenchmarkOpenCVDilate2D(); ::benchmark::Initialize(&argc, argv); ::benchmark::RunSpecifiedBenchmarks(); @@ -65,6 +111,20 @@ int main(int argc, char **argv) { generateResultOpenCVFilter2D(); generateResultBuddyConv2D(argv); generateResultBuddyCorr2D(argv); + generateResultBuddyErosion2D(argv); + generateResultBuddyDilation2D(argv); + generateResultBuddyOpening2D(argv); + generateResultBuddyClosing2D(argv); + generateResultBuddyTopHat2D(argv); + generateResultBuddyBottomHat2D(argv); + generateResultBuddyMorphGrad2D(argv); + generateResultOpenCVTopHat2D(); + generateResultOpenCVBottomHat2D(); + generateResultOpenCVMorphGrad2D(); + generateResultOpenCVErode2D(); + generateResultOpenCVDilate2D(); + generateResultOpenCVOpening2D(); + generateResultOpenCVClosing2D(); generateResultEigenConvolve2D(); return 0; diff --git a/benchmarks/ImageProcessing/OpenCVMorph2DBenchmark.cpp b/benchmarks/ImageProcessing/OpenCVMorph2DBenchmark.cpp new file mode 100644 index 0000000000000000000000000000000000000000..49169468f36272dd750677d20980da3634dc467a --- /dev/null +++ b/benchmarks/ImageProcessing/OpenCVMorph2DBenchmark.cpp @@ -0,0 +1,455 @@ +//===- OpenCVMorph2DBenchmark.cpp ----------------------------------------===// +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//===----------------------------------------------------------------------===// +// +// This file implements the benchmark for OpenCV's Morphological Operations. +// +//===----------------------------------------------------------------------===// + +#include "ImageProcessing/Kernels.h" +#include <benchmark/benchmark.h> +#include <opencv2/opencv.hpp> + +using namespace cv; +using namespace std; + +// Declare input image, kernel and output image. +Mat inputImageMorph2D, kernelMorph2D, outputErode2D, outputDilate2D, + outputOpening2D, outputClosing2D, outputTopHat2D, outputBottomHat2D, + outputMorphGrad2D; + +// Declare Boundary Options supported. +enum BoundaryOption { constant_padding, replicate_padding }; + +BoundaryOption OpenCVBoundaryType1; + +void initializeOpenCVMorph2D(char **argv) { + inputImageMorph2D = imread(argv[1], IMREAD_GRAYSCALE); + + kernelMorph2D = Mat(get<1>(kernelMap1[argv[4]]), get<2>(kernelMap1[argv[4]]), + CV_8UC1, get<0>(kernelMap1[argv[4]])); + + if (static_cast<string>(argv[3]) == "REPLICATE_PADDING") { + OpenCVBoundaryType1 = replicate_padding; + } else { + OpenCVBoundaryType1 = constant_padding; + } +} + +// Benchmarking function. +static void OpenCV_Erode2D_Constant_Padding(benchmark::State &state) { + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) { + erode(inputImageMorph2D, outputErode2D, kernelMorph2D, cv::Point(1, 1), 5, + cv::BORDER_CONSTANT, 0.0); + } + } +} + +static void OpenCV_Erode2D_Replicate_Padding(benchmark::State &state) { + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) { + erode(inputImageMorph2D, outputErode2D, kernelMorph2D, cv::Point(1, 1), 5, + cv::BORDER_REPLICATE, 0.0); + } + } +} + +// Benchmarking function. +static void OpenCV_Dilate2D_Constant_Padding(benchmark::State &state) { + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) { + dilate(inputImageMorph2D, outputDilate2D, kernelMorph2D, cv::Point(1, 1), + 5, cv::BORDER_CONSTANT, 0.0); + } + } +} + +static void OpenCV_Dilate2D_Replicate_Padding(benchmark::State &state) { + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) { + dilate(inputImageMorph2D, outputDilate2D, kernelMorph2D, cv::Point(1, 1), + 5, cv::BORDER_REPLICATE, 0.0); + } + } +} + +// Benchmarking function. +static void OpenCV_Opening2D_Constant_Padding(benchmark::State &state) { + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) { + cv::morphologyEx(inputImageMorph2D, outputOpening2D, 2, kernelMorph2D, + cv::Point(1, 1), 3, cv::BORDER_CONSTANT, 0.0); + } + } +} + +static void OpenCV_Opening2D_Replicate_Padding(benchmark::State &state) { + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) { + cv::morphologyEx(inputImageMorph2D, outputOpening2D, 2, kernelMorph2D, + cv::Point(1, 1), 3, cv::BORDER_REPLICATE, 0.0); + } + } +} + +// Benchmarking function. +static void OpenCV_Closing2D_Constant_Padding(benchmark::State &state) { + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) { + cv::morphologyEx(inputImageMorph2D, outputClosing2D, 2, kernelMorph2D, + cv::Point(1, 1), 3, cv::BORDER_CONSTANT, 0.0); + } + } +} + +static void OpenCV_Closing2D_Replicate_Padding(benchmark::State &state) { + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) { + cv::morphologyEx(inputImageMorph2D, outputClosing2D, 2, kernelMorph2D, + cv::Point(1, 1), 3, cv::BORDER_REPLICATE, 0.0); + } + } +} + +// Benchmarking function. +static void OpenCV_TopHat2D_Constant_Padding(benchmark::State &state) { + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) { + cv::morphologyEx(inputImageMorph2D, outputTopHat2D, 5, kernelMorph2D, + cv::Point(1, 1), 3, cv::BORDER_CONSTANT, 0.0); + } + } +} + +static void OpenCV_TopHat2D_Replicate_Padding(benchmark::State &state) { + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) { + cv::morphologyEx(inputImageMorph2D, outputTopHat2D, 5, kernelMorph2D, + cv::Point(1, 1), 3, cv::BORDER_REPLICATE, 0.0); + } + } +} + +// Benchmarking function. +static void OpenCV_BottomHat2D_Constant_Padding(benchmark::State &state) { + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) { + cv::morphologyEx(inputImageMorph2D, outputBottomHat2D, 6, kernelMorph2D, + cv::Point(1, 1), 3, cv::BORDER_CONSTANT, 0.0); + } + } +} + +static void OpenCV_BottomHat2D_Replicate_Padding(benchmark::State &state) { + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) { + cv::morphologyEx(inputImageMorph2D, outputBottomHat2D, 6, kernelMorph2D, + cv::Point(1, 1), 3, cv::BORDER_REPLICATE, 0.0); + } + } +} + +// Benchmarking function. +static void OpenCV_MorphGrad2D_Constant_Padding(benchmark::State &state) { + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) { + cv::morphologyEx(inputImageMorph2D, outputMorphGrad2D, 4, kernelMorph2D, + cv::Point(1, 1), 3, cv::BORDER_CONSTANT, 0.0); + } + } +} + +static void OpenCV_MorphGrad2D_Replicate_Padding(benchmark::State &state) { + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) { + cv::morphologyEx(inputImageMorph2D, outputMorphGrad2D, 4, kernelMorph2D, + cv::Point(1, 1), 3, cv::BORDER_REPLICATE, 0.0); + } + } +} + +// Register benchmarking function. +void registerBenchmarkOpenCVErode2D() { + if (OpenCVBoundaryType1 == replicate_padding) { + BENCHMARK(OpenCV_Erode2D_Replicate_Padding)->Arg(1); + } else { + BENCHMARK(OpenCV_Erode2D_Constant_Padding)->Arg(1); + } +} + +// Register benchmarking function. +void registerBenchmarkOpenCVDilate2D() { + if (OpenCVBoundaryType1 == replicate_padding) { + BENCHMARK(OpenCV_Dilate2D_Replicate_Padding)->Arg(1); + } else { + BENCHMARK(OpenCV_Dilate2D_Constant_Padding)->Arg(1); + } +} + +// Register benchmarking function. +void registerBenchmarkOpenCVOpening2D() { + if (OpenCVBoundaryType1 == replicate_padding) { + BENCHMARK(OpenCV_Opening2D_Replicate_Padding)->Arg(1); + } else { + BENCHMARK(OpenCV_Opening2D_Constant_Padding)->Arg(1); + } +} + +// Register benchmarking function. +void registerBenchmarkOpenCVClosing2D() { + if (OpenCVBoundaryType1 == replicate_padding) { + BENCHMARK(OpenCV_Closing2D_Replicate_Padding)->Arg(1); + } else { + BENCHMARK(OpenCV_Closing2D_Constant_Padding)->Arg(1); + } +} + +// Register benchmarking function. +void registerBenchmarkOpenCVTopHat2D() { + if (OpenCVBoundaryType1 == replicate_padding) { + BENCHMARK(OpenCV_TopHat2D_Replicate_Padding)->Arg(1); + } else { + BENCHMARK(OpenCV_TopHat2D_Constant_Padding)->Arg(1); + } +} + +// Register benchmarking function. +void registerBenchmarkOpenCVBottomHat2D() { + if (OpenCVBoundaryType1 == replicate_padding) { + BENCHMARK(OpenCV_BottomHat2D_Replicate_Padding)->Arg(1); + } else { + BENCHMARK(OpenCV_BottomHat2D_Constant_Padding)->Arg(1); + } +} + +// Register benchmarking function. +void registerBenchmarkOpenCVMorphGrad2D() { + if (OpenCVBoundaryType1 == replicate_padding) { + BENCHMARK(OpenCV_MorphGrad2D_Replicate_Padding)->Arg(1); + } else { + BENCHMARK(OpenCV_MorphGrad2D_Constant_Padding)->Arg(1); + } +} + +// Generate result image. +void generateResultOpenCVErode2D() { + if (OpenCVBoundaryType1 == replicate_padding) { + erode(inputImageMorph2D, outputErode2D, kernelMorph2D, cv::Point(1, 1), 5, + cv::BORDER_REPLICATE, 0.0); + } else { + erode(inputImageMorph2D, outputErode2D, kernelMorph2D, cv::Point(1, 1), 5, + cv::BORDER_CONSTANT, 0.0); + } + + // Choose a PNG compression level + vector<int> compressionParams; + compressionParams.push_back(IMWRITE_PNG_COMPRESSION); + compressionParams.push_back(9); + + // Write output to PNG. + bool result = false; + try { + result = + imwrite("ResultOpenCVErode2D.png", outputErode2D, compressionParams); + } catch (const cv::Exception &ex) { + fprintf(stderr, "Exception converting image to PNG format: %s\n", + ex.what()); + } + if (result) + cout << "Saved PNG file." << endl; + else + cout << "ERROR: Can't save PNG file." << endl; +} + +// Generate result image. +void generateResultOpenCVDilate2D() { + if (OpenCVBoundaryType1 == replicate_padding) { + dilate(inputImageMorph2D, outputDilate2D, kernelMorph2D, cv::Point(1, 1), 5, + cv::BORDER_REPLICATE, 0.0); + } else { + dilate(inputImageMorph2D, outputDilate2D, kernelMorph2D, cv::Point(1, 1), 5, + cv::BORDER_CONSTANT, 0.0); + } + + // Choose a PNG compression level + vector<int> compressionParams; + compressionParams.push_back(IMWRITE_PNG_COMPRESSION); + compressionParams.push_back(9); + + // Write output to PNG. + bool result = false; + try { + result = + imwrite("ResultOpenCVDilate2D.png", outputDilate2D, compressionParams); + } catch (const cv::Exception &ex) { + fprintf(stderr, "Exception converting image to PNG format: %s\n", + ex.what()); + } + if (result) + cout << "Saved PNG file." << endl; + else + cout << "ERROR: Can't save PNG file." << endl; +} + +// Generate result image. +void generateResultOpenCVOpening2D() { + if (OpenCVBoundaryType1 == replicate_padding) { + cv::morphologyEx(inputImageMorph2D, outputOpening2D, 2, kernelMorph2D, + cv::Point(1, 1), 3, cv::BORDER_REPLICATE, 0.0); + } else { + cv::morphologyEx(inputImageMorph2D, outputOpening2D, 2, kernelMorph2D, + cv::Point(1, 1), 3, cv::BORDER_CONSTANT, 0.0); + } + + // Choose a PNG compression level + vector<int> compressionParams; + compressionParams.push_back(IMWRITE_PNG_COMPRESSION); + compressionParams.push_back(9); + + // Write output to PNG. + bool result = false; + try { + result = imwrite("ResultOpenCVOpening2D.png", outputOpening2D, + compressionParams); + } catch (const cv::Exception &ex) { + fprintf(stderr, "Exception converting image to PNG format: %s\n", + ex.what()); + } + if (result) + cout << "Saved PNG file." << endl; + else + cout << "ERROR: Can't save PNG file." << endl; +} + +// Generate result image. +void generateResultOpenCVClosing2D() { + if (OpenCVBoundaryType1 == replicate_padding) { + cv::morphologyEx(inputImageMorph2D, outputClosing2D, 2, kernelMorph2D, + cv::Point(1, 1), 3, cv::BORDER_REPLICATE, 0.0); + } else { + cv::morphologyEx(inputImageMorph2D, outputClosing2D, 2, kernelMorph2D, + cv::Point(1, 1), 3, cv::BORDER_CONSTANT, 0.0); + } + + // Choose a PNG compression level + vector<int> compressionParams; + compressionParams.push_back(IMWRITE_PNG_COMPRESSION); + compressionParams.push_back(9); + + // Write output to PNG. + bool result = false; + try { + result = imwrite("ResultOpenCVClosing2D.png", outputClosing2D, + compressionParams); + } catch (const cv::Exception &ex) { + fprintf(stderr, "Exception converting image to PNG format: %s\n", + ex.what()); + } + if (result) + cout << "Saved PNG file." << endl; + else + cout << "ERROR: Can't save PNG file." << endl; +} + +// Generate result image. +void generateResultOpenCVTopHat2D() { + if (OpenCVBoundaryType1 == replicate_padding) { + cv::morphologyEx(inputImageMorph2D, outputTopHat2D, 5, kernelMorph2D, + cv::Point(1, 1), 3, cv::BORDER_REPLICATE, 0.0); + } else { + cv::morphologyEx(inputImageMorph2D, outputTopHat2D, 5, kernelMorph2D, + cv::Point(1, 1), 3, cv::BORDER_CONSTANT, 0.0); + } + + // Choose a PNG compression level + vector<int> compressionParams; + compressionParams.push_back(IMWRITE_PNG_COMPRESSION); + compressionParams.push_back(9); + + // Write output to PNG. + bool result = false; + try { + result = + imwrite("ResultOpenCVTopHat2D.png", outputTopHat2D, compressionParams); + } catch (const cv::Exception &ex) { + fprintf(stderr, "Exception converting image to PNG format: %s\n", + ex.what()); + } + if (result) + cout << "Saved PNG file." << endl; + else + cout << "ERROR: Can't save PNG file." << endl; +} + +// Generate result image. +void generateResultOpenCVBottomHat2D() { + if (OpenCVBoundaryType1 == replicate_padding) { + cv::morphologyEx(inputImageMorph2D, outputBottomHat2D, 6, kernelMorph2D, + cv::Point(1, 1), 3, cv::BORDER_REPLICATE, 0.0); + } else { + cv::morphologyEx(inputImageMorph2D, outputBottomHat2D, 6, kernelMorph2D, + cv::Point(1, 1), 3, cv::BORDER_CONSTANT, 0.0); + } + + // Choose a PNG compression level + vector<int> compressionParams; + compressionParams.push_back(IMWRITE_PNG_COMPRESSION); + compressionParams.push_back(9); + + // Write output to PNG. + bool result = false; + try { + result = imwrite("ResultOpenCVBottomHat2D.png", outputBottomHat2D, + compressionParams); + } catch (const cv::Exception &ex) { + fprintf(stderr, "Exception converting image to PNG format: %s\n", + ex.what()); + } + if (result) + cout << "Saved PNG file." << endl; + else + cout << "ERROR: Can't save PNG file." << endl; +} + +// Generate result image. +void generateResultOpenCVMorphGrad2D() { + if (OpenCVBoundaryType1 == replicate_padding) { + cv::morphologyEx(inputImageMorph2D, outputMorphGrad2D, 4, kernelMorph2D, + cv::Point(1, 1), 3, cv::BORDER_REPLICATE, 0.0); + } else { + cv::morphologyEx(inputImageMorph2D, outputMorphGrad2D, 4, kernelMorph2D, + cv::Point(1, 1), 3, cv::BORDER_CONSTANT, 0.0); + } + + // Choose a PNG compression level + vector<int> compressionParams; + compressionParams.push_back(IMWRITE_PNG_COMPRESSION); + compressionParams.push_back(9); + + // Write output to PNG. + bool result = false; + try { + result = imwrite("ResultOpenCVMorphGrad2D.png", outputMorphGrad2D, + compressionParams); + } catch (const cv::Exception &ex) { + fprintf(stderr, "Exception converting image to PNG format: %s\n", + ex.what()); + } + if (result) + cout << "Saved PNG file." << endl; + else + cout << "ERROR: Can't save PNG file." << endl; +} diff --git a/include/ImageProcessing/Kernels.h b/include/ImageProcessing/Kernels.h index ac159f348de44feb1d35c265d598ea9ea78eb98d..afa3109ef3680186e83aa5f0ccc9074925ee6dd7 100644 --- a/include/ImageProcessing/Kernels.h +++ b/include/ImageProcessing/Kernels.h @@ -78,6 +78,10 @@ static int logKernelCols = 5; static float random3x3KernelAlign[9] = {0, 4, 1, 3, 3, 8, 9, 6, 3}; + +static uint8_t random3x3KernelAlignInt[9] = {0, 4, 1, + 3, 3, 8, + 9, 6, 3}; static int random3x3KernelRows = 3; static int random3x3KernelCols = 3; @@ -85,7 +89,7 @@ static float random5x5KernelAlign[25] = {1, 9, 8, 8, 1, 6, 6, 3, 3, 7, 1, 9, 5, 5, 7, 4, 5, 4, 3, 2, - 9, 8, 3, 8, 9}; + 9, 8, 3, 8, 9}; static int random5x5KernelRows = 5; static int random5x5KernelCols = 5; @@ -95,7 +99,7 @@ static float random7x7KernelAlign[49] = {6, 3, 1, 5, 1, 9, 4, 4, 5, 2, 6, 3, 9, 1, 7, 7, 2, 6, 7, 8, 6, 2, 8, 9, 2, 2, 7, 8, - 8, 9, 2, 3, 5, 3, 5}; + 8, 9, 2, 3, 5, 3, 5}; static int random7x7KernelRows = 7; static int random7x7KernelCols = 7; @@ -107,7 +111,7 @@ static float random9x9KernelAlign[81] = {7, 9, 5, 0, 9, 8, 4, 9, 9, 7, 2, 9, 8, 1, 4, 5, 7, 7, 7, 3, 4, 4, 3, 3, 4, 0, 7, 2, 7, 3, 5, 2, 3, 4, 2, 3, - 9, 5, 2, 7, 7, 4, 8, 7, 2}; + 9, 5, 2, 7, 7, 4, 8, 7, 2}; static int random9x9KernelRows = 9; static int random9x9KernelCols = 9; @@ -121,7 +125,7 @@ static float random11x11KernelAlign[121] = {4, 5, 7, 6, 3, 6, 6, 6, 1, 9, 8, 0, 6, 7, 9, 7, 5, 6, 6, 1, 8, 0, 0, 7, 8, 3, 3, 8, 3, 2, 6, 9, 2, 6, 5, 8, 1, 0, 7, 5, 8, 9, 7, 5, - 6, 8, 4, 3, 7, 0, 6, 5, 1, 6, 5}; + 6, 8, 4, 3, 7, 0, 6, 5, 1, 6, 5}; static int random11x11KernelRows = 11; static int random11x11KernelCols = 11; @@ -137,7 +141,7 @@ static float random13x13KernelAlign[169] = {8, 0, 6, 6, 7, 3, 4, 0, 6, 1, 5, 4, 3, 1, 5, 4, 0, 7, 9, 4, 0, 2, 9, 3, 2, 0, 4, 4, 1, 4, 6, 2, 8, 9, 7, 6, 8, 2, 8, 2, 0, 6, 6, 3, 0, 1, 8, 0, 8, 9, 6, - 9, 1, 5, 2, 6, 8, 8, 2, 1, 4, 9, 3, 2}; + 9, 1, 5, 2, 6, 8, 8, 2, 1, 4, 9, 3, 2}; static int random13x13KernelRows = 13; static int random13x13KernelCols = 13; @@ -173,7 +177,11 @@ static std::map<std::string, std::tuple<float*, int, int>> kernelMap = { {"random9x9KernelAlign", {random9x9KernelAlign, random9x9KernelRows, random9x9KernelCols}}, {"random11x11KernelAlign", {random11x11KernelAlign, random11x11KernelRows, random11x11KernelCols}}, {"random13x13KernelAlign", {random13x13KernelAlign, random13x13KernelRows, random13x13KernelCols}}, - {"random15x15KernelAlign", {random15x15KernelAlign, random15x15KernelRows, random15x15KernelCols}} + {"random15x15KernelAlign", {random15x15KernelAlign, random15x15KernelRows, random15x15KernelCols}} +}; + +static std::map<std::string, std::tuple<uint8_t*, int, int>> kernelMap1 = { + {"random3x3KernelAlignInt", {random3x3KernelAlignInt, random3x3KernelRows, random3x3KernelCols}} }; // clang-format on