mirror of
https://github.com/boostorg/gil.git
synced 2026-01-24 05:52:13 +00:00
* Added all standard morphological transformations * Should handle grayscale dilation/erosion * Added test cases and improved code structure * Should handle multichannel images
84 lines
2.9 KiB
C++
84 lines
2.9 KiB
C++
//
|
|
// Copyright 2021 Prathamesh Tagore <prathameshtagore@gmail.com>
|
|
//
|
|
// Use, modification and distribution are subject to the Boost Software License,
|
|
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
|
// http://www.boost.org/LICENSE_1_0.txt)
|
|
//
|
|
#include <boost/core/lightweight_test.hpp>
|
|
#include <boost/gil.hpp>
|
|
#include <array>
|
|
#include <cmath>
|
|
#include <vector>
|
|
|
|
namespace gil = boost::gil;
|
|
|
|
// This function utilizes the fact that sum of distances of a point on an ellipse from its foci
|
|
// is equal to the length of major axis of the ellipse.
|
|
// Parameters b and a represent half of lengths of vertical and horizontal axis respectively.
|
|
void test_rasterizer_follows_equation(
|
|
std::vector<std::array<std::ptrdiff_t, 2>> trajectory_points, float a, float b)
|
|
{
|
|
float focus_x, focus_y;
|
|
if (a > b) // For horizontal ellipse
|
|
{
|
|
focus_x = a * std::sqrt(1 - b * b / (a * a));
|
|
focus_y = 0;
|
|
}
|
|
else // For vertical ellipse
|
|
{
|
|
focus_x = 0;
|
|
focus_y = b * std::sqrt(1 - a * a / (b * b));
|
|
}
|
|
|
|
for (auto trajectory_point : trajectory_points)
|
|
{
|
|
// To suppress conversion warnings from compiler
|
|
std::array<float, 2> point {
|
|
static_cast<float>(trajectory_point[0]), static_cast<float>(trajectory_point[1])};
|
|
|
|
double dist_sum = std::sqrt(std::pow(focus_x - point[0], 2) +
|
|
std::pow(focus_y - point[1], 2)) + std::sqrt(std::pow( - focus_x - point[0], 2) +
|
|
std::pow( - focus_y - point[1], 2));
|
|
if (a > b)
|
|
{
|
|
BOOST_TEST(std::abs(dist_sum - 2 * a) < 1);
|
|
}
|
|
else
|
|
{
|
|
BOOST_TEST(std::abs(dist_sum - 2 * b) < 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
// This function verifies that the difference between x co-ordinates and y co-ordinates for two
|
|
// successive trajectory points is less than or equal to 1. This ensures that the curve is connected.
|
|
void test_connectivity(std::vector<std::array<std::ptrdiff_t, 2>> points)
|
|
{
|
|
for (std::size_t i = 1; i < points.size(); ++i)
|
|
{
|
|
std::ptrdiff_t diff_x = points[i][0] - points[i - 1][0];
|
|
std::ptrdiff_t diff_y = points[i][1] - points[i - 1][1];
|
|
BOOST_TEST_LE(diff_x, 1);
|
|
BOOST_TEST_LE(diff_y, 1);
|
|
}
|
|
}
|
|
|
|
// We verify all test cases for the portion of ellipse in first quadrant, since all other portions
|
|
// can be constructed with simple reflection, they tend to be correct if first quadrant is verified.
|
|
int main()
|
|
{
|
|
for (float a = 1; a < 101; ++a)
|
|
{
|
|
for (float b = 1; b < 101; ++b)
|
|
{
|
|
auto rasterizer = gil::midpoint_elliptical_rasterizer{};
|
|
std::vector<std::array<std::ptrdiff_t, 2>> points = rasterizer.obtain_trajectory(
|
|
{static_cast<unsigned int>(a), static_cast<unsigned int>(b)});
|
|
test_rasterizer_follows_equation(points, a, b);
|
|
test_connectivity(points);
|
|
}
|
|
}
|
|
return boost::report_errors();
|
|
}
|