/******************************************************************************** * Copyright (c) 2023 CEA-List * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at * http://www.eclipse.org/legal/epl-2.0. * * SPDX-License-Identifier: EPL-2.0 * ********************************************************************************/ #include <catch2/catch_test_macros.hpp> #include <catch2/catch_template_test_macros.hpp> #include <memory> #include <string> #include "opencv2/core.hpp" #include "aidge/backend/opencv/utils/Utils.hpp" #include "aidge/data/Tensor.hpp" #include "aidge/backend/opencv/data/TensorImpl.hpp" #include "aidge/backend/cpu/data/TensorImpl.hpp" #include "Tools.hpp" using namespace Aidge; // TEMPLATE_TEST_CASE("Opencv Utils", "[Utils][OpenCV]", char, unsigned char, short, unsigned short, int, float, double) { // TODO : perform test for char and double TEMPLATE_TEST_CASE("Opencv Utils", "[Utils][OpenCV]", signed char, unsigned char, short, unsigned short, int, float, double) { constexpr int num_test_matrices = 50; SECTION("Test create tensor from opencv and convert to cpu") { // Generate random cv::mat for (int i = 0; i < num_test_matrices; ++i) { // Opencv mat have maximum 512 channels int ch = std::rand() % 512 + 1; int rows = std::rand() % 10 + 1; int cols = std::rand() % 10 + 1; std::vector<cv::Mat> channels; cv::Mat mat; for (int c = 0; c < ch; ++c){ // Create a random matrix cv::Mat randomMat = createRandomMat<TestType>(rows, cols); // Add each random matrix to the vector channels.push_back(randomMat); } // Merge the vector of cv mat into one cv mat cv::merge(channels, mat); // Check the size and datatype of the matrix REQUIRE(mat.rows == rows); REQUIRE(mat.cols == cols); REQUIRE(mat.channels() == ch); REQUIRE(mat.depth() == cv::DataType<TestType>::type); // Instanciate a tensor opencv auto tensorOcv = tensorOpencv(mat); // Check the size of the tensor REQUIRE(mat.channels() == tensorOcv->dims()[0]); REQUIRE(mat.rows == tensorOcv->dims()[1]); REQUIRE(mat.cols == tensorOcv->dims()[2]); //Get the matrix inside the tensor TensorImpl_opencv_* tImpl_opencv = dynamic_cast<TensorImpl_opencv_*>(tensorOcv->getImpl().get()); auto mat_tensor = tImpl_opencv->data(); // Split the mat from tensor opencv into channels std::vector<cv::Mat> channels_split; cv::split(mat_tensor, channels_split); // Convert opencv tensor to cpu tensor auto tensorCpu = convertCpu(tensorOcv); // Get the cpu ptr of the converted tensor auto cpu_ptr = static_cast<TestType*>(tensorCpu->getImpl()->rawPtr()); // Compare the tensor cpu values with the cv mat in an elementwise fashion // Loop over channels for (int c = 0; c < ch; ++c) { // Loop over rows for (int i = 0; i < rows; ++i) { // Loop over columns for (int j = 0; j < cols; ++j) { TestType elementValue = channels_split[c].at<TestType>(i, j); TestType elementValue_cpu = cpu_ptr[c*(rows*cols)+i*cols+j]; REQUIRE(elementValue == elementValue_cpu); } } } } } }