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
|