types.cpp 10.7 KB
Newer Older
Ozan Tonkal's avatar
Ozan Tonkal committed
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
/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                           License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of the copyright holders may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
// Authors:
//  * Ozan Tonkal, ozantonkal@gmail.com
//  * Anatoly Baksheev, Itseez Inc.  myname.mysurname <> mycompany.com
//
//  OpenCV Viz module is complete rewrite of
//  PCL visualization module (www.pointclouds.org)
//
//M*/

Anatoly Baksheev's avatar
Anatoly Baksheev committed
49
#include "precomp.hpp"
50

Anatoly Baksheev's avatar
Anatoly Baksheev committed
51 52 53
////////////////////////////////////////////////////////////////////
/// cv::viz::KeyboardEvent

Ozan Tonkal's avatar
Ozan Tonkal committed
54
cv::viz::KeyboardEvent::KeyboardEvent(bool _action, const String& _key_sym, unsigned char key, bool alt, bool ctrl, bool shift)
Ozan Tonkal's avatar
Ozan Tonkal committed
55
  : action_(_action), modifiers_(0), key_code_(key), key_sym_(_key_sym)
Anatoly Baksheev's avatar
Anatoly Baksheev committed
56 57 58 59 60 61 62 63 64 65 66
{
  if (alt)
    modifiers_ = Alt;

  if (ctrl)
    modifiers_ |= Ctrl;

  if (shift)
    modifiers_ |= Shift;
}

Ozan Tonkal's avatar
Ozan Tonkal committed
67 68 69 70 71 72 73
bool cv::viz::KeyboardEvent::isAltPressed() const { return (modifiers_ & Alt) != 0; }
bool cv::viz::KeyboardEvent::isCtrlPressed() const { return (modifiers_ & Ctrl) != 0; }
bool cv::viz::KeyboardEvent::isShiftPressed() const { return (modifiers_ & Shift) != 0; }
unsigned char cv::viz::KeyboardEvent::getKeyCode() const { return key_code_; }
const cv::String& cv::viz::KeyboardEvent::getKeySym() const { return key_sym_; }
bool cv::viz::KeyboardEvent::keyDown() const { return action_; }
bool cv::viz::KeyboardEvent::keyUp() const { return !action_; }
Anatoly Baksheev's avatar
Anatoly Baksheev committed
74 75 76 77

////////////////////////////////////////////////////////////////////
/// cv::viz::MouseEvent

Ozan Tonkal's avatar
Ozan Tonkal committed
78
cv::viz::MouseEvent::MouseEvent(const Type& _type, const MouseButton& _button, const Point& _p,  bool alt, bool ctrl, bool shift)
Anatoly Baksheev's avatar
Anatoly Baksheev committed
79 80 81 82 83 84 85 86 87 88 89
    : type(_type), button(_button), pointer(_p), key_state(0)
{
    if (alt)
        key_state = KeyboardEvent::Alt;

    if (ctrl)
        key_state |= KeyboardEvent::Ctrl;

    if (shift)
        key_state |= KeyboardEvent::Shift;
}
ozantonkal's avatar
ozantonkal committed
90 91 92 93 94 95

////////////////////////////////////////////////////////////////////
/// cv::viz::Mesh3d

