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_CHECKER_MODEL_HPP
30 #define _MCC_CHECKER_MODEL_HPP
31 
32 namespace cv
33 {
34 namespace mcc
35 {
36 
37 //! @addtogroup mcc
38 //! @{
39 
40 /** CChartModel
41       *
42       * @brief Class for handing the different chart models.
43       *
44       *  This class contains the variables and functions which are specific
45       *  to a given chart type and will be used for it detections.
46 
47       */
48 
49 class CChartModel
50 {
51 
52 public:
53     /** SUBCCMModel
54         *
55         * @brief Information about a continuous subregion of the chart.
56         *
57         * Usually not all the cells of the chart can be detected by the
58         * detector. This submodel contains the information about the
59         * detected squares.
60         */
61 
62     typedef struct
63         _SUBCCMModel
64     {
65 
66         cv::Mat sub_chart;
67         cv::Size2i color_size;
68         std::vector<cv::Point2f> centers;
69 
70     } SUBCCMModel;
71 
72 public:
73     CChartModel(const TYPECHART chartType);
74     ~CChartModel();
75 
76     /** @brief evaluate submodel in this checker type*/
77     bool evaluate(const SUBCCMModel &subModel, int &offset, int &iTheta, float &error);
78 
79     // function utils
80 
81     void copyToColorMat(OutputArray lab, int cs = 0);
82     void rotate90();
83     void flip();
84 
85 public:
86     // Cie L*a*b* values use illuminant D50 2 degree observer sRGB values for
87     // for iluminante D65.
88 
89     cv::Size2i size;
90     cv::Size2f boxsize;
91     std::vector<cv::Point2f> box;
92     std::vector<cv::Point2f> cellchart;
93     std::vector<cv::Point2f> center;
94     std::vector<std::vector<float>> chart;
95 
96 protected:
97     /** \brief match checker color
98           * \param[in] subModel sub-checker
99           * \param[in] iTheta angle
100           * \param[out] error
101           * \param[out] ierror
102           * \return state
103           */
104     bool match(const SUBCCMModel &subModel, int iTheta, float &error, int &ierror);
105 
106     /** \brief euclidian dist L2 for Lab space
107           * \note
108           * \f$ \sum_i \sqrt (\sum_k (ab1-ab2)_k.^2) \f$
109           * \param[in] lab1
110           * \param[in] lab2
111           * \return distance
112           */
113     float dist_color_lab(InputArray lab1, InputArray lab2);
114 
115     /** \brief rotate matrix 90 degree */
116     void rot90(InputOutputArray mat, int itheta);
117 };
118 /** CChecker
119       *
120       * \brief checker model
121       * \author Pedro Marrero Fernandez
122       *
123       */
124 class CCheckerImpl : public CChecker
125 {
126 public:
127 public:
CCheckerImpl()128     CCheckerImpl() {}
~CCheckerImpl()129     ~CCheckerImpl() {}
130 
131     void setTarget(TYPECHART _target)  CV_OVERRIDE;
132     void setBox(std::vector<Point2f> _box) CV_OVERRIDE;
133     void setChartsRGB(Mat _chartsRGB) CV_OVERRIDE;
134     void setChartsYCbCr(Mat _chartsYCbCr) CV_OVERRIDE;
135     void setCost(float _cost) CV_OVERRIDE;
136     void setCenter(Point2f _center) CV_OVERRIDE;
137 
138     TYPECHART getTarget() CV_OVERRIDE;
139     std::vector<Point2f> getBox() CV_OVERRIDE;
140     Mat getChartsRGB() CV_OVERRIDE;
141     Mat getChartsYCbCr() CV_OVERRIDE;
142     float getCost() CV_OVERRIDE;
143     Point2f getCenter() CV_OVERRIDE;
144 
145 private:
146     TYPECHART target;             ///< type of checkercolor
147     std::vector<cv::Point2f> box; ///< positions of the corners
148     cv::Mat chartsRGB;             ///< charts profile in rgb color space
149     cv::Mat chartsYCbCr;         ///< charts profile in YCbCr color space
150     float cost;                     ///< cost to aproximate
151     cv::Point2f center;             ///< center of the chart.
152 };
153 
154 //////////////////////////////////////////////////////////////////////////////////////////////
155 // CheckerDraw
156 
157 /** \brief checker draw
158       * \author Pedro Marrero Fernandez
159       */
160 class CCheckerDrawImpl : public CCheckerDraw
161 {
162 
163 public:
CCheckerDrawImpl(Ptr<CChecker> pChecker,cv::Scalar color=CV_RGB (0,250,0),int thickness=2)164     CCheckerDrawImpl(Ptr<CChecker> pChecker, cv::Scalar color = CV_RGB(0, 250, 0), int thickness = 2)
165         : m_pChecker(pChecker), m_color(color), m_thickness(thickness)
166     {
167         CV_Assert(pChecker);
168     }
169 
170     void draw(InputOutputArray img) CV_OVERRIDE;
171 
172 private:
173     Ptr<CChecker> m_pChecker;
174     cv::Scalar m_color;
175     int m_thickness;
176 
177 private:
178     /** \brief transformation perspetive*/
179     void transform_points_forward(
180         InputArray T,
181         const std::vector<cv::Point2f> &X,
182         std::vector<cv::Point2f> &Xt);
183 };
184 // @}
185 
186 } // namespace mcc
187 } // namespace cv
188 
189 #endif //_MCC_CHECKER_MODEL_HPP
190