ImageT.tcc 24 KB

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