From 525d5fc82232a94300561db37864a1435fb36a0e Mon Sep 17 00:00:00 2001 From: Tae-Young Chung Date: Tue, 4 Oct 2022 17:22:21 +0900 Subject: [PATCH] mv3d: add mv_test_3d for testing mv3d module [Version]: 0.23.34-0 [Issue type] : update test Change-Id: I859593365ddc19cc232a8073a5bbe87e8f46081b Signed-off-by: Tae-Young Chung --- packaging/capi-media-vision.spec | 2 +- test/testsuites/mv3d/CMakeLists.txt | 19 ++- test/testsuites/mv3d/test_3d.cpp | 283 ++++++++++++++++++++++++++++++++++++ 3 files changed, 302 insertions(+), 2 deletions(-) create mode 100644 test/testsuites/mv3d/test_3d.cpp diff --git a/packaging/capi-media-vision.spec b/packaging/capi-media-vision.spec index a08c8bb..c358f35 100644 --- a/packaging/capi-media-vision.spec +++ b/packaging/capi-media-vision.spec @@ -1,6 +1,6 @@ Name: capi-media-vision Summary: Media Vision library for Tizen Native API -Version: 0.23.33 +Version: 0.23.34 Release: 0 Group: Multimedia/Framework License: Apache-2.0 and BSD-3-Clause diff --git a/test/testsuites/mv3d/CMakeLists.txt b/test/testsuites/mv3d/CMakeLists.txt index 47a1378..1b27aeb 100644 --- a/test/testsuites/mv3d/CMakeLists.txt +++ b/test/testsuites/mv3d/CMakeLists.txt @@ -1,3 +1,4 @@ +## mv_depth_test_suite with images project(mv_depth_test_suite) cmake_minimum_required(VERSION 2.6...3.13) @@ -29,7 +30,8 @@ if(BUILD_VISUALIZER) endif() install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) -## mv_depthstream + +## mv_depthstream_test_sutie pkg_check_modules(GLIB_PKG glib-2.0) if (NOT GLIB_PKG_FOUND) @@ -67,3 +69,18 @@ if(BUILD_VISUALIZER) endif() install(TARGETS mv_depthstream_test_suite DESTINATION ${CMAKE_INSTALL_BINDIR}) + +## mv_test_3d by gtest +project(mv_test_3d) +cmake_minimum_required(VERSION 2.6...3.13) + +set(TEST_3D mv_test_3d) + +add_executable(${TEST_3D} test_3d.cpp) + +target_link_libraries(${TEST_3D} gtest gtest_main + mv_3d + mv_image_helper +) + +install(TARGETS ${TEST_3D} DESTINATION ${CMAKE_INSTALL_BINDIR}) \ No newline at end of file diff --git a/test/testsuites/mv3d/test_3d.cpp b/test/testsuites/mv3d/test_3d.cpp new file mode 100644 index 0000000..37645f2 --- /dev/null +++ b/test/testsuites/mv3d/test_3d.cpp @@ -0,0 +1,283 @@ +/** + * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ + +#include +#include +#include + +#include "gtest/gtest.h" +#include "ImageHelper.h" +#include "mv_3d.h" + +using namespace testing; + +// 0:image,1 camera, test sequence name if image, width, height, min disp, max disp, camera parameter +typedef std::tuple ParamTypes; +#define IMAGE_RES_PATH "/usr/share/capi-media-vision/dfseval" +#define PCD_OUTPUT_PATH "/tmp" +#define DEPTH_INTRINSIC_FILENAME "calibOcv.yaml" +#define PCD_WRITE_FILENAME "test_pontcloud.pcd" +#define IMAGE_FILENAME_LEFT "im0.jpeg" +#define IMAGE_FILENAME_RIGHT "im1.jpeg" +#define PCD_SAMPLING_RATIO 0.05 +#define PCD_OUTLIER_REMOVAL_POINT 3 +#define PCD_OUTLIER_REMOVAL_RADIUS 0.5 + +enum { TEST_MODE_IMAGE = 0, TEST_MODE_CAMERA = 1 }; +static GCond gThreadCond; +static GMutex gThreadMutex; +static void WaitUntil() +{ + g_mutex_lock(&gThreadMutex); + g_print("\t[__wait] waiting... until finishing\n"); + g_cond_wait(&gThreadCond, &gThreadMutex); + g_print("\t[__wait] get signal from callback\n"); + g_mutex_unlock(&gThreadMutex); +} + +static void Signal() +{ + g_mutex_lock(&gThreadMutex); + g_cond_signal(&gThreadCond); + g_print("\t[__signal] send signal to test proc\n"); + g_mutex_unlock(&gThreadMutex); +} + +class Mv3DTestsFixture : public ::testing::TestWithParam +{ +protected: + Mv3DTestsFixture() = default; + ~Mv3DTestsFixture() = default; + + void SetUp() final + { + ASSERT_EQ(mv_3d_create(&mDepthHandle), MEDIA_VISION_ERROR_NONE); + ASSERT_EQ(mv_create_engine_config(&mEngineCfgHandle),MEDIA_VISION_ERROR_NONE); + + std::tie(mTestMode, + mImageName, + mWidth, + mHeight, + mMinDisparity, + mMaxDisparity, + mCameraCalibrationPath) = GetParam(); + + ASSERT_EQ(mv_engine_config_set_int_attribute(mEngineCfgHandle, + MV_3D_DEPTH_WIDTH, + mWidth), MEDIA_VISION_ERROR_NONE); + + + ASSERT_EQ(mv_engine_config_set_int_attribute(mEngineCfgHandle, + MV_3D_DEPTH_HEIGHT, + mHeight), MEDIA_VISION_ERROR_NONE); + + ASSERT_EQ(mv_engine_config_set_int_attribute(mEngineCfgHandle, + MV_3D_DEPTH_MIN_DISPARITY, + mMinDisparity), MEDIA_VISION_ERROR_NONE); + + ASSERT_EQ(mv_engine_config_set_int_attribute(mEngineCfgHandle, + MV_3D_DEPTH_MAX_DISPARITY, + mMaxDisparity), MEDIA_VISION_ERROR_NONE); + + if (mTestMode == 0) + mCameraCalibrationPath = std::string(IMAGE_RES_PATH) + std::string("/") + + mImageName + std::string("/") + + std::string(DEPTH_INTRINSIC_FILENAME); + else + ASSERT_FALSE(mCameraCalibrationPath.empty()) << "there is no calibration file"; + + ASSERT_EQ(mv_engine_config_set_string_attribute(mEngineCfgHandle, + MV_3D_DEPTH_STEREO_CONFIG_FILE_PATH, + mCameraCalibrationPath.c_str()), MEDIA_VISION_ERROR_NONE); + + ASSERT_EQ(mv_engine_config_set_double_attribute(mEngineCfgHandle, + MV_3D_POINTCLOUD_SAMPLING_RATIO, + PCD_SAMPLING_RATIO), MEDIA_VISION_ERROR_NONE); + + ASSERT_EQ(mv_engine_config_set_int_attribute(mEngineCfgHandle, + MV_3D_POINTCLOUD_OUTLIER_REMOVAL_POINTS, + PCD_OUTLIER_REMOVAL_POINT), MEDIA_VISION_ERROR_NONE); + + ASSERT_EQ(mv_engine_config_set_double_attribute(mEngineCfgHandle, + MV_3D_POINTCLOUD_OUTLIER_REMOVAL_RADIUS, + PCD_OUTLIER_REMOVAL_RADIUS), MEDIA_VISION_ERROR_NONE); + + ASSERT_EQ(mv_engine_config_set_string_attribute(mEngineCfgHandle, + MV_3D_POINTCLOUD_OUTPUT_FILE_PATH, + PCD_OUTPUT_PATH), MEDIA_VISION_ERROR_NONE); + } + + + void TearDown() final + { + ASSERT_EQ(mv_3d_destroy(mDepthHandle), MEDIA_VISION_ERROR_NONE); + ASSERT_EQ(mv_destroy_engine_config(mEngineCfgHandle), MEDIA_VISION_ERROR_NONE); + + if (mLeftSourceHandle) { + ASSERT_EQ(mv_destroy_source(mLeftSourceHandle), MEDIA_VISION_ERROR_NONE); + } + + if (mRightSourceHandle) { + ASSERT_EQ(mv_destroy_source(mRightSourceHandle), MEDIA_VISION_ERROR_NONE); + } + } + + void LoadImage() + { + auto imagePath = std::string(IMAGE_RES_PATH) + std::string("/") + mImageName; + auto leftImageFilePath = imagePath + std::string("/") + std::string(IMAGE_FILENAME_LEFT); + auto rightImageFilePath = imagePath + std::string("/") + std::string(IMAGE_FILENAME_RIGHT); + + ASSERT_EQ(access(leftImageFilePath.c_str(), F_OK | R_OK), 0) << leftImageFilePath << " doesn't exist"; + ASSERT_EQ(mv_create_source(&mLeftSourceHandle), MEDIA_VISION_ERROR_NONE); + ASSERT_EQ(MediaVision::Common::ImageHelper::loadImageToSource( + leftImageFilePath.c_str(), mLeftSourceHandle), MEDIA_VISION_ERROR_NONE); + + ASSERT_EQ(access(rightImageFilePath.c_str(), F_OK | R_OK), 0) << rightImageFilePath << " doesn't exist"; + ASSERT_EQ(mv_create_source(&mRightSourceHandle), MEDIA_VISION_ERROR_NONE); + ASSERT_EQ(MediaVision::Common::ImageHelper::loadImageToSource( + rightImageFilePath.c_str(), mRightSourceHandle), MEDIA_VISION_ERROR_NONE); + } + + mv_source_h mLeftSourceHandle {nullptr}; + mv_source_h mRightSourceHandle {nullptr}; + mv_engine_config_h mEngineCfgHandle {nullptr}; + + int mTestMode {TEST_MODE_IMAGE}; + std::string mImageName {""}; + int mWidth {0}; + int mHeight {0}; + int mMinDisparity {0}; + int mMaxDisparity {0}; + std::string mCameraCalibrationPath {""}; + +public: + mv_3d_h mDepthHandle {nullptr}; + bool mIsDepthCallbackInvoked {false}; + bool mIsPointCloudCallbackInvoked {false}; + bool mIsPointCloudWriteSuccess {false}; + bool mIsRunAsync {false}; +}; + +static void _depth_cb(mv_source_h source, unsigned short *depth, unsigned int width, + unsigned int height, void *user_data) +{ + auto mv3dTestsFixture = static_cast(user_data); + mv3dTestsFixture->mIsDepthCallbackInvoked = true; +} + +static void _pointcloud_cb(mv_source_h source, + mv_3d_pointcloud_h pointcloud, + void *user_data) +{ + auto mv3dTestsFixture = static_cast(user_data); + mv3dTestsFixture->mIsPointCloudCallbackInvoked = true; + if (mv3dTestsFixture->mIsRunAsync) + Signal(); +} + +static void _pointcloud_write_file_cb(mv_source_h source, + mv_3d_pointcloud_h pointcloud, + void *user_data) +{ + auto mv3dTestsFixture = static_cast(user_data); + mv3dTestsFixture->mIsPointCloudCallbackInvoked = true; + + int ret = mv_3d_pointcloud_write_file(mv3dTestsFixture->mDepthHandle, pointcloud, MV_3D_POINTCLOUD_TYPE_PCD_BIN, PCD_WRITE_FILENAME); + if (ret == MEDIA_VISION_ERROR_NONE) + mv3dTestsFixture->mIsPointCloudWriteSuccess = true; +} + +TEST_P(Mv3DTestsFixture, Configure) +{ + ASSERT_EQ(mv_3d_configure(mDepthHandle, mEngineCfgHandle), MEDIA_VISION_ERROR_NONE); +} + +TEST_P(Mv3DTestsFixture, SetCallback) +{ + ASSERT_EQ(mv_3d_set_depth_cb(mDepthHandle, _depth_cb, this), MEDIA_VISION_ERROR_NONE); + ASSERT_EQ(mv_3d_set_pointcloud_cb(mDepthHandle, _pointcloud_cb, this), MEDIA_VISION_ERROR_NONE); +} + +TEST_P(Mv3DTestsFixture, Prepare) +{ + ASSERT_EQ(mv_3d_configure(mDepthHandle, mEngineCfgHandle), MEDIA_VISION_ERROR_NONE); + ASSERT_EQ(mv_3d_set_depth_cb(mDepthHandle, _depth_cb, this), MEDIA_VISION_ERROR_NONE); + ASSERT_EQ(mv_3d_set_pointcloud_cb(mDepthHandle, _pointcloud_cb, this), MEDIA_VISION_ERROR_NONE); + ASSERT_EQ(mv_3d_prepare(mDepthHandle), MEDIA_VISION_ERROR_NONE); +} + +TEST_P(Mv3DTestsFixture, Runsync) +{ + ASSERT_EQ(mv_3d_configure(mDepthHandle, mEngineCfgHandle), MEDIA_VISION_ERROR_NONE); + ASSERT_EQ(mv_3d_set_depth_cb(mDepthHandle, _depth_cb, this), MEDIA_VISION_ERROR_NONE); + ASSERT_EQ(mv_3d_set_pointcloud_cb(mDepthHandle, _pointcloud_cb, this), MEDIA_VISION_ERROR_NONE); + ASSERT_EQ(mv_3d_prepare(mDepthHandle), MEDIA_VISION_ERROR_NONE); + + if (mTestMode == 0) { + LoadImage(); + } + ASSERT_EQ(mv_3d_run(mDepthHandle, mLeftSourceHandle, mRightSourceHandle, nullptr), MEDIA_VISION_ERROR_NONE); + ASSERT_TRUE(mIsDepthCallbackInvoked); + ASSERT_TRUE(mIsPointCloudCallbackInvoked); +} + +TEST_P(Mv3DTestsFixture, RunAsync) +{ + mIsRunAsync = true; + ASSERT_EQ(mv_3d_configure(mDepthHandle, mEngineCfgHandle), MEDIA_VISION_ERROR_NONE); + ASSERT_EQ(mv_3d_set_depth_cb(mDepthHandle, _depth_cb, this), MEDIA_VISION_ERROR_NONE); + ASSERT_EQ(mv_3d_set_pointcloud_cb(mDepthHandle, _pointcloud_cb, this), MEDIA_VISION_ERROR_NONE); + ASSERT_EQ(mv_3d_prepare(mDepthHandle), MEDIA_VISION_ERROR_NONE); + + if (mTestMode == 0) { + LoadImage(); + } + ASSERT_EQ(mv_3d_run_async(mDepthHandle, mLeftSourceHandle, mRightSourceHandle, nullptr), MEDIA_VISION_ERROR_NONE); + + WaitUntil(); + ASSERT_TRUE(mIsDepthCallbackInvoked); + ASSERT_TRUE(mIsPointCloudCallbackInvoked); +} + +TEST_P(Mv3DTestsFixture, PointCloudWriteFile) +{ + ASSERT_EQ(mv_3d_configure(mDepthHandle, mEngineCfgHandle), MEDIA_VISION_ERROR_NONE); + ASSERT_EQ(mv_3d_set_depth_cb(mDepthHandle, _depth_cb, this), MEDIA_VISION_ERROR_NONE); + ASSERT_EQ(mv_3d_set_pointcloud_cb(mDepthHandle, _pointcloud_write_file_cb, this), MEDIA_VISION_ERROR_NONE); + ASSERT_EQ(mv_3d_prepare(mDepthHandle), MEDIA_VISION_ERROR_NONE); + + if (mTestMode == 0) { + LoadImage(); + } + ASSERT_EQ(mv_3d_run(mDepthHandle, mLeftSourceHandle, mRightSourceHandle, nullptr), MEDIA_VISION_ERROR_NONE); + ASSERT_TRUE(mIsDepthCallbackInvoked); + ASSERT_TRUE(mIsPointCloudCallbackInvoked); + ASSERT_TRUE(mIsPointCloudWriteSuccess); +} + +INSTANTIATE_TEST_SUITE_P( + Mv3DTests, + Mv3DTestsFixture, + ::Values( + ParamTypes(TEST_MODE_IMAGE, std::string("Adirondack"), 718, 496, 8, 72, std::string())) +); + +int main(int argc, char **argv) +{ + InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file -- 2.7.4