/******************************************************************************* * Copyright (c) 2021 Nerian Vision GmbH * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. *******************************************************************************/ #ifndef VISIONTRANSFER_RECONSTRUCT3D_H #define VISIONTRANSFER_RECONSTRUCT3D_H #include #include #include "visiontransfer/common.h" #include "visiontransfer/imageset.h" #ifdef OPEN3D_VERSION # include #endif namespace visiontransfer { /** * \brief Transforms a disparity map into a set of 3D points. * * Use this class for reconstructing the 3D location for each valid * point in a disparity map. */ class VT_EXPORT Reconstruct3D { public: /** * \brief Constructs a new object for 3D reconstructing. */ Reconstruct3D(); ~Reconstruct3D(); #ifndef DOXYGEN_SHOULD_SKIP_THIS /** * \brief Reconstructs the 3D location of each pixel in the given * disparity map. * * \param dispMap Pointer to the data of the disparity map. The disparity map is * assumed to have a N-bit subpixel resolution. This means that each * value needs to be divided by the subpixel factor to receive the true disparity. * \param width Width of the disparity map. * \param height Height of the disparity map. * \param rowStride Row stride (i.e. distance between two rows in bytes) of the * disparity map. * \param q Disparity-to-depth mapping matrix of size 4x4. The matrix is * stored in a row-wise alignment. Obtain this matrix from your * camera calibration data. * \param minDisparity The minimum disparity, again with N-bit subpixel * resolution. Lower disparities will be clamped to this value before * computing the 3D location. * \param subpixelFactor Subpixel division factor for disparity value. * \param maxDisparity The maximum value that occurs in the disparity map. Any value * greater or equal will be marked as invalid. * * This method is deprecated in favor of createPointMap(const ImageSet&, unsigned short). */ DEPRECATED("Use createPointMap(const ImageSet&, ...) instead.") float* createPointMap(const unsigned short* dispMap, int width, int height, int rowStride, const float* q, unsigned short minDisparity = 1, int subpixelFactor = 16, unsigned short maxDisparity = 0xFFF); #endif /** * \brief Reconstructs the 3D location of each pixel in the given * disparity map. * * \param imageSet Image set containing the disparity map. * \param minDisparity The minimum disparity with N-bit subpixel resolution. * * The output map will have a size of exactly 4*width*height float values. For each * point the x, y and z coordinates are stored consecutively, plus one additional * float (four bytes) as padding. Invalid disparities will be set to the given minimum disparity. * * If the minimum disparity is set to 0, points with a disparity of 0 or an invalid * disparity will receive a z coordinate of +inf. If a larger minimum disparity is given, * points with a lower disparity will be at a fix depth that corresponds to this * disparity. * * The returned point map is valid until the next call of createPointMap(), createZMap(), or * writePlyFile(). */ float* createPointMap(const ImageSet& imageSet, unsigned short minDisparity = 1); /** * \brief Converts the disparit in an image set to a depth map * * \param imageSet Image set containing the disparity map. * \param minDisparity The minimum disparity with N-bit subpixel resolution. * \param maxDisparity The maximum value that occurs in the disparity map. Any value * greater or equal will be marked as invalid. * * The output map will have a size of exactly width*height float values. Each * value represents the depth at the given pixel coordinate in meters. * * This method is closely related to createPointMap(). It only computes the * Z coordinates, whereas createPointMap() also computes X and Y coordinates * for each image point. * * If the minimum disparity is set to 0, points with a disparity of 0 or an invalid * disparity will receive a z coordinate of +inf. If a larger minimum disparity is given, * points with a lower disparity will be at a fix depth that corresponds to this * disparity. * * The returned map is valid until the next call of createZMap(), createPointMap() or * writePlyFile(). */ float* createZMap(const ImageSet& imageSet, unsigned short minDisparity = 1, unsigned short maxDisparity = 0xFFF); /** * \brief Reconstructs the 3D location of one individual point. * * \param imageX X component of the image location. * \param imageY Y component of the image location. * \param disparity Value of the disparity map at the image location. * It is assumed that the lower N bits are the fractional component. * This means that each value needs to be divided by a subpixel factor to * receive the true disparity. * \param q Disparity-to-depth mapping matrix of size 4x4. The matrix is * stored in a row-wise alignment. Obtain this matrix from your * camera calibration data. * \param pointX Destination variable for the 3D point X component. * \param pointY Destination variable for the 3D point Y component. * \param pointZ Destination variable for the 3D point Z component. * \param subpixelFactor Subpixel division factor for disparity value. * * * This method projects a single point from a disparity map to a * 3D location. If the 3D coordinates of multiple points are of interest, * createPointMap() should be used for best performance. */ void projectSinglePoint(int imageX, int imageY, unsigned short disparity, const float* q, float& pointX, float& pointY, float& pointZ, int subpixelFactor = 16); #ifndef DOXYGEN_SHOULD_SKIP_THIS /** * \brief Projects the given disparity map to 3D points and exports the result to * a PLY file. * * \param file The output file * \param dispMap Pointer to the data of the disparity map. The disparity map is * assumed to have a N-bit subpixel resolution. This means that each * value needs to be divided by a subpixel factor to receive the true disparity. * \param image Rectified left input image in 8-bit gray scale format. * \param width Width of the disparity map and left image. * \param height Height of the disparity map and left image. * \param format Pixel format for the left image. * \param dispRowStride Row stride (i.e. distance between two rows in bytes) of the * disparity map. * \param imageRowStride Row stride (i.e. distance between two rows in bytes) of the * left image. * \param q Disparity-to-depth mapping matrix of size 4x4. The matrix is * stored in a row-wise alignment. Obtain this matrix from your * camera calibration data. * \param maxZ Maximum allowed z-coordinate. Points with a higher z-coordinate * are not exported. * \param binary Specifies whether the ASCII or binary PLY-format should be used. * \param subpixelFactor Subpixel division factor for disparity value. * \param maxDisparity The maximum value that occurs in the disparity map. Any value * greater or equal will be marked as invalid. * * This method is deprecated in favor of * writePlyFile(const char*, const ImageSet&, double maxZ, bool); */ DEPRECATED("Use writePlyFile(const char*, const ImageSet&, ...) instead.") void writePlyFile(const char* file, const unsigned short* dispMap, const unsigned char* image, int width, int height, ImageSet::ImageFormat format, int dispRowStride, int imageRowStride, const float* q, double maxZ = std::numeric_limits::max(), bool binary = false, int subpixelFactor = 16, unsigned short maxDisparity = 0xFFF); #endif /** * \brief Projects the given disparity map to 3D points and exports the result to * a PLY file. * * \param file The name for the output file. * \param imageSet Image set containing camera image and disparity map. * \param maxZ Maximum allowed z-coordinate. * \param binary Specifies whether the ASCII or binary PLY-format should be used. * */ void writePlyFile(const char* file, const ImageSet& imageSet, double maxZ = std::numeric_limits::max(), bool binary = false); #ifdef PCL_MAJOR_VERSION /** * \brief Projects the given disparity map to a PCL point cloud without pixel intensities * * \param imageSet Image set containing the disparity map. * \param frameId Frame ID that will be assigned to the created point cloud. * \param minDisparity The minimum disparity with N-bit subpixel resolution. * * For this method to be available, the PCL headers must be included before * the libvisiontransfer headers! * * If the minimum disparity is set to 0, points with a disparity of 0 or an invalid * disparity will receive a z coordinate of +inf. If a larger minimum disparity is given, * points with a lower disparity will be at a fix depth that corresponds to this * disparity. */ inline pcl::PointCloud::Ptr createXYZCloud(const ImageSet& imageSet, const char* frameId, unsigned short minDisparity = 0); /** * \brief Projects the given disparity map to a PCL point cloud, including pixel intensities. * * See createXYZCloud() for details. */ inline pcl::PointCloud::Ptr createXYZICloud(const ImageSet& imageSet, const char* frameId, unsigned short minDisparity = 0); /** * \brief Projects the given disparity map to a PCL point cloud, including pixel RGB data. * * See createXYZCloud() for details. */ inline pcl::PointCloud::Ptr createXYZRGBCloud(const ImageSet& imageSet, const char* frameId, unsigned short minDisparity = 0); #endif #ifdef OPEN3D_VERSION /** * \brief Projects the given disparity map to a Open3D point cloud * * \param imageSet Image set containing the disparity map. * \param withColor If true, color information will be copied to the * pointcloud. * \param minDisparity The minimum disparity with N-bit subpixel resolution. * * For this method to be available, the Open3d headers must be included before * the libvisiontransfer headers! * * If the minimum disparity is set to 0, points with a disparity of 0 or an invalid * disparity will receive a z coordinate of +inf. If a larger minimum disparity is given, * points with a lower disparity will be at a fix depth that corresponds to this * disparity. */ inline std::shared_ptr createOpen3DCloud(const ImageSet& imageSet, bool withColor, unsigned short minDisparity = 0); /** * \brief Converts the given disparity map to a Open3D RGBDn image * * \param imageSet Image set containing the disparity map. * \param minDisparity The minimum disparity with N-bit subpixel resolution. * * For this method to be available, the Open3d headers must be included before * the libvisiontransfer headers! * * If the minimum disparity is set to 0, points with a disparity of 0 or an invalid * disparity will receive a z coordinate of +inf. If a larger minimum disparity is given, * points with a lower disparity will be at a fix depth that corresponds to this * disparity. */ inline std::shared_ptr createOpen3DImageRGBD(const ImageSet& imageSet, unsigned short minDisparity = 0); #endif private: // We follow the pimpl idiom class Pimpl; Pimpl* pimpl; // This class cannot be copied Reconstruct3D(const Reconstruct3D& other); Reconstruct3D& operator=(const Reconstruct3D&); #ifdef PCL_MAJOR_VERSION // Initializes a PCL point cloud template typename pcl::PointCloud::Ptr initPointCloud(const ImageSet& imageSet, const char* frameId); #endif }; } // namespace #include "visiontransfer/reconstruct3d-pcl.h" #include "visiontransfer/reconstruct3d-open3d.h" #endif