TestMorph.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613
  1. #include "TestMorph.h"
  2. #include "core/image/ImageT.h"
  3. #include "core/image/ColorImageT.h"
  4. #include "core/image/Morph.h"
  5. using namespace std;
  6. using namespace NICE;
  7. CPPUNIT_TEST_SUITE_REGISTRATION( TestMorph );
  8. void TestMorph::setUp()
  9. {
  10. }
  11. void TestMorph::tearDown()
  12. {
  13. }
  14. void TestMorph::testRanking()
  15. {
  16. Image* temp, *result;
  17. Image srcall(5,5);
  18. srcall.set(0);
  19. for(int j=1; j<=3; ++j)
  20. for(int i=1; i<=3; ++i)
  21. srcall.setPixelQuick(i,j, i+3*(j-1) );
  22. for(int i=1; i<=9; ++i) {
  23. result = NICE::rank(srcall, 1,i);
  24. CPPUNIT_ASSERT_EQUAL(i, static_cast<int>(result->getPixel(2,2)));
  25. }
  26. int width = 10;
  27. int height = 10;
  28. Image src(width,height);
  29. for(int y=0; y<height; ++y)
  30. for(int x=0; x<width; ++x)
  31. src(x,y) = x+y;
  32. // test exceptions
  33. CPPUNIT_ASSERT_THROW(NICE::rank(src,1,0), ImageException);
  34. CPPUNIT_ASSERT_THROW(NICE::rank(src,1,10), ImageException);
  35. // test ranking operation
  36. // rank = min
  37. result = NICE::rank(src, 1,1);
  38. for(int j=1; j<height-1; ++j)
  39. for(int i=1; i<width-1; ++i)
  40. CPPUNIT_ASSERT_EQUAL((i-1)+(j-1), static_cast<int>(result->getPixel(i,j)));
  41. // rank = 2
  42. result = NICE::rank(src, 1,2,result);
  43. for(int j=1; j<height-1; ++j)
  44. for(int i=1; i<width-1; ++i)
  45. CPPUNIT_ASSERT_EQUAL(i+j-1 , static_cast<int>(result->getPixel(i,j)));
  46. // rank = median
  47. result = NICE::rank(src, 1,5,result);
  48. for(int j=1; j<height-1; ++j)
  49. for(int i=1; i<width-1; ++i)
  50. CPPUNIT_ASSERT_EQUAL(i+j , static_cast<int>(result->getPixel(i,j)));
  51. // rank = 7
  52. result = NICE::rank(src, 1,7,result);
  53. for(int j=1; j<height-1; ++j)
  54. for(int i=1; i<width-1; ++i)
  55. CPPUNIT_ASSERT_EQUAL(i+j+1 , static_cast<int>(result->getPixel(i,j)));
  56. // rank = max
  57. result = NICE::rank(src, 1,9,result);
  58. for(int j=1; j<height-1; ++j)
  59. for(int i=1; i<width-1; ++i)
  60. CPPUNIT_ASSERT_EQUAL((i+1)+(j+1), static_cast<int>(result->getPixel(i,j)));
  61. // test IP ranking operation with the help of the testet ranking operation
  62. // rank = min
  63. result = NICE::rank(src, 1,1);
  64. temp = new Image(src);
  65. rankingIP(*temp, 1);
  66. for(int y=1; y<height-1; ++y)
  67. for(int x=1; x<width-1; ++x)
  68. CPPUNIT_ASSERT_EQUAL( static_cast<int>((*result)(x,y)), static_cast<int>((*temp)(x,y)) );
  69. // rank = 2
  70. result = NICE::rank(src, 1,2,result);
  71. temp = new Image(src);
  72. rankingIP(*temp, 2);
  73. for(int y=1; y<height-1; ++y)
  74. for(int x=1; x<width-1; ++x)
  75. CPPUNIT_ASSERT_EQUAL( static_cast<int>((*result)(x,y)), static_cast<int>((*temp)(x,y)) );
  76. // rank = median
  77. result = NICE::rank(src, 1,5,result);
  78. temp = new Image(src);
  79. rankingIP(*temp, 5);
  80. for(int y=1; y<height-1; ++y)
  81. for(int x=1; x<width-1; ++x)
  82. CPPUNIT_ASSERT_EQUAL( static_cast<int>((*result)(x,y)), static_cast<int>((*temp)(x,y)) );
  83. // rank = 7
  84. result = NICE::rank(src, 1,7,result);
  85. temp = new Image(src);
  86. rankingIP(*temp, 7);
  87. for(int y=1; y<height-1; ++y)
  88. for(int x=1; x<width-1; ++x)
  89. CPPUNIT_ASSERT_EQUAL( static_cast<int>((*result)(x,y)), static_cast<int>((*temp)(x,y)) );
  90. // rank = max
  91. result = NICE::rank(src, 1,9,result);
  92. temp = new Image(src);
  93. rankingIP(*temp, 9);
  94. for(int y=1; y<height-1; ++y)
  95. for(int x=1; x<width-1; ++x)
  96. CPPUNIT_ASSERT_EQUAL( static_cast<int>((*result)(x,y)), static_cast<int>((*temp)(x,y)) );
  97. }
  98. void TestMorph::testMorphological()
  99. {
  100. int width = 10;
  101. int height = 10;
  102. Image src(width,height);
  103. for(int y=0; y<height; ++y)
  104. for(int x=0; x<width; ++x)
  105. src(x,y) = x+y;
  106. Image* result;
  107. // test erode, median, dilate (3x3)
  108. // erode = minimum filter
  109. result = erode(src);
  110. for(int j=1; j<height-1; ++j)
  111. for(int i=1; i<width-1; ++i)
  112. CPPUNIT_ASSERT_EQUAL((i-1)+(j-1), static_cast<int>(result->getPixel(i,j)));
  113. // median
  114. result = median(src,result);
  115. for(int j=1; j<height-1; ++j)
  116. for(int i=1; i<width-1; ++i)
  117. CPPUNIT_ASSERT_EQUAL(i+j , static_cast<int>(result->getPixel(i,j)));
  118. // test median with another image
  119. {
  120. Image t(5,5);
  121. t(0,0) =5; t(0,1) =1; t(0,2) =4; t(0,3) =7; t(0,4) =4;
  122. t(1,0) =1; t(1,1) =9; t(1,2) =8; t(1,3) =1; t(1,4) =3;
  123. t(2,0) =5; t(2,1) =2; t(2,2) =3; t(2,3) =3; t(2,4) =3;
  124. t(3,0) =8; t(3,1) =3; t(3,2) =7; t(3,3) =6; t(3,4) =7;
  125. t(4,0) =2; t(4,1) =5; t(4,2) =4; t(4,3) =8; t(4,4) =7;
  126. Image* r = median(t);
  127. CPPUNIT_ASSERT_EQUAL(4, static_cast<int>(r->getPixel(1,1)));
  128. CPPUNIT_ASSERT_EQUAL(5, static_cast<int>(r->getPixel(2,1)));
  129. CPPUNIT_ASSERT_EQUAL(4, static_cast<int>(r->getPixel(3,1)));
  130. CPPUNIT_ASSERT_EQUAL(3, static_cast<int>(r->getPixel(1,2)));
  131. CPPUNIT_ASSERT_EQUAL(3, static_cast<int>(r->getPixel(2,2)));
  132. CPPUNIT_ASSERT_EQUAL(4, static_cast<int>(r->getPixel(3,2)));
  133. CPPUNIT_ASSERT_EQUAL(3, static_cast<int>(r->getPixel(1,3)));
  134. CPPUNIT_ASSERT_EQUAL(3, static_cast<int>(r->getPixel(2,3)));
  135. CPPUNIT_ASSERT_EQUAL(6, static_cast<int>(r->getPixel(3,3)));
  136. // now check if ip median has the same results
  137. medianIP(t);
  138. for(int y=1; y<=3; ++y)
  139. for(int x=1; x<=3; ++x)
  140. CPPUNIT_ASSERT_EQUAL(static_cast<int>(t(x,y)),
  141. static_cast<int>(r->getPixel(x,y)));
  142. }
  143. // dilate = maximum filter
  144. result = dilate(src,result);
  145. for(int j=1; j<height-1; ++j)
  146. for(int i=1; i<width-1; ++i)
  147. CPPUNIT_ASSERT_EQUAL((i+1)+(j+1), static_cast<int>(result->getPixel(i,j)));
  148. // now test dilate, median, erode, opening and closing on binary images (0,255)
  149. src = Image(13,13);
  150. src = 0;
  151. src(3,3) = src(4,3) = src(5,3) = src(6,3) = src(7,3) = src(8,3) = 255;
  152. src(4,4) = src(5,4) = src(7,4) = 255;
  153. src(4,5) = src(5,5) = src(6,5) = src(7,5) = src(8,5) = 255;
  154. src(4,6) = src(5,6) = src(6,6) = src(7,6) = 255;
  155. src(3,7) = src(4,7) = src(5,7) = src(6,7) = src(7,7) = 255;
  156. src(3,8) = src(4,8) = src(5,8) = src(6,8) = 255;
  157. src(3,9) = src(4,9) = src(5,9) = src(6,9) = src(9,9) = 255;
  158. // erode
  159. result = erode(src);
  160. CPPUNIT_ASSERT_EQUAL(255, static_cast<int>(result->getPixel(5, 6)));
  161. CPPUNIT_ASSERT_EQUAL(255, static_cast<int>(result->getPixel(6, 6)));
  162. CPPUNIT_ASSERT_EQUAL(255, static_cast<int>(result->getPixel(5, 7)));
  163. CPPUNIT_ASSERT_EQUAL(255, static_cast<int>(result->getPixel(4, 8)));
  164. CPPUNIT_ASSERT_EQUAL(255, static_cast<int>(result->getPixel(5, 8)));
  165. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel(4, 6)));
  166. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel(4, 7)));
  167. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel(6, 7)));
  168. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel(6, 8)));
  169. for(int i=3; i<=7; ++i)
  170. {
  171. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel(i, 5)));
  172. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel(i, 9)));
  173. }
  174. for(int i=5; i<=9; ++i)
  175. {
  176. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel(3,i)));
  177. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel(7,i)));
  178. }
  179. // median
  180. result = median(src,result);
  181. for(int i=1; i<result->height()-1; ++i) {
  182. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel( 1, i)));
  183. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel( 2, i)));
  184. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel( 9, i)));
  185. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel(10, i)));
  186. }
  187. for(int i=1; i<result->width()-1; ++i) {
  188. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel(i, 1)));
  189. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel(i, 2)));
  190. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel(i,10)));
  191. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel(i,11)));
  192. }
  193. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel( 3, 3)));
  194. CPPUNIT_ASSERT_EQUAL(255, static_cast<int>(result->getPixel( 3, 7)));
  195. CPPUNIT_ASSERT_EQUAL(255, static_cast<int>(result->getPixel( 3, 8)));
  196. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel( 3, 9)));
  197. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel( 3,10)));
  198. CPPUNIT_ASSERT_EQUAL(255, static_cast<int>(result->getPixel( 4, 9)));
  199. CPPUNIT_ASSERT_EQUAL(255, static_cast<int>(result->getPixel( 5, 9)));
  200. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel( 6, 9)));
  201. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel( 7, 3)));
  202. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel( 8, 3)));
  203. CPPUNIT_ASSERT_EQUAL(255, static_cast<int>(result->getPixel( 8, 4)));
  204. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel( 8, 5)));
  205. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel( 9, 9)));
  206. Image med1(3,3);
  207. med1(0,0) = 1; med1(1,0) = 1; med1(2,0) = 1;
  208. med1(0,1) = 1; med1(1,1) = 1; med1(2,1) = 2;
  209. med1(0,2) = 2; med1(1,2) = 2; med1(2,2) = 2;
  210. result = median(med1);
  211. CPPUNIT_ASSERT_EQUAL( 1, static_cast<int>(result->getPixel(1,1)));
  212. med1(0,0) = 1; med1(1,0) = 1; med1(2,0) = 1;
  213. med1(0,1) = 1; med1(1,1) = 2; med1(2,1) = 2;
  214. med1(0,2) = 2; med1(1,2) = 2; med1(2,2) = 2;
  215. result = median(med1);
  216. CPPUNIT_ASSERT_EQUAL( 2, static_cast<int>(result->getPixel(1,1)));
  217. // dilate
  218. result = dilate(src);
  219. for(int y=2; y<result->height()-2; ++y)
  220. for(int x=2; x<result->width()-3; ++x)
  221. if( (x==2&&y==5) || (x==9&&y==7) )
  222. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel(x,y)));
  223. else
  224. CPPUNIT_ASSERT_EQUAL(255, static_cast<int>(result->getPixel(x,y)));
  225. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel(10, 2)));
  226. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel(10, 3)));
  227. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel(10, 4)));
  228. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel(10, 5)));
  229. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel(10, 6)));
  230. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel(10, 7)));
  231. CPPUNIT_ASSERT_EQUAL(255, static_cast<int>(result->getPixel(10, 8)));
  232. CPPUNIT_ASSERT_EQUAL(255, static_cast<int>(result->getPixel(10, 9)));
  233. CPPUNIT_ASSERT_EQUAL(255, static_cast<int>(result->getPixel(10,10)));
  234. // opening
  235. result = opening(src,result);
  236. for(int i=2; i<result->width()-2; ++i) {
  237. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel(i, 3)));
  238. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel(i, 4)));
  239. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel(i,10)));
  240. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel(i,11)));
  241. }
  242. for(int i=2; i<result->height()-2; ++i) {
  243. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel( 1,i)));
  244. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel( 2,i)));
  245. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel( 8,i)));
  246. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel( 9,i)));
  247. }
  248. for(int i=3; i<=7; ++i)
  249. for(int j=5; j<=9; ++j)
  250. if( (i==3&&j>=5&&j<=6) || (i==7&&j>=8&&j<=9) )
  251. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel(i,j)));
  252. else
  253. CPPUNIT_ASSERT_EQUAL(255, static_cast<int>(result->getPixel(i,j)));
  254. // closing
  255. result = closing(src,result);
  256. for(int i=1; i<result->width()-1; ++i) {
  257. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel(i, 1)));
  258. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel(i, 2)));
  259. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel(i,10)));
  260. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel(i,11)));
  261. }
  262. for(int i=1; i<result->height()-1; ++i) {
  263. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel( 1,i)));
  264. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel( 2,i)));
  265. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel(10,i)));
  266. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel(11,i)));
  267. }
  268. for(int i=3; i<=8; ++i)
  269. for(int j=3; j<=9; ++j)
  270. if( (i==3&&j>=4&&j<=6) || (i==8&&j>=6&&j<=8) )
  271. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>(result->getPixel(i,j)));
  272. else
  273. CPPUNIT_ASSERT_EQUAL(255, static_cast<int>(result->getPixel(i,j)));
  274. CPPUNIT_ASSERT_EQUAL(255, static_cast<int>(result->getPixel( 9, 9)));
  275. }
  276. void TestMorph::testMorphologicalIP()
  277. {
  278. Image src(13,13);
  279. src.set(0);
  280. src(3,3) = src(4,3) = src(5,3) = src(6,3) = src(7,3) = src(8,3) = 255;
  281. src(4,4) = src(5,4) = src(7,4) = 255;
  282. src(4,5) = src(5,5) = src(6,5) = src(7,5) = src(8,5) = 255;
  283. src(4,6) = src(5,6) = src(6,6) = src(7,6) = 255;
  284. src(3,7) = src(4,7) = src(5,7) = src(6,7) = src(7,7) = 255;
  285. src(3,8) = src(4,8) = src(5,8) = src(6,8) = 255;
  286. src(3,9) = src(4,9) = src(5,9) = src(6,9) = src(9,9) = 255;
  287. Image* result, *temp;
  288. // test IP operations with the help of the testet non IP operations
  289. // erodeIP
  290. result = erode(src);
  291. temp = new Image(src);
  292. erodeIP(*temp);
  293. for(int y=1; y<result->height()-1; ++y)
  294. for(int x=1; x<result->width()-1; ++x)
  295. CPPUNIT_ASSERT_EQUAL( static_cast<int>((*result)(x,y)), static_cast<int>((*temp)(x,y)) );
  296. // medianIP
  297. result = median(src);
  298. temp = new Image(src);
  299. medianIP(*temp);
  300. for(int y=1; y<result->height()-1; ++y)
  301. for(int x=1; x<result->width()-1; ++x)
  302. CPPUNIT_ASSERT_EQUAL( static_cast<int>((*result)(x,y)), static_cast<int>((*temp)(x,y)) );
  303. // dilateIP
  304. result = dilate(src);
  305. temp = new Image(src);
  306. dilateIP(*temp);
  307. for(int y=1; y<result->height()-1; ++y)
  308. for(int x=1; x<result->width()-1; ++x)
  309. CPPUNIT_ASSERT_EQUAL( static_cast<int>((*result)(x,y)), static_cast<int>((*temp)(x,y)) );
  310. // openingIP
  311. result = opening(src,result);
  312. temp = new Image(src);
  313. openingIP(*temp);
  314. for(int y=2; y<result->height()-2; ++y)
  315. for(int x=2; x<result->width()-2; ++x)
  316. CPPUNIT_ASSERT_EQUAL( static_cast<int>((*result)(x,y)), static_cast<int>((*temp)(x,y)) );
  317. // closingIP
  318. result = closing(src,result);
  319. temp = new Image(src);
  320. closingIP(*temp);
  321. for(int y=2; y<result->height()-2; ++y)
  322. for(int x=2; x<result->width()-2; ++x)
  323. CPPUNIT_ASSERT_EQUAL( static_cast<int>((*result)(x,y)), static_cast<int>((*temp)(x,y)) );
  324. }
  325. void TestMorph::testRankingWithStructure()
  326. {
  327. Image* result, *rresult;
  328. Image src = Image(10,11);
  329. src.set(0);
  330. src(2,2) = src(3,2) = src(4,2) = src(5,2) =src(6,2) = src(7,2) = 255;
  331. src(3,3) = src(5,3) = src(6,3) = 255;
  332. src(3,4) = src(4,4) = src(5,4) = src(6,4) = src(7,4) = 255;
  333. src(3,5) = src(4,5) = src(5,5) = src(6,5) = 255;
  334. src(2,6) = src(3,6) = src(4,6) = src(5,6) = src(6,6) = 255;
  335. src(2,7) = src(3,7) = src(4,7) = src(5,7) = 255;
  336. src(2,8) = src(3,8) = src(4,8) = src(5,8) = src(8,8) = 255;
  337. // test ranking operation
  338. CharMatrix structure(3,3);
  339. // 3x3 quadratic structure Element
  340. {
  341. structure = 1;
  342. // rank = 1
  343. rresult = erode(src);
  344. result = NICE::rank(src, structure, 1);
  345. for(int y=1; y<src.height()-1; ++y)
  346. for(int x=1; x<src.width()-1; ++x)
  347. CPPUNIT_ASSERT_EQUAL( static_cast<int>((*rresult)(x,y)), static_cast<int>((*result)(x,y)) );
  348. // rank = 2
  349. rresult = NICE::rank(src, 1, 2, rresult);
  350. result = NICE::rank(src, structure, 2, result);
  351. for(int y=1; y<src.height()-1; ++y)
  352. for(int x=1; x<src.width()-1; ++x)
  353. CPPUNIT_ASSERT_EQUAL( static_cast<int>((*rresult)(x,y)), static_cast<int>((*result)(x,y)) );
  354. // rank = median
  355. rresult = median(src, rresult);
  356. result = NICE::rank(src, structure, 5, result);
  357. for(int y=1; y<src.height()-1; ++y)
  358. for(int x=1; x<src.width()-1; ++x)
  359. CPPUNIT_ASSERT_EQUAL( static_cast<int>((*rresult)(x,y)), static_cast<int>((*result)(x,y)) );
  360. // rank = 7
  361. rresult = NICE::rank(src, 1, 7, rresult);
  362. result = NICE::rank(src, structure, 7, result);
  363. for(int y=1; y<src.height()-1; ++y)
  364. for(int x=1; x<src.width()-1; ++x)
  365. CPPUNIT_ASSERT_EQUAL( static_cast<int>((*rresult)(x,y)), static_cast<int>((*result)(x,y)) );
  366. // rank = 9
  367. rresult = dilate(src, rresult);
  368. result = NICE::rank(src, structure, 9, result);
  369. for(int y=1; y<src.height()-1; ++y)
  370. for(int x=1; x<src.width()-1; ++x)
  371. CPPUNIT_ASSERT_EQUAL( static_cast<int>((*rresult)(x,y)), static_cast<int>((*result)(x,y)) );
  372. }
  373. }
  374. void TestMorph::testMorphologicalWithStructure()
  375. {
  376. Image* result = NULL;
  377. Image src (10,11);
  378. src = 0;
  379. src(2,2) = src(3,2) = src(4,2) = src(5,2) =src(6,2) = src(7,2) = 255;
  380. src(3,3) = src(5,3) = src(6,3) = 255;
  381. src(3,4) = src(4,4) = src(5,4) = src(6,4) = src(7,4) = 255;
  382. src(3,5) = src(4,5) = src(5,5) = src(6,5) = 255;
  383. src(2,6) = src(3,6) = src(4,6) = src(5,6) = src(6,6) = 255;
  384. src(2,7) = src(3,7) = src(4,7) = src(5,7) = 255;
  385. src(2,8) = src(3,8) = src(4,8) = src(5,8) = src(8,8) = 255;
  386. // test some specific corner and line structure elements with the erode operator
  387. {
  388. src = Image(12,12);
  389. src = 0;
  390. src(4,4) = src(5,4) = src(6,4) = src(7,4) = src(7,5) = src(7,6) = src(7,7) = 255;
  391. src(6,7) = src(5,7) = src(4,7) = src(4,6) = src(4,5) = 255;
  392. // test lines
  393. CharMatrix hl(5,5,0), vl(5,5,0);
  394. hl(2,1) = hl(2,2) = hl(2,3) = 1;
  395. vl(1,2) = vl(2,2) = vl(3,2) = 1;
  396. // horizontal line
  397. CPPUNIT_ASSERT_NO_THROW(result = erode(src, hl));
  398. CPPUNIT_ASSERT_EQUAL(255, static_cast<int>((*result)(5,4)));
  399. CPPUNIT_ASSERT_EQUAL(255, static_cast<int>((*result)(6,4)));
  400. CPPUNIT_ASSERT_EQUAL(255, static_cast<int>((*result)(5,7)));
  401. CPPUNIT_ASSERT_EQUAL(255, static_cast<int>((*result)(6,7)));
  402. // vertical line
  403. CPPUNIT_ASSERT_NO_THROW(result = erode(src, vl));
  404. CPPUNIT_ASSERT_EQUAL(255, static_cast<int>((*result)(4,5)));
  405. CPPUNIT_ASSERT_EQUAL(255, static_cast<int>((*result)(4,6)));
  406. CPPUNIT_ASSERT_EQUAL(255, static_cast<int>((*result)(7,5)));
  407. CPPUNIT_ASSERT_EQUAL(255, static_cast<int>((*result)(7,6)));
  408. // test edges
  409. CharMatrix tl(5,5,0), tr(5,5,0), bl(5,5,0), br(5,5,0);
  410. tl(2,2) = tl(3,2) = tl(4,2) = tl(2,3) = tl(2,4) = 1;
  411. tr(2,2) = tr(3,2) = tr(4,2) = tr(2,1) = tr(2,0) = 1;
  412. bl(2,2) = bl(2,3) = bl(2,4) = bl(1,2) = bl(0,2) = 1;
  413. br(2,2) = br(2,1) = br(2,0) = br(1,2) = br(0,2) = 1;
  414. CPPUNIT_ASSERT_NO_THROW(result = erode(src, tl));
  415. CPPUNIT_ASSERT_EQUAL(255, static_cast<int>((*result)(4,4)));
  416. CPPUNIT_ASSERT_NO_THROW(result = erode(src, tr));
  417. CPPUNIT_ASSERT_EQUAL(255, static_cast<int>((*result)(7,4)));
  418. CPPUNIT_ASSERT_NO_THROW(result = erode(src, bl));
  419. CPPUNIT_ASSERT_EQUAL(255, static_cast<int>((*result)(4,7)));
  420. CPPUNIT_ASSERT_NO_THROW(result = erode(src, br));
  421. CPPUNIT_ASSERT_EQUAL(255, static_cast<int>((*result)(7,7)));
  422. }
  423. // test erode and dilate with a cross structure element
  424. {
  425. src = 0;
  426. for(int y=4; y<=7; ++y)
  427. for(int x=4; x<=7; ++x)
  428. src(x,y) = 255;
  429. CharMatrix cross(3,3,0);
  430. cross(0,1) = cross(1,0) = cross(1,1) = cross(1,2) = cross(2,1) = 1;
  431. // erode
  432. CPPUNIT_ASSERT_NO_THROW(result = erode(src, cross));
  433. for(int y=1; y<result->height()-1; ++y)
  434. for(int x=1; x<result->width()-1; ++x)
  435. if( y>=5 && y<=6 && x>=5 && x<=6 )
  436. CPPUNIT_ASSERT_EQUAL(255, static_cast<int>((*result)(x,y)));
  437. else
  438. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>((*result)(x,y)));
  439. // dialte
  440. CPPUNIT_ASSERT_NO_THROW(result = dilate(src, cross));
  441. for(int i=1; i<=10; ++i)
  442. {
  443. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>((*result)(i, 1)));
  444. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>((*result)(i, 2)));
  445. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>((*result)(i, 9)));
  446. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>((*result)(i,10)));
  447. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>((*result)( 1,i)));
  448. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>((*result)( 2,i)));
  449. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>((*result)( 9,i)));
  450. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>((*result)(10,i)));
  451. }
  452. for(int y=3; y<=8; ++y)
  453. for(int x=8; x<=8; ++x)
  454. if( (x==3)&&(y==3) || (x==8)&&(y==3) || (x==3)&&(y==8) || (x==8)&&(y==8) )
  455. CPPUNIT_ASSERT_EQUAL( 0, static_cast<int>((*result)(x,y)));
  456. else
  457. CPPUNIT_ASSERT_EQUAL(255, static_cast<int>((*result)(x,y)));
  458. }
  459. }
  460. void TestMorph::testHitAndMiss()
  461. {
  462. // test some corner structure Elements with the hitAndMiss operator
  463. {
  464. Image src(12,12);
  465. src.set(0);
  466. for(int y=4; y<=7; ++y)
  467. for(int x=4; x<=7; ++x)
  468. src(x,y) = 255;
  469. CharMatrix tl(5,5,0), tr(5,5,0), bl(5,5,0), br(5,5,0);
  470. tl(2,2) = tl(3,2) = tl(4,2) = tl(2,3) = tl(3,3) = tl(4,3) = tl(2,4) = tl(3,4) = tl(4,4) = 1;
  471. tr(2,0) = tr(2,1) = tr(2,2) = tr(3,0) = tr(3,1) = tr(3,2) = tr(4,0) = tr(4,1) = tr(4,2) = 1;
  472. bl(0,2) = bl(0,3) = bl(0,4) = bl(1,2) = bl(1,3) = bl(1,4) = bl(2,2) = bl(2,3) = bl(2,4) = 1;
  473. br(0,0) = br(0,1) = br(0,2) = br(1,0) = br(1,1) = br(1,2) = br(2,0) = br(2,1) = br(2,2) = 1;
  474. Image* result = new Image(src.width(), src.height());
  475. Image exp(src.width()-2*2, src.height()-2*2);
  476. result = hitAndMiss(src, tl, result);
  477. exp.set(0);
  478. exp.setPixelQuick(2,2,255);
  479. CPPUNIT_ASSERT_EQUAL(true, *result->createSubImage(Rect(2,2,result->width()-4,result->height()-4))==exp);
  480. result = hitAndMiss(src, tr, result);
  481. exp.set(0);
  482. exp.setPixelQuick(5,2,255);
  483. CPPUNIT_ASSERT_EQUAL(true, *result->createSubImage(Rect(2,2,result->width()-4,result->height()-4))==exp);
  484. result = hitAndMiss(src, bl, result);
  485. exp.set(0);
  486. exp.setPixelQuick(2,5,255);
  487. CPPUNIT_ASSERT_EQUAL(true, *result->createSubImage(Rect(2,2,result->width()-4,result->height()-4))==exp);
  488. result = hitAndMiss(src, br, result);
  489. exp.set(0);
  490. exp.setPixelQuick(5,5,255);
  491. CPPUNIT_ASSERT_EQUAL(true, *result->createSubImage(Rect(2,2,result->width()-4,result->height()-4))==exp);
  492. // clean up
  493. delete result;
  494. }
  495. // now we try to find the letter A out of A and B with the hitAndMiss operator
  496. {
  497. Image src(19,11);
  498. src.set(0);
  499. src(4,3) = src(5,3) = src(6,3) = src(4,4) = src(6,4) = src(5,5) = 255;
  500. src(4,5) = src(6,5) = src(4,6) = src(6,6) = src(4,7) = src(6,7) = 255;
  501. src(12,3) = src(13,3) = src(14,3) = src(12,4) = src(14,4) = 255;
  502. src(12,5) = src(13,5) = src(14,5) = src(12,6) = src(14,6) = 255;
  503. src(12,7) = src(13,7) = src(14,7) = 255;
  504. CharMatrix CharTest(7,5);
  505. CharTest = 0;
  506. CharTest(1,1) = CharTest(1,2) = CharTest(1,3) = CharTest(2,1) = CharTest(2,3) = CharTest(3,1) = 1;
  507. CharTest(3,2) = CharTest(3,3) = CharTest(4,1) = CharTest(4,3) = CharTest(5,1) = CharTest(5,3) = 1;
  508. Image* result = new Image(src.width(), src.height());
  509. result = hitAndMiss(src, CharTest, result);
  510. Image exp(src.width()-4, src.height()-4);
  511. exp.set(0);
  512. exp.setPixelQuick(3,3, 255);
  513. CPPUNIT_ASSERT_EQUAL(true, *result->createSubImage(Rect(2,2,result->width()-4,result->height()-4))==exp);
  514. // clean up
  515. delete result;
  516. }
  517. }