HoviTron Video Pipeline
Parameters.cpp
1/* The copyright in this software is being made available under the BSD
2* License, included below. This software may be subject to other third party
3* and contributor rights, including patent rights, and no such rights are
4* granted under this license.
5*
6* Copyright (c) 2010-2018, ITU/ISO/IEC
7* All rights reserved.
8*
9* Redistribution and use in source and binary forms, with or without
10* modification, are permitted provided that the following conditions are met:
11*
12* * Redistributions of source code must retain the above copyright notice,
13* this list of conditions and the following disclaimer.
14* * Redistributions in binary form must reproduce the above copyright notice,
15* this list of conditions and the following disclaimer in the documentation
16* and/or other materials provided with the distribution.
17* * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
18* be used to endorse or promote products derived from this software without
19* specific prior written permission.
20*
21* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31* THE POSSIBILITY OF SUCH DAMAGE.
32*/
33
34/*
35Original authors:
36
37Universite Libre de Bruxelles, Brussels, Belgium:
38 Sarah Fachada, Sarah.Fernandes.Pinto.Fachada@ulb.ac.be
39 Daniele Bonatto, Daniele.Bonatto@ulb.ac.be
40 Arnaud Schenkel, arnaud.schenkel@ulb.ac.be
41
42Koninklijke Philips N.V., Eindhoven, The Netherlands:
43 Bart Kroon, bart.kroon@philips.com
44 Bart Sonneveldt, bart.sonneveldt@philips.com
45*/
46
47#include "../include/Parameters.h"
48#include "../include/PoseTraces.h"
49#include "../include/helpersSynthesis.h"
50
51#include <cassert>
52#include <iostream>
53#include <stdexcept>
54
55namespace rvs
56{
57
58 Parameters::Parameters(json::Node root)
59 : m_root(root)
60 {}
61
62 Parameters Parameters::readFrom(json::Node root)
63 {
64 Parameters parameters(root);
65
66 parameters.setProjectionFrom(root);
67 parameters.setPositionFrom(root);
68 parameters.setRotationFrom(root);
69 parameters.setDepthRangeFrom(root);
70 parameters.setHasInvalidDepth(root);
71 parameters.setResolutionFrom(root);
72 parameters.setBitDepthColorFrom(root);
73 parameters.setBitDepthDepthFrom(root);
74 parameters.setColorFormatFrom(root);
75 parameters.setDepthColorFormatFrom(root);
76 parameters.setHorRangeFrom(root);
77 parameters.setVerRangeFrom(root);
78 parameters.setCropRegionFrom(root);
79 parameters.setFocalFrom(root);
80 parameters.setPrinciplePointFrom(root);
81 Parameters::validateUnused(root);
82
83 return parameters;
84 }
85
86 json::Node const& Parameters::getRoot() const
87 {
88 return m_root;
89 }
90
91 std::string const& Parameters::getProjectionType() const
92 {
93 return m_projectionType;
94 }
95
96 cv::Vec3f Parameters::getRotation() const
97 {
98 return m_rotation;
99 }
100
101 void Parameters::setRotation(cv::Vec3f rotation)
102 {
103 m_rotation = rotation;
104 }
105
106 cv::Matx33f Parameters::getRotationMatrix() const
107 {
108 auto const radperdeg = 0.01745329252f;
109 return EulerAnglesToRotationMatrix(radperdeg * m_rotation);
110 }
111
112
113 cv::Vec3f Parameters::getPosition() const
114 {
115 return m_position;
116 }
117
118 void Parameters::setPosition(cv::Vec3f position)
119 {
120 m_position = position;
121 }
122
123 cv::Vec2f Parameters::getDepthRange() const
124 {
125 return m_depthRange;
126 }
127
128 bool Parameters::hasInvalidDepth() const
129 {
130 return m_hasInvalidDepth;
131 }
132
133 cv::Size Parameters::getPaddedSize() const
134 {
135 return m_resolution;
136 }
137
138 cv::Size Parameters::getSize() const
139 {
140 return m_cropRegion.size();
141 }
142
143 cv::Rect Parameters::getCropRegion() const
144 {
145 return m_cropRegion;
146 }
147
148 int Parameters::getColorBitDepth() const
149 {
150 return m_bitDepthColor;
151 }
152
153 int Parameters::getDepthBitDepth() const
154 {
155 return m_bitDepthDepth;
156 }
157
158 ColorFormat Parameters::getColorFormat() const
159 {
160 return m_colorFormat;
161 }
162
163 ColorFormat Parameters::getDepthColorFormat() const
164 {
165 return m_depthColorFormat;
166 }
167
168 cv::Vec2f Parameters::getHorRange() const
169 {
170 assert(m_projectionType == ProjectionType::equirectangular);
171 return m_horRange;
172 }
173
174 cv::Vec2f Parameters::getVerRange() const
175 {
176 assert(m_projectionType == ProjectionType::equirectangular);
177 return m_verRange;
178 }
179
180 bool Parameters::isFullHorRange() const
181 {
182 return m_isFullHorRange;
183 }
184
185 cv::Vec2f Parameters::getFocal() const
186 {
187 assert(m_projectionType == ProjectionType::perspective);
188 return m_focal;
189 }
190
191 cv::Vec2f Parameters::getPrinciplePoint() const
192 {
193 assert(m_projectionType == ProjectionType::perspective);
194 return m_principlePoint - cv::Vec2f(cv::Point2f(m_cropRegion.tl()));
195 }
196
197 void Parameters::printTo(std::ostream& stream) const
198 {
199 stream << m_resolution << ' ' << m_bitDepthColor << "b " << m_bitDepthDepth << "b " << m_depthRange;
200 if (m_cropRegion != cv::Rect(cv::Point(), m_resolution)) {
201 stream << m_cropRegion;
202 }
203 stream << ' ' << m_projectionType << ' ';
204 if (m_projectionType == ProjectionType::equirectangular) {
205 stream << m_horRange << ' ' << m_verRange;
206 }
207 if (m_projectionType == ProjectionType::perspective) {
208 stream << m_focal << ' ' << m_principlePoint;
209 }
210 stream << ' ' << m_position << ' ' << m_rotation;
211 }
212
213 void Parameters::setProjectionFrom(json::Node root)
214 {
215 m_projectionType = root.require("Projection").asString();
216 }
217
218 void Parameters::validateUnused(json::Node root)
219 {
220 if (root.require("Depthmap").asInt() != 1) {
221 throw std::runtime_error("This version of RVS only supports Depthmap 1");
222 }
223
224 // NOTE: This field is not used consistently by the 3DoF+ test material.
225 // For RVS instead use the order of the camera names to determine the blending order.
226 root.require("Background").asInt();
227 }
228
229 namespace
230 {
231 template<int N> cv::Vec<float, N> asFloatVec(json::Node node)
232 {
233 if (node.size() != N) {
234 throw std::runtime_error("JSON parser: Expected a vector of floats");
235 }
236 cv::Vec<float, N> v;
237 for (int i = 0; i != N; ++i) {
238 v[i] = node.at(i).asFloat();
239 }
240 return v;
241 }
242
243 template<int N> cv::Vec<int, N> asIntVec(json::Node node)
244 {
245 if (node.size() != N) {
246 throw std::runtime_error("JSON parser: Expected a vector of floats");
247 }
248 cv::Vec<int, N> v;
249 for (int i = 0; i != N; ++i) {
250 v[i] = node.at(i).asInt();
251 }
252 return v;
253 }
254 }
255
256 void Parameters::setPositionFrom(json::Node root)
257 {
258 m_position = asFloatVec<3>(root.require("Position"));
259 }
260
261 void Parameters::setRotationFrom(json::Node root)
262 {
263 m_rotation = asFloatVec<3>(root.require("Rotation"));
264 }
265
266 void Parameters::setDepthRangeFrom(json::Node root)
267 {
268 m_depthRange = asFloatVec<2>(root.require("Depth_range"));
269 if (!(m_depthRange[0] < m_depthRange[1])) {
270 throw std::runtime_error("Inverted depth range: [near, far] with near > far is not allowed");
271 }
272 if (m_depthRange[1] > 1000.f) {
273 throw std::runtime_error("Invalid depth range: [near, far] with far > 1000 is not allowed because 1000 stands for infinity. Please restrict depth range or change world units.");
274 }
275 }
276
277 void Parameters::setHasInvalidDepth(json::Node root)
278 {
279 // Backwards compatible with RVS 2
280 m_hasInvalidDepth = true;
281
282 auto node = root.optional("HasInvalidDepth");
283 if (node) {
284 m_hasInvalidDepth = node.asBool();
285 }
286 }
287
288 void Parameters::setResolutionFrom(json::Node root)
289 {
290 m_resolution = cv::Size(asIntVec<2>(root.require("Resolution")));
291 }
292
293 void Parameters::setBitDepthColorFrom(json::Node root)
294 {
295 m_bitDepthColor = root.require("BitDepthColor").asInt();
296 }
297
298 void Parameters::setBitDepthDepthFrom(json::Node root)
299 {
300 m_bitDepthDepth = root.require("BitDepthDepth").asInt();
301 }
302
303 void Parameters::setColorFormatFrom(json::Node root)
304 {
305 auto colorFormat = root.require("ColorSpace").asString();
306
307 if (colorFormat == "YUV420") {
308 m_colorFormat = ColorFormat::YUV420;
309 }
310 else
311 throw std::runtime_error("This version of RVS only supports YUV420 color space for texture");
312 }
313
314 void Parameters::setDepthColorFormatFrom(json::Node root)
315 {
316 auto depthColorFormat = root.require("DepthColorSpace").asString();
317
318 if (depthColorFormat == "YUV420") {
319 m_depthColorFormat = ColorFormat::YUV420;
320 }
321 else if (depthColorFormat == "YUV400") {
322 m_depthColorFormat = ColorFormat::YUV400;
323 }
324 else
325 throw std::runtime_error("This version of RVS only supports YUV420 and YUV400 color space for depth");
326 }
327
328 void Parameters::setHorRangeFrom(json::Node root)
329 {
330 if (m_projectionType == ProjectionType::equirectangular) {
331 m_horRange = asFloatVec<2>(root.require("Hor_range"));
332
333 m_isFullHorRange = false;
334 try {
335 m_isFullHorRange = asIntVec<2>(root.require("Hor_range")) == cv::Vec2i(-180, 180);
336 }
337 catch (std::runtime_error&) {}
338 }
339 }
340
341 void Parameters::setVerRangeFrom(json::Node root)
342 {
343 if (m_projectionType == ProjectionType::equirectangular) {
344 m_verRange = asFloatVec<2>(root.require("Ver_range"));
345 }
346 }
347
348 void Parameters::setCropRegionFrom(json::Node root)
349 {
350 auto node = root.optional("Crop_region");
351 if (node) {
352 auto values = asIntVec<4>(node);
353 m_cropRegion = cv::Rect(values[0], values[1], values[2], values[3]);
354 }
355 else {
356 m_cropRegion = cv::Rect(cv::Point(), m_resolution);
357 }
358 }
359
360 void Parameters::setFocalFrom(json::Node root)
361 {
362 if (m_projectionType == ProjectionType::perspective) {
363 m_focal = asFloatVec<2>(root.require("Focal"));
364 }
365 }
366
367 void Parameters::setPrinciplePointFrom(json::Node root)
368 {
369 if (m_projectionType == ProjectionType::perspective) {
370 m_principlePoint = asFloatVec<2>(root.require("Principle_point"));
371 }
372 }
373
374 void Parameters::setNewResolution(int w, int h){
375 auto oldRes = cv::Size(m_resolution);
376 m_resolution = cv::Size(w,h);
377 m_cropRegion = cv::Rect(cv::Point(), m_resolution);
378 float factorW = float(w)/float(oldRes.width);
379 float factorH = float(h)/float(oldRes.height);
380 m_principlePoint[0] *= factorW;
381 m_principlePoint[1] *= factorH;
382 auto factor = std::min(factorW,factorH);
383 m_focal[0] *= factor;
384 m_focal[1] *= factor;
385
386 }
387
388 void Parameters::setFov(cv::Vec4f & fov) {
389
390 auto range = m_depthRange[0] * m_depthRange[1];
391 auto rangeOffset = m_depthRange[0] - m_depthRange[1];
392
393 auto tl = std::tan(fov[0]); //left
394 auto tr = std::tan(fov[1]); //right
395 auto tt = std::tan(fov[2]); //top
396 auto tb = std::tan(fov[3]); //down
397
398 auto tw = tr - tl;
399 auto th = tt - tb;
400
401 auto x0 = (-tl) / tw;
402 auto y0 = (-tb) / th;
403
404 m_focal[0] = m_resolution.width / tw;
405 m_focal[1] = m_resolution.height / th;
406
407
408 m_principlePoint[0] = x0 * m_resolution.width;
409 m_principlePoint[1] = (1-y0) * m_resolution.height;
410 }
411}
Node optional(std::string const &key) const
Definition: JsonParser.cpp:238
std::size_t size() const
Definition: JsonParser.cpp:277
std::string const & asString() const
Definition: JsonParser.cpp:314
Node require(std::string const &key) const
Definition: JsonParser.cpp:259
int asInt() const
Definition: JsonParser.cpp:303
Node at(std::size_t index) const
Definition: JsonParser.cpp:269
bool asBool() const
Definition: JsonParser.cpp:322
float asFloat() const
Definition: JsonParser.cpp:298