struct cv::viz::Mesh3d::loadMeshImpl
{
96
    static cv::viz::Mesh3d loadMesh(const String &file)
ozantonkal's avatar
ozantonkal committed
97
    {
98
        Mesh3d mesh;
ozantonkal's avatar
ozantonkal committed
99 100 101 102

        vtkSmartPointer<vtkPLYReader> reader = vtkSmartPointer<vtkPLYReader>::New();
        reader->SetFileName(file.c_str());
        reader->Update();
Ozan Tonkal's avatar
Ozan Tonkal committed
103

Ozan Tonkal's avatar
Ozan Tonkal committed
104
        vtkSmartPointer<vtkPolyData> poly_data = reader->GetOutput();
105
        CV_Assert("File does not exist or file format is not supported." && poly_data);
Ozan Tonkal's avatar
Ozan Tonkal committed
106

Ozan Tonkal's avatar
Ozan Tonkal committed
107 108
        vtkSmartPointer<vtkPoints> mesh_points = poly_data->GetPoints();
        vtkIdType nr_points = mesh_points->GetNumberOfPoints();
ozantonkal's avatar
ozantonkal committed
109

110
        mesh.cloud.create(1, nr_points, CV_32FC3);
ozantonkal's avatar
ozantonkal committed
111

112
        Vec3f *mesh_cloud = mesh.cloud.ptr<Vec3f>();
Ozan Tonkal's avatar
Ozan Tonkal committed
113
        for (vtkIdType i = 0; i < mesh_points->GetNumberOfPoints(); i++)
ozantonkal's avatar
ozantonkal committed
114
        {
Anatoly Baksheev's avatar
Anatoly Baksheev committed
115
            Vec3d point;
Ozan Tonkal's avatar
Ozan Tonkal committed
116
            mesh_points->GetPoint(i, point.val);
Anatoly Baksheev's avatar
Anatoly Baksheev committed
117
            mesh_cloud[i] = point;
ozantonkal's avatar
ozantonkal committed
118 119 120
        }

        // Then the color information, if any
121 122 123
        vtkUnsignedCharArray* poly_colors = 0;
        if (poly_data->GetPointData())
            poly_colors = vtkUnsignedCharArray::SafeDownCast(poly_data->GetPointData()->GetScalars());
Ozan Tonkal's avatar
Ozan Tonkal committed
124

Ozan Tonkal's avatar
Ozan Tonkal committed
125
        if (poly_colors && (poly_colors->GetNumberOfComponents() == 3))
ozantonkal's avatar
ozantonkal committed
126
        {
127 128
            mesh.colors.create(1, nr_points, CV_8UC3);
            Vec3b *mesh_colors = mesh.colors.ptr<cv::Vec3b>();
ozantonkal's avatar
ozantonkal committed
129

Ozan Tonkal's avatar
Ozan Tonkal committed
130
            for (vtkIdType i = 0; i < mesh_points->GetNumberOfPoints(); i++)
ozantonkal's avatar
ozantonkal committed
131
            {
Anatoly Baksheev's avatar
Anatoly Baksheev committed
132
                Vec3b point_color;
Ozan Tonkal's avatar
Ozan Tonkal committed
133
                poly_colors->GetTupleValue(i, point_color.val);
ozantonkal's avatar
ozantonkal committed
134

135
                std::swap(point_color[0], point_color[2]); // RGB -> BGR
Anatoly Baksheev's avatar
Anatoly Baksheev committed
136
                mesh_colors[i] = point_color;
ozantonkal's avatar
ozantonkal committed
137 138 139
            }
        }
        else
140
            mesh.colors.release();
ozantonkal's avatar
ozantonkal committed
141 142 143 144

        // Now handle the polygons
        vtkIdType* cell_points;
        vtkIdType nr_cell_points;
Ozan Tonkal's avatar
Ozan Tonkal committed
145 146
        vtkCellArray * mesh_polygons = poly_data->GetPolys();
        mesh_polygons->InitTraversal();
Ozan Tonkal's avatar
Ozan Tonkal committed
147

148
        mesh.polygons.create(1, mesh_polygons->GetSize(), CV_32SC1);
Ozan Tonkal's avatar
Ozan Tonkal committed
149

150
        int* polygons = mesh.polygons.ptr<int>();
Ozan Tonkal's avatar
Ozan Tonkal committed
151
        while (mesh_polygons->GetNextCell(nr_cell_points, cell_points))
ozantonkal's avatar
ozantonkal committed
152 153 154
        {
            *polygons++ = nr_cell_points;
            for (int i = 0; i < nr_cell_points; ++i)
Ozan Tonkal's avatar
Ozan Tonkal committed
155
                *polygons++ = static_cast<int>(cell_points[i]);
ozantonkal's avatar
ozantonkal committed
156 157 158 159 160 161
        }

        return mesh;
    }
};

