1 // This file is part of OpenCV project.
2 // It is subject to the license terms in the LICENSE file found in the top-level directory
3 // of this distribution and at http://opencv.org/license.html.
4 
5 /*
6  * MIT License
7  *
8  * Copyright (c) 2018 Pedro Diamel Marrero Fernández
9  *
10  * Permission is hereby granted, free of charge, to any person obtaining a copy
11  * of this software and associated documentation files (the "Software"), to deal
12  * in the Software without restriction, including without limitation the rights
13  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14  * copies of the Software, and to permit persons to whom the Software is
15  * furnished to do so, subject to the following conditions:
16  *
17  * The above copyright notice and this permission notice shall be included in all
18  * copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26  * SOFTWARE.
27  */
28 
29 #ifndef _MCC_COMMON_HPP
30 #define _MCC_COMMON_HPP
31 
32 namespace cv
33 {
34 namespace mcc
35 {
36 
37 Rect poly2mask(const std::vector<Point2f> &poly, Size size, InputOutputArray mask);
38 
39 template <typename T>
circshift(std::vector<T> & A,int shiff)40 void circshift(std::vector<T> &A, int shiff)
41 {
42     if (A.empty() || shiff < 1)
43         return;
44     int n = A.size();
45 
46     if (shiff >= n)
47         return;
48 
49     std::vector<T> Tmp(n);
50     for (int i = shiff; i < n + shiff; i++)
51         Tmp[(i % n)] = A[i - shiff];
52 
53     A = Tmp;
54 }
55 
56 float perimeter(const std::vector<cv::Point2f> &ps);
57 
58 cv::Point2f mace_center(const std::vector<cv::Point2f> &ps);
59 
60 template <typename T>
unique(const std::vector<T> & A,std::vector<T> & U)61 void unique(const std::vector<T> &A, std::vector<T> &U)
62 {
63 
64     int n = (int)A.size();
65     std::vector<T> Tm = A;
66 
67     std::sort(Tm.begin(), Tm.end());
68 
69     U.clear();
70     U.push_back(Tm[0]);
71     for (int i = 1; i < n; i++)
72         if (Tm[i] != Tm[i - 1])
73             U.push_back(Tm[i]);
74 }
75 
76 template <typename T>
polyanticlockwise(std::vector<T> & points)77 void polyanticlockwise(std::vector<T> &points)
78 {
79     // Sort the points in anti-clockwise order
80     // Trace a line between the first and second point.
81     // If the third point is at the right side, then the points are anti-clockwise
82     cv::Point v1 = points[1] - points[0];
83     cv::Point v2 = points[2] - points[0];
84 
85     double o = (v1.x * v2.y) - (v1.y * v2.x);
86 
87     if (o < 0.0) //if the third point is in the left side, then sort in anti-clockwise order
88         std::swap(points[1], points[3]);
89 }
90 template <typename T>
polyclockwise(std::vector<T> & points)91 void polyclockwise(std::vector<T> &points)
92 {
93     // Sort the points in clockwise order
94     // Trace a line between the first and second point.
95     // If the third point is at the right side, then the points are clockwise
96     cv::Point v1 = points[1] - points[0];
97     cv::Point v2 = points[2] - points[0];
98 
99     double o = (v1.x * v2.y) - (v1.y * v2.x);
100 
101     if (o > 0.0) //if the third point is in the left side, then sort in clockwise order
102         std::swap(points[1], points[3]);
103 }
104 // Does lexical cast of the input argument to string
105 template <typename T>
ToString(const T & value)106 std::string ToString(const T &value)
107 {
108     std::ostringstream stream;
109     stream << value;
110     return stream.str();
111 }
112 
113 template <typename T>
change(T & a,T & b)114 void change(T &a, T &b)
115 {
116     T c = a;
117     a = b;
118     b = c;
119 }
120 
121 template <typename T>
sort(std::vector<T> & A,std::vector<int> & idx,bool ord=true)122 void sort(std::vector<T> &A, std::vector<int> &idx, bool ord = true)
123 {
124     size_t N = A.size();
125     if (N == 0)
126         return;
127 
128     idx.clear();
129     idx.resize(N);
130     for (size_t i = 0; i < N; i++)
131         idx[i] = (int)i;
132 
133     for (size_t i = 0; i < N - 1; i++)
134     {
135 
136         size_t k = i;
137         T valor = A[i];
138         for (size_t j = i + 1; j < N; j++)
139         {
140             if ((A[j] < valor && ord) || (A[j] > valor && !ord))
141             {
142                 valor = A[j];
143                 k = j;
144             }
145         }
146 
147         if (k == i)
148             continue;
149 
150         change(A[i], A[k]);
151         change(idx[i], idx[k]);
152     }
153 }
154 
155 } // namespace mcc
156 } // namespace cv
157 
158 #endif //_MCC_COMMON_HPP
159