blob: 20a56f73bf1f95010851de760a11e3a983eae5e3 [file] [log] [blame]
Brian Silvermane4664162020-02-15 15:27:46 -08001#include "y2020/vision/sift/fast_gaussian.h"
2
3#include <opencv2/imgproc.hpp>
4#include "gtest/gtest.h"
5
6#include "y2020/vision/sift/fast_gaussian_all.h"
7
8namespace frc971 {
9namespace vision {
10namespace testing {
11
12class FastGaussianTest : public ::testing::Test {
13 public:
14 cv::Mat RandomImage(int width = 500, int height = 500, int type = CV_8UC3) {
15 cv::Mat result(width, height, type);
16 cv::randu(result, 0, 255);
17 return result;
18 }
19
20 void ExpectEqual(const cv::Mat &a, const cv::Mat &b, double epsilon = 1e-10) {
21 const cv::Mat difference = a - b;
22 double min, max;
23 cv::minMaxLoc(difference, &min, &max);
24 EXPECT_GE(min, -epsilon);
25 EXPECT_LE(max, epsilon);
26 }
27};
28
29// Verifies that the default GaussianBlur parameters work out to 15x15 with
30// sigma of 1.6.
31TEST_F(FastGaussianTest, DefaultGaussianSize) {
32 const auto image = RandomImage(500, 500, CV_32FC3);
33 cv::Mat default_blurred, explicitly_blurred;
34 cv::GaussianBlur(image, default_blurred, cv::Size(), 1.6, 1.6);
35 cv::GaussianBlur(image, explicitly_blurred, cv::Size(15, 15), 1.6, 1.6);
36 ExpectEqual(default_blurred, explicitly_blurred);
37}
38
39// Verifies that with 8U just a 9x9 blur is as much as you get.
40TEST_F(FastGaussianTest, GaussianSizeS8) {
41 const auto image = RandomImage(500, 500, CV_8UC3);
42 cv::Mat big_blurred, little_blurred;
43 cv::GaussianBlur(image, big_blurred, cv::Size(15, 15), 1.6, 1.6);
44 cv::GaussianBlur(image, little_blurred, cv::Size(9, 9), 1.6, 1.6);
45 ExpectEqual(big_blurred, little_blurred);
46}
47
48// Verifies that FastGaussian and cv::GaussianBlur give the same result.
49TEST_F(FastGaussianTest, FastGaussian) {
Brian Silvermana9ada662020-02-16 21:00:19 -080050 const auto image = RandomImage(480, 640, CV_16SC1);
Brian Silvermane4664162020-02-15 15:27:46 -080051 cv::Mat slow, fast, fast_direct;
52 static constexpr double kSigma = 1.9465878414647133;
53 static constexpr int kSize = 13;
54
55 cv::GaussianBlur(image, slow, cv::Size(kSize, kSize), kSigma, kSigma);
56 FastGaussian(image, &fast, kSigma);
57
58 // Explicitly call the generated code, to verify that our chosen parameters do
59 // in fact result in using the generated one.
60 fast_direct.create(slow.size(), slow.type());
61 ASSERT_EQ(0,
62 DoGeneratedFastGaussian(MatToHalide<const int16_t>(image),
63 MatToHalide<int16_t>(fast_direct), kSigma));
64
65
66 // 50/65536 = 0.00076, which is under 1%, which is pretty close.
67 ExpectEqual(slow, fast, 50);
68 // The wrapper should be calling the exact same code, so it should end up with
69 // the exact same result.
70 ExpectEqual(fast, fast_direct, 0);
71}
72
73} // namespace testing
74} // namespace vision
75} // namespace frc971