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_DETECTOR_HPP
30 #define _MCC_CHECKER_DETECTOR_HPP
31 
32 #include "opencv2/mcc.hpp"
33 #include "charts.hpp"
34 
35 namespace cv
36 {
37 namespace mcc
38 {
39 
40 class CCheckerDetectorImpl : public CCheckerDetector
41 {
42 
43     typedef std::vector<cv::Point> PointsVector;
44     typedef std::vector<PointsVector> ContoursVector;
45 
46 public:
47     CCheckerDetectorImpl();
48     virtual ~CCheckerDetectorImpl();
49 
50     bool setNet(cv::dnn::Net _net) CV_OVERRIDE;
51 
52     bool process(InputArray image, const TYPECHART chartType,
53                  const std::vector<cv::Rect> &regionsOfInterest,
54                  const int nc = 1, bool use_net = false,
55                  const Ptr<DetectorParameters> &params = DetectorParameters::create()) CV_OVERRIDE;
56 
57     bool process(InputArray image, const TYPECHART chartType,
58                  const int nc = 1, bool use_net = false,
59                  const Ptr<DetectorParameters> &params = DetectorParameters::create()) CV_OVERRIDE;
60 
getBestColorChecker()61     Ptr<CChecker> getBestColorChecker() CV_OVERRIDE
62     {
63         if (m_checkers.size())
64             return m_checkers[0];
65         return nullptr;
66     }
67 
getListColorChecker()68     std::vector<Ptr<CChecker>> getListColorChecker() CV_OVERRIDE
69     {
70         return m_checkers;
71     }
72 
73 protected: // methods pipeline
74     bool _no_net_process(InputArray image, const TYPECHART chartType,
75                          const int nc,
76                          const Ptr<DetectorParameters> &params,
77                          std::vector<cv::Rect> regionsOfInterest);
78     /// prepareImage
79     /** \brief Prepare Image
80       * \param[in] bgrMat image in color space BGR
81       * \param[out] grayOut gray scale
82       * \param[out] bgrOut rescale image
83       * \param[out] aspOut aspect ratio
84       * \param[in] max_size rescale factor in max dim
85       */
86     virtual void
87     prepareImage(InputArray bgr, OutputArray grayOut, OutputArray bgrOut, float &aspOut, const Ptr<DetectorParameters> &params) const;
88 
89     /// performThreshold
90     /** \brief Adaptative threshold
91       * \param[in] grayscaleImg gray scale image
92       * \param[in] thresholdImg binary image
93       * \param[in] wndx, wndy windows size
94       * \param[in] step
95       */
96     virtual void
97     performThreshold(InputArray grayscaleImg, OutputArrayOfArrays thresholdImg, const Ptr<DetectorParameters> &params) const;
98 
99     /// findContours
100     /** \brief find contour in the image
101     * \param[in] srcImg binary imagen
102     * \param[out] contours
103     * \param[in] minContourPointsAllowed
104     */
105     virtual void
106     findContours(InputArray srcImg, ContoursVector &contours, const Ptr<DetectorParameters> &params) const;
107 
108     /// findCandidates
109     /** \brief find posibel candidates
110     * \param[in] contours
111     * \param[out] detectedCharts
112     * \param[in] minContourLengthAllowed
113     */
114     virtual void
115     findCandidates(const ContoursVector &contours, std::vector<CChart> &detectedCharts, const Ptr<DetectorParameters> &params);
116 
117     /// clustersAnalysis
118     /** \brief clusters charts analysis
119     * \param[in] detectedCharts
120     * \param[out] groups
121     */
122     virtual void
123     clustersAnalysis(const std::vector<CChart> &detectedCharts, std::vector<int> &groups, const Ptr<DetectorParameters> &params);
124 
125     /// checkerRecognize
126     /** \brief checker color recognition
127     * \param[in] img
128     * \param[in] detectedCharts
129     * \param[in] G
130     * \param[out] colorChartsOut
131     */
132     virtual void
133     checkerRecognize(InputArray img, const std::vector<CChart> &detectedCharts, const std::vector<int> &G,
134                      const TYPECHART chartType, std::vector<std::vector<cv::Point2f>> &colorChartsOut,
135                      const Ptr<DetectorParameters> &params);
136 
137     /// checkerAnalysis
138     /** \brief evaluate checker
139     * \param[in] img
140     * \param[in] img_org
141     * \param[in] colorCharts
142     * \param[out] checker
143     * \param[in] asp
144     */
145     virtual void
146     checkerAnalysis(InputArray img_rgb_f,
147                     const TYPECHART chartType, const unsigned int nc,
148                     const std::vector<std::vector<cv::Point2f>> &colorCharts,
149                     std::vector<Ptr<CChecker>> &checkers, float asp,
150                     const Ptr<DetectorParameters> &params,
151                     const cv::Mat &img_rgb_org,
152                     const cv::Mat &img_ycbcr_org,
153                     std::vector<cv::Mat> &rgb_planes,
154                     std::vector<cv::Mat> &ycbcr_planes);
155 
156     virtual void
157     removeTooCloseDetections(const Ptr<DetectorParameters> &params);
158 
159 protected:
160     std::vector<Ptr<CChecker>> m_checkers;
161     dnn::Net net;
162     bool net_used = false;
163 
164 private: // methods aux
165     void get_subbox_chart_physical(
166         const std::vector<cv::Point2f> &points,
167         std::vector<cv::Point2f> &chartPhy,
168         cv::Size &size);
169 
170     void reduce_array(
171         const std::vector<float> &x,
172         std::vector<float> &x_new,
173         float tol);
174 
175     void transform_points_forward(
176         InputArray T,
177         const std::vector<cv::Point2f> &X,
178         std::vector<cv::Point2f> &Xt);
179 
180     void transform_points_inverse(
181         InputArray T,
182         const std::vector<cv::Point2f> &X,
183         std::vector<cv::Point2f> &Xt);
184 
185     void get_profile(
186         const std::vector<cv::Point2f> &ibox,
187         const TYPECHART chartType,
188         OutputArray charts_rgb,
189         OutputArray charts_ycbcr,
190         InputArray im_rgb,
191         InputArray im_ycbcr,
192         std::vector<cv::Mat> &rgb_planes,
193         std::vector<cv::Mat> &ycbcr_planes);
194 
195     /* \brief cost function
196      *  e(p) = ||f(p)||^2 = \sum_k (mu_{k,p}*r_k')/||mu_{k,p}||||r_k|| + ...
197      *                   + \sum_k || \sigma_{k,p} ||^2
198      */
199     float cost_function(InputArray img, InputOutputArray mask, InputArray lab,
200                         const std::vector<cv::Point2f> &ibox,
201                         const TYPECHART chartType);
202 };
203 
204 } // namespace mcc
205 } // namespace cv
206 
207 #endif //_MCC_CHECKER_DETECTOR_HPP
208