/************************************************************************/ /* */ /* Copyright 2004 by Ullrich Koethe */ /* Cognitive Systems Group, University of Hamburg, Germany */ /* */ /* This file is part of the VIGRA computer vision library. */ /* ( Version 1.5.0, Dec 07 2006 ) */ /* The VIGRA Website is */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* Please direct questions, bug reports, and contributions to */ /* koethe@informatik.uni-hamburg.de or */ /* vigra@kogs1.informatik.uni-hamburg.de */ /* */ /* Permission is hereby granted, free of charge, to any person */ /* obtaining a copy of this software and associated documentation */ /* files (the "Software"), to deal in the Software without */ /* restriction, including without limitation the rights to use, */ /* copy, modify, merge, publish, distribute, sublicense, and/or */ /* sell copies of the Software, and to permit persons to whom the */ /* Software is furnished to do so, subject to the following */ /* conditions: */ /* */ /* The above copyright notice and this permission notice shall be */ /* included in all copies or substantial portions of the */ /* Software. */ /* */ /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */ /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */ /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */ /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */ /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ /* OTHER DEALINGS IN THE SOFTWARE. */ /* */ /************************************************************************/ #include #include "unittest.hxx" #include "vigra/stdimage.hxx" #include "vigra/basicimageview.hxx" #include "vigra/imageiterator.hxx" #include "vigra/impex.hxx" #include "vigra/imagecontainer.hxx" #include "vigra/inspectimage.hxx" #include "vigra/pixelneighborhood.hxx" #include "vigra/contourcirculator.hxx" using vigra::Diff2D; using namespace vigra; unsigned char * testData(unsigned char) { static unsigned char data[] = {1,2,3,4,5,6,7,8,9}; return data; } double * testData(double) { static double data[] = {1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9}; return data; } RGBValue * testData(RGBValue) { typedef RGBValue BRGB; static BRGB data[] = { BRGB(1,1,1), BRGB(2,2,2), BRGB(3,3,3), BRGB(4,4,4), BRGB(5,5,5), BRGB(6,6,6), BRGB(7,7,7), BRGB(8,8,8), BRGB(9,9,9) }; return data; } RGBValue * testData(RGBValue) { typedef vigra::RGBValue FRGB; static FRGB data[] = { FRGB(1.1, 1.1, 1.1), FRGB(2.2, 2.2, 2.2), FRGB(3.3, 3.3, 3.3), FRGB(4.4, 4.4, 4.4), FRGB(5.5, 5.5, 5.5), FRGB(6.6, 6.6, 6.6), FRGB(7.7, 7.7, 7.7), FRGB(8.8, 8.8, 8.8), FRGB(9.9, 9.9, 9.9) }; return data; } template struct ImageTest { typedef IMAGE Image; typedef typename Image::value_type value_type; value_type internalMemory[9]; value_type * data; ImageTest(IMAGE const & image) : img(image), data(testData(value_type())) { typename Image::Accessor acc = img.accessor(); typename Image::iterator i = img.begin(); acc.set(data[0], i); ++i; acc.set(data[1], i); ++i; acc.set(data[2], i); ++i; acc.set(data[3], i); ++i; acc.set(data[4], i); ++i; acc.set(data[5], i); ++i; acc.set(data[6], i); ++i; acc.set(data[7], i); ++i; acc.set(data[8], i); ++i; should(i == img.end()); } template void scanImage(Iterator ul, Iterator lr) { Iterator y = ul; Iterator x = ul; typename Image::Accessor acc = img.accessor(); should(acc(x) == data[0]); ++x.x; should(acc(x) == data[1]); ++x.x; should(acc(x) == data[2]); ++x.x; should(x.x == lr.x); ++y.y; x = y; should(acc(x) == data[3]); ++x.x; should(acc(x) == data[4]); ++x.x; should(acc(x) == data[5]); ++y.y; x = y; should(acc(x) == data[6]); ++x.x; should(acc(x) == data[7]); ++x.x; should(acc(x) == data[8]); ++y.y; should(y.y == lr.y); y = ul; should(acc(y, vigra::Diff2D(1,1)) == data[4]); } template void scanRows(Iterator r1, Iterator r2, Iterator r3, int w) { Iterator end = r1 + w; typename Image::Accessor acc = img.accessor(); should(acc(r1) == data[0]); ++r1; should(acc(r1) == data[1]); ++r1; should(acc(r1) == data[2]); ++r1; should(r1 == end); end = r2 + w; should(acc(r2) == data[3]); ++r2; should(acc(r2) == data[4]); ++r2; should(acc(r2) == data[5]); ++r2; should(r2 == end); end = r3 + w; should(acc(r3) == data[6]); ++r3; should(acc(r3) == data[7]); ++r3; should(acc(r3) == data[8]); ++r3; should(r3 == end); } template void scanColumns(Iterator c1, Iterator c2, Iterator c3, int h) { Iterator end = c1 + h; typename Image::Accessor acc = img.accessor(); should(acc(c1) == data[0]); ++c1; should(acc(c1) == data[3]); ++c1; should(acc(c1) == data[6]); ++c1; should(c1 == end); end = c2 + h; should(acc(c2) == data[1]); ++c2; should(acc(c2) == data[4]); ++c2; should(acc(c2) == data[7]); ++c2; should(c2 == end); end = c3 + h; should(acc(c3) == data[2]); ++c3; should(acc(c3) == data[5]); ++c3; should(acc(c3) == data[8]); ++c3; should(c3 == end); } void testIterator() { typename Image::Iterator ul = img.upperLeft(); typename Image::Iterator lr = img.lowerRight(); scanImage(ul, lr); scanRows(ul.rowIterator(), (ul+Diff2D(0,1)).rowIterator(), (ul+Diff2D(0,2)).rowIterator(), img.width()); scanRows(img.rowBegin(0), img.rowBegin(1), img.rowBegin(2), img.width()); scanColumns(ul.columnIterator(), (ul+Diff2D(1,0)).columnIterator(), (ul+Diff2D(2,0)).columnIterator(), img.height()); scanColumns(img.columnBegin(0), img.columnBegin(1), img.columnBegin(2), img.height()); typename Image::Accessor acc = img.accessor(); typename Image::iterator i = img.begin(); should(acc(i, 4) == data[4]); } void testIndex() { for (int y=0; y struct BasicImageTest : public ImageTest { BasicImageTest() : ImageTest(IMAGE(Diff2D(3,3))) {} // next lines needed due to gcc 2.95 bug void testIterator() { ImageTest::testIterator(); } void testIndex() { ImageTest::testIndex(); } void testConstructor() { ImageTest::testConstructor(); } void copyImage() { ImageTest::copyImage(); } void swapImage() { IMAGE other(1,1); other(0,0) = this->data[2]; this->img.swap(other); shouldEqual(this->img.width(), 1); shouldEqual(this->img.height(), 1); shouldEqual(this->img(0,0), this->data[2]); shouldEqual(other.width(), 3); shouldEqual(other.height(), 3); shouldEqual(other(2,2), this->data[8]); } }; template struct BasicImageViewTest : public ImageTest { BasicImageViewTest() : ImageTest(IMAGE(ImageTest::internalMemory, Diff2D(3,3))) {} // next lines needed due to gcc 2.95 bug void testIterator() { ImageTest::testIterator(); } void testIndex() { ImageTest::testIndex(); } void copyImage() { ImageTest::copyImage(); } }; template struct StridedImageIteratorTest { T * data_; StridedImageIteratorTest() : data_(testData(T())) {} void testIterator() { int w = 3, h = 3; int xskip = 2, yskip = 2; int ws = w / xskip + 1, hs = h / yskip + 1; StridedImageIterator ul(data_, w, xskip, yskip); StridedImageIterator lr = ul + Diff2D(ws, hs); shouldEqual(ws, lr.x - ul.x); shouldEqual(hs, lr.y - ul.y); shouldEqual(Diff2D(ws, hs), lr - ul); StridedImageIterator x = ul; typename StridedImageIterator::row_iterator r = ul.rowIterator(); typename StridedImageIterator::row_iterator rend = r + ws; shouldEqual(data_[0], *x); shouldEqual(data_[0], *r); should(x.x < lr.x); should(r < rend); ++x.x; ++r; shouldEqual(data_[2], *x); shouldEqual(data_[2], *r); should(x.x < lr.x); should(r < rend); ++x.x; ++r; should(x.x == lr.x); should(r == rend); ++ul.y; x = ul; r = ul.rowIterator(); rend = r + ws; shouldEqual(data_[6], *x); shouldEqual(data_[6], *r); should(x.x < lr.x); should(r < rend); ++x.x; ++r; shouldEqual(data_[8], *x); shouldEqual(data_[8], *r); should(x.x < lr.x); should(r < rend); ++x.x; ++r; should(x.x == lr.x); should(r == rend); ++ul.y; should(ul.y == lr.y); } }; struct ImageTestSuite : public vigra::test_suite { ImageTestSuite() : vigra::test_suite("ImageTestSuite") { add( testCase( &BasicImageTest >::testIterator)); add( testCase( &BasicImageTest >::testIndex)); add( testCase( &BasicImageTest >::testConstructor)); add( testCase( &BasicImageTest >::copyImage)); add( testCase( &BasicImageTest >::swapImage)); add( testCase( &BasicImageTest >::testIterator)); add( testCase( &BasicImageTest >::testIndex)); add( testCase( &BasicImageTest >::testConstructor)); add( testCase( &BasicImageTest >::copyImage)); add( testCase( &BasicImageTest >::swapImage)); add( testCase( &BasicImageTest > >::testIterator)); add( testCase( &BasicImageTest > >::testIndex)); add( testCase( &BasicImageTest > >::testConstructor)); add( testCase( &BasicImageTest > >::copyImage)); add( testCase( &BasicImageTest > >::swapImage)); add( testCase( &BasicImageTest > >::testIterator)); add( testCase( &BasicImageTest > >::testIndex)); add( testCase( &BasicImageTest > >::testConstructor)); add( testCase( &BasicImageTest > >::copyImage)); add( testCase( &BasicImageTest > >::swapImage)); add( testCase( &BasicImageViewTest >::testIterator)); add( testCase( &BasicImageViewTest >::testIndex)); add( testCase( &BasicImageViewTest >::copyImage)); add( testCase( &BasicImageViewTest >::testIterator)); add( testCase( &BasicImageViewTest >::testIndex)); add( testCase( &BasicImageViewTest >::copyImage)); add( testCase( &BasicImageViewTest > >::testIterator)); add( testCase( &BasicImageViewTest > >::testIndex)); add( testCase( &BasicImageViewTest > >::copyImage)); add( testCase( &BasicImageViewTest > >::testIterator)); add( testCase( &BasicImageViewTest > >::testIndex)); add( testCase( &BasicImageViewTest > >::copyImage)); add( testCase( &StridedImageIteratorTest::testIterator)); add( testCase( &StridedImageIteratorTest >::testIterator)); } }; struct CompareFunctor { double sumDifference_; CompareFunctor(): sumDifference_(0) {} void operator()(const float &a, const float &b) { sumDifference_+= VIGRA_CSTD::abs(a-b); } double operator()() { return sumDifference_; } }; struct ImageContainerTests { ImageImportInfo info; int w, h; FImage lennaImage; ImageContainerTests() : info("lenna.xv"), w(info.width()), h(info.height()), lennaImage(w, h) { importImage(info, destImage(lennaImage)); } void initArrayWithImageTest() { ImageArray threeLennas(3, lennaImage); CompareFunctor cmp; inspectTwoImages(srcImageRange(threeLennas[0]), srcImage(threeLennas[2]), cmp); shouldEqual(cmp(), 0.0); Diff2D newsize(50, 50); threeLennas.resizeImages(newsize); for (ImageArray::iterator it= threeLennas.begin(); it!= threeLennas.end(); it++) shouldEqual((*it).size(), newsize); } void initArrayWithSizeTest() { Diff2D testsize(50, 50); ImageArray ia(6, testsize); for (unsigned int i=0; i ia2(ia.begin(), ia.end()); shouldEqual(ia2.imageSize(), testsize); ia2.erase(ia2.begin()+1); shouldEqual(ia2.size(), ia.size()-1); ia.clear(); shouldEqual(ia.size(), 0); } }; struct ImageContainerTestSuite : public vigra::test_suite { ImageContainerTestSuite() : vigra::test_suite("ImageContainerTestSuite") { add( testCase( &ImageContainerTests::initArrayWithImageTest ) ); add( testCase( &ImageContainerTests::initArrayWithSizeTest ) ); } }; struct NeighborhoodCirculatorTest { typedef vigra::NeighborhoodCirculator EightCirculator; typedef vigra::NeighborhoodCirculator FourCirculator; vigra::BImage img; EightCirculator eightCirc; FourCirculator fourCirc; NeighborhoodCirculatorTest() : img(4, 4), eightCirc(img.upperLeft() + vigra::Diff2D(1, 1)), fourCirc(img.upperLeft() + vigra::Diff2D(1, 1)) { for(int y= 0; y CrackCirc; vigra::BImage img; CrackContourCirculatorTest() : img(8,8) { static int imdata[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; for(int i = 0; i