rgbd.hpp 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094
  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. CV_WRAP_AS(apply) 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. CV_WRAP_AS(apply) 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. /** Constructor
  348. * @param block_size The size of the blocks to look at for a stable MSE
  349. * @param min_size The minimum size of a cluster to be considered a plane
  350. * @param threshold The maximum distance of a point from a plane to belong to it (in meters)
  351. * @param sensor_error_a coefficient of the sensor error. 0 by default, 0.0075 for a Kinect
  352. * @param sensor_error_b coefficient of the sensor error. 0 by default
  353. * @param sensor_error_c coefficient of the sensor error. 0 by default
  354. * @param method The method to use to compute the planes.
  355. */
  356. RgbdPlane(int method, int block_size,
  357. int min_size, double threshold, double sensor_error_a = 0,
  358. double sensor_error_b = 0, double sensor_error_c = 0);
  359. ~RgbdPlane();
  360. CV_WRAP static Ptr<RgbdPlane> create(int method, int block_size, int min_size, double threshold,
  361. double sensor_error_a = 0, double sensor_error_b = 0,
  362. double sensor_error_c = 0);
  363. /** Find The planes in a depth image
  364. * @param points3d the 3d points organized like the depth image: rows x cols with 3 channels
  365. * @param normals the normals for every point in the depth image
  366. * @param mask An image where each pixel is labeled with the plane it belongs to
  367. * and 255 if it does not belong to any plane
  368. * @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
  369. * and c < 0 (so that the normal points towards the camera)
  370. */
  371. CV_WRAP_AS(apply) void
  372. operator()(InputArray points3d, InputArray normals, OutputArray mask,
  373. OutputArray plane_coefficients);
  374. /** Find The planes in a depth image but without doing a normal check, which is faster but less accurate
  375. * @param points3d the 3d points organized like the depth image: rows x cols with 3 channels
  376. * @param mask An image where each pixel is labeled with the plane it belongs to
  377. * and 255 if it does not belong to any plane
  378. * @param plane_coefficients the coefficients of the corresponding planes (a,b,c,d) such that ax+by+cz+d=0
  379. */
  380. CV_WRAP_AS(apply) void
  381. operator()(InputArray points3d, OutputArray mask, OutputArray plane_coefficients);
  382. CV_WRAP int getBlockSize() const
  383. {
  384. return block_size_;
  385. }
  386. CV_WRAP void setBlockSize(int val)
  387. {
  388. block_size_ = val;
  389. }
  390. CV_WRAP int getMinSize() const
  391. {
  392. return min_size_;
  393. }
  394. CV_WRAP void setMinSize(int val)
  395. {
  396. min_size_ = val;
  397. }
  398. CV_WRAP int getMethod() const
  399. {
  400. return method_;
  401. }
  402. CV_WRAP void setMethod(int val)
  403. {
  404. method_ = val;
  405. }
  406. CV_WRAP double getThreshold() const
  407. {
  408. return threshold_;
  409. }
  410. CV_WRAP void setThreshold(double val)
  411. {
  412. threshold_ = val;
  413. }
  414. CV_WRAP double getSensorErrorA() const
  415. {
  416. return sensor_error_a_;
  417. }
  418. CV_WRAP void setSensorErrorA(double val)
  419. {
  420. sensor_error_a_ = val;
  421. }
  422. CV_WRAP double getSensorErrorB() const
  423. {
  424. return sensor_error_b_;
  425. }
  426. CV_WRAP void setSensorErrorB(double val)
  427. {
  428. sensor_error_b_ = val;
  429. }
  430. CV_WRAP double getSensorErrorC() const
  431. {
  432. return sensor_error_c_;
  433. }
  434. CV_WRAP void setSensorErrorC(double val)
  435. {
  436. sensor_error_c_ = val;
  437. }
  438. private:
  439. /** The method to use to compute the planes */
  440. int method_;
  441. /** The size of the blocks to look at for a stable MSE */
  442. int block_size_;
  443. /** The minimum size of a cluster to be considered a plane */
  444. int min_size_;
  445. /** How far a point can be from a plane to belong to it (in meters) */
  446. double threshold_;
  447. /** coefficient of the sensor error with respect to the. All 0 by default but you want a=0.0075 for a Kinect */
  448. double sensor_error_a_, sensor_error_b_, sensor_error_c_;
  449. };
  450. /** Object that contains a frame data.
  451. */
  452. struct CV_EXPORTS_W RgbdFrame
  453. {
  454. RgbdFrame();
  455. RgbdFrame(const Mat& image, const Mat& depth, const Mat& mask=Mat(), const Mat& normals=Mat(), int ID=-1);
  456. virtual ~RgbdFrame();
  457. 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);
  458. CV_WRAP virtual void
  459. release();
  460. CV_PROP int ID;
  461. CV_PROP Mat image;
  462. CV_PROP Mat depth;
  463. CV_PROP Mat mask;
  464. CV_PROP Mat normals;
  465. };
  466. /** Object that contains a frame data that is possibly needed for the Odometry.
  467. * It's used for the efficiency (to pass precomputed/cached data of the frame that participates
  468. * in the Odometry processing several times).
  469. */
  470. struct CV_EXPORTS_W OdometryFrame : public RgbdFrame
  471. {
  472. /** These constants are used to set a type of cache which has to be prepared depending on the frame role:
  473. * srcFrame or dstFrame (see compute method of the Odometry class). For the srcFrame and dstFrame different cache data may be required,
  474. * some part of a cache may be common for both frame roles.
  475. * @param CACHE_SRC The cache data for the srcFrame will be prepared.
  476. * @param CACHE_DST The cache data for the dstFrame will be prepared.
  477. * @param CACHE_ALL The cache data for both srcFrame and dstFrame roles will be computed.
  478. */
  479. enum
  480. {
  481. CACHE_SRC = 1, CACHE_DST = 2, CACHE_ALL = CACHE_SRC + CACHE_DST
  482. };
  483. OdometryFrame();
  484. OdometryFrame(const Mat& image, const Mat& depth, const Mat& mask=Mat(), const Mat& normals=Mat(), int ID=-1);
  485. 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);
  486. CV_WRAP virtual void
  487. release() CV_OVERRIDE;
  488. CV_WRAP void
  489. releasePyramids();
  490. CV_PROP std::vector<Mat> pyramidImage;
  491. CV_PROP std::vector<Mat> pyramidDepth;
  492. CV_PROP std::vector<Mat> pyramidMask;
  493. CV_PROP std::vector<Mat> pyramidCloud;
  494. CV_PROP std::vector<Mat> pyramid_dI_dx;
  495. CV_PROP std::vector<Mat> pyramid_dI_dy;
  496. CV_PROP std::vector<Mat> pyramidTexturedMask;
  497. CV_PROP std::vector<Mat> pyramidNormals;
  498. CV_PROP std::vector<Mat> pyramidNormalsMask;
  499. };
  500. /** Base class for computation of odometry.
  501. */
  502. class CV_EXPORTS_W Odometry: public Algorithm
  503. {
  504. public:
  505. /** A class of transformation*/
  506. enum
  507. {
  508. ROTATION = 1, TRANSLATION = 2, RIGID_BODY_MOTION = 4
  509. };
  510. CV_WRAP static inline float
  511. DEFAULT_MIN_DEPTH()
  512. {
  513. return 0.f; // in meters
  514. }
  515. CV_WRAP static inline float
  516. DEFAULT_MAX_DEPTH()
  517. {
  518. return 4.f; // in meters
  519. }
  520. CV_WRAP static inline float
  521. DEFAULT_MAX_DEPTH_DIFF()
  522. {
  523. return 0.07f; // in meters
  524. }
  525. CV_WRAP static inline float
  526. DEFAULT_MAX_POINTS_PART()
  527. {
  528. return 0.07f; // in [0, 1]
  529. }
  530. CV_WRAP static inline float
  531. DEFAULT_MAX_TRANSLATION()
  532. {
  533. return 0.15f; // in meters
  534. }
  535. CV_WRAP static inline float
  536. DEFAULT_MAX_ROTATION()
  537. {
  538. return 15; // in degrees
  539. }
  540. /** Method to compute a transformation from the source frame to the destination one.
  541. * Some odometry algorithms do not used some data of frames (eg. ICP does not use images).
  542. * In such case corresponding arguments can be set as empty Mat.
  543. * The method returns true if all internal computions were possible (e.g. there were enough correspondences,
  544. * system of equations has a solution, etc) and resulting transformation satisfies some test if it's provided
  545. * by the Odometry inheritor implementation (e.g. thresholds for maximum translation and rotation).
  546. * @param srcImage Image data of the source frame (CV_8UC1)
  547. * @param srcDepth Depth data of the source frame (CV_32FC1, in meters)
  548. * @param srcMask Mask that sets which pixels have to be used from the source frame (CV_8UC1)
  549. * @param dstImage Image data of the destination frame (CV_8UC1)
  550. * @param dstDepth Depth data of the destination frame (CV_32FC1, in meters)
  551. * @param dstMask Mask that sets which pixels have to be used from the destination frame (CV_8UC1)
  552. * @param Rt Resulting transformation from the source frame to the destination one (rigid body motion):
  553. dst_p = Rt * src_p, where dst_p is a homogeneous point in the destination frame and src_p is
  554. homogeneous point in the source frame,
  555. Rt is 4x4 matrix of CV_64FC1 type.
  556. * @param initRt Initial transformation from the source frame to the destination one (optional)
  557. */
  558. CV_WRAP bool
  559. compute(const Mat& srcImage, const Mat& srcDepth, const Mat& srcMask, const Mat& dstImage, const Mat& dstDepth,
  560. const Mat& dstMask, OutputArray Rt, const Mat& initRt = Mat()) const;
  561. /** One more method to compute a transformation from the source frame to the destination one.
  562. * It is designed to save on computing the frame data (image pyramids, normals, etc.).
  563. */
  564. CV_WRAP_AS(compute2) bool
  565. compute(Ptr<OdometryFrame>& srcFrame, Ptr<OdometryFrame>& dstFrame, OutputArray Rt, const Mat& initRt = Mat()) const;
  566. /** Prepare a cache for the frame. The function checks the precomputed/passed data (throws the error if this data
  567. * does not satisfy) and computes all remaining cache data needed for the frame. Returned size is a resolution
  568. * of the prepared frame.
  569. * @param frame The odometry which will process the frame.
  570. * @param cacheType The cache type: CACHE_SRC, CACHE_DST or CACHE_ALL.
  571. */
  572. CV_WRAP virtual Size prepareFrameCache(Ptr<OdometryFrame>& frame, int cacheType) const;
  573. CV_WRAP static Ptr<Odometry> create(const String & odometryType);
  574. /** @see setCameraMatrix */
  575. CV_WRAP virtual cv::Mat getCameraMatrix() const = 0;
  576. /** @copybrief getCameraMatrix @see getCameraMatrix */
  577. CV_WRAP virtual void setCameraMatrix(const cv::Mat &val) = 0;
  578. /** @see setTransformType */
  579. CV_WRAP virtual int getTransformType() const = 0;
  580. /** @copybrief getTransformType @see getTransformType */
  581. CV_WRAP virtual void setTransformType(int val) = 0;
  582. protected:
  583. virtual void
  584. checkParams() const = 0;
  585. virtual bool
  586. computeImpl(const Ptr<OdometryFrame>& srcFrame, const Ptr<OdometryFrame>& dstFrame, OutputArray Rt,
  587. const Mat& initRt) const = 0;
  588. };
  589. /** Odometry based on the paper "Real-Time Visual Odometry from Dense RGB-D Images",
  590. * F. Steinbucker, J. Strum, D. Cremers, ICCV, 2011.
  591. */
  592. class CV_EXPORTS_W RgbdOdometry: public Odometry
  593. {
  594. public:
  595. RgbdOdometry();
  596. /** Constructor.
  597. * @param cameraMatrix Camera matrix
  598. * @param minDepth Pixels with depth less than minDepth will not be used (in meters)
  599. * @param maxDepth Pixels with depth larger than maxDepth will not be used (in meters)
  600. * @param maxDepthDiff Correspondences between pixels of two given frames will be filtered out
  601. * if their depth difference is larger than maxDepthDiff (in meters)
  602. * @param iterCounts Count of iterations on each pyramid level.
  603. * @param minGradientMagnitudes For each pyramid level the pixels will be filtered out
  604. * if they have gradient magnitude less than minGradientMagnitudes[level].
  605. * @param maxPointsPart The method uses a random pixels subset of size frameWidth x frameHeight x pointsPart
  606. * @param transformType Class of transformation
  607. */
  608. RgbdOdometry(const Mat& cameraMatrix, float minDepth = Odometry::DEFAULT_MIN_DEPTH(), float maxDepth = Odometry::DEFAULT_MAX_DEPTH(),
  609. float maxDepthDiff = Odometry::DEFAULT_MAX_DEPTH_DIFF(), const std::vector<int>& iterCounts = std::vector<int>(),
  610. const std::vector<float>& minGradientMagnitudes = std::vector<float>(), float maxPointsPart = Odometry::DEFAULT_MAX_POINTS_PART(),
  611. int transformType = Odometry::RIGID_BODY_MOTION);
  612. CV_WRAP static Ptr<RgbdOdometry> create(const Mat& cameraMatrix = Mat(), float minDepth = Odometry::DEFAULT_MIN_DEPTH(), float maxDepth = Odometry::DEFAULT_MAX_DEPTH(),
  613. float maxDepthDiff = Odometry::DEFAULT_MAX_DEPTH_DIFF(), const std::vector<int>& iterCounts = std::vector<int>(),
  614. const std::vector<float>& minGradientMagnitudes = std::vector<float>(), float maxPointsPart = Odometry::DEFAULT_MAX_POINTS_PART(),
  615. int transformType = Odometry::RIGID_BODY_MOTION);
  616. CV_WRAP virtual Size prepareFrameCache(Ptr<OdometryFrame>& frame, int cacheType) const CV_OVERRIDE;
  617. CV_WRAP cv::Mat getCameraMatrix() const CV_OVERRIDE
  618. {
  619. return cameraMatrix;
  620. }
  621. CV_WRAP void setCameraMatrix(const cv::Mat &val) CV_OVERRIDE
  622. {
  623. cameraMatrix = val;
  624. }
  625. CV_WRAP double getMinDepth() const
  626. {
  627. return minDepth;
  628. }
  629. CV_WRAP void setMinDepth(double val)
  630. {
  631. minDepth = val;
  632. }
  633. CV_WRAP double getMaxDepth() const
  634. {
  635. return maxDepth;
  636. }
  637. CV_WRAP void setMaxDepth(double val)
  638. {
  639. maxDepth = val;
  640. }
  641. CV_WRAP double getMaxDepthDiff() const
  642. {
  643. return maxDepthDiff;
  644. }
  645. CV_WRAP void setMaxDepthDiff(double val)
  646. {
  647. maxDepthDiff = val;
  648. }
  649. CV_WRAP cv::Mat getIterationCounts() const
  650. {
  651. return iterCounts;
  652. }
  653. CV_WRAP void setIterationCounts(const cv::Mat &val)
  654. {
  655. iterCounts = val;
  656. }
  657. CV_WRAP cv::Mat getMinGradientMagnitudes() const
  658. {
  659. return minGradientMagnitudes;
  660. }
  661. CV_WRAP void setMinGradientMagnitudes(const cv::Mat &val)
  662. {
  663. minGradientMagnitudes = val;
  664. }
  665. CV_WRAP double getMaxPointsPart() const
  666. {
  667. return maxPointsPart;
  668. }
  669. CV_WRAP void setMaxPointsPart(double val)
  670. {
  671. maxPointsPart = val;
  672. }
  673. CV_WRAP int getTransformType() const CV_OVERRIDE
  674. {
  675. return transformType;
  676. }
  677. CV_WRAP void setTransformType(int val) CV_OVERRIDE
  678. {
  679. transformType = val;
  680. }
  681. CV_WRAP double getMaxTranslation() const
  682. {
  683. return maxTranslation;
  684. }
  685. CV_WRAP void setMaxTranslation(double val)
  686. {
  687. maxTranslation = val;
  688. }
  689. CV_WRAP double getMaxRotation() const
  690. {
  691. return maxRotation;
  692. }
  693. CV_WRAP void setMaxRotation(double val)
  694. {
  695. maxRotation = val;
  696. }
  697. protected:
  698. virtual void
  699. checkParams() const CV_OVERRIDE;
  700. virtual bool
  701. computeImpl(const Ptr<OdometryFrame>& srcFrame, const Ptr<OdometryFrame>& dstFrame, OutputArray Rt,
  702. const Mat& initRt) const CV_OVERRIDE;
  703. // Some params have commented desired type. It's due to AlgorithmInfo::addParams does not support it now.
  704. /*float*/
  705. double minDepth, maxDepth, maxDepthDiff;
  706. /*vector<int>*/
  707. Mat iterCounts;
  708. /*vector<float>*/
  709. Mat minGradientMagnitudes;
  710. double maxPointsPart;
  711. Mat cameraMatrix;
  712. int transformType;
  713. double maxTranslation, maxRotation;
  714. };
  715. /** Odometry based on the paper "KinectFusion: Real-Time Dense Surface Mapping and Tracking",
  716. * Richard A. Newcombe, Andrew Fitzgibbon, at al, SIGGRAPH, 2011.
  717. */
  718. class CV_EXPORTS_W ICPOdometry: public Odometry
  719. {
  720. public:
  721. ICPOdometry();
  722. /** Constructor.
  723. * @param cameraMatrix Camera matrix
  724. * @param minDepth Pixels with depth less than minDepth will not be used
  725. * @param maxDepth Pixels with depth larger than maxDepth will not be used
  726. * @param maxDepthDiff Correspondences between pixels of two given frames will be filtered out
  727. * if their depth difference is larger than maxDepthDiff
  728. * @param maxPointsPart The method uses a random pixels subset of size frameWidth x frameHeight x pointsPart
  729. * @param iterCounts Count of iterations on each pyramid level.
  730. * @param transformType Class of trasformation
  731. */
  732. ICPOdometry(const Mat& cameraMatrix, float minDepth = Odometry::DEFAULT_MIN_DEPTH(), float maxDepth = Odometry::DEFAULT_MAX_DEPTH(),
  733. float maxDepthDiff = Odometry::DEFAULT_MAX_DEPTH_DIFF(), float maxPointsPart = Odometry::DEFAULT_MAX_POINTS_PART(),
  734. const std::vector<int>& iterCounts = std::vector<int>(), int transformType = Odometry::RIGID_BODY_MOTION);
  735. CV_WRAP static Ptr<ICPOdometry> create(const Mat& cameraMatrix = Mat(), float minDepth = Odometry::DEFAULT_MIN_DEPTH(), float maxDepth = Odometry::DEFAULT_MAX_DEPTH(),
  736. float maxDepthDiff = Odometry::DEFAULT_MAX_DEPTH_DIFF(), float maxPointsPart = Odometry::DEFAULT_MAX_POINTS_PART(),
  737. const std::vector<int>& iterCounts = std::vector<int>(), int transformType = Odometry::RIGID_BODY_MOTION);
  738. CV_WRAP virtual Size prepareFrameCache(Ptr<OdometryFrame>& frame, int cacheType) const CV_OVERRIDE;
  739. CV_WRAP cv::Mat getCameraMatrix() const CV_OVERRIDE
  740. {
  741. return cameraMatrix;
  742. }
  743. CV_WRAP void setCameraMatrix(const cv::Mat &val) CV_OVERRIDE
  744. {
  745. cameraMatrix = val;
  746. }
  747. CV_WRAP double getMinDepth() const
  748. {
  749. return minDepth;
  750. }
  751. CV_WRAP void setMinDepth(double val)
  752. {
  753. minDepth = val;
  754. }
  755. CV_WRAP double getMaxDepth() const
  756. {
  757. return maxDepth;
  758. }
  759. CV_WRAP void setMaxDepth(double val)
  760. {
  761. maxDepth = val;
  762. }
  763. CV_WRAP double getMaxDepthDiff() const
  764. {
  765. return maxDepthDiff;
  766. }
  767. CV_WRAP void setMaxDepthDiff(double val)
  768. {
  769. maxDepthDiff = val;
  770. }
  771. CV_WRAP cv::Mat getIterationCounts() const
  772. {
  773. return iterCounts;
  774. }
  775. CV_WRAP void setIterationCounts(const cv::Mat &val)
  776. {
  777. iterCounts = val;
  778. }
  779. CV_WRAP double getMaxPointsPart() const
  780. {
  781. return maxPointsPart;
  782. }
  783. CV_WRAP void setMaxPointsPart(double val)
  784. {
  785. maxPointsPart = val;
  786. }
  787. CV_WRAP int getTransformType() const CV_OVERRIDE
  788. {
  789. return transformType;
  790. }
  791. CV_WRAP void setTransformType(int val) CV_OVERRIDE
  792. {
  793. transformType = val;
  794. }
  795. CV_WRAP double getMaxTranslation() const
  796. {
  797. return maxTranslation;
  798. }
  799. CV_WRAP void setMaxTranslation(double val)
  800. {
  801. maxTranslation = val;
  802. }
  803. CV_WRAP double getMaxRotation() const
  804. {
  805. return maxRotation;
  806. }
  807. CV_WRAP void setMaxRotation(double val)
  808. {
  809. maxRotation = val;
  810. }
  811. CV_WRAP Ptr<RgbdNormals> getNormalsComputer() const
  812. {
  813. return normalsComputer;
  814. }
  815. protected:
  816. virtual void
  817. checkParams() const CV_OVERRIDE;
  818. virtual bool
  819. computeImpl(const Ptr<OdometryFrame>& srcFrame, const Ptr<OdometryFrame>& dstFrame, OutputArray Rt,
  820. const Mat& initRt) const CV_OVERRIDE;
  821. // Some params have commented desired type. It's due to AlgorithmInfo::addParams does not support it now.
  822. /*float*/
  823. double minDepth, maxDepth, maxDepthDiff;
  824. /*float*/
  825. double maxPointsPart;
  826. /*vector<int>*/
  827. Mat iterCounts;
  828. Mat cameraMatrix;
  829. int transformType;
  830. double maxTranslation, maxRotation;
  831. mutable Ptr<RgbdNormals> normalsComputer;
  832. };
  833. /** Odometry that merges RgbdOdometry and ICPOdometry by minimize sum of their energy functions.
  834. */
  835. class CV_EXPORTS_W RgbdICPOdometry: public Odometry
  836. {
  837. public:
  838. RgbdICPOdometry();
  839. /** Constructor.
  840. * @param cameraMatrix Camera matrix
  841. * @param minDepth Pixels with depth less than minDepth will not be used
  842. * @param maxDepth Pixels with depth larger than maxDepth will not be used
  843. * @param maxDepthDiff Correspondences between pixels of two given frames will be filtered out
  844. * if their depth difference is larger than maxDepthDiff
  845. * @param maxPointsPart The method uses a random pixels subset of size frameWidth x frameHeight x pointsPart
  846. * @param iterCounts Count of iterations on each pyramid level.
  847. * @param minGradientMagnitudes For each pyramid level the pixels will be filtered out
  848. * if they have gradient magnitude less than minGradientMagnitudes[level].
  849. * @param transformType Class of trasformation
  850. */
  851. RgbdICPOdometry(const Mat& cameraMatrix, float minDepth = Odometry::DEFAULT_MIN_DEPTH(), float maxDepth = Odometry::DEFAULT_MAX_DEPTH(),
  852. float maxDepthDiff = Odometry::DEFAULT_MAX_DEPTH_DIFF(), float maxPointsPart = Odometry::DEFAULT_MAX_POINTS_PART(),
  853. const std::vector<int>& iterCounts = std::vector<int>(),
  854. const std::vector<float>& minGradientMagnitudes = std::vector<float>(),
  855. int transformType = Odometry::RIGID_BODY_MOTION);
  856. CV_WRAP static Ptr<RgbdICPOdometry> create(const Mat& cameraMatrix = Mat(), float minDepth = Odometry::DEFAULT_MIN_DEPTH(), float maxDepth = Odometry::DEFAULT_MAX_DEPTH(),
  857. float maxDepthDiff = Odometry::DEFAULT_MAX_DEPTH_DIFF(), float maxPointsPart = Odometry::DEFAULT_MAX_POINTS_PART(),
  858. const std::vector<int>& iterCounts = std::vector<int>(),
  859. const std::vector<float>& minGradientMagnitudes = std::vector<float>(),
  860. int transformType = Odometry::RIGID_BODY_MOTION);
  861. CV_WRAP virtual Size prepareFrameCache(Ptr<OdometryFrame>& frame, int cacheType) const CV_OVERRIDE;
  862. CV_WRAP cv::Mat getCameraMatrix() const CV_OVERRIDE
  863. {
  864. return cameraMatrix;
  865. }
  866. CV_WRAP void setCameraMatrix(const cv::Mat &val) CV_OVERRIDE
  867. {
  868. cameraMatrix = val;
  869. }
  870. CV_WRAP double getMinDepth() const
  871. {
  872. return minDepth;
  873. }
  874. CV_WRAP void setMinDepth(double val)
  875. {
  876. minDepth = val;
  877. }
  878. CV_WRAP double getMaxDepth() const
  879. {
  880. return maxDepth;
  881. }
  882. CV_WRAP void setMaxDepth(double val)
  883. {
  884. maxDepth = val;
  885. }
  886. CV_WRAP double getMaxDepthDiff() const
  887. {
  888. return maxDepthDiff;
  889. }
  890. CV_WRAP void setMaxDepthDiff(double val)
  891. {
  892. maxDepthDiff = val;
  893. }
  894. CV_WRAP double getMaxPointsPart() const
  895. {
  896. return maxPointsPart;
  897. }
  898. CV_WRAP void setMaxPointsPart(double val)
  899. {
  900. maxPointsPart = val;
  901. }
  902. CV_WRAP cv::Mat getIterationCounts() const
  903. {
  904. return iterCounts;
  905. }
  906. CV_WRAP void setIterationCounts(const cv::Mat &val)
  907. {
  908. iterCounts = val;
  909. }
  910. CV_WRAP cv::Mat getMinGradientMagnitudes() const
  911. {
  912. return minGradientMagnitudes;
  913. }
  914. CV_WRAP void setMinGradientMagnitudes(const cv::Mat &val)
  915. {
  916. minGradientMagnitudes = val;
  917. }
  918. CV_WRAP int getTransformType() const CV_OVERRIDE
  919. {
  920. return transformType;
  921. }
  922. CV_WRAP void setTransformType(int val) CV_OVERRIDE
  923. {
  924. transformType = val;
  925. }
  926. CV_WRAP double getMaxTranslation() const
  927. {
  928. return maxTranslation;
  929. }
  930. CV_WRAP void setMaxTranslation(double val)
  931. {
  932. maxTranslation = val;
  933. }
  934. CV_WRAP double getMaxRotation() const
  935. {
  936. return maxRotation;
  937. }
  938. CV_WRAP void setMaxRotation(double val)
  939. {
  940. maxRotation = val;
  941. }
  942. CV_WRAP Ptr<RgbdNormals> getNormalsComputer() const
  943. {
  944. return normalsComputer;
  945. }
  946. protected:
  947. virtual void
  948. checkParams() const CV_OVERRIDE;
  949. virtual bool
  950. computeImpl(const Ptr<OdometryFrame>& srcFrame, const Ptr<OdometryFrame>& dstFrame, OutputArray Rt,
  951. const Mat& initRt) const CV_OVERRIDE;
  952. // Some params have commented desired type. It's due to AlgorithmInfo::addParams does not support it now.
  953. /*float*/
  954. double minDepth, maxDepth, maxDepthDiff;
  955. /*float*/
  956. double maxPointsPart;
  957. /*vector<int>*/
  958. Mat iterCounts;
  959. /*vector<float>*/
  960. Mat minGradientMagnitudes;
  961. Mat cameraMatrix;
  962. int transformType;
  963. double maxTranslation, maxRotation;
  964. mutable Ptr<RgbdNormals> normalsComputer;
  965. };
  966. /** Warp the image: compute 3d points from the depth, transform them using given transformation,
  967. * then project color point cloud to an image plane.
  968. * This function can be used to visualize results of the Odometry algorithm.
  969. * @param image The image (of CV_8UC1 or CV_8UC3 type)
  970. * @param depth The depth (of type used in depthTo3d fuction)
  971. * @param mask The mask of used pixels (of CV_8UC1), it can be empty
  972. * @param Rt The transformation that will be applied to the 3d points computed from the depth
  973. * @param cameraMatrix Camera matrix
  974. * @param distCoeff Distortion coefficients
  975. * @param warpedImage The warped image.
  976. * @param warpedDepth The warped depth.
  977. * @param warpedMask The warped mask.
  978. */
  979. CV_EXPORTS_W
  980. void
  981. warpFrame(const Mat& image, const Mat& depth, const Mat& mask, const Mat& Rt, const Mat& cameraMatrix,
  982. const Mat& distCoeff, OutputArray warpedImage, OutputArray warpedDepth = noArray(), OutputArray warpedMask = noArray());
  983. // TODO Depth interpolation
  984. // Curvature
  985. // Get rescaleDepth return dubles if asked for
  986. //! @}
  987. } /* namespace rgbd */
  988. } /* namespace cv */
  989. #include "opencv2/rgbd/linemod.hpp"
  990. #endif /* __cplusplus */
  991. #endif
  992. /* End of file. */