162
cv::viz::Mesh3d cv::viz::Mesh3d::loadMesh(const String& file)
ozantonkal's avatar
ozantonkal committed
163 164 165
{
    return loadMeshImpl::loadMesh(file);
}
166 167 168 169

////////////////////////////////////////////////////////////////////
/// Camera implementation

170
cv::viz::Camera::Camera(float f_x, float f_y, float c_x, float c_y, const Size &window_size)
171
{
172
    init(f_x, f_y, c_x, c_y, window_size);
173 174
}

175
cv::viz::Camera::Camera(const Vec2f &fov, const Size &window_size)
176 177 178
{
    CV_Assert(window_size.width > 0 && window_size.height > 0);
    setClip(Vec2d(0.01, 1000.01)); // Default clipping
179
    setFov(fov);
180 181 182 183
    window_size_ = window_size;
    // Principal point at the center
    principal_point_ = Vec2f(static_cast<float>(window_size.width)*0.5f, static_cast<float>(window_size.height)*0.5f);
    focal_ = Vec2f(principal_point_[0] / tan(fov_[0]*0.5f), principal_point_[1] / tan(fov_[1]*0.5f));
184 185
}

186 187 188 189 190 191 192 193 194
cv::viz::Camera::Camera(const cv::Matx33f & K, const Size &window_size)
{
    float f_x = K(0,0);
    float f_y = K(1,1);
    float c_x = K(0,2);
    float c_y = K(1,2);
    init(f_x, f_y, c_x, c_y, window_size);
}

195
cv::viz::Camera::Camera(const Matx44f &proj, const Size &window_size)
Ozan Tonkal's avatar
Ozan Tonkal committed
196
{
197
    CV_Assert(window_size.width > 0 && window_size.height > 0);
Ozan Tonkal's avatar
Ozan Tonkal committed
198

199 200 201 202 203 204
    double near = proj(2,3) / (proj(2,2) - 1.0);
    double far = near * (proj(2,2) - 1.0) / (proj(2,2) + 1.0);
    double left = near * (proj(0,2)-1) / proj(0,0);
    double right = 2.0 * near / proj(0,0) + left;
    double bottom = near * (proj(1,2)-1) / proj(1,1);
    double top = 2.0 * near / proj(1,1) + bottom;
Ozan Tonkal's avatar
Ozan Tonkal committed
205

Ozan Tonkal's avatar
Ozan Tonkal committed
206
    double epsilon = 2.2204460492503131e-16;
Ozan Tonkal's avatar
Ozan Tonkal committed
207

Ozan Tonkal's avatar
Ozan Tonkal committed
208
    if (fabs(left-right) < epsilon) principal_point_[0] = static_cast<float>(window_size.width) * 0.5f;
Ozan Tonkal's avatar
Ozan Tonkal committed
209
    else principal_point_[0] = (left * static_cast<float>(window_size.width)) / (left - right);
210
    focal_[0] = -near * principal_point_[0] / left;
Ozan Tonkal's avatar
Ozan Tonkal committed
211 212 213

    if (fabs(top-bottom) < epsilon) principal_point_[1] = static_cast<float>(window_size.height) * 0.5f;
    else principal_point_[1] = (top * static_cast<float>(window_size.height)) / (top - bottom);
214
    focal_[1] = near * principal_point_[1] / top;
Ozan Tonkal's avatar
Ozan Tonkal committed
215

216
    setClip(Vec2d(near, far));
217
    fov_[0] = (atan2(principal_point_[0],focal_[0]) + atan2(window_size.width-principal_point_[0],focal_[0]));
218
    fov_[1] = (atan2(principal_point_[1],focal_[1]) + atan2(window_size.height-principal_point_[1],focal_[1]));
Ozan Tonkal's avatar
Ozan Tonkal committed
219

220
    window_size_ = window_size;
221 222
}

