From bc3dd2452f41900f03348486b83c4d917c8f3964 Mon Sep 17 00:00:00 2001 From: Nghia Ho Date: Wed, 31 Jul 2013 23:43:25 +1000 Subject: [PATCH] Added test cpp --- modules/imgproc/doc/pics/intersection.png | Bin 0 -> 32696 bytes modules/imgproc/test/test_intersection.cpp | 499 +++++++++++++++++++++++++++++ 2 files changed, 499 insertions(+) create mode 100644 modules/imgproc/doc/pics/intersection.png create mode 100644 modules/imgproc/test/test_intersection.cpp diff --git a/modules/imgproc/doc/pics/intersection.png b/modules/imgproc/doc/pics/intersection.png new file mode 100644 index 0000000000000000000000000000000000000000..4d1367c55e4dcebcd798d331b4a1ad9d97709694 GIT binary patch literal 32696 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

9Pq^EOkj^*9E(elf0)ONnyv&r%C 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 literal 0 HcmV?d00001 diff --git a/modules/imgproc/test/test_intersection.cpp b/modules/imgproc/test/test_intersection.cpp new file mode 100644 index 0000000..3a53d6f --- /dev/null +++ b/modules/imgproc/test/test_intersection.cpp @@ -0,0 +1,499 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2008-2011, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// @Authors +// Nghia Ho, nghiaho12@yahoo.com +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of OpenCV Foundation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the OpenCV Foundation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" + +using namespace cv; +using namespace std; + +#define ACCURACY 0.00001 + +class CV_RotatedRectangleIntersectionTest: public cvtest::ArrayTest +{ +public: + +protected: + void run (int); + +private: + void test1(); + void test2(); + void test3(); + void test4(); + void test5(); + void test6(); + void test7(); + void test8(); + void test9(); +}; + +void CV_RotatedRectangleIntersectionTest::run(int) +{ + // See pics/intersection.png for the scenarios we are testing + + // Test the following scenarios: + // 1 - no intersection + // 2 - partial intersection, rectangle translated + // 3 - partial intersection, rectangle rotated 45 degree on the corner, forms a triangle intersection + // 4 - full intersection, rectangles of same size directly on top of each other + // 5 - partial intersection, rectangle on top rotated 45 degrees + // 6 - partial intersection, rectangle on top of different size + // 7 - full intersection, rectangle fully enclosed in the other + // 8 - partial intersection, rectangle corner just touching. point contact + // 9 - partial intersetion. rectangle side by side, line contact + + test1(); + test2(); + test3(); + test4(); + test5(); + test6(); + test7(); + test8(); + test9(); +} + +void CV_RotatedRectangleIntersectionTest::test1() +{ + // no intersection + + RotatedRect rect1, rect2; + + rect1.center.x = 0; + rect1.center.y = 0; + rect1.size.width = 2; + rect1.size.height = 2; + rect1.angle = 12.0f; + + rect2.center.x = 10; + rect2.center.y = 10; + rect2.size.width = 2; + rect2.size.height = 2; + rect2.angle = 34.0f; + + vector vertices; + + int ret = rotatedRectangleIntersection(rect1, rect2, vertices); + + CV_Assert(ret == INTERSECT_NONE); + CV_Assert(vertices.empty()); +} + +void CV_RotatedRectangleIntersectionTest::test2() +{ + // partial intersection, rectangles translated + + RotatedRect rect1, rect2; + + rect1.center.x = 0; + rect1.center.y = 0; + rect1.size.width = 2; + rect1.size.height = 2; + rect1.angle = 0; + + rect2.center.x = 1; + rect2.center.y = 1; + rect2.size.width = 2; + rect2.size.height = 2; + rect2.angle = 0; + + vector vertices; + + int ret = rotatedRectangleIntersection(rect1, rect2, vertices); + + CV_Assert(ret == INTERSECT_PARTIAL); + CV_Assert(vertices.size() == 4); + + vector possibleVertices(4); + + possibleVertices[0] = Point2f(0.0f, 0.0f); + possibleVertices[1] = Point2f(1.0f, 1.0f); + possibleVertices[2] = Point2f(0.0f, 1.0f); + possibleVertices[3] = Point2f(1.0f, 0.0f); + + for( size_t i = 0; i < vertices.size(); i++ ) + { + double bestR = DBL_MAX; + + for( size_t j = 0; j < possibleVertices.size(); j++ ) + { + double dx = vertices[i].x - possibleVertices[j].x; + double dy = vertices[i].y - possibleVertices[j].y; + double r = sqrt(dx*dx + dy*dy); + + bestR = std::min(bestR, r); + } + + CV_Assert(bestR < ACCURACY); + } +} + +void CV_RotatedRectangleIntersectionTest::test3() +{ + // partial intersection, rectangles rotated 45 degree on the corner, forms a triangle intersection + RotatedRect rect1, rect2; + + rect1.center.x = 0; + rect1.center.y = 0; + rect1.size.width = 2; + rect1.size.height = 2; + rect1.angle = 0; + + rect2.center.x = 1; + rect2.center.y = 1; + rect2.size.width = sqrt(2.0f); + rect2.size.height = 20; + rect2.angle = 45.0f; + + vector vertices; + + int ret = rotatedRectangleIntersection(rect1, rect2, vertices); + + CV_Assert(ret == INTERSECT_PARTIAL); + CV_Assert(vertices.size() == 3); + + vector possibleVertices(3); + + possibleVertices[0] = Point2f(1.0f, 1.0f); + possibleVertices[1] = Point2f(0.0f, 1.0f); + possibleVertices[2] = Point2f(1.0f, 0.0f); + + for( size_t i = 0; i < vertices.size(); i++ ) + { + double bestR = DBL_MAX; + + for( size_t j = 0; j < possibleVertices.size(); j++ ) + { + double dx = vertices[i].x - possibleVertices[j].x; + double dy = vertices[i].y - possibleVertices[j].y; + double r = sqrt(dx*dx + dy*dy); + + bestR = std::min(bestR, r); + } + + CV_Assert(bestR < ACCURACY); + } +} + +void CV_RotatedRectangleIntersectionTest::test4() +{ + // full intersection, rectangles of same size directly on top of each other + + RotatedRect rect1, rect2; + + rect1.center.x = 0; + rect1.center.y = 0; + rect1.size.width = 2; + rect1.size.height = 2; + rect1.angle = 0; + + rect2.center.x = 0; + rect2.center.y = 0; + rect2.size.width = 2; + rect2.size.height = 2; + rect2.angle = 0; + + vector vertices; + + int ret = rotatedRectangleIntersection(rect1, rect2, vertices); + + CV_Assert(ret == INTERSECT_FULL); + CV_Assert(vertices.size() == 4); + + vector possibleVertices(4); + + possibleVertices[0] = Point2f(-1.0f, 1.0f); + possibleVertices[1] = Point2f(1.0f, -1.0f); + possibleVertices[2] = Point2f(-1.0f, -1.0f); + possibleVertices[3] = Point2f(1.0f, 1.0f); + + for( size_t i = 0; i < vertices.size(); i++ ) + { + double bestR = DBL_MAX; + + for( size_t j = 0; j < possibleVertices.size(); j++ ) + { + double dx = vertices[i].x - possibleVertices[j].x; + double dy = vertices[i].y - possibleVertices[j].y; + double r = sqrt(dx*dx + dy*dy); + + bestR = std::min(bestR, r); + } + + CV_Assert(bestR < ACCURACY); + } +} + +void CV_RotatedRectangleIntersectionTest::test5() +{ + // partial intersection, rectangle on top rotated 45 degrees + + RotatedRect rect1, rect2; + + rect1.center.x = 0; + rect1.center.y = 0; + rect1.size.width = 2; + rect1.size.height = 2; + rect1.angle = 0; + + rect2.center.x = 0; + rect2.center.y = 0; + rect2.size.width = 2; + rect2.size.height = 2; + rect2.angle = 45.0f; + + vector vertices; + + int ret = rotatedRectangleIntersection(rect1, rect2, vertices); + + CV_Assert(ret == INTERSECT_PARTIAL); + CV_Assert(vertices.size() == 8); + + vector possibleVertices(8); + + possibleVertices[0] = Point2f(-1.0f, -0.414214f); + possibleVertices[1] = Point2f(-1.0f, 0.414214f); + possibleVertices[2] = Point2f(-0.414214f, -1.0f); + possibleVertices[3] = Point2f(0.414214f, -1.0f); + possibleVertices[4] = Point2f(1.0f, -0.414214f); + possibleVertices[5] = Point2f(1.0f, 0.414214f); + possibleVertices[6] = Point2f(0.414214f, 1.0f); + possibleVertices[7] = Point2f(-0.414214f, 1.0f); + + for( size_t i = 0; i < vertices.size(); i++ ) + { + double bestR = DBL_MAX; + + for( size_t j = 0; j < possibleVertices.size(); j++ ) + { + double dx = vertices[i].x - possibleVertices[j].x; + double dy = vertices[i].y - possibleVertices[j].y; + double r = sqrt(dx*dx + dy*dy); + + bestR = std::min(bestR, r); + } + + CV_Assert(bestR < ACCURACY); + } +} + +void CV_RotatedRectangleIntersectionTest::test6() +{ + // 6 - partial intersection, rectangle on top of different size + + RotatedRect rect1, rect2; + + rect1.center.x = 0; + rect1.center.y = 0; + rect1.size.width = 2; + rect1.size.height = 2; + rect1.angle = 0; + + rect2.center.x = 0; + rect2.center.y = 0; + rect2.size.width = 2; + rect2.size.height = 10; + rect2.angle = 0; + + vector vertices; + + int ret = rotatedRectangleIntersection(rect1, rect2, vertices); + + CV_Assert(ret == INTERSECT_PARTIAL); + CV_Assert(vertices.size() == 4); + + vector possibleVertices(4); + + possibleVertices[0] = Point2f(1.0f, 1.0f); + possibleVertices[1] = Point2f(1.0f, -1.0f); + possibleVertices[2] = Point2f(-1.0f, -1.0f); + possibleVertices[3] = Point2f(-1.0f, 1.0f); + + for( size_t i = 0; i < vertices.size(); i++ ) + { + double bestR = DBL_MAX; + + for( size_t j = 0; j < possibleVertices.size(); j++ ) + { + double dx = vertices[i].x - possibleVertices[j].x; + double dy = vertices[i].y - possibleVertices[j].y; + double r = sqrt(dx*dx + dy*dy); + + bestR = std::min(bestR, r); + } + + CV_Assert(bestR < ACCURACY); + } +} + +void CV_RotatedRectangleIntersectionTest::test7() +{ + // full intersection, rectangle fully enclosed in the other + + RotatedRect rect1, rect2; + + rect1.center.x = 0; + rect1.center.y = 0; + rect1.size.width = 12.34; + rect1.size.height = 56.78; + rect1.angle = 0; + + rect2.center.x = 0; + rect2.center.y = 0; + rect2.size.width = 2; + rect2.size.height = 2; + rect2.angle = 0; + + vector vertices; + + int ret = rotatedRectangleIntersection(rect1, rect2, vertices); + + CV_Assert(ret == INTERSECT_FULL); + CV_Assert(vertices.size() == 4); + + vector possibleVertices(4); + + possibleVertices[0] = Point2f(1.0f, 1.0f); + possibleVertices[1] = Point2f(1.0f, -1.0f); + possibleVertices[2] = Point2f(-1.0f, -1.0f); + possibleVertices[3] = Point2f(-1.0f, 1.0f); + + for( size_t i = 0; i < vertices.size(); i++ ) + { + double bestR = DBL_MAX; + + for( size_t j = 0; j < possibleVertices.size(); j++ ) + { + double dx = vertices[i].x - possibleVertices[j].x; + double dy = vertices[i].y - possibleVertices[j].y; + double r = sqrt(dx*dx + dy*dy); + + bestR = std::min(bestR, r); + } + + CV_Assert(bestR < ACCURACY); + } +} + +void CV_RotatedRectangleIntersectionTest::test8() +{ + // full intersection, rectangle fully enclosed in the other + + RotatedRect rect1, rect2; + + rect1.center.x = 0; + rect1.center.y = 0; + rect1.size.width = 2; + rect1.size.height = 2; + rect1.angle = 0; + + rect2.center.x = 2; + rect2.center.y = 2; + rect2.size.width = 2; + rect2.size.height = 2; + rect2.angle = 0; + + vector vertices; + + int ret = rotatedRectangleIntersection(rect1, rect2, vertices); + + CV_Assert(ret == INTERSECT_PARTIAL); + CV_Assert(vertices.size() == 1); + + double dx = vertices[0].x - 1; + double dy = vertices[0].y - 1; + double r = sqrt(dx*dx + dy*dy); + + CV_Assert(r < ACCURACY); +} + +void CV_RotatedRectangleIntersectionTest::test9() +{ + // full intersection, rectangle fully enclosed in the other + + RotatedRect rect1, rect2; + + rect1.center.x = 0; + rect1.center.y = 0; + rect1.size.width = 2; + rect1.size.height = 2; + rect1.angle = 0; + + rect2.center.x = 2; + rect2.center.y = 0; + rect2.size.width = 2; + rect2.size.height = 123.45; + rect2.angle = 0; + + vector vertices; + + int ret = rotatedRectangleIntersection(rect1, rect2, vertices); + + CV_Assert(ret == INTERSECT_PARTIAL); + CV_Assert(vertices.size() == 2); + + vector possibleVertices(2); + + possibleVertices[0] = Point2f(1.0f, 1.0f); + possibleVertices[1] = Point2f(1.0f, -1.0f); + + for( size_t i = 0; i < vertices.size(); i++ ) + { + double bestR = DBL_MAX; + + for( size_t j = 0; j < possibleVertices.size(); j++ ) + { + double dx = vertices[i].x - possibleVertices[j].x; + double dy = vertices[i].y - possibleVertices[j].y; + double r = sqrt(dx*dx + dy*dy); + + bestR = std::min(bestR, r); + } + + CV_Assert(bestR < ACCURACY); + } +} + +TEST (Imgproc_RotatedRectangleIntersection, accuracy) { CV_RotatedRectangleIntersectionTest test; test.safe_run(); } -- 2.7.4