ImageT.tcc 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814
  1. /*
  2. * LImUn - Library for ImageT Understanding
  3. * - libimage - An ImageT library
  4. * See file License for license information.
  5. */
  6. #include "core/image/ImageT.h"
  7. #include <core/basics/tools.h>
  8. #include <memory>
  9. namespace NICE {
  10. template<class P>
  11. ImageT<P>& ImageT<P>::operator= ( const P c ) {
  12. #ifdef NICE_USELIB_IPP
  13. IppiSize ippiSize = { this->width(), this->height() };
  14. ippiSet_C1R ( static_cast<P> ( c ), this->getPixelPointer(), this->rowStepsize(), ippiSize );
  15. #else
  16. Ipp8u* pos = reinterpret_cast<Ipp8u*> ( this->getPixelPointer() );
  17. P *row[this->height() ];
  18. for ( int y = 0;y < this->height(); ++y ) {
  19. row[y] = reinterpret_cast<P*> ( pos );
  20. pos += this->rowStepsize();
  21. }
  22. P *p;
  23. for ( int y = 0;y < this->height(); ++y ) {
  24. p = row[y];
  25. for ( int x = 0;x < this->width(); ++x, p++ ) {
  26. *p = c;
  27. }
  28. }
  29. #endif
  30. return *this;
  31. }
  32. template<class P>
  33. ImageT<P>::ImageT ( const int width, const int height,
  34. const GrayColorImageCommonImplementation::MemoryLayout _memoryLayout ) {
  35. this->allocPixel ( width, height, _memoryLayout );
  36. }
  37. template<class P>
  38. ImageT<P>::ImageT ( const ImageT<P>& orig, const GrayColorImageCommonImplementation::MemoryLayout copyMode ) :
  39. BlockImageAccessT<P> () {
  40. this->fromRaw ( orig.getPixelPointer(), orig.width(), orig.height(), orig.rowStepsize(), this->toCopyLayout ( copyMode, orig ) );
  41. }
  42. template<class P>
  43. ImageT<P>& ImageT<P>::operator= ( const ImageT<P>& orig ) {
  44. if ( this->width() == orig.width() && this->height() == orig.height() ) {
  45. doFromRaw ( orig.getPixelPointer(), orig.rowStepsize() );
  46. } else {
  47. fromRaw ( orig.getPixelPointer(), orig.width(), orig.height(), orig.rowStepsize(), this->toCopyLayout (
  48. GrayColorImageCommonImplementation::originalAlignment, orig ) );
  49. }
  50. return *this;
  51. }
  52. template<class P>
  53. ImageT<P>::ImageT ( ImageT<P>& orig, const GrayColorImageCommonImplementation::ShallowCopyMode shallow ) {
  54. UNUSED_PARAMETER ( shallow );
  55. setForeignPointer ( orig.getPixelPointer(), orig.width(), orig.height(), orig.getStepsize(), sizeof ( P ) );
  56. }
  57. template<class P>
  58. ImageT<P>::ImageT ( const P* raw, const int width, const int height, const int stepsize,
  59. const GrayColorImageCommonImplementation::MemoryLayout copyMode ) {
  60. fromRaw ( raw, width, height, stepsize, copyMode );
  61. }
  62. template<class P>
  63. ImageT<P>::ImageT ( P* raw, const int width, const int height, const int stepsize,
  64. const GrayColorImageCommonImplementation::ShallowCopyMode shallow ) {
  65. UNUSED_PARAMETER ( shallow );
  66. this->setForeignPointer ( raw, width, height, stepsize, sizeof ( P ) );
  67. }
  68. template<class P>
  69. ImageT<P>::ImageT ( const P* raw, const int width, const int height,
  70. const GrayColorImageCommonImplementation::MemoryLayout copyMode ) {
  71. fromRaw ( raw, width, height, sizeof ( P ) * width, copyMode );
  72. }
  73. template<class P>
  74. ImageT<P>::ImageT ( P* raw, const int width, const int height,
  75. const GrayColorImageCommonImplementation::ShallowCopyMode shallow ) {
  76. UNUSED_PARAMETER ( shallow );
  77. this->setForeignPointer ( raw, width, height, sizeof ( P ) * width, sizeof ( P ) );
  78. }
  79. template<class P>
  80. ImageT<P>::ImageT ( const ImageT<P>& orig, const GrayColorImageCommonImplementation::ShallowCopyMode shallow ) {
  81. UNUSED_PARAMETER ( shallow );
  82. this->setForeignPointerConst ( orig.getPixelPointer(), orig.width(), orig.height(), orig.rowStepsize(), orig.columnStepsize() );
  83. }
  84. template<class P>
  85. ImageT<P>::ImageT ( const P* raw, const int width, const int height, const int stepsize,
  86. const GrayColorImageCommonImplementation::ShallowCopyMode shallow ) {
  87. UNUSED_PARAMETER ( shallow );
  88. this->setForeignPointerConst ( raw, width, height, stepsize, sizeof ( P ) );
  89. }
  90. template<class P>
  91. ImageT<P>::ImageT() {
  92. this->allocPixel ( 0, 0, GrayColorImageCommonImplementation::ippAlignment );
  93. }
  94. template<class P>
  95. ImageT<P>::ImageT ( const std::string& FileName, const GrayColorImageCommonImplementation::MemoryLayout _memoryLayout ) {
  96. this->allocPixel ( 0, 0, _memoryLayout );
  97. this->read ( ImageFile ( FileName ) /*, _memoryLayout*/ );
  98. }
  99. template<class P>
  100. void ImageT<P>::doAllocPixelNoAlignment() {
  101. this->setPixelPointer ( new P[this->m_xsize * this->m_ysize] );
  102. this->m_rowStepsize = sizeof ( P ) * this->m_xsize;
  103. }
  104. template<class P>
  105. void ImageT<P>::doAllocPixelIPP() {
  106. // no IPP in generic implementation (-> specialization in ImageT.cpp)
  107. doAllocPixelNoAlignment();
  108. this->m_memoryLayout = GrayColorImageCommonImplementation::noAlignment;
  109. }
  110. #ifdef NICE_USELIB_IPP
  111. template<>
  112. void ImageT<Ipp8u>::doAllocPixelIPP();
  113. template<>
  114. void ImageT<Ipp16s>::doAllocPixelIPP();
  115. template<>
  116. void ImageT<Ipp32f>::doAllocPixelIPP();
  117. #endif //NICE_USELIB_IPP
  118. template<class P>
  119. ImageT<P>::~ImageT() {
  120. }
  121. template<class P>
  122. void ImageT<P>::fromRaw ( const P* raw, const int width, const int height, const int rowStepsize,
  123. const GrayColorImageCommonImplementation::MemoryLayout copyMode ) {
  124. if ( copyMode == GrayColorImageCommonImplementation::internal__foreignPointer || copyMode
  125. == GrayColorImageCommonImplementation::originalAlignment ) {
  126. fthrow ( ImageException,
  127. "internal__foreignPointer and originalAlignment not supported here" );
  128. } else if ( copyMode == GrayColorImageCommonImplementation::keepAlignment && this->width() >= width && this->height()
  129. >= height ) {
  130. fthrow ( ImageException, "not enough image space for copying data without reallocation" );
  131. } else {
  132. this->allocPixel ( width, height, copyMode );
  133. doFromRaw ( raw, rowStepsize );
  134. }
  135. }
  136. template<class P>
  137. void ImageT<P>::doFromRaw ( const P* raw, const int rowStepsize ) {
  138. // no IPP in generic implementation (-> specialization in ImageT.cpp)
  139. for ( int y = 0; y < this->height(); y++ ) {
  140. const P* line = pointerToPixel1 ( raw, 0, y, rowStepsize );
  141. const P* lineTargetEnd = this->getPixelPointerYEnd ( y );
  142. for ( P* lineTarget = this->getPixelPointerY ( y ); lineTarget < lineTargetEnd; lineTarget++ ) {
  143. *lineTarget = *line;
  144. line++;
  145. }
  146. }
  147. }
  148. #ifdef NICE_USELIB_IPP
  149. template<>
  150. void ImageT<Ipp8u>::doFromRaw ( const Pixel* raw, const int stepsize );
  151. template<>
  152. void ImageT<Ipp16s>::doFromRaw ( const Pixel* raw, const int stepsize );
  153. template<>
  154. void ImageT<Ipp32f>::doFromRaw ( const Pixel* raw, const int stepsize );
  155. #endif //NICE_USELIB_IPP
  156. template<class P>
  157. P ImageT<P>::getPixel ( const int x, const int y ) const {
  158. if ( this->isWithinImage ( x, y ) ) {
  159. return getPixelQuick ( x, y );
  160. } else {
  161. fthrow ( ImageException,
  162. "ImageT<P>::getPixel: (x,y) out of range." );
  163. }
  164. }
  165. template<class P>
  166. P ImageT<P>::getPixel ( const Coord &coord ) const {
  167. if ( this->isWithinImage ( coord.x, coord.y ) ) {
  168. return getPixelQuick ( coord.x, coord.y );
  169. } else {
  170. fthrow ( ImageException,
  171. "ImageT<P>::getPixel: (coord) out of range." );
  172. }
  173. }
  174. // used by ImageT<P>::getPixelBilinear()
  175. template<class P>
  176. inline P getPixel0 ( const ImageT<P>& img, int x, int y ) {
  177. if ( x < 0 ) {
  178. x = 0;
  179. } else if ( x >= img.width() ) {
  180. x = img.width() - 1;
  181. }
  182. if ( y < 0 ) {
  183. y = 0;
  184. } else if ( y >= img.height() ) {
  185. y = img.height() - 1;
  186. }
  187. return img.getPixelQuick ( x, y );
  188. }
  189. template<class P>
  190. float ImageT<P>::getPixelBilinear ( const float x, const float y ) const {
  191. if ( int ( x ) < this->width() && int ( ceil ( x ) ) >= 0 && int ( y ) < this->height() && int ( ceil ( y ) ) >= 0 ) {
  192. int xi = ( int ) x;
  193. int yi = ( int ) y;
  194. float dx1 = float ( x ) - xi;
  195. float dy1 = float ( y ) - yi;
  196. float dx2 = 1.0 - dx1;
  197. float dy2 = 1.0 - dy1;
  198. float g1 = getPixel0 ( *this, xi, yi );
  199. float g2 = getPixel0 ( *this, xi + 1, yi );
  200. float g3 = getPixel0 ( *this, xi, yi + 1 );
  201. float g4 = getPixel0 ( *this, xi + 1, yi + 1 );
  202. return dx2 * ( dy2 * g1 + dy1 * g3 ) + dx1 * ( dy2 * g2 + dy1 * g4 );
  203. } else {
  204. std::stringstream s;
  205. s << "ImageT<P>::getPixelBilinear: (x,y) out of range: " << x << ", " << y << ".";
  206. fthrow ( ImageException, s.str() );
  207. }
  208. }
  209. template<class P>
  210. void ImageT<P>::setPixel ( const int x, const int y, const P value ) {
  211. if ( this->isWithinImage ( x, y ) ) {
  212. setPixelQuick ( x, y, value );
  213. } else {
  214. fthrow ( ImageException,
  215. "ImageT<P>::setPixel: (x,y) out of range." );
  216. }
  217. }
  218. template<class P>
  219. void ImageT<P>::setPixelSave ( const int x, const int y, const P value ) {
  220. if ( this->isWithinImage ( x, y ) ) {
  221. setPixelQuick ( x, y, value );
  222. }
  223. }
  224. template<class P>
  225. void ImageT<P>::set ( const P& value ) {
  226. #ifdef NICE_USELIB_IPP
  227. // FIXME: does not work for double. Does it work for other types than unsigned char?
  228. if ( sizeof ( P ) == 1 ) {
  229. IppStatus ret = ippiSet_C1R ( value, this->getPixelPointer(), this->getStepsize(), makeROIFullImage ( *this ) );
  230. if ( ret != ippStsNoErr )
  231. fthrow ( ImageException, ippGetStatusString ( ret ) );
  232. return;
  233. }
  234. #endif // NICE_USELIB_IPP
  235. P *p;
  236. for ( int y = 0; y < this->height(); ++y )
  237. {
  238. p = this->getPixelPointerY ( y );
  239. for ( int x = 0; x < this->width(); ++x, ++p )
  240. *p = value;
  241. }
  242. }
  243. template<class P>
  244. void ImageT<P>::mirror ( IppiAxis axis ) {
  245. #ifdef NICE_USELIB_IPP
  246. IppStatus ret = ippiMirror_C1IR ( this->getPixelPointer(), this->getStepsize(), makeROIFullImage ( *this ), axis );
  247. if ( ret != ippStsNoErr )
  248. fthrow ( ImageException, ippGetStatusString ( ret ) );
  249. #else
  250. bool mirrorX = ( axis == ippAxsVertical || axis == ippAxsBoth ) ? true : false;
  251. bool mirrorY = ( axis == ippAxsHorizontal || axis == ippAxsBoth ) ? true : false;
  252. for ( int y = 0; y <= ( mirrorY ? this->height() / 2 - 1 : this->height() - 1 ); ++y )
  253. for ( int x = 0; x <= ( mirrorX ? this->width() / 2 - 1 : this->width() - 1 ); ++x )
  254. std::swap ( ( *this ) ( Coord ( x, y ) ),
  255. ( *this ) ( Coord ( ( mirrorX ? this->width() - 1 - x : x ), ( mirrorY ? this->height() - 1 - y : y ) ) ) );
  256. #endif
  257. }
  258. template<class P>
  259. void ImageT<P>::transpose() {
  260. if ( this->width() != this->height() )
  261. fthrow ( ImageException, "Image size must be symetric." );
  262. #ifdef NICE_USELIB_IPP
  263. IppStatus ret = ippiTranspose_C1IR ( this->getPixelPointer(), this->getStepsize(), makeROIFullImage ( *this ) );
  264. if ( ret != ippStsNoErr )
  265. fthrow ( ImageException, ippGetStatusString ( ret ) );
  266. #else
  267. for ( int y = 0; y < this->height(); ++y )
  268. for ( int x = 0; x < y; ++x )
  269. std::swap ( ( *this ) ( Coord ( x, y ) ), ( *this ) ( Coord ( y, x ) ) );
  270. #endif
  271. }
  272. template<class P>
  273. void ImageT<P>::invert() {
  274. fthrow ( ImageException, "Datatype not yet supported." );
  275. }
  276. template<>
  277. void ImageT<Ipp8u>::invert();
  278. template<class P>
  279. void ImageT<P>::abs()
  280. {
  281. #ifdef NICE_USELIB_IPP
  282. IppStatus ret = ippiAbs_C1IR ( this->getPixelPointer(),
  283. this->getStepsize(),
  284. makeROIFullImage ( *this ) );
  285. if ( ret != ippStsNoErr )
  286. fthrow ( ImageException, ippGetStatusString ( ret ) );
  287. #else
  288. P* p;
  289. for ( int y = 0; y < this->height(); ++y )
  290. {
  291. p = this->getPixelPointerY ( y );
  292. for ( int x = 0; x < this->width(); ++x, ++p )
  293. *p = ( *p < 0 ) ? -*p : *p;
  294. }
  295. #endif
  296. }
  297. template<class P>
  298. P ImageT<P>::min() const
  299. {
  300. P min = std::numeric_limits<P>::max();
  301. #ifdef NICE_USELIB_IPP
  302. IppStatus ret = ippiMin_C1R ( this->getPixelPointer(),
  303. this->getStepsize(),
  304. makeROIFullImage ( *this ), &min );
  305. if ( ret != ippStsNoErr )
  306. fthrow ( ImageException, ippGetStatusString ( ret ) );
  307. #else
  308. const P* p;
  309. for ( int y = 0; y < this->height(); ++y )
  310. {
  311. p = this->getPixelPointerY ( y );
  312. for ( int x = 0; x < this->width(); ++x, ++p )
  313. min = ( *p < min ) ? *p : min;
  314. }
  315. #endif
  316. return min;
  317. }
  318. template<class P>
  319. P ImageT<P>::max() const
  320. {
  321. P max = std::numeric_limits<P>::min();
  322. #ifdef NICE_USELIB_IPP
  323. IppStatus ret = ippiMax_C1R ( this->getPixelPointer(),
  324. this->getStepsize(),
  325. makeROIFullImage ( *this ), &max );
  326. if ( ret != ippStsNoErr )
  327. fthrow ( ImageException, ippGetStatusString ( ret ) );
  328. #else
  329. const P* p;
  330. for ( int y = 0; y < this->height(); ++y )
  331. {
  332. p = this->getPixelPointerY ( y );
  333. for ( int x = 0; x < this->width(); ++x, ++p )
  334. max = ( *p > max ) ? *p : max;
  335. }
  336. #endif
  337. return max;
  338. }
  339. template<class P>
  340. void ImageT<P>::minmax ( P& min, P& max ) const
  341. {
  342. #ifdef NICE_USELIB_IPP
  343. IppStatus ret = ippiMinMax_C1R ( this->getPixelPointer(),
  344. this->getStepsize(),
  345. makeROIFullImage ( *this ), &min, &max );
  346. if ( ret != ippStsNoErr )
  347. fthrow ( ImageException, ippGetStatusString ( ret ) );
  348. #else
  349. min = std::numeric_limits<P>::max();
  350. max = - std::numeric_limits<P>::max();
  351. const P* p;
  352. for ( int y = 0; y < this->height(); ++y )
  353. {
  354. p = this->getPixelPointerY ( y );
  355. for ( int x = 0; x < this->width(); ++x, ++p )
  356. {
  357. min = ( *p < min ) ? *p : min;
  358. max = ( *p > max ) ? *p : max;
  359. }
  360. }
  361. #endif
  362. }
  363. template<class P>
  364. Coord ImageT<P>::minIndex() const
  365. {
  366. P min = std::numeric_limits<P>::max();
  367. Coord index;
  368. #ifdef NICE_USELIB_IPP
  369. IppStatus ret = ippiMinIndx_C1R ( this->getPixelPointer(),
  370. this->getStepsize(),
  371. makeROIFullImage ( *this ), &min, &index.x, &index.y );
  372. if ( ret != ippStsNoErr )
  373. fthrow ( ImageException, ippGetStatusString ( ret ) );
  374. #else
  375. const P* p;
  376. for ( int y = 0; y < this->height(); ++y )
  377. {
  378. p = this->getPixelPointerY ( y );
  379. for ( int x = 0; x < this->width(); ++x, ++p )
  380. if ( *p < min ) {
  381. min = *p;
  382. index.x = x;
  383. index.y = y;
  384. }
  385. }
  386. #endif
  387. return index;
  388. }
  389. template<class P>
  390. Coord ImageT<P>::maxIndex() const
  391. {
  392. P max = std::numeric_limits<P>::min();
  393. Coord index;
  394. #ifdef NICE_USELIB_IPP
  395. IppStatus ret = ippiMaxIndx_C1R ( this->getPixelPointer(),
  396. this->getStepsize(),
  397. makeROIFullImage ( *this ), &max, &index.x, &index.y );
  398. if ( ret != ippStsNoErr )
  399. fthrow ( ImageException, ippGetStatusString ( ret ) );
  400. #else
  401. const P* p;
  402. for ( int y = 0; y < this->height(); ++y )
  403. {
  404. p = this->getPixelPointerY ( y );
  405. for ( int x = 0; x < this->width(); ++x, ++p )
  406. if ( *p > max ) {
  407. max = static_cast<P> ( *p );
  408. index.x = x;
  409. index.y = y;
  410. }
  411. }
  412. #endif
  413. return index;
  414. }
  415. template<class P>
  416. void ImageT<P>::minmaxIndex ( Coord& minidx, Coord& maxidx ) const
  417. {
  418. Ipp32f min, max;
  419. #ifdef NICE_USELIB_IPP
  420. IppiPoint minindex, maxindex;
  421. IppStatus ret = ippiMinMaxIndx_C1R ( this->getPixelPointer(), this->getStepsize(),
  422. makeROIFullImage ( *this ),
  423. &min, &max, &minindex, &maxindex );
  424. if ( ret != ippStsNoErr )
  425. fthrow ( ImageException, ippGetStatusString ( ret ) );
  426. minidx = Coord ( minindex.x, minindex.y );
  427. maxidx = Coord ( maxindex.x, maxindex.y );
  428. #else
  429. min = std::numeric_limits<Ipp32f>::max();
  430. max = std::numeric_limits<Ipp32f>::min();
  431. const P* p;
  432. for ( int y = 0; y < this->height(); ++y )
  433. {
  434. p = this->getPixelPointerY ( y );
  435. for ( int x = 0; x < this->width(); ++x, ++p )
  436. {
  437. if ( *p < min ) {
  438. min = *p;
  439. minidx.x = x;
  440. minidx.y = y;
  441. }
  442. if ( *p > max ) {
  443. max = *p;
  444. maxidx.x = x;
  445. maxidx.y = y;
  446. }
  447. }
  448. }
  449. #endif
  450. }
  451. template<class P>
  452. double ImageT<P>::sum() const
  453. {
  454. double sum = 0;
  455. #ifdef NICE_USELIB_IPP
  456. IppStatus ret = ippiSum_C1R ( this->getPixelPointer(),
  457. this->getStepsize(),
  458. makeROIFullImage ( *this ), &sum );
  459. if ( ret != ippStsNoErr )
  460. fthrow ( ImageException, ippGetStatusString ( ret ) );
  461. #else
  462. const P* p;
  463. for ( int y = 0; y < this->height(); ++y )
  464. {
  465. p = this->getPixelPointerY ( y );
  466. for ( int x = 0; x < this->width(); ++x, ++p )
  467. sum += *p;
  468. }
  469. #endif
  470. return sum;
  471. }
  472. template<class P>
  473. double ImageT<P>::mean() const
  474. {
  475. P mean = 0;
  476. #ifdef NICE_USELIB_IPP
  477. Ipp64f fmean;
  478. IppStatus ret = ippiMean_C1R ( this->getPixelPointer(), this->getStepsize(),
  479. makeROIFullImage ( *this ), &fmean );
  480. mean = static_cast<P> ( fmean );
  481. if ( ret != ippStsNoErr )
  482. fthrow ( ImageException, ippGetStatusString ( ret ) );
  483. #else
  484. mean = static_cast<P> ( this->sum() / ( this->width() * this->height() ) );
  485. #endif
  486. return mean;
  487. }
  488. template<class P>
  489. void ImageT<P>::meanStdDev ( double& mean, double& stddev ) const
  490. {
  491. #ifdef NICE_USELIB_IPP
  492. IppStatus ret = ippiMean_StdDev_C1R ( this->getPixelPointer(),
  493. this->getStepsize(),
  494. makeROIFullImage ( *this ), &mean, &stddev );
  495. if ( ret != ippStsNoErr )
  496. fthrow ( ImageException, ippGetStatusString ( ret ) );
  497. #else
  498. mean = this->mean();
  499. stddev = 0.0;
  500. double temp = 0;
  501. const P* p;
  502. for ( int y = 0; y < this->height(); ++y )
  503. {
  504. p = this->getPixelPointerY ( y );
  505. for ( int x = 0; x < this->width(); ++x, ++p )
  506. {
  507. temp = *p - mean;
  508. stddev += temp * temp;
  509. }
  510. }
  511. // ipp divide it by (this->width()*this->height()) not by (this->width()*this->height())-1) !
  512. stddev = sqrt ( static_cast<double> ( stddev / ( this->width() * this->height() ) ) );
  513. #endif
  514. }
  515. template<class P>
  516. ImageT<P>* ImageT<P>::copyRect ( const Rect& rect, ImageT<P>* dst )
  517. {
  518. Rect roi = clipRect ( *this, rect );
  519. ImageT<P>* result = createResultBuffer ( roi.width, roi.height, dst );
  520. #ifdef NICE_USELIB_IPP
  521. Ipp8u const *src_rect = this->getPixelPointerXY ( roi.left, roi.top );
  522. IppStatus ret = ippiCopy_C1R ( src_rect, this->getStepsize(),
  523. result->getPixelPointer(),
  524. result->getStepsize(), makeROIRect ( *this, roi ) );
  525. if ( ret != ippStsNoErr )
  526. fthrow ( ImageException, ippGetStatusString ( ret ) );
  527. #else // NICE_USELIB_IPP
  528. P *pS, *pD;
  529. for ( int y = 0; y < roi.height; ++y )
  530. {
  531. pS = this->getPixelPointerXY ( roi.left, roi.top + y );
  532. pD = result->getPixelPointerY ( y );
  533. for ( int x = 0; x < roi.width; ++x, ++pS, ++pD )
  534. *pD = *pS;
  535. }
  536. #endif // NICE_USELIB_IPP
  537. return ( result );
  538. }
  539. // PGM
  540. template<class P>
  541. void ImageT<P>::readPGM ( const char *pgmFileName, const GrayColorImageCommonImplementation::MemoryLayout _memoryLayout ) {
  542. readPGM ( std::string ( pgmFileName ), _memoryLayout );
  543. }
  544. template<class P>
  545. void ImageT<P>::readPGM ( const std::string& pgmFileName,
  546. const GrayColorImageCommonImplementation::MemoryLayout _memoryLayout ) {
  547. // not in generic implementation (-> specialization in ImageT.cpp)
  548. fthrow ( ImageException,
  549. "ImageT<P> readPGM currently supported for ImageT<Ipp8u> only." );
  550. }
  551. template<>
  552. void ImageT<Ipp8u>::readPGM ( const std::string& pgmFileName,
  553. const GrayColorImageCommonImplementation::MemoryLayout _memoryLayout );
  554. template<class P>
  555. void ImageT<P>::readRaw ( const char* rawFilename, const GrayColorImageCommonImplementation::MemoryLayout _memoryLayout ) {
  556. unsigned int width = 0;
  557. unsigned int height = 0;
  558. std::ifstream in ( rawFilename );
  559. in >> width >> height;
  560. this->allocPixel ( width, height, _memoryLayout );
  561. for ( unsigned int x = 0; x < width; ++x ) {
  562. for ( unsigned int y = 0; y < height; ++y ) {
  563. P value;
  564. in >> value;
  565. this->operator() ( x,y ) = value;
  566. }
  567. }
  568. in.close();
  569. }
  570. template<class P>
  571. void ImageT<P>::readRaw ( const std::string& rawFilename,
  572. const GrayColorImageCommonImplementation::MemoryLayout _memoryLayout ) {
  573. readRaw ( rawFilename.c_str(), _memoryLayout );
  574. }
  575. template<class P>
  576. void ImageT<P>::writePGM ( const char* pgmFileName ) const {
  577. // not in generic implementation (-> specialization in ImageT.cpp)
  578. fthrow ( ImageException,
  579. "ImageT<P> writePGM currently supported for ImageT<Ipp8u> only." );
  580. }
  581. template<>
  582. void ImageT<Ipp8u>::writePGM ( const char* pgmFileName ) const;
  583. template<class P>
  584. void ImageT<P>::writePGM ( const std::string& pgmFilename ) const {
  585. writePGM ( pgmFilename.c_str() );
  586. }
  587. template<class P>
  588. void ImageT<P>::writeRaw ( const char* rawFilename ) const {
  589. std::ofstream out ( rawFilename );
  590. unsigned int width = this->width();
  591. unsigned int height = this->height();
  592. out << width << " " << height << std::endl;
  593. for ( unsigned int x = 0; x < width; ++x ) {
  594. for ( unsigned int y = 0; y < height; ++y ) {
  595. out << this->operator() ( x, y ) << " ";
  596. }
  597. out << std::endl;
  598. }
  599. out.close();
  600. }
  601. template<class P>
  602. void ImageT<P>::writeRaw ( const std::string& rawFilename ) const {
  603. writeRaw ( rawFilename.c_str() );
  604. }
  605. template<class P>
  606. void ImageT<P>::writeColored ( const ImageFile &file ) const {
  607. std::auto_ptr<ColorImageT<Ipp8u> > colored ( signedImageToRGB ( *this, NULL ) );
  608. file.writer ( dynamic_cast<GrayColorImageCommonImplementationT<Ipp8u> *> ( colored.get() ) );
  609. }
  610. //template<class P>
  611. //void ImageT<P>::writeColored(const ImageFile &file) const
  612. //{
  613. // file.writer(this);
  614. //}
  615. //template <>
  616. //void ImageT<Ipp32f>::writeColored(const ImageFile &file) const;
  617. //template <>
  618. //void ImageT<Ipp16s>::writeColored(const ImageFile &file) const;
  619. // Drawable
  620. template<class P>
  621. void ImageT<P>::draw ( Drawable<P> &drawable ) {
  622. drawable.draw ( *this );
  623. }
  624. template<class P>
  625. template<typename DrawableIterator>
  626. void ImageT<P>::drawIter ( const DrawableIterator begin, const DrawableIterator end ) {
  627. DrawableIterator it = begin;
  628. for ( ; it != end; it++ )
  629. it->draw ( *this );
  630. }
  631. template<class P>
  632. template<typename DrawableIterator>
  633. void ImageT<P>::drawIter ( const DrawableIterator begin, size_t number ) {
  634. DrawableIterator it = begin;
  635. for ( size_t i = 0; i < number; i++, it++ )
  636. it->draw ( *this );
  637. }
  638. template<class P>
  639. void ImageT<P>::draw ( Drawable<P> &drawable, const P& gray ) {
  640. drawable.draw ( *this, gray );
  641. }
  642. template<class P>
  643. template<typename DrawableIterator>
  644. void ImageT<P>::drawIter ( const DrawableIterator begin, const DrawableIterator end, const P& gray ) {
  645. DrawableIterator it = begin;
  646. for ( ; it != end; it++ )
  647. it->draw ( *this, gray );
  648. }
  649. template<class P>
  650. template<typename DrawableIterator>
  651. void ImageT<P>::drawIter ( const DrawableIterator begin, size_t number, const P& gray ) {
  652. DrawableIterator it = begin;
  653. for ( size_t i = 0; i < number; i++, it++ )
  654. it->draw ( *this, gray );
  655. }
  656. template<class P> inline bool ImageT<P>::operator== ( const ImageT<P>& g ) const {
  657. if ( this->height() != g.height() || this->width() != g.width() ) {
  658. fthrow ( ImageException, "ImageT<P> width and height does not match" );
  659. } else if ( this->width() == 0 || this->height() == 0 ) {
  660. return true;
  661. }
  662. const P* pSrc1, *pSrc2;
  663. for ( int i = 0; i < this->height(); ++i ) {
  664. pSrc1 = this->getPixelPointerY ( i );
  665. pSrc2 = g.getPixelPointerY ( i );
  666. for ( int j = 0; j < this->width(); ++j, ++pSrc1, ++pSrc2 )
  667. if ( *pSrc1 != *pSrc2 )
  668. return false;
  669. }
  670. return true;
  671. }
  672. template<class P> inline bool ImageT<P>::operator!= ( const ImageT<P>& g ) const {
  673. return ! ( this->operator== ( g ) );
  674. }
  675. template<class P> inline bool ImageT<P>::operator== ( const ColorT<P> &color ) const {
  676. P* pSrc;
  677. for ( int i = 0; i < this->height(); ++i ) {
  678. pSrc = this->getPixelPointerY ( i );
  679. for ( int j = 0; j < this->width(); ++j, ++pSrc )
  680. if ( color != *pSrc )
  681. return false;
  682. }
  683. return true;
  684. }
  685. template<class P> inline bool ImageT<P>::operator!= ( const ColorT<P> &color ) const {
  686. return ! ( this->operator== ( color ) );
  687. }
  688. template<class P> inline bool ImageT<P>::operator== ( P color ) const {
  689. for ( int i = 0; i < this->height(); i++ )
  690. for ( int j = 0; j < this->width(); j++ )
  691. if ( this->getPixelQuick ( j, i ) != color )
  692. return false;
  693. return true;
  694. }
  695. template<class P> inline bool ImageT<P>::operator!= ( P color ) const {
  696. return ! ( this->operator== ( color ) );
  697. }
  698. } // namespace