File: transformations.rst

package info (click to toggle)
opencv 2.4.9.1%2Bdfsg1-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 124,160 kB
  • ctags: 63,847
  • sloc: xml: 509,055; cpp: 490,794; lisp: 23,208; python: 21,174; java: 19,317; ansic: 1,038; sh: 128; makefile: 80
file content (202 lines) | stat: -rw-r--r-- 5,883 bytes parent folder | download | duplicates (3)
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
.. _transformations:

Transformations
***************

Goal
====

In this tutorial you will learn how to

.. container:: enumeratevisibleitemswithsquare

  * How to use makeTransformToGlobal to compute pose
  * How to use makeCameraPose and Viz3d::setViewerPose
  * How to visualize camera position by axes and by viewing frustum

Code
====

You can download the code from :download:`here <../../../../samples/cpp/tutorial_code/viz/transformations.cpp>`.

.. code-block:: cpp

    #include <opencv2/viz/vizcore.hpp>
    #include <iostream>
    #include <fstream>

    using namespace cv;
    using namespace std;

    /**
     * @function cvcloud_load
     * @brief load bunny.ply
     */
    Mat cvcloud_load()
    {
        Mat cloud(1, 1889, CV_32FC3);
        ifstream ifs("bunny.ply");

        string str;
        for(size_t i = 0; i < 12; ++i)
            getline(ifs, str);

        Point3f* data = cloud.ptr<cv::Point3f>();
        float dummy1, dummy2;
        for(size_t i = 0; i < 1889; ++i)
            ifs >> data[i].x >> data[i].y >> data[i].z >> dummy1 >> dummy2;

        cloud *= 5.0f;
        return cloud;
    }

    /**
     * @function main
     */
    int main(int argn, char **argv)
    {
        if (argn < 2)
        {
            cout << "Usage: " << endl << "./transformations [ G | C ]" << endl;
            return 1;
        }

        bool camera_pov = (argv[1][0] == 'C');

        /// Create a window
        viz::Viz3d myWindow("Coordinate Frame");

        /// Add coordinate axes
        myWindow.showWidget("Coordinate Widget", viz::WCoordinateSystem());

        /// Let's assume camera has the following properties
        Point3f cam_pos(3.0f,3.0f,3.0f), cam_focal_point(3.0f,3.0f,2.0f), cam_y_dir(-1.0f,0.0f,0.0f);

        /// We can get the pose of the cam using makeCameraPose
        Affine3f cam_pose = viz::makeCameraPose(cam_pos, cam_focal_point, cam_y_dir);

        /// We can get the transformation matrix from camera coordinate system to global using
        /// - makeTransformToGlobal. We need the axes of the camera
        Affine3f transform = viz::makeTransformToGlobal(Vec3f(0.0f,-1.0f,0.0f), Vec3f(-1.0f,0.0f,0.0f), Vec3f(0.0f,0.0f,-1.0f), cam_pos);

        /// Create a cloud widget.
        Mat bunny_cloud = cvcloud_load();
        viz::WCloud cloud_widget(bunny_cloud, viz::Color::green());

        /// Pose of the widget in camera frame
        Affine3f cloud_pose = Affine3f().translate(Vec3f(0.0f,0.0f,3.0f));
        /// Pose of the widget in global frame
        Affine3f cloud_pose_global = transform * cloud_pose;

        /// Visualize camera frame
        if (!camera_pov)
        {
            viz::WCameraPosition cpw(0.5); // Coordinate axes
            viz::WCameraPosition cpw_frustum(Vec2f(0.889484, 0.523599)); // Camera frustum
            myWindow.showWidget("CPW", cpw, cam_pose);
            myWindow.showWidget("CPW_FRUSTUM", cpw_frustum, cam_pose);
        }

        /// Visualize widget
        myWindow.showWidget("bunny", cloud_widget, cloud_pose_global);

        /// Set the viewer pose to that of camera
        if (camera_pov)
            myWindow.setViewerPose(cam_pose);

        /// Start event loop.
        myWindow.spin();

        return 0;
    }


Explanation
===========

Here is the general structure of the program:

* Create a visualization window.

.. code-block:: cpp

    /// Create a window
    viz::Viz3d myWindow("Transformations");

* Get camera pose from camera position, camera focal point and y direction.

.. code-block:: cpp

    /// Let's assume camera has the following properties
    Point3f cam_pos(3.0f,3.0f,3.0f), cam_focal_point(3.0f,3.0f,2.0f), cam_y_dir(-1.0f,0.0f,0.0f);

    /// We can get the pose of the cam using makeCameraPose
    Affine3f cam_pose = viz::makeCameraPose(cam_pos, cam_focal_point, cam_y_dir);

* Obtain transform matrix knowing the axes of camera coordinate system.

.. code-block:: cpp

    /// We can get the transformation matrix from camera coordinate system to global using
    /// - makeTransformToGlobal. We need the axes of the camera
    Affine3f transform = viz::makeTransformToGlobal(Vec3f(0.0f,-1.0f,0.0f), Vec3f(-1.0f,0.0f,0.0f), Vec3f(0.0f,0.0f,-1.0f), cam_pos);

* Create a cloud widget from bunny.ply file

.. code-block:: cpp

    /// Create a cloud widget.
    Mat bunny_cloud = cvcloud_load();
    viz::WCloud cloud_widget(bunny_cloud, viz::Color::green());

* Given the pose in camera coordinate system, estimate the global pose.

.. code-block:: cpp

    /// Pose of the widget in camera frame
    Affine3f cloud_pose = Affine3f().translate(Vec3f(0.0f,0.0f,3.0f));
    /// Pose of the widget in global frame
    Affine3f cloud_pose_global = transform * cloud_pose;

* If the view point is set to be global, visualize camera coordinate frame and viewing frustum.

.. code-block:: cpp

    /// Visualize camera frame
    if (!camera_pov)
    {
        viz::WCameraPosition cpw(0.5); // Coordinate axes
        viz::WCameraPosition cpw_frustum(Vec2f(0.889484, 0.523599)); // Camera frustum
        myWindow.showWidget("CPW", cpw, cam_pose);
        myWindow.showWidget("CPW_FRUSTUM", cpw_frustum, cam_pose);
    }

* Visualize the cloud widget with the estimated global pose

.. code-block:: cpp

    /// Visualize widget
    myWindow.showWidget("bunny", cloud_widget, cloud_pose_global);

* If the view point is set to be camera's, set viewer pose to **cam_pose**.

.. code-block:: cpp

    /// Set the viewer pose to that of camera
    if (camera_pov)
        myWindow.setViewerPose(cam_pose);

Results
=======

#. Here is the result from the camera point of view.

    .. image:: images/camera_view_point.png
        :alt: Camera Viewpoint
        :align: center

#. Here is the result from global point of view.

    .. image:: images/global_view_point.png
        :alt: Global Viewpoint
        :align: center