mv3d: add mv_test_3d for testing mv3d module 88/282488/5
authorTae-Young Chung <ty83.chung@samsung.com>
Tue, 4 Oct 2022 08:22:21 +0000 (17:22 +0900)
committerTae-Young Chung <ty83.chung@samsung.com>
Tue, 4 Oct 2022 13:32:06 +0000 (22:32 +0900)
[Version]: 0.23.34-0
[Issue type] : update test

Change-Id: I859593365ddc19cc232a8073a5bbe87e8f46081b
Signed-off-by: Tae-Young Chung <ty83.chung@samsung.com>
packaging/capi-media-vision.spec
test/testsuites/mv3d/CMakeLists.txt
test/testsuites/mv3d/test_3d.cpp [new file with mode: 0644]

index a08c8bb..c358f35 100644 (file)
@@ -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
index 47a1378..1b27aeb 100644 (file)
@@ -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 (file)
index 0000000..37645f2
--- /dev/null
@@ -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 <unistd.h>
+#include <pthread.h>
+#include <glib-2.0/glib.h>
+
+#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<int, std::string, int, int, int, int, std::string> 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<ParamTypes>
+{
+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<Mv3DTestsFixture *>(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<Mv3DTestsFixture *>(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<Mv3DTestsFixture *>(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