1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
8 //
9 //
10 // License Agreement
11 // For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2013, OpenCV Foundation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
21 //
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
25 //
26 // * The name of the copyright holders may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 // Authors:
41 // * Ozan Tonkal, ozantonkal@gmail.com
42 // * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
43 //
44 //M*/
45
46 #include "precomp.hpp"
47
48 ////////////////////////////////////////////////////////////////////
49 /// Events
50
KeyboardEvent(Action _action,const String & _symbol,unsigned char _code,int _modifiers)51 cv::viz::KeyboardEvent::KeyboardEvent(Action _action, const String& _symbol, unsigned char _code, int _modifiers)
52 : action(_action), symbol(_symbol), code(_code), modifiers(_modifiers) {}
53
MouseEvent(const Type & _type,const MouseButton & _button,const Point & _pointer,int _modifiers)54 cv::viz::MouseEvent::MouseEvent(const Type& _type, const MouseButton& _button, const Point& _pointer, int _modifiers)
55 : type(_type), button(_button), pointer(_pointer), modifiers(_modifiers) {}
56
57 ////////////////////////////////////////////////////////////////////
58 /// cv::viz::Mesh3d
59
load(const String & file)60 cv::viz::Mesh cv::viz::Mesh::load(const String& file)
61 {
62 vtkSmartPointer<vtkPLYReader> reader = vtkSmartPointer<vtkPLYReader>::New();
63 reader->SetFileName(file.c_str());
64 reader->Update();
65
66 vtkSmartPointer<vtkPolyData> polydata = reader->GetOutput();
67 CV_Assert("File does not exist or file format is not supported." && polydata);
68
69 Mesh mesh;
70 vtkSmartPointer<vtkCloudMatSink> sink = vtkSmartPointer<vtkCloudMatSink>::New();
71 sink->SetOutput(mesh.cloud, mesh.colors, mesh.normals, mesh.tcoords);
72 sink->SetInputConnection(reader->GetOutputPort());
73 sink->Write();
74
75 // Now handle the polygons
76 vtkSmartPointer<vtkCellArray> polygons = polydata->GetPolys();
77 mesh.polygons.create(1, polygons->GetSize(), CV_32SC1);
78 int* poly_ptr = mesh.polygons.ptr<int>();
79
80 polygons->InitTraversal();
81 vtkIdType nr_cell_points, *cell_points;
82 while (polygons->GetNextCell(nr_cell_points, cell_points))
83 {
84 *poly_ptr++ = nr_cell_points;
85 for (vtkIdType i = 0; i < nr_cell_points; ++i)
86 *poly_ptr++ = (int)cell_points[i];
87 }
88
89 return mesh;
90 }
91
92 ////////////////////////////////////////////////////////////////////
93 /// Camera implementation
94
Camera(double fx,double fy,double cx,double cy,const Size & window_size)95 cv::viz::Camera::Camera(double fx, double fy, double cx, double cy, const Size &window_size)
96 {
97 init(fx, fy, cx, cy, window_size);
98 }
99
Camera(const Vec2d & fov,const Size & window_size)100 cv::viz::Camera::Camera(const Vec2d &fov, const Size &window_size)
101 {
102 CV_Assert(window_size.width > 0 && window_size.height > 0);
103 setClip(Vec2d(0.01, 1000.01)); // Default clipping
104 setFov(fov);
105 window_size_ = window_size;
106 // Principal point at the center
107 principal_point_ = Vec2f(static_cast<float>(window_size.width)*0.5f, static_cast<float>(window_size.height)*0.5f);
108 focal_ = Vec2f(principal_point_[0] / tan(fov_[0]*0.5f), principal_point_[1] / tan(fov_[1]*0.5f));
109 }
110
Camera(const cv::Matx33d & K,const Size & window_size)111 cv::viz::Camera::Camera(const cv::Matx33d & K, const Size &window_size)
112 {
113 double f_x = K(0,0);
114 double f_y = K(1,1);
115 double c_x = K(0,2);
116 double c_y = K(1,2);
117 init(f_x, f_y, c_x, c_y, window_size);
118 }
119
Camera(const Matx44d & proj,const Size & window_size)120 cv::viz::Camera::Camera(const Matx44d &proj, const Size &window_size)
121 {
122 CV_Assert(window_size.width > 0 && window_size.height > 0);
123
124 double near = proj(2,3) / (proj(2,2) - 1.0);
125 double far = near * (proj(2,2) - 1.0) / (proj(2,2) + 1.0);
126 double left = near * (proj(0,2)-1) / proj(0,0);
127 double right = 2.0 * near / proj(0,0) + left;
128 double bottom = near * (proj(1,2)-1) / proj(1,1);
129 double top = 2.0 * near / proj(1,1) + bottom;
130
131 double epsilon = 2.2204460492503131e-16;
132
133 principal_point_[0] = fabs(left-right) < epsilon ? window_size.width * 0.5 : (left * window_size.width) / (left - right);
134 principal_point_[1] = fabs(top-bottom) < epsilon ? window_size.height * 0.5 : (top * window_size.height) / (top - bottom);
135
136 focal_[0] = -near * principal_point_[0] / left;
137 focal_[1] = near * principal_point_[1] / top;
138
139 setClip(Vec2d(near, far));
140 fov_[0] = atan2(principal_point_[0], focal_[0]) + atan2(window_size.width-principal_point_[0], focal_[0]);
141 fov_[1] = atan2(principal_point_[1], focal_[1]) + atan2(window_size.height-principal_point_[1], focal_[1]);
142
143 window_size_ = window_size;
144 }
145
init(double fx,double fy,double cx,double cy,const Size & window_size)146 void cv::viz::Camera::init(double fx, double fy, double cx, double cy, const Size &window_size)
147 {
148 CV_Assert(window_size.width > 0 && window_size.height > 0);
149 setClip(Vec2d(0.01, 1000.01));// Default clipping
150
151 fov_[0] = atan2(cx, fx) + atan2(window_size.width - cx, fx);
152 fov_[1] = atan2(cy, fy) + atan2(window_size.height - cy, fy);
153
154 principal_point_[0] = cx;
155 principal_point_[1] = cy;
156
157 focal_[0] = fx;
158 focal_[1] = fy;
159
160 window_size_ = window_size;
161 }
162
setWindowSize(const Size & window_size)163 void cv::viz::Camera::setWindowSize(const Size &window_size)
164 {
165 CV_Assert(window_size.width > 0 && window_size.height > 0);
166
167 // Get the scale factor and update the principal points
168 float scalex = static_cast<float>(window_size.width) / static_cast<float>(window_size_.width);
169 float scaley = static_cast<float>(window_size.height) / static_cast<float>(window_size_.height);
170
171 principal_point_[0] *= scalex;
172 principal_point_[1] *= scaley;
173 focal_ *= scaley;
174 // Vertical field of view is fixed! Update horizontal field of view
175 fov_[0] = (atan2(principal_point_[0],focal_[0]) + atan2(window_size.width-principal_point_[0],focal_[0]));
176
177 window_size_ = window_size;
178 }
179
computeProjectionMatrix(Matx44d & proj) const180 void cv::viz::Camera::computeProjectionMatrix(Matx44d &proj) const
181 {
182 double top = clip_[0] * principal_point_[1] / focal_[1];
183 double left = -clip_[0] * principal_point_[0] / focal_[0];
184 double right = clip_[0] * (window_size_.width - principal_point_[0]) / focal_[0];
185 double bottom = -clip_[0] * (window_size_.height - principal_point_[1]) / focal_[1];
186
187 double temp1 = 2.0 * clip_[0];
188 double temp2 = 1.0 / (right - left);
189 double temp3 = 1.0 / (top - bottom);
190 double temp4 = 1.0 / (clip_[0] - clip_[1]);
191
192 proj = Matx44d::zeros();
193 proj(0,0) = temp1 * temp2;
194 proj(1,1) = temp1 * temp3;
195 proj(0,2) = (right + left) * temp2;
196 proj(1,2) = (top + bottom) * temp3;
197 proj(2,2) = (clip_[1]+clip_[0]) * temp4;
198 proj(3,2) = -1.0;
199 proj(2,3) = (temp1 * clip_[1]) * temp4;
200 }
201
KinectCamera(const Size & window_size)202 cv::viz::Camera cv::viz::Camera::KinectCamera(const Size &window_size)
203 {
204 Matx33d K(525.0, 0.0, 320.0, 0.0, 525.0, 240.0, 0.0, 0.0, 1.0);
205 return Camera(K, window_size);
206 }
207