223
void cv::viz::Camera::init(float f_x, float f_y, float c_x, float c_y, const Size &window_size)
224 225
{
    CV_Assert(window_size.width > 0 && window_size.height > 0);
226
    setClip(Vec2d(0.01, 1000.01));// Default clipping
Ozan Tonkal's avatar
Ozan Tonkal committed
227

228 229
    fov_[0] = (atan2(c_x,f_x) + atan2(window_size.width-c_x,f_x));
    fov_[1] = (atan2(c_y,f_y) + atan2(window_size.height-c_y,f_y));
Ozan Tonkal's avatar
Ozan Tonkal committed
230

231 232
    principal_point_[0] = c_x;
    principal_point_[1] = c_y;
Ozan Tonkal's avatar
Ozan Tonkal committed
233

234 235
    focal_[0] = f_x;
    focal_[1] = f_y;
Ozan Tonkal's avatar
Ozan Tonkal committed
236

237
    window_size_ = window_size;
238 239
}

240
void cv::viz::Camera::setWindowSize(const Size &window_size)
241 242
{
    CV_Assert(window_size.width > 0 && window_size.height > 0);
Ozan Tonkal's avatar
Ozan Tonkal committed
243

244
    // Get the scale factor and update the principal points
245 246
    float scalex = static_cast<float>(window_size.width) / static_cast<float>(window_size_.width);
    float scaley = static_cast<float>(window_size.height) / static_cast<float>(window_size_.height);
Ozan Tonkal's avatar
Ozan Tonkal committed
247

248 249 250 251 252
    principal_point_[0] *= scalex;
    principal_point_[1] *= scaley;
    focal_ *= scaley;
    // Vertical field of view is fixed!  Update horizontal field of view
    fov_[0] = (atan2(principal_point_[0],focal_[0]) + atan2(window_size.width-principal_point_[0],focal_[0]));
Ozan Tonkal's avatar
Ozan Tonkal committed
253

254
    window_size_ = window_size;
255
}
256

257
void cv::viz::Camera::computeProjectionMatrix(Matx44f &proj) const
258
{
259 260 261 262
    double top = clip_[0] * principal_point_[1] / focal_[1];
    double left = -clip_[0] * principal_point_[0] / focal_[0];
    double right = clip_[0] * (window_size_.width - principal_point_[0]) / focal_[0];
    double bottom = -clip_[0] * (window_size_.height - principal_point_[1]) / focal_[1];
Ozan Tonkal's avatar
Ozan Tonkal committed
263

264 265 266
    double temp1 = 2.0 * clip_[0];
    double temp2 = 1.0 / (right - left);
    double temp3 = 1.0 / (top - bottom);
267
    double temp4 = 1.0 / (clip_[0] - clip_[1]);
Ozan Tonkal's avatar
Ozan Tonkal committed
268

269 270 271 272 273
    proj = Matx44d::zeros();
    proj(0,0) = temp1 * temp2;
    proj(1,1) = temp1 * temp3;
    proj(0,2) = (right + left) * temp2;
    proj(1,2) = (top + bottom) * temp3;
274
    proj(2,2) = (clip_[1]+clip_[0]) * temp4;
275
    proj(3,2) = -1.0;
276
    proj(2,3) = (temp1 * clip_[1]) * temp4;
277 278 279 280
}

cv::viz::Camera cv::viz::Camera::KinectCamera(const Size &window_size)
{
281 282
    // Without distortion, RGB Camera
    // Received from http://nicolas.burrus.name/index.php/Research/KinectCalibration
Ozan Tonkal's avatar
Ozan Tonkal committed
283
    Matx33f K = Matx33f::zeros();
284 285 286 287 288 289
    K(0,0) = 5.2921508098293293e+02;
    K(0,2) = 3.2894272028759258e+02;
    K(1,1) = 5.2556393630057437e+02;
    K(1,2) = 2.6748068171871557e+02;
    K(2,2) = 1.0f;
    return Camera(K, window_size);
Ozan Tonkal's avatar
Ozan Tonkal committed
290
}