forked from SolarFramework/SolARModuleOpenCV
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSolARPerspectiveControllerOpencv.cpp
More file actions
124 lines (112 loc) · 5.2 KB
/
SolARPerspectiveControllerOpencv.cpp
File metadata and controls
124 lines (112 loc) · 5.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/**
* @copyright Copyright (c) 2017 B-com http://www.b-com.com/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "SolARPerspectiveControllerOpencv.h"
#include "SolAROpenCVHelper.h"
#include "opencv2/opencv.hpp"
#include "core/Log.h"
namespace xpcf = org::bcom::xpcf;
XPCF_DEFINE_FACTORY_CREATE_INSTANCE(SolAR::MODULES::OPENCV::SolARPerspectiveControllerOpencv)
namespace SolAR {
using namespace datastructure;
namespace MODULES {
namespace OPENCV {
SolARPerspectiveControllerOpencv::SolARPerspectiveControllerOpencv():ConfigurableBase(xpcf::toUUID<SolARPerspectiveControllerOpencv>())
{
declareInterface<api::image::IPerspectiveController>(this);
declareProperty("outputImageWidth", m_outputImageWidth);
declareProperty("outputImageHeight", m_outputImageHeight);
}
FrameworkReturnCode SolARPerspectiveControllerOpencv::correct(const SRef<Image> inputImg, const Contour2Df & contour, SRef<Image> & outputImage)
{
std::vector<cv::Point2f> points;
cv::Size patches_size(m_outputImageWidth, m_outputImageHeight);
std::vector<cv::Point2f> markerCorners2D;
markerCorners2D.push_back(cv::Point2f(0, 0));
markerCorners2D.push_back(cv::Point2f(m_outputImageWidth - 1, 0));
markerCorners2D.push_back(cv::Point2f(m_outputImageWidth - 1, m_outputImageHeight - 1));
markerCorners2D.push_back(cv::Point2f(0, m_outputImageHeight - 1));
cv::Mat cv_inputImg = SolAROpenCVHelper::mapToOpenCV(inputImg);
// For each contour, extract the patch
if (contour.size()>=4)
{
for(unsigned int j =0; j < 4; ++j)
{
points.push_back(cv::Point2f(contour[j].getX(),contour[j].getY()));
}
// Find the perspective transformation that brings current marker to rectangular form
cv::Mat markerTransform = cv::getPerspectiveTransform(points, markerCorners2D);
// Transform image to get a canonical marker image
cv::Mat cv_patch;
cv::warpPerspective(cv_inputImg, cv_patch, markerTransform, patches_size);
SolAROpenCVHelper::convertToSolar(cv_patch, outputImage);
return FrameworkReturnCode::_SUCCESS;
}
else
{
outputImage = nullptr;
return FrameworkReturnCode::_ERROR_;
}
}
FrameworkReturnCode SolARPerspectiveControllerOpencv::correct(const SRef<Image> inputImg, const std::vector<Contour2Df> & contours, std::vector<SRef<Image>> & patches)
{
if (inputImg == nullptr)
{
LOG_ERROR("The input image for PerspectiveControllerOpenCV is null");
return FrameworkReturnCode::_ERROR_;
}
if (m_outputImageWidth <=0 || m_outputImageHeight <=0)
{
LOG_ERROR("The width or height of the output image for PerspectiveControllerOpenCV is null or negative");
return FrameworkReturnCode::_ERROR_;
}
std::vector<cv::Point2f> points;
cv::Size patches_size(m_outputImageWidth, m_outputImageHeight);
std::vector<cv::Point2f> markerCorners2D;
markerCorners2D.push_back(cv::Point2f(0, 0));
markerCorners2D.push_back(cv::Point2f(m_outputImageWidth - 1, 0));
markerCorners2D.push_back(cv::Point2f(m_outputImageWidth - 1, m_outputImageHeight - 1));
markerCorners2D.push_back(cv::Point2f(0, m_outputImageHeight - 1));
cv::Mat cv_inputImg = SolAROpenCVHelper::mapToOpenCV(inputImg);
patches.clear();
// For each contour, extract the patch
for (size_t i = 0; i<contours.size(); i++)
{
points.clear();
// If the contour contains at least 4 points
if (contours[i].size() >= 4)
{
for(unsigned int j =0; j < 4; ++j)
{
points.push_back(cv::Point2f((contours[i])[j].getX(),(contours[i])[j].getY()));
}
// Find the perspective transformation that brings current marker to rectangular form
cv::Mat markerTransform = cv::getPerspectiveTransform(points, markerCorners2D);
// Transform image to get a canonical marker image
cv::Mat cv_patch;
cv::warpPerspective(cv_inputImg, cv_patch, markerTransform, patches_size);
SRef<Image> patch;
SolAROpenCVHelper::convertToSolar(cv_patch, patch);
patches.push_back(patch);
}
// else add a empty image to ensure the order of contours and output corrected images.
else
patches.push_back(nullptr);
}
return FrameworkReturnCode::_SUCCESS;
}
}
}
} // end of namespace Solar