PageRenderTime 59ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/src/DGtal/images/ImageHelper.h

https://github.com/nnormand/DGtal
C Header | 452 lines | 127 code | 42 blank | 283 comment | 4 complexity | 1dd7db0b66241ccb3455163a1a65ea54 MD5 | raw file
  1. /**
  2. * This program is free software: you can redistribute it and/or modify
  3. * it under the terms of the GNU Lesser General Public License as
  4. * published by the Free Software Foundation, either version 3 of the
  5. * License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. *
  15. **/
  16. #pragma once
  17. /**
  18. * @file ImageHelper.h
  19. * @author Tristan Roussillon (\c tristan.roussillon@liris.cnrs.fr )
  20. * Laboratoire d'InfoRmatique en Image et Systèmes d'information - LIRIS (CNRS, UMR 5205), CNRS, France
  21. *
  22. * @date 2012/02/15
  23. *
  24. * Header file for module ImageHelper.cpp
  25. *
  26. * This file is part of the DGtal library.
  27. */
  28. #if defined(ImageHelper_RECURSES)
  29. #error Recursive header files inclusion detected in ImageHelper.h
  30. #else // defined(ImageHelper_RECURSES)
  31. /** Prevents recursive inclusion of headers. */
  32. #define ImageHelper_RECURSES
  33. #if !defined ImageHelper_h
  34. /** Prevents repeated inclusion of headers. */
  35. #define ImageHelper_h
  36. //////////////////////////////////////////////////////////////////////////////
  37. // Inclusions
  38. #include <iostream>
  39. #include <algorithm>
  40. #include <functional>
  41. #include "DGtal/base/Common.h"
  42. #include "DGtal/base/BasicFunctors.h"
  43. #include "DGtal/base/CConstSinglePassRange.h"
  44. #include "DGtal/kernel/BasicPointPredicates.h"
  45. #include "DGtal/kernel/CPointFunctor.h"
  46. #include "DGtal/kernel/CPointPredicate.h"
  47. #include "DGtal/kernel/domains/CDomain.h"
  48. #include "DGtal/images/CConstImage.h"
  49. #include "DGtal/images/ConstImageAdapter.h"
  50. #include "DGtal/images/CImage.h"
  51. #include "DGtal/base/CQuantity.h"
  52. #include "DGtal/images/ImageContainerBySTLMap.h"
  53. #include "DGtal/images/SetValueIterator.h"
  54. #include "DGtal/kernel/sets/DigitalSetFromMap.h"
  55. #include "DGtal/kernel/sets/CDigitalSet.h"
  56. #include "DGtal/kernel/NumberTraits.h"
  57. #include "DGtal/base/ConstAlias.h"
  58. //////////////////////////////////////////////////////////////////////////////
  59. namespace DGtal
  60. {
  61. /// useful functions
  62. /**
  63. * Fill a set through the inserter @a ito
  64. * with the points of the range [@a itb , @a ite )
  65. * such that @a aPred is true
  66. *
  67. * @param itb begin iterator on points
  68. * @param ite end iterator on points
  69. * @param ito output iterator on points
  70. * @param aPred any predicate
  71. *
  72. * @tparam I any model of input iterator
  73. * @tparam O any model of output iterator
  74. * @tparam P any model of concepts::CPointPredicate
  75. */
  76. template<typename I, typename O, typename P>
  77. void setFromPointsRangeAndPredicate(const I& itb, const I& ite, const O& ito, const P& aPred);
  78. /**
  79. * Fill a set through the inserter @a ito
  80. * with the points of the range [@a itb , @a ite )
  81. * such that their associated value
  82. * (returned by @a aFunctor ) is less than or
  83. * equal to @a aThreshold
  84. *
  85. * @param itb begin iterator on points
  86. * @param ite end iterator on points
  87. * @param ito output iterator on points
  88. * @param aFunctor any functor on points
  89. * @param aThreshold any value (default: 0)
  90. *
  91. * @tparam I any model of input iterator
  92. * @tparam O any model of output iterator
  93. * @tparam F any model of CPointFunctor
  94. */
  95. template<typename I, typename O, typename F>
  96. void setFromPointsRangeAndFunctor(const I& itb, const I& ite,
  97. const O& ito, const F& aFunctor,
  98. const typename F::Value& aThreshold = 0);
  99. /**
  100. * Fill a set through the inserter @a ito
  101. * with the points lying within the domain
  102. * of the image @a aImg whose value
  103. * (in the image) is less than or equal to
  104. * @a aThreshold
  105. *
  106. * @param aImg any image
  107. * @param ito set inserter
  108. * @param aThreshold any value (default: 0)
  109. *
  110. * @tparam I any model of CConstImage
  111. * @tparam O any model of output iterator
  112. */
  113. template<typename I, typename O>
  114. void setFromImage(const I& aImg,
  115. const O& ito,
  116. const typename I::Value& aThreshold = 0);
  117. /**
  118. * Fill a set through the inserter @a ito
  119. * with the points lying within the domain
  120. * of the image @a aImg whose value
  121. * (in the image) lies between @a low and @a up
  122. * (both included)
  123. *
  124. * @param aImg any image
  125. * @param ito set inserter
  126. * @param low lower value
  127. * @param up upper value
  128. *
  129. * @tparam I any model of CConstImage
  130. * @tparam O any model of output iterator
  131. */
  132. template<typename I, typename O>
  133. void setFromImage(const I& aImg,
  134. const O& ito,
  135. const typename I::Value& low,
  136. const typename I::Value& up);
  137. /**
  138. * Set the values of @a aImg at @a aValue
  139. * for each points of the range [ @a itb , @a ite )
  140. *
  141. * @param itb begin iterator on points
  142. * @param ite end iterator on points
  143. * @param aImg (returned) image
  144. * @param aValue any value (default: 0)
  145. *
  146. * @tparam It any model of forward iterator
  147. * @tparam Im any model of CImage
  148. */
  149. template<typename It, typename Im>
  150. void imageFromRangeAndValue(const It& itb, const It& ite, Im& aImg,
  151. const typename Im::Value& aValue = 0);
  152. /**
  153. * Set the values of @a aImg at @a aValue
  154. * for each points of the range @a aRange
  155. *
  156. * @param aRange any range
  157. * @param aImg (returned) image
  158. * @param aValue any value (default: 0)
  159. *
  160. * @tparam R any model of CConstSinglePassRange
  161. * @tparam I any model of CImage
  162. */
  163. template<typename R, typename I>
  164. void imageFromRangeAndValue(const R& aRange, I& aImg,
  165. const typename I::Value& aValue = 0);
  166. /**
  167. * In a window corresponding to the domain of @a aImg,
  168. * copy the values of @a aFun into @a aImg
  169. *
  170. * @param aImg (returned) image
  171. * @param aFun a unary functor
  172. *
  173. * @tparam I any model of CImage
  174. * @tparam F any model of CPointFunctor
  175. */
  176. template<typename I, typename F>
  177. void imageFromFunctor(I& aImg, const F& aFun);
  178. /**
  179. * Copy the values of @a aImg2 into @a aImg1 .
  180. *
  181. * @param aImg1 the image to fill
  182. * @param aImg2 the image to copy
  183. *
  184. * @tparam I1 any model of CImage
  185. * @tparam I2 any model of CConstImage
  186. */
  187. template<typename I1, typename I2>
  188. void imageFromImage(I1& aImg1, const I2& aImg2);
  189. /**
  190. * Insert @a aPoint in @a aSet and if (and only if)
  191. * @a aPoint is a newly inserted point.
  192. * Then set @a aValue at @a aPoint in @a aImg.
  193. *
  194. * @param aImg an image
  195. * @param aSet a digital set
  196. * @param aPoint a point
  197. * @param aValue a value
  198. *
  199. * @return 'true' if a new point was inserted in @a aSet
  200. * but 'false' if the same point already exist in @a aSet
  201. *
  202. * @tparam I any model of CImage
  203. * @tparam S any model of CDigitalSet
  204. *
  205. * The general behavior is like:
  206. * @code
  207. bool found = true;
  208. if ( aSet.find( aPoint ) == aSet.end() )
  209. { //if not found
  210. found = false;
  211. aSet.insert( aPoint );
  212. aImg.setValue( aPoint, aValue );
  213. }
  214. return !found;
  215. * @endcode
  216. *
  217. * However, this code is specialized if
  218. * I is an ImageContainerBySTLMap and
  219. * S is a @link DigitalSetFromMap DigitalSetFromMap\<I\>@endlink as follows:
  220. * @code
  221. std::pair<P, V>
  222. pair( aPoint, aValue );
  223. std::pair<Iterator, bool> res
  224. = aImg.insert( pair );
  225. return res.second;
  226. * @endcode
  227. *
  228. * @see ImageContainerBySTLMap DigitalSetFromMap
  229. * @see insertAndAlwaysSetValue
  230. */
  231. template<typename I, typename S>
  232. bool insertAndSetValue(I& aImg, S& aSet,
  233. const typename I::Point& aPoint,
  234. const typename I::Value& aValue );
  235. /**
  236. * Insert @a aPoint in @a aSet and
  237. * set @a aValue at @a aPoint in @a aImg.
  238. *
  239. * @param aImg an image
  240. * @param aSet a digital set
  241. * @param aPoint a point
  242. * @param aValue a value
  243. *
  244. * @return 'true' if a new point was inserted in @a aSet
  245. * but 'false' if the same point already exist in @a aSet
  246. *
  247. * @tparam I any model of CImage
  248. * @tparam S any model of CDigitalSet
  249. *
  250. * The general behavior is like:
  251. * @code
  252. bool found = false;
  253. if ( aSet.find( aPoint ) != aSet.end() )
  254. found = true;
  255. //always set value
  256. aSet.insert( aPoint );
  257. aImg.setValue( aPoint, aValue );
  258. return !found;
  259. * @endcode
  260. *
  261. * However, this code is specialized if
  262. * I is an ImageContainerBySTLMap and
  263. * S is a @link DigitalSetFromMap DigitalSetFromMap\<I\>@endlink as follows:
  264. * @code
  265. std::pair<P, V>
  266. pair( aPoint, aValue );
  267. std::pair<Iterator, bool> res
  268. = aImg.insert( pair );
  269. bool flag = res.second;
  270. if (flag == false) //set value even in this case
  271. res.first->second = aValue;
  272. return flag;
  273. * @endcode
  274. *
  275. * @see ImageContainerBySTLMap DigitalSetFromMap
  276. * @see insertAndSetValue
  277. */
  278. template<typename I, typename S>
  279. bool insertAndAlwaysSetValue(I& aImg, S& aSet,
  280. const typename I::Point& aPoint,
  281. const typename I::Value& aValue );
  282. /**
  283. * Read the value contained in @a aImg at @a aPoint
  284. * if @a aPoint belongs to @a aSet.
  285. *
  286. * @param aImg an image
  287. * @param aSet a digital set
  288. * @param aPoint a point
  289. * @param aValue (returned) value
  290. *
  291. * @return 'true' if a new point is found and the value read
  292. * but 'false' otherwise
  293. *
  294. * @tparam I any model of CConstImage
  295. * @tparam S any model of CDigitalSet
  296. *
  297. * The general behavior is like:
  298. * @code
  299. * @endcode
  300. *
  301. * However, this code is specialized if
  302. * I is an ImageContainerBySTLMap and
  303. * S is a @link DigitalSetFromMap DigitalSetFromMap\<I\>@endlink as follows:
  304. * @code
  305. * @endcode
  306. *
  307. * @see ImageContainerBySTLMap DigitalSetFromMap
  308. * @see insertAndSetValue
  309. */
  310. template<typename I, typename S>
  311. bool findAndGetValue(const I& aImg, const S& aSet,
  312. const typename I::Point& aPoint,
  313. typename I::Value& aValue );
  314. /**
  315. * Create a Point Functor from a Point Predicate and an Image.
  316. *
  317. * @tparam Image a model of CImage.
  318. * @tparam PointPredicate a model of concepts::CPointPredicate.
  319. * @tparam TValue a model of CQuantity. Type return by the functor.
  320. *
  321. */
  322. template<typename Image, typename PointPredicate, typename TValue=DGtal::int32_t>
  323. class ImageToConstantFunctor
  324. {
  325. public:
  326. typedef typename Image::Point Point;
  327. typedef TValue Value;
  328. BOOST_CONCEPT_ASSERT(( concepts::CConstImage<Image> ));
  329. BOOST_CONCEPT_ASSERT(( concepts::CPointPredicate<PointPredicate> ));
  330. BOOST_CONCEPT_ASSERT(( concepts::CQuantity<Value> ));
  331. /*BOOST_CONCEPT_USAGE(ImageToConstantFunctor)
  332. {
  333. Point p1;
  334. typename PointPredicate::Point p2;
  335. ConceptUtils::sameType( p1, p2 );
  336. }*/
  337. /**
  338. *
  339. *
  340. * @param[in] anImage image
  341. * @param[in] aPointPred predicate on points
  342. * @param[in] aVal const value when functor answer true.
  343. * @param[in] reverseValues used to reverse values returned by the predicate. (Some shapes consider inner as > 0, others as < 0)
  344. */
  345. ImageToConstantFunctor( ConstAlias< Image > anImage,
  346. ConstAlias< PointPredicate > aPointPred,
  347. Value aVal = NumberTraits< Value >::ONE,
  348. bool reverseValues = false )
  349. : myImage(&anImage),
  350. myPointPred(&aPointPred),
  351. myVal(aVal),
  352. reverse(reverseValues)
  353. {}
  354. /**
  355. *
  356. * @param[in] aPoint point to evaluate.
  357. *
  358. * @return val between _ZERO_ or aVal
  359. */
  360. Value operator()( const Point &aPoint ) const
  361. {
  362. if ((myImage->domain().isInside(aPoint)))
  363. {
  364. if( reverse )
  365. {
  366. if( !myPointPred->operator()(aPoint) )
  367. {
  368. return myVal;
  369. }
  370. else
  371. {
  372. return NumberTraits<Value>::ZERO;
  373. }
  374. }
  375. else
  376. {
  377. if( myPointPred->operator()(aPoint) )
  378. {
  379. return myVal;
  380. }
  381. else
  382. {
  383. return NumberTraits<Value>::ZERO;
  384. }
  385. }
  386. }
  387. else
  388. {
  389. return NumberTraits<Value>::ZERO;
  390. }
  391. }
  392. private:
  393. /// const pointor to an image
  394. const Image *myImage;
  395. /// const pointor to a predicate on points
  396. const PointPredicate *myPointPred;
  397. /// constant value when functor answer true.
  398. Value myVal;
  399. /// reverse values returned by the predicate. (Some shapes consider inner as > 0, others as < 0)
  400. bool reverse;
  401. };
  402. } // namespace DGtal
  403. ///////////////////////////////////////////////////////////////////////////////
  404. // Includes inline functions
  405. #include "DGtal/images/ImageHelper.ih"
  406. // //
  407. ///////////////////////////////////////////////////////////////////////////////
  408. #endif // !defined ImageHelper_h
  409. #undef ImageHelper_RECURSES
  410. #endif // else defined(ImageHelper_RECURSES)