Skip to content

Add support for testing DIP dialect's 2D correlation op with OpenCV #23

New issue

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

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

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,13 @@ $ cmake -G Ninja .. \
-DBUDDY_OPT_STRIP_MINING=<strip mining size, default: 256> \
-DBUDDY_OPT_ATTR=<ISA vector extension, default: avx512f>
$ cmake --build . --
$ ninja test
$ ninja test && ninja image-processing-integration-tests
```

For executing Image Processing integration tests :
```
cd bin
./image-processing-integration-tests <optional_image_path>
```

where `<optional_image_path>` is an optional parameter used for pointing to the image which is to be used while executing tests.
1 change: 1 addition & 0 deletions include/ImageProcessing/Kernels.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#define IMAGE_PROCESSING_KERNELS

// clang-format off
#include <vector>
#include <string>
#include <map>

Expand Down
File renamed without changes.
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
add_subdirectory(UnitTests)
add_subdirectory(IntegrationTests)
1 change: 1 addition & 0 deletions tests/IntegrationTests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add_subdirectory(ImageProcessing)
19 changes: 19 additions & 0 deletions tests/IntegrationTests/ImageProcessing/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
find_package(OpenCV REQUIRED CONFIG)
include_directories(${OpenCV_INCLUDE_DIRS})

add_executable(
image-processing-integration-tests
DIPCorr2DTest.cpp
)

include(GoogleTest)
gtest_discover_tests(image-processing-integration-tests)

target_link_libraries(
image-processing-integration-tests
${OpenCV_LIBS}
BuddyCorr2D
Container

gtest_main
)
114 changes: 114 additions & 0 deletions tests/IntegrationTests/ImageProcessing/DIPCorr2DTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
#include "ImageProcessing/Kernels.h"
#include "Utils/Container.h"

#include <opencv2/imgcodecs.hpp>
#include <opencv2/opencv.hpp>

#include <gtest/gtest.h>
#include <iostream>
#include <string>

using namespace cv;
using namespace std;

// Declare the Corr2D C interface.
extern "C" {
void _mlir_ciface_corr_2d_constant_padding(
MemRef<float, 2> *input, MemRef<float, 2> *kernel, MemRef<float, 2> *output,
unsigned int centerX, unsigned int centerY, float constantValue);
}

// Fixture for testing the dip.corr_2d operation.
class FilterTest : public ::testing::Test {
public:
static void setImageNames(int argc, char **argv) {
if (argc > 1)
testImageName = argv[1];
else
testImageName = "../../benchmarks/ImageProcessing/Images/YuTu.png";
}

const std::string getTestImageName() { return testImageName; }

private:
static std::string testImageName;
};

std::string FilterTest::testImageName;

bool equalImages(const Mat &img1, const Mat &img2) {
if (img1.rows != img2.rows || img1.cols != img2.cols) {
std::cout << "Produced outputs by DIP and OpenCV differ. Image dimensions "
"are not equal\n";
return 0;
}

for (unsigned int y = 0; y < img1.rows; ++y) {
for (unsigned int x = 0; x < img1.cols; ++x) {
if (abs(img1.at<float>(x, y) - img2.at<float>(x, y)) > 10e-2) {
std::cout << "Produced outputs by DIP and OpenCV differ.\n";
return 0;
}
}
}
return 1;
}

void testKernelImpl(const Mat &inputImage, unsigned int kernelRows,
unsigned int kernelCols, float *kernelArray, unsigned int x,
unsigned int y) {
// Define container sizes.
intptr_t sizesImage[2] = {inputImage.rows, inputImage.cols};
intptr_t sizesKernel[2] = {kernelRows, kernelCols};

// Define input, kernel, and output.
MemRef<float, 2> input(inputImage, sizesImage);
MemRef<float, 2> kernel(kernelArray, sizesKernel);
MemRef<float, 2> output(sizesImage);

for (int i = 0; i < inputImage.rows; i++)
for (int j = 0; j < inputImage.cols; j++)
output[i * inputImage.rows + j] = 0;

Mat kernel1 = Mat(kernelRows, kernelCols, CV_32FC1, kernelArray);
Mat opencvOutput;

_mlir_ciface_corr_2d_constant_padding(&input, &kernel, &output, x, y, 0);

filter2D(inputImage, opencvOutput, CV_32FC1, kernel1, cv::Point(x, y), 0.0,
cv::BORDER_CONSTANT);

// Define a cv::Mat with the output of corr_2d.
Mat dipOutput(inputImage.rows, inputImage.cols, CV_32FC1, output.getData());

if (!equalImages(dipOutput, opencvOutput)) {
std::cout << "Different images produced by OpenCV and DIP for kernel :\n"
<< kernel1
<< "\n"
"when anchor point was : ("
<< x << ", " << y << ").\n";
return;
}
}

void testKernel(const Mat &inputImage, unsigned int kernelRows,
unsigned int kernelCols, float *kernelArray) {
for (unsigned int y = 0; y < kernelRows; ++y)
for (unsigned int x = 0; x < kernelCols; ++x)
testKernelImpl(inputImage, kernelRows, kernelCols, kernelArray, x, y);
}

TEST_F(FilterTest, OpenCVComparison) {
for (auto kernel : kernelMap) {
cv::Mat testImage = cv::imread(getTestImageName(), cv::IMREAD_GRAYSCALE);
testKernel(testImage, get<1>(kernel.second), get<2>(kernel.second),
get<0>(kernel.second));
}
}

int main(int argc, char **argv) {
FilterTest::setImageNames(argc, argv);

::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
2 changes: 1 addition & 1 deletion tests/UnitTests/TestContainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
//
//===----------------------------------------------------------------------===//

#include "Test.h"
#include "Utils/Container.h"
#include "Utils/Test.h"
#include <opencv2/opencv.hpp>

// Fixture for testing the MemRef class.
Expand Down