score-back/tests/test_stereo_matcher.cpp
Artur Mukhamadiev f8177d8926 fix(cloud_point): validation, thread safety, and test cleanup
- Parse port inside try block for proper error reporting instead of unhandled exception
- Make frame_counter atomic to eliminate data race under TcpServer per-client threads
- Validate num_disparities is positive multiple of 16 in StereoMatcherFactory
- Validate stereo pair dimensions match in ScaredDatasetLoader
- Silence nodiscard warnings via std::ignore in tests

TG-3 #ready-for-test
TG-2 #ready-for-test
2026-07-12 22:28:21 +03:00

81 lines
2.6 KiB
C++

#include <gtest/gtest.h>
#include <opencv2/core.hpp>
#include <tuple>
#include "cloud_point/cpu_stereo_matcher.hpp"
#include "cloud_point/gpu_stereo_matcher.hpp"
#include "cloud_point/stereo_matcher_factory.hpp"
using namespace score;
namespace {
/// @brief Create a simple synthetic stereo pair with a horizontal shift.
std::pair<cv::Mat, cv::Mat> make_synthetic_stereo(int shift = 2) {
cv::Mat left = cv::Mat::zeros(100, 100, CV_8UC1);
cv::Mat right = cv::Mat::zeros(100, 100, CV_8UC1);
for (int y = 0; y < 100; ++y) {
for (int x = 0; x < 100; ++x) {
left.at<uchar>(y, x) = static_cast<uchar>(x % 256);
right.at<uchar>(y, x) = static_cast<uchar>((x + shift) % 256);
}
}
return {left, right};
}
} // namespace
TEST(StereoMatcherTest, CpuMatcherComputesDisparity) {
auto [left, right] = make_synthetic_stereo();
CpuStereoMatcher matcher;
cv::Mat disparity = matcher.compute(left, right);
EXPECT_FALSE(disparity.empty());
EXPECT_EQ(disparity.rows, left.rows);
EXPECT_EQ(disparity.cols, left.cols);
}
TEST(StereoMatcherTest, FactoryCpuCreatesNonNull) {
auto matcher = StereoMatcherFactory::create(StereoAlgorithmType::CPU);
ASSERT_NE(matcher, nullptr);
auto [left, right] = make_synthetic_stereo();
cv::Mat disparity = matcher->compute(left, right);
EXPECT_FALSE(disparity.empty());
}
TEST(StereoMatcherTest, FactoryRejectsInvalidNumDisparities) {
EXPECT_THROW(std::ignore = StereoMatcherFactory::create(
StereoAlgorithmType::CPU, 0),
std::invalid_argument);
EXPECT_THROW(std::ignore = StereoMatcherFactory::create(
StereoAlgorithmType::CPU, -16),
std::invalid_argument);
EXPECT_THROW(std::ignore = StereoMatcherFactory::create(
StereoAlgorithmType::CPU, 150),
std::invalid_argument);
}
TEST(StereoMatcherTest, FactoryAcceptsValidNumDisparities) {
auto matcher = StereoMatcherFactory::create(StereoAlgorithmType::CPU, 160);
ASSERT_NE(matcher, nullptr);
}
TEST(StereoMatcherTest, FactoryGpuFallsBackToCpuWhenUnavailable) {
// On this machine CUDA is absent; factory should fall back to CPU.
auto matcher = StereoMatcherFactory::create(StereoAlgorithmType::GPU);
ASSERT_NE(matcher, nullptr);
auto [left, right] = make_synthetic_stereo();
EXPECT_NO_THROW(std::ignore = matcher->compute(left, right));
}
TEST(StereoMatcherTest, GpuMatcherThrowsOnThisMachine) {
// Direct construction of GpuStereoMatcher should throw because
// HAVE_OPENCV_CUDA is undefined here.
EXPECT_THROW(GpuStereoMatcher(), std::runtime_error);
}