rgbd.hpp 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075
  1. /*
  2. * Software License Agreement (BSD License)
  3. *
  4. * Copyright (c) 2009, Willow Garage, Inc.
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * * Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * * Redistributions in binary form must reproduce the above
  14. * copyright notice, this list of conditions and the following
  15. * disclaimer in the documentation and/or other materials provided
  16. * with the distribution.
  17. * * Neither the name of Willow Garage, Inc. nor the names of its
  18. * contributors may be used to endorse or promote products derived
  19. * from this software without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  24. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  25. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  26. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  27. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  28. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  29. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  31. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  32. * POSSIBILITY OF SUCH DAMAGE.
  33. *
  34. */
  35. #ifndef __OPENCV_RGBD_HPP__
  36. #define __OPENCV_RGBD_HPP__
  37. #ifdef __cplusplus
  38. #include <opencv2/core.hpp>
  39. #include <limits>
  40. /** @defgroup rgbd RGB-Depth Processing
  41. */
  42. namespace cv
  43. {
  44. namespace rgbd
  45. {
  46. //! @addtogroup rgbd
  47. //! @{
  48. /** Checks if the value is a valid depth. For CV_16U or CV_16S, the convention is to be invalid if it is
  49. * a limit. For a float/double, we just check if it is a NaN
  50. * @param depth the depth to check for validity
  51. */
  52. CV_EXPORTS
  53. inline bool
  54. isValidDepth(const float & depth)
  55. {
  56. return !cvIsNaN(depth);
  57. }
  58. CV_EXPORTS
  59. inline bool
  60. isValidDepth(const double & depth)
  61. {
  62. return !cvIsNaN(depth);
  63. }
  64. CV_EXPORTS
  65. inline bool
  66. isValidDepth(const short int & depth)
  67. {
  68. return (depth != std::numeric_limits<short int>::min()) && (depth != std::numeric_limits<short int>::max());
  69. }
  70. CV_EXPORTS
  71. inline bool
  72. isValidDepth(const unsigned short int & depth)
  73. {
  74. return (depth != std::numeric_limits<unsigned short int>::min())
  75. && (depth != std::numeric_limits<unsigned short int>::max());
  76. }
  77. CV_EXPORTS
  78. inline bool
  79. isValidDepth(const int & depth)
  80. {
  81. return (depth != std::numeric_limits<int>::min()) && (depth != std::numeric_limits<int>::max());
  82. }
  83. CV_EXPORTS
  84. inline bool
  85. isValidDepth(const unsigned int & depth)
  86. {
  87. return (depth != std::numeric_limits<unsigned int>::min()) && (depth != std::numeric_limits<unsigned int>::max());
  88. }
  89. /** Object that can compute the normals in an image.
  90. * It is an object as it can cache data for speed efficiency
  91. * The implemented methods are either:
  92. * - FALS (the fastest) and SRI from
  93. * ``Fast and Accurate Computation of Surface Normals from Range Images``
  94. * by H. Badino, D. Huber, Y. Park and T. Kanade
  95. * - the normals with bilateral filtering on a depth image from
  96. * ``Gradient Response Maps for Real-Time Detection of Texture-Less Objects``
  97. * by S. Hinterstoisser, C. Cagniart, S. Ilic, P. Sturm, N. Navab, P. Fua, and V. Lepetit
  98. */
  99. class CV_EXPORTS_W RgbdNormals: public Algorithm
  100. {
  101. public:
  102. enum RGBD_NORMALS_METHOD
  103. {
  104. RGBD_NORMALS_METHOD_FALS = 0,
  105. RGBD_NORMALS_METHOD_LINEMOD = 1,
  106. RGBD_NORMALS_METHOD_SRI = 2
  107. };
  108. RgbdNormals()
  109. :
  110. rows_(0),
  111. cols_(0),
  112. depth_(0),
  113. K_(Mat()),
  114. window_size_(0),
  115. method_(RGBD_NORMALS_METHOD_FALS),
  116. rgbd_normals_impl_(0)
  117. {
  118. }
  119. /** Constructor
  120. * @param rows the number of rows of the depth image normals will be computed on
  121. * @param cols the number of cols of the depth image normals will be computed on
  122. * @param depth the depth of the normals (only CV_32F or CV_64F)
  123. * @param K the calibration matrix to use
  124. * @param window_size the window size to compute the normals: can only be 1,3,5 or 7
  125. * @param method one of the methods to use: RGBD_NORMALS_METHOD_SRI, RGBD_NORMALS_METHOD_FALS
  126. */
  127. RgbdNormals(int rows, int cols, int depth, InputArray K, int window_size = 5, int method =
  128. RgbdNormals::RGBD_NORMALS_METHOD_FALS);
  129. ~RgbdNormals();
  130. CV_WRAP static Ptr<RgbdNormals> create(int rows, int cols, int depth, InputArray K, int window_size = 5, int method =
  131. RgbdNormals::RGBD_NORMALS_METHOD_FALS);
  132. /** Given a set of 3d points in a depth image, compute the normals at each point.
  133. * @param points a rows x cols x 3 matrix of CV_32F/CV64F or a rows x cols x 1 CV_U16S
  134. * @param normals a rows x cols x 3 matrix
  135. */
  136. void
  137. operator()(InputArray points, OutputArray normals) const;
  138. /** Initializes some data that is cached for later computation
  139. * If that function is not called, it will be called the first time normals are computed
  140. */
  141. CV_WRAP void
  142. initialize() const;
  143. CV_WRAP int getRows() const
  144. {
  145. return rows_;
  146. }
  147. CV_WRAP void setRows(int val)
  148. {
  149. rows_ = val;
  150. }
  151. CV_WRAP int getCols() const
  152. {
  153. return cols_;
  154. }
  155. CV_WRAP void setCols(int val)
  156. {
  157. cols_ = val;
  158. }
  159. CV_WRAP int getWindowSize() const
  160. {
  161. return window_size_;
  162. }
  163. CV_WRAP void setWindowSize(int val)
  164. {
  165. window_size_ = val;
  166. }
  167. CV_WRAP int getDepth() const
  168. {
  169. return depth_;
  170. }
  171. CV_WRAP void setDepth(int val)
  172. {
  173. depth_ = val;
  174. }
  175. CV_WRAP cv::Mat getK() const
  176. {
  177. return K_;
  178. }
  179. CV_WRAP void setK(const cv::Mat &val)
  180. {
  181. K_ = val;
  182. }
  183. CV_WRAP int getMethod() const
  184. {
  185. return method_;
  186. }
  187. CV_WRAP void setMethod(int val)
  188. {
  189. method_ = val;
  190. }
  191. protected:
  192. void
  193. initialize_normals_impl(int rows, int cols, int depth, const Mat & K, int window_size, int method) const;
  194. int rows_, cols_, depth_;
  195. Mat K_;
  196. int window_size_;
  197. int method_;
  198. mutable void* rgbd_normals_impl_;
  199. };
  200. /** Object that can clean a noisy depth image
  201. */
  202. class CV_EXPORTS_W DepthCleaner: public Algorithm
  203. {
  204. public:
  205. /** NIL method is from
  206. * ``Modeling Kinect Sensor Noise for Improved 3d Reconstruction and Tracking``
  207. * by C. Nguyen, S. Izadi, D. Lovel
  208. */
  209. enum DEPTH_CLEANER_METHOD
  210. {
  211. DEPTH_CLEANER_NIL
  212. };
  213. DepthCleaner()
  214. :
  215. depth_(0),
  216. window_size_(0),
  217. method_(DEPTH_CLEANER_NIL),
  218. depth_cleaner_impl_(0)
  219. {
  220. }
  221. /** Constructor
  222. * @param depth the depth of the normals (only CV_32F or CV_64F)
  223. * @param window_size the window size to compute the normals: can only be 1,3,5 or 7
  224. * @param method one of the methods to use: RGBD_NORMALS_METHOD_SRI, RGBD_NORMALS_METHOD_FALS
  225. */
  226. DepthCleaner(int depth, int window_size = 5, int method = DepthCleaner::DEPTH_CLEANER_NIL);
  227. ~DepthCleaner();
  228. CV_WRAP static Ptr<DepthCleaner> create(int depth, int window_size = 5, int method = DepthCleaner::DEPTH_CLEANER_NIL);
  229. /** Given a set of 3d points in a depth image, compute the normals at each point.
  230. * @param points a rows x cols x 3 matrix of CV_32F/CV64F or a rows x cols x 1 CV_U16S
  231. * @param depth a rows x cols matrix of the cleaned up depth
  232. */
  233. void
  234. operator()(InputArray points, OutputArray depth) const;
  235. /** Initializes some data that is cached for later computation
  236. * If that function is not called, it will be called the first time normals are computed
  237. */
  238. CV_WRAP void
  239. initialize() const;
  240. CV_WRAP int getWindowSize() const
  241. {
  242. return window_size_;
  243. }
  244. CV_WRAP void setWindowSize(int val)
  245. {
  246. window_size_ = val;
  247. }
  248. CV_WRAP int getDepth() const
  249. {
  250. return depth_;
  251. }
  252. CV_WRAP void setDepth(int val)
  253. {
  254. depth_ = val;
  255. }
  256. CV_WRAP int getMethod() const
  257. {
  258. return method_;
  259. }
  260. CV_WRAP void setMethod(int val)
  261. {
  262. method_ = val;
  263. }
  264. protected:
  265. void
  266. initialize_cleaner_impl() const;
  267. int depth_;
  268. int window_size_;
  269. int method_;
  270. mutable void* depth_cleaner_impl_;
  271. };
  272. /** Registers depth data to an external camera
  273. * Registration is performed by creating a depth cloud, transforming the cloud by
  274. * the rigid body transformation between the cameras, and then projecting the
  275. * transformed points into the RGB camera.
  276. *
  277. * uv_rgb = K_rgb * [R | t] * z * inv(K_ir) * uv_ir
  278. *
  279. * Currently does not check for negative depth values.
  280. *
  281. * @param unregisteredCameraMatrix the camera matrix of the depth camera
  282. * @param registeredCameraMatrix the camera matrix of the external camera
  283. * @param registeredDistCoeffs the distortion coefficients of the external camera
  284. * @param Rt the rigid body transform between the cameras. Transforms points from depth camera frame to external camera frame.
  285. * @param unregisteredDepth the input depth data
  286. * @param outputImagePlaneSize the image plane dimensions of the external camera (width, height)
  287. * @param registeredDepth the result of transforming the depth into the external camera
  288. * @param depthDilation whether or not the depth is dilated to avoid holes and occlusion errors (optional)
  289. */
  290. CV_EXPORTS_W
  291. void
  292. registerDepth(InputArray unregisteredCameraMatrix, InputArray registeredCameraMatrix, InputArray registeredDistCoeffs,
  293. InputArray Rt, InputArray unregisteredDepth, const Size& outputImagePlaneSize,
  294. OutputArray registeredDepth, bool depthDilation=false);
  295. /**
  296. * @param depth the depth image
  297. * @param in_K
  298. * @param in_points the list of xy coordinates
  299. * @param points3d the resulting 3d points
  300. */
  301. CV_EXPORTS_W
  302. void
  303. depthTo3dSparse(InputArray depth, InputArray in_K, InputArray in_points, OutputArray points3d);
  304. /** Converts a depth image to an organized set of 3d points.
  305. * The coordinate system is x pointing left, y down and z away from the camera
  306. * @param depth the depth image (if given as short int CV_U, it is assumed to be the depth in millimeters
  307. * (as done with the Microsoft Kinect), otherwise, if given as CV_32F or CV_64F, it is assumed in meters)
  308. * @param K The calibration matrix
  309. * @param points3d the resulting 3d points. They are of depth the same as `depth` if it is CV_32F or CV_64F, and the
  310. * depth of `K` if `depth` is of depth CV_U
  311. * @param mask the mask of the points to consider (can be empty)
  312. */
  313. CV_EXPORTS_W
  314. void
  315. depthTo3d(InputArray depth, InputArray K, OutputArray points3d, InputArray mask = noArray());
  316. /** If the input image is of type CV_16UC1 (like the Kinect one), the image is converted to floats, divided
  317. * by 1000 to get a depth in meters, and the values 0 are converted to std::numeric_limits<float>::quiet_NaN()
  318. * Otherwise, the image is simply converted to floats
  319. * @param in the depth image (if given as short int CV_U, it is assumed to be the depth in millimeters
  320. * (as done with the Microsoft Kinect), it is assumed in meters)
  321. * @param depth the desired output depth (floats or double)
  322. * @param out The rescaled float depth image
  323. */
  324. CV_EXPORTS_W
  325. void
  326. rescaleDepth(InputArray in, int depth, OutputArray out);
  327. /** Object that can compute planes in an image
  328. */
  329. class CV_EXPORTS_W RgbdPlane: public Algorithm
  330. {
  331. public:
  332. enum RGBD_PLANE_METHOD
  333. {
  334. RGBD_PLANE_METHOD_DEFAULT
  335. };
  336. RgbdPlane(int method = RgbdPlane::RGBD_PLANE_METHOD_DEFAULT)
  337. :
  338. method_(method),
  339. block_size_(40),
  340. min_size_(block_size_*block_size_),
  341. threshold_(0.01),
  342. sensor_error_a_(0),
  343. sensor_error_b_(0),
  344. sensor_error_c_(0)
  345. {
  346. }
  347. /** Find The planes in a depth image
  348. * @param points3d the 3d points organized like the depth image: rows x cols with 3 channels
  349. * @param normals the normals for every point in the depth image
  350. * @param mask An image where each pixel is labeled with the plane it belongs to
  351. * and 255 if it does not belong to any plane
  352. * @param plane_coefficients the coefficients of the corresponding planes (a,b,c,d) such that ax+by+cz+d=0, norm(a,b,c)=1
  353. * and c < 0 (so that the normal points towards the camera)
  354. */
  355. void
  356. operator()(InputArray points3d, InputArray normals, OutputArray mask,
  357. OutputArray plane_coefficients);
  358. /** Find The planes in a depth image but without doing a normal check, which is faster but less accurate
  359. * @param points3d the 3d points organized like the depth image: rows x cols with 3 channels
  360. * @param mask An image where each pixel is labeled with the plane it belongs to
  361. * and 255 if it does not belong to any plane
  362. * @param plane_coefficients the coefficients of the corresponding planes (a,b,c,d) such that ax+by+cz+d=0
  363. */
  364. void
  365. operator()(InputArray points3d, OutputArray mask, OutputArray plane_coefficients);
  366. CV_WRAP int getBlockSize() const
  367. {
  368. return block_size_;
  369. }
  370. CV_WRAP void setBlockSize(int val)
  371. {
  372. block_size_ = val;
  373. }
  374. CV_WRAP int getMinSize() const
  375. {
  376. return min_size_;
  377. }
  378. CV_WRAP void setMinSize(int val)
  379. {
  380. min_size_ = val;
  381. }
  382. CV_WRAP int getMethod() const
  383. {
  384. return method_;
  385. }
  386. CV_WRAP void setMethod(int val)
  387. {
  388. method_ = val;
  389. }
  390. CV_WRAP double getThreshold() const
  391. {
  392. return threshold_;
  393. }
  394. CV_WRAP void setThreshold(double val)
  395. {
  396. threshold_ = val;
  397. }
  398. CV_WRAP double getSensorErrorA() const
  399. {
  400. return sensor_error_a_;
  401. }
  402. CV_WRAP void setSensorErrorA(double val)
  403. {
  404. sensor_error_a_ = val;
  405. }
  406. CV_WRAP double getSensorErrorB() const
  407. {
  408. return sensor_error_b_;
  409. }
  410. CV_WRAP void setSensorErrorB(double val)
  411. {
  412. sensor_error_b_ = val;
  413. }
  414. CV_WRAP double getSensorErrorC() const
  415. {
  416. return sensor_error_c_;
  417. }
  418. CV_WRAP void setSensorErrorC(double val)
  419. {
  420. sensor_error_c_ = val;
  421. }
  422. private:
  423. /** The method to use to compute the planes */
  424. int method_;
  425. /** The size of the blocks to look at for a stable MSE */
  426. int block_size_;
  427. /** The minimum size of a cluster to be considered a plane */
  428. int min_size_;
  429. /** How far a point can be from a plane to belong to it (in meters) */
  430. double threshold_;
  431. /** coefficient of the sensor error with respect to the. All 0 by default but you want a=0.0075 for a Kinect */
  432. double sensor_error_a_, sensor_error_b_, sensor_error_c_;
  433. };
  434. /** Object that contains a frame data.
  435. */
  436. struct CV_EXPORTS_W RgbdFrame
  437. {
  438. RgbdFrame();
  439. RgbdFrame(const Mat& image, const Mat& depth, const Mat& mask=Mat(), const Mat& normals=Mat(), int ID=-1);
  440. virtual ~RgbdFrame();
  441. CV_WRAP static Ptr<RgbdFrame> create(const Mat& image=Mat(), const Mat& depth=Mat(), const Mat& mask=Mat(), const Mat& normals=Mat(), int ID=-1);
  442. CV_WRAP virtual void
  443. release();
  444. CV_PROP int ID;
  445. CV_PROP Mat image;
  446. CV_PROP Mat depth;
  447. CV_PROP Mat mask;
  448. CV_PROP Mat normals;
  449. };
  450. /** Object that contains a frame data that is possibly needed for the Odometry.
  451. * It's used for the efficiency (to pass precomputed/cached data of the frame that participates
  452. * in the Odometry processing several times).
  453. */
  454. struct CV_EXPORTS_W OdometryFrame : public RgbdFrame
  455. {
  456. /** These constants are used to set a type of cache which has to be prepared depending on the frame role:
  457. * srcFrame or dstFrame (see compute method of the Odometry class). For the srcFrame and dstFrame different cache data may be required,
  458. * some part of a cache may be common for both frame roles.
  459. * @param CACHE_SRC The cache data for the srcFrame will be prepared.
  460. * @param CACHE_DST The cache data for the dstFrame will be prepared.
  461. * @param CACHE_ALL The cache data for both srcFrame and dstFrame roles will be computed.
  462. */
  463. enum
  464. {
  465. CACHE_SRC = 1, CACHE_DST = 2, CACHE_ALL = CACHE_SRC + CACHE_DST
  466. };
  467. OdometryFrame();
  468. OdometryFrame(const Mat& image, const Mat& depth, const Mat& mask=Mat(), const Mat& normals=Mat(), int ID=-1);
  469. CV_WRAP static Ptr<OdometryFrame> create(const Mat& image=Mat(), const Mat& depth=Mat(), const Mat& mask=Mat(), const Mat& normals=Mat(), int ID=-1);
  470. CV_WRAP virtual void
  471. release();
  472. CV_WRAP void
  473. releasePyramids();
  474. CV_PROP std::vector<Mat> pyramidImage;
  475. CV_PROP std::vector<Mat> pyramidDepth;
  476. CV_PROP std::vector<Mat> pyramidMask;
  477. CV_PROP std::vector<Mat> pyramidCloud;
  478. CV_PROP std::vector<Mat> pyramid_dI_dx;
  479. CV_PROP std::vector<Mat> pyramid_dI_dy;
  480. CV_PROP std::vector<Mat> pyramidTexturedMask;
  481. CV_PROP std::vector<Mat> pyramidNormals;
  482. CV_PROP std::vector<Mat> pyramidNormalsMask;
  483. };
  484. /** Base class for computation of odometry.
  485. */
  486. class CV_EXPORTS_W Odometry: public Algorithm
  487. {
  488. public:
  489. /** A class of transformation*/
  490. enum
  491. {
  492. ROTATION = 1, TRANSLATION = 2, RIGID_BODY_MOTION = 4
  493. };
  494. CV_WRAP static inline float
  495. DEFAULT_MIN_DEPTH()
  496. {
  497. return 0.f; // in meters
  498. }
  499. CV_WRAP static inline float
  500. DEFAULT_MAX_DEPTH()
  501. {
  502. return 4.f; // in meters
  503. }
  504. CV_WRAP static inline float
  505. DEFAULT_MAX_DEPTH_DIFF()
  506. {
  507. return 0.07f; // in meters
  508. }
  509. CV_WRAP static inline float
  510. DEFAULT_MAX_POINTS_PART()
  511. {
  512. return 0.07f; // in [0, 1]
  513. }
  514. CV_WRAP static inline float
  515. DEFAULT_MAX_TRANSLATION()
  516. {
  517. return 0.15f; // in meters
  518. }
  519. CV_WRAP static inline float
  520. DEFAULT_MAX_ROTATION()
  521. {
  522. return 15; // in degrees
  523. }
  524. /** Method to compute a transformation from the source frame to the destination one.
  525. * Some odometry algorithms do not used some data of frames (eg. ICP does not use images).
  526. * In such case corresponding arguments can be set as empty Mat.
  527. * The method returns true if all internal computions were possible (e.g. there were enough correspondences,
  528. * system of equations has a solution, etc) and resulting transformation satisfies some test if it's provided
  529. * by the Odometry inheritor implementation (e.g. thresholds for maximum translation and rotation).
  530. * @param srcImage Image data of the source frame (CV_8UC1)
  531. * @param srcDepth Depth data of the source frame (CV_32FC1, in meters)
  532. * @param srcMask Mask that sets which pixels have to be used from the source frame (CV_8UC1)
  533. * @param dstImage Image data of the destination frame (CV_8UC1)
  534. * @param dstDepth Depth data of the destination frame (CV_32FC1, in meters)
  535. * @param dstMask Mask that sets which pixels have to be used from the destination frame (CV_8UC1)
  536. * @param Rt Resulting transformation from the source frame to the destination one (rigid body motion):
  537. dst_p = Rt * src_p, where dst_p is a homogeneous point in the destination frame and src_p is
  538. homogeneous point in the source frame,
  539. Rt is 4x4 matrix of CV_64FC1 type.
  540. * @param initRt Initial transformation from the source frame to the destination one (optional)
  541. */
  542. CV_WRAP bool
  543. compute(const Mat& srcImage, const Mat& srcDepth, const Mat& srcMask, const Mat& dstImage, const Mat& dstDepth,
  544. const Mat& dstMask, OutputArray Rt, const Mat& initRt = Mat()) const;
  545. /** One more method to compute a transformation from the source frame to the destination one.
  546. * It is designed to save on computing the frame data (image pyramids, normals, etc.).
  547. */
  548. CV_WRAP_AS(compute2) bool
  549. compute(Ptr<OdometryFrame>& srcFrame, Ptr<OdometryFrame>& dstFrame, OutputArray Rt, const Mat& initRt = Mat()) const;
  550. /** Prepare a cache for the frame. The function checks the precomputed/passed data (throws the error if this data
  551. * does not satisfy) and computes all remaining cache data needed for the frame. Returned size is a resolution
  552. * of the prepared frame.
  553. * @param frame The odometry which will process the frame.
  554. * @param cacheType The cache type: CACHE_SRC, CACHE_DST or CACHE_ALL.
  555. */
  556. CV_WRAP virtual Size prepareFrameCache(Ptr<OdometryFrame>& frame, int cacheType) const;
  557. CV_WRAP static Ptr<Odometry> create(const String & odometryType);
  558. /** @see setCameraMatrix */
  559. CV_WRAP virtual cv::Mat getCameraMatrix() const = 0;
  560. /** @copybrief getCameraMatrix @see getCameraMatrix */
  561. CV_WRAP virtual void setCameraMatrix(const cv::Mat &val) = 0;
  562. /** @see setTransformType */
  563. CV_WRAP virtual int getTransformType() const = 0;
  564. /** @copybrief getTransformType @see getTransformType */
  565. CV_WRAP virtual void setTransformType(int val) = 0;
  566. protected:
  567. virtual void
  568. checkParams() const = 0;
  569. virtual bool
  570. computeImpl(const Ptr<OdometryFrame>& srcFrame, const Ptr<OdometryFrame>& dstFrame, OutputArray Rt,
  571. const Mat& initRt) const = 0;
  572. };
  573. /** Odometry based on the paper "Real-Time Visual Odometry from Dense RGB-D Images",
  574. * F. Steinbucker, J. Strum, D. Cremers, ICCV, 2011.
  575. */
  576. class CV_EXPORTS_W RgbdOdometry: public Odometry
  577. {
  578. public:
  579. RgbdOdometry();
  580. /** Constructor.
  581. * @param cameraMatrix Camera matrix
  582. * @param minDepth Pixels with depth less than minDepth will not be used (in meters)
  583. * @param maxDepth Pixels with depth larger than maxDepth will not be used (in meters)
  584. * @param maxDepthDiff Correspondences between pixels of two given frames will be filtered out
  585. * if their depth difference is larger than maxDepthDiff (in meters)
  586. * @param iterCounts Count of iterations on each pyramid level.
  587. * @param minGradientMagnitudes For each pyramid level the pixels will be filtered out
  588. * if they have gradient magnitude less than minGradientMagnitudes[level].
  589. * @param maxPointsPart The method uses a random pixels subset of size frameWidth x frameHeight x pointsPart
  590. * @param transformType Class of transformation
  591. */
  592. RgbdOdometry(const Mat& cameraMatrix, float minDepth = Odometry::DEFAULT_MIN_DEPTH(), float maxDepth = Odometry::DEFAULT_MAX_DEPTH(),
  593. float maxDepthDiff = Odometry::DEFAULT_MAX_DEPTH_DIFF(), const std::vector<int>& iterCounts = std::vector<int>(),
  594. const std::vector<float>& minGradientMagnitudes = std::vector<float>(), float maxPointsPart = Odometry::DEFAULT_MAX_POINTS_PART(),
  595. int transformType = Odometry::RIGID_BODY_MOTION);
  596. CV_WRAP static Ptr<RgbdOdometry> create(const Mat& cameraMatrix = Mat(), float minDepth = Odometry::DEFAULT_MIN_DEPTH(), float maxDepth = Odometry::DEFAULT_MAX_DEPTH(),
  597. float maxDepthDiff = Odometry::DEFAULT_MAX_DEPTH_DIFF(), const std::vector<int>& iterCounts = std::vector<int>(),
  598. const std::vector<float>& minGradientMagnitudes = std::vector<float>(), float maxPointsPart = Odometry::DEFAULT_MAX_POINTS_PART(),
  599. int transformType = Odometry::RIGID_BODY_MOTION);
  600. CV_WRAP virtual Size prepareFrameCache(Ptr<OdometryFrame>& frame, int cacheType) const;
  601. CV_WRAP cv::Mat getCameraMatrix() const
  602. {
  603. return cameraMatrix;
  604. }
  605. CV_WRAP void setCameraMatrix(const cv::Mat &val)
  606. {
  607. cameraMatrix = val;
  608. }
  609. CV_WRAP double getMinDepth() const
  610. {
  611. return minDepth;
  612. }
  613. CV_WRAP void setMinDepth(double val)
  614. {
  615. minDepth = val;
  616. }
  617. CV_WRAP double getMaxDepth() const
  618. {
  619. return maxDepth;
  620. }
  621. CV_WRAP void setMaxDepth(double val)
  622. {
  623. maxDepth = val;
  624. }
  625. CV_WRAP double getMaxDepthDiff() const
  626. {
  627. return maxDepthDiff;
  628. }
  629. CV_WRAP void setMaxDepthDiff(double val)
  630. {
  631. maxDepthDiff = val;
  632. }
  633. CV_WRAP cv::Mat getIterationCounts() const
  634. {
  635. return iterCounts;
  636. }
  637. CV_WRAP void setIterationCounts(const cv::Mat &val)
  638. {
  639. iterCounts = val;
  640. }
  641. CV_WRAP cv::Mat getMinGradientMagnitudes() const
  642. {
  643. return minGradientMagnitudes;
  644. }
  645. CV_WRAP void setMinGradientMagnitudes(const cv::Mat &val)
  646. {
  647. minGradientMagnitudes = val;
  648. }
  649. CV_WRAP double getMaxPointsPart() const
  650. {
  651. return maxPointsPart;
  652. }
  653. CV_WRAP void setMaxPointsPart(double val)
  654. {
  655. maxPointsPart = val;
  656. }
  657. CV_WRAP int getTransformType() const
  658. {
  659. return transformType;
  660. }
  661. CV_WRAP void setTransformType(int val)
  662. {
  663. transformType = val;
  664. }
  665. CV_WRAP double getMaxTranslation() const
  666. {
  667. return maxTranslation;
  668. }
  669. CV_WRAP void setMaxTranslation(double val)
  670. {
  671. maxTranslation = val;
  672. }
  673. CV_WRAP double getMaxRotation() const
  674. {
  675. return maxRotation;
  676. }
  677. CV_WRAP void setMaxRotation(double val)
  678. {
  679. maxRotation = val;
  680. }
  681. protected:
  682. virtual void
  683. checkParams() const;
  684. virtual bool
  685. computeImpl(const Ptr<OdometryFrame>& srcFrame, const Ptr<OdometryFrame>& dstFrame, OutputArray Rt,
  686. const Mat& initRt) const;
  687. // Some params have commented desired type. It's due to AlgorithmInfo::addParams does not support it now.
  688. /*float*/
  689. double minDepth, maxDepth, maxDepthDiff;
  690. /*vector<int>*/
  691. Mat iterCounts;
  692. /*vector<float>*/
  693. Mat minGradientMagnitudes;
  694. double maxPointsPart;
  695. Mat cameraMatrix;
  696. int transformType;
  697. double maxTranslation, maxRotation;
  698. };
  699. /** Odometry based on the paper "KinectFusion: Real-Time Dense Surface Mapping and Tracking",
  700. * Richard A. Newcombe, Andrew Fitzgibbon, at al, SIGGRAPH, 2011.
  701. */
  702. class CV_EXPORTS_W ICPOdometry: public Odometry
  703. {
  704. public:
  705. ICPOdometry();
  706. /** Constructor.
  707. * @param cameraMatrix Camera matrix
  708. * @param minDepth Pixels with depth less than minDepth will not be used
  709. * @param maxDepth Pixels with depth larger than maxDepth will not be used
  710. * @param maxDepthDiff Correspondences between pixels of two given frames will be filtered out
  711. * if their depth difference is larger than maxDepthDiff
  712. * @param maxPointsPart The method uses a random pixels subset of size frameWidth x frameHeight x pointsPart
  713. * @param iterCounts Count of iterations on each pyramid level.
  714. * @param transformType Class of trasformation
  715. */
  716. ICPOdometry(const Mat& cameraMatrix, float minDepth = Odometry::DEFAULT_MIN_DEPTH(), float maxDepth = Odometry::DEFAULT_MAX_DEPTH(),
  717. float maxDepthDiff = Odometry::DEFAULT_MAX_DEPTH_DIFF(), float maxPointsPart = Odometry::DEFAULT_MAX_POINTS_PART(),
  718. const std::vector<int>& iterCounts = std::vector<int>(), int transformType = Odometry::RIGID_BODY_MOTION);
  719. CV_WRAP static Ptr<ICPOdometry> create(const Mat& cameraMatrix = Mat(), float minDepth = Odometry::DEFAULT_MIN_DEPTH(), float maxDepth = Odometry::DEFAULT_MAX_DEPTH(),
  720. float maxDepthDiff = Odometry::DEFAULT_MAX_DEPTH_DIFF(), float maxPointsPart = Odometry::DEFAULT_MAX_POINTS_PART(),
  721. const std::vector<int>& iterCounts = std::vector<int>(), int transformType = Odometry::RIGID_BODY_MOTION);
  722. CV_WRAP virtual Size prepareFrameCache(Ptr<OdometryFrame>& frame, int cacheType) const;
  723. CV_WRAP cv::Mat getCameraMatrix() const
  724. {
  725. return cameraMatrix;
  726. }
  727. CV_WRAP void setCameraMatrix(const cv::Mat &val)
  728. {
  729. cameraMatrix = val;
  730. }
  731. CV_WRAP double getMinDepth() const
  732. {
  733. return minDepth;
  734. }
  735. CV_WRAP void setMinDepth(double val)
  736. {
  737. minDepth = val;
  738. }
  739. CV_WRAP double getMaxDepth() const
  740. {
  741. return maxDepth;
  742. }
  743. CV_WRAP void setMaxDepth(double val)
  744. {
  745. maxDepth = val;
  746. }
  747. CV_WRAP double getMaxDepthDiff() const
  748. {
  749. return maxDepthDiff;
  750. }
  751. CV_WRAP void setMaxDepthDiff(double val)
  752. {
  753. maxDepthDiff = val;
  754. }
  755. CV_WRAP cv::Mat getIterationCounts() const
  756. {
  757. return iterCounts;
  758. }
  759. CV_WRAP void setIterationCounts(const cv::Mat &val)
  760. {
  761. iterCounts = val;
  762. }
  763. CV_WRAP double getMaxPointsPart() const
  764. {
  765. return maxPointsPart;
  766. }
  767. CV_WRAP void setMaxPointsPart(double val)
  768. {
  769. maxPointsPart = val;
  770. }
  771. CV_WRAP int getTransformType() const
  772. {
  773. return transformType;
  774. }
  775. CV_WRAP void setTransformType(int val)
  776. {
  777. transformType = val;
  778. }
  779. CV_WRAP double getMaxTranslation() const
  780. {
  781. return maxTranslation;
  782. }
  783. CV_WRAP void setMaxTranslation(double val)
  784. {
  785. maxTranslation = val;
  786. }
  787. CV_WRAP double getMaxRotation() const
  788. {
  789. return maxRotation;
  790. }
  791. CV_WRAP void setMaxRotation(double val)
  792. {
  793. maxRotation = val;
  794. }
  795. CV_WRAP Ptr<RgbdNormals> getNormalsComputer() const
  796. {
  797. return normalsComputer;
  798. }
  799. protected:
  800. virtual void
  801. checkParams() const;
  802. virtual bool
  803. computeImpl(const Ptr<OdometryFrame>& srcFrame, const Ptr<OdometryFrame>& dstFrame, OutputArray Rt,
  804. const Mat& initRt) const;
  805. // Some params have commented desired type. It's due to AlgorithmInfo::addParams does not support it now.
  806. /*float*/
  807. double minDepth, maxDepth, maxDepthDiff;
  808. /*float*/
  809. double maxPointsPart;
  810. /*vector<int>*/
  811. Mat iterCounts;
  812. Mat cameraMatrix;
  813. int transformType;
  814. double maxTranslation, maxRotation;
  815. mutable Ptr<RgbdNormals> normalsComputer;
  816. };
  817. /** Odometry that merges RgbdOdometry and ICPOdometry by minimize sum of their energy functions.
  818. */
  819. class CV_EXPORTS_W RgbdICPOdometry: public Odometry
  820. {
  821. public:
  822. RgbdICPOdometry();
  823. /** Constructor.
  824. * @param cameraMatrix Camera matrix
  825. * @param minDepth Pixels with depth less than minDepth will not be used
  826. * @param maxDepth Pixels with depth larger than maxDepth will not be used
  827. * @param maxDepthDiff Correspondences between pixels of two given frames will be filtered out
  828. * if their depth difference is larger than maxDepthDiff
  829. * @param maxPointsPart The method uses a random pixels subset of size frameWidth x frameHeight x pointsPart
  830. * @param iterCounts Count of iterations on each pyramid level.
  831. * @param minGradientMagnitudes For each pyramid level the pixels will be filtered out
  832. * if they have gradient magnitude less than minGradientMagnitudes[level].
  833. * @param transformType Class of trasformation
  834. */
  835. RgbdICPOdometry(const Mat& cameraMatrix, float minDepth = Odometry::DEFAULT_MIN_DEPTH(), float maxDepth = Odometry::DEFAULT_MAX_DEPTH(),
  836. float maxDepthDiff = Odometry::DEFAULT_MAX_DEPTH_DIFF(), float maxPointsPart = Odometry::DEFAULT_MAX_POINTS_PART(),
  837. const std::vector<int>& iterCounts = std::vector<int>(),
  838. const std::vector<float>& minGradientMagnitudes = std::vector<float>(),
  839. int transformType = Odometry::RIGID_BODY_MOTION);
  840. CV_WRAP static Ptr<RgbdICPOdometry> create(const Mat& cameraMatrix = Mat(), float minDepth = Odometry::DEFAULT_MIN_DEPTH(), float maxDepth = Odometry::DEFAULT_MAX_DEPTH(),
  841. float maxDepthDiff = Odometry::DEFAULT_MAX_DEPTH_DIFF(), float maxPointsPart = Odometry::DEFAULT_MAX_POINTS_PART(),
  842. const std::vector<int>& iterCounts = std::vector<int>(),
  843. const std::vector<float>& minGradientMagnitudes = std::vector<float>(),
  844. int transformType = Odometry::RIGID_BODY_MOTION);
  845. CV_WRAP virtual Size prepareFrameCache(Ptr<OdometryFrame>& frame, int cacheType) const;
  846. CV_WRAP cv::Mat getCameraMatrix() const
  847. {
  848. return cameraMatrix;
  849. }
  850. CV_WRAP void setCameraMatrix(const cv::Mat &val)
  851. {
  852. cameraMatrix = val;
  853. }
  854. CV_WRAP double getMinDepth() const
  855. {
  856. return minDepth;
  857. }
  858. CV_WRAP void setMinDepth(double val)
  859. {
  860. minDepth = val;
  861. }
  862. CV_WRAP double getMaxDepth() const
  863. {
  864. return maxDepth;
  865. }
  866. CV_WRAP void setMaxDepth(double val)
  867. {
  868. maxDepth = val;
  869. }
  870. CV_WRAP double getMaxDepthDiff() const
  871. {
  872. return maxDepthDiff;
  873. }
  874. CV_WRAP void setMaxDepthDiff(double val)
  875. {
  876. maxDepthDiff = val;
  877. }
  878. CV_WRAP double getMaxPointsPart() const
  879. {
  880. return maxPointsPart;
  881. }
  882. CV_WRAP void setMaxPointsPart(double val)
  883. {
  884. maxPointsPart = val;
  885. }
  886. CV_WRAP cv::Mat getIterationCounts() const
  887. {
  888. return iterCounts;
  889. }
  890. CV_WRAP void setIterationCounts(const cv::Mat &val)
  891. {
  892. iterCounts = val;
  893. }
  894. CV_WRAP cv::Mat getMinGradientMagnitudes() const
  895. {
  896. return minGradientMagnitudes;
  897. }
  898. CV_WRAP void setMinGradientMagnitudes(const cv::Mat &val)
  899. {
  900. minGradientMagnitudes = val;
  901. }
  902. CV_WRAP int getTransformType() const
  903. {
  904. return transformType;
  905. }
  906. CV_WRAP void setTransformType(int val)
  907. {
  908. transformType = val;
  909. }
  910. CV_WRAP double getMaxTranslation() const
  911. {
  912. return maxTranslation;
  913. }
  914. CV_WRAP void setMaxTranslation(double val)
  915. {
  916. maxTranslation = val;
  917. }
  918. CV_WRAP double getMaxRotation() const
  919. {
  920. return maxRotation;
  921. }
  922. CV_WRAP void setMaxRotation(double val)
  923. {
  924. maxRotation = val;
  925. }
  926. CV_WRAP Ptr<RgbdNormals> getNormalsComputer() const
  927. {
  928. return normalsComputer;
  929. }
  930. protected:
  931. virtual void
  932. checkParams() const;
  933. virtual bool
  934. computeImpl(const Ptr<OdometryFrame>& srcFrame, const Ptr<OdometryFrame>& dstFrame, OutputArray Rt,
  935. const Mat& initRt) const;
  936. // Some params have commented desired type. It's due to AlgorithmInfo::addParams does not support it now.
  937. /*float*/
  938. double minDepth, maxDepth, maxDepthDiff;
  939. /*float*/
  940. double maxPointsPart;
  941. /*vector<int>*/
  942. Mat iterCounts;
  943. /*vector<float>*/
  944. Mat minGradientMagnitudes;
  945. Mat cameraMatrix;
  946. int transformType;
  947. double maxTranslation, maxRotation;
  948. mutable Ptr<RgbdNormals> normalsComputer;
  949. };
  950. /** Warp the image: compute 3d points from the depth, transform them using given transformation,
  951. * then project color point cloud to an image plane.
  952. * This function can be used to visualize results of the Odometry algorithm.
  953. * @param image The image (of CV_8UC1 or CV_8UC3 type)
  954. * @param depth The depth (of type used in depthTo3d fuction)
  955. * @param mask The mask of used pixels (of CV_8UC1), it can be empty
  956. * @param Rt The transformation that will be applied to the 3d points computed from the depth
  957. * @param cameraMatrix Camera matrix
  958. * @param distCoeff Distortion coefficients
  959. * @param warpedImage The warped image.
  960. * @param warpedDepth The warped depth.
  961. * @param warpedMask The warped mask.
  962. */
  963. CV_EXPORTS_W
  964. void
  965. warpFrame(const Mat& image, const Mat& depth, const Mat& mask, const Mat& Rt, const Mat& cameraMatrix,
  966. const Mat& distCoeff, OutputArray warpedImage, OutputArray warpedDepth = noArray(), OutputArray warpedMask = noArray());
  967. // TODO Depth interpolation
  968. // Curvature
  969. // Get rescaleDepth return dubles if asked for
  970. //! @}
  971. } /* namespace rgbd */
  972. } /* namespace cv */
  973. #include "opencv2/rgbd/linemod.hpp"
  974. #endif /* __cplusplus */
  975. #endif
  976. /* End of file. */