File: distortion.hpp

package info (click to toggle)
sight 25.2.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 42,184 kB
  • sloc: cpp: 289,476; xml: 17,257; ansic: 9,878; python: 1,379; sh: 144; makefile: 33
file content (158 lines) | stat: -rw-r--r-- 5,023 bytes parent folder | download | duplicates (2)
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
/************************************************************************
 *
 * Copyright (C) 2018-2024 IRCAD France
 * Copyright (C) 2018-2020 IHU Strasbourg
 *
 * This file is part of Sight.
 *
 * Sight is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Sight is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with Sight. If not, see <https://www.gnu.org/licenses/>.
 *
 ***********************************************************************/

#pragma once

#include <data/camera.hpp>
#include <data/image.hpp>

#include <service/filter.hpp>

#ifdef OPENCV_CUDA_SUPPORT
#include <opencv2/cudawarping.hpp>
#else
#include <opencv2/core/mat.hpp>
#endif // OPENCV_CUDA_SUPPORT

namespace sight::module::geometry::vision
{

/**
 * @brief   Distort or undistort an image according to camera intrinsics and distortion coefficients.
 *
 * The service can be used either to transform an image or to output the distortion map. The latter case is used when
 * you want to perform the distortion directly in the rendering pipeline.
 *
 * @section Slots Slots
 * - \b change_state() : enabled/disabled the distortion correction.
 *
 * @section XML XML Configuration
 *
 * @code{.xml}
    <service type="sight::module::geometry::vision::distortion">
        <in key="camera" uid="..." />
        <in key="input" uid="..." />
        <inout key="output" uid="..." />
        <mode>distort</mode>
    </service>
   @endcode
 * Or
 * @code{.xml}
    <service type="sight::module::geometry::vision::distortion">
        <in key="camera" uid="..." />
        <inout key="map" uid="..." />
        <mode>distort</mode>
    </service>
   @endcode
 * @subsection Input Input
 * - \b camera [sight::data::camera]: camera containing calibration information.
 * - \b input [sight::data::image]: input image to distort.
 * @subsection In-Out In-Out
 * - \b output [sight::data::image]: output image.
 * - \b map [sight::data::image]: distortion map. Useful mainly if you want to perform the distortion directly with the
 * renderer.
 * @subsection Configuration Configuration:
 * - \b mode(optional) : "distort" or "undistort" the output image (default: "distort").
 */
class distortion : public service::filter
{
public:

    SIGHT_DECLARE_SERVICE(distortion, sight::service::filter);

    /**
     * @name Slots API
     * @{
     */
    static const core::com::slots::key_t CHANGE_STATE_SLOT;
    using change_state_slot_t = core::com::slot<void ()>;
    ///@}

    /// Constructor.
    distortion() noexcept;

    /// Destructor. Does nothing
    ~distortion() noexcept override = default;

    /**
     * @brief Connect data::image::MODIFIED_SIG to service::slots::UPDATE
     * and data::image::BUFFER_MODIFIED_SIG to service::slots::UPDATE
     */
    service::connections_t auto_connections() const override;

protected:

    /// Does nothing
    void configuring() override;

    /// Retrieve the camera.
    void starting() override;

    /// Do nothing.
    void stopping() override;

    /// Distort the image.
    void updating() override;

private:

    /// Distort or undistort the video.
    void remap();

    /// Slot: enable/disable the distort correction.
    void change_state();

    /// Slot: compute the distortion map.
    void calibrate();

    /// True if the undistortion is enabled.
    bool m_is_enabled {false};

    /// If true, distort the output image, otherwise we undistort it
    bool m_distort {true};

    /// True when a calibration mismatch is detected, this avoids to pop-up the error at each update
    bool m_calibration_mismatch {false};

    /// This is used to reset m_calibrationMismatch when the image resolution changes
    data::image::size_t m_prev_image_size {0, 0, 0};

#if OPENCV_CUDA_SUPPORT
    cv::cuda::GpuMat m_map_x;
    cv::cuda::GpuMat m_map_y;
#else
    cv::Mat m_map_x;
    cv::Mat m_map_y;
#endif // OPENCV_CUDA_SUPPORT

    static constexpr std::string_view CAMERA_INPUT = "camera";
    static constexpr std::string_view IMAGE_INPUT  = "input";
    static constexpr std::string_view IMAGE_INOUT  = "output";
    static constexpr std::string_view MAP_INOUT    = "map";

    sight::data::ptr<sight::data::camera, sight::data::access::in> m_camera {this, CAMERA_INPUT};
    sight::data::ptr<sight::data::image, sight::data::access::in> m_image {this, IMAGE_INPUT};
    sight::data::ptr<sight::data::image, sight::data::access::inout> m_output {this, IMAGE_INOUT};
    sight::data::ptr<sight::data::image, sight::data::access::inout> m_map {this, MAP_INOUT};
};

} // namespace sight::module::geometry::vision