Home | History | Annotate | Download | only in src
      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