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 (at) gmail.com 42 // * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com 43 // 44 //M*/ 45 46 #include "precomp.hpp" 47 48 //////////////////////////////////////////////////////////////////// 49 /// Events 50 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 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 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 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 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 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 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 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 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 180 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 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