1 #ifndef IMAGEHIERARCHY_TEST_HXX
2 #define IMAGEHIERARCHY_TEST_HXX
3 
4 #include "parent_test_class.hxx"
5 
6 template<class Policy>
7 class ImageHierarchyTest
8 : public ImageTest<Policy>
9 {
10 public:
11     typedef typename Policy::Image              Image;              // zu testende Klasse z.B. GrayImage, VariableBandsImage usw.
12     typedef typename Policy::ChildImage         ChildImage;         // unterscheidet sich von zu testender Klasse Image, nur wenn einer der abstrakten Klassen VariableBandImage oder SingleBandImage oder die Klasse SelectBandImage getestet wird, sonst entspricht es der Klasse Image.
13     typedef typename Policy::value_type         value_type;         // value_type der zu testenden Klasse
14     typedef typename Policy::child_value_type   child_value_type;   // value_type der Klasse an der die zu testende Klasse getestet wird, also z.B. VariableBandsImage wird am Beispiel von Vector2Image getestet dann ist child_value_type die value_type von Vector2Image
15 
16     /** testet die Konstruktorden der imagehierarchy Klasse, an die die InnerImage (BasicImage<float>)
17     * uebergeben wird, also Image (InnerImage i)
18     */
testInnerImageConstructor()19     void testInnerImageConstructor()
20     {
21         std::auto_ptr<Image> image1(Policy::factory(new typename ChildImage::InnerImage(3, 4, child_data[0])));
22         should(image1->height() == 4);
23         should(image1->width() == 3);
24         should(image1->size() == vigra::Diff2D(3,4));
25         should(image1->end() == std::find_if(image1->begin(), image1->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), child_data[0])));
26 
27         std::auto_ptr<Image> image2(Policy::factory(new typename ChildImage::InnerImage(0, 0, child_data[1])));
28         should(image2->height() == 0);
29         should(image2->width() == 0);
30         should(image2->size() == vigra::Diff2D(0,0));
31         should(image2->end() == std::find_if(image2->begin(), image2->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), child_data[1])));
32     }
33 
34     /** testet die clone() Methode der Klasse aus imagehierarchy
35     */
testClone()36     void testClone()
37     {
38         /*
39         *  Im Falle der Aenderungsvornehmungen an einem der Images, werden die Aenderungen auch nur an einem sichtbar
40         */
41         std::auto_ptr<typename Image::CloneType> image1(image1_->clone());
42         should(equal(*image1, *image1_));
43         should(equalPixels(image1_->begin(),image1_->end(), image1->begin()));
44         should(&(*image1) != &(*image1_));
45 
46         /* Aenderung mit der init-Funktion
47         */
48         image1->init(data[5]);
49         should((*image1_->begin()) != static_cast<typename Image::PixelType> (data[5]));
50         should(image1->end() == std::find_if(image1->begin(), image1->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[5])));
51 
52         image1_->init(data[6]);
53         should(image1->end() == std::find_if(image1->begin(), image1->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[5])));
54         should(image1_->end() == std::find_if(image1_->begin(), image1_->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[6])));
55 
56         std::auto_ptr<typename Image::CloneType> image0(image0_->clone());
57         should(equal(*image0, *image0_));
58         should(equalPixels(image0_->begin(),image0_->end(), image0->begin()));image1_->init(data[6]);
59         should(&(*image0) != &(*image0_));
60 
61         /* Aenderung mit dem Zuweisungsoperator -> siehe in testShallowCopy()
62         */
63         (*image0_) = (*image1_);
64         should(image0->size() == vigra::Diff2D(0,0));
65         should(image0_->size() == vigra::Diff2D(3,5));
66         should(!equal(*image0, *image0_));
67         should(equal(*image1_, *image0_));
68     }
69 
70     /** testet die shallowCopy() Methode der Klassen aus imagehierarchy.
71     */
testShallowCopy()72     void testShallowCopy()
73     {
74         /*
75         *  Im Falle der Aenderungsvornehmungen an einem der Images, werden die Aenderungen an beiden sichtbar
76         *  Es gibt nur zwei Aenderungsmoeglichkeiten init() und Zuweisung eines anderen Images
77         *  bei der Zuweisung werden die Zeiger von den eigenen Daten auf die anderen umgeleitet,
78         *  und das entspricht nicht dem Sinn der shallowCopy
79         */
80         std::auto_ptr<Image> image1(image1_->shallowCopy());
81         should(equal(*image1, *image1_));
82         should(&(*image1) != &(*image1_));
83 
84         /* Aenderung mit der init-Funktion
85         */
86         image1->init(data[7]);
87         should(image1->end() == std::find_if(image1->begin(), image1->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[7])));
88         should(image1_->end() == std::find_if(image1_->begin(), image1_->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[7])));
89 
90         image1->init(data[8]);
91         should(image1->end() == std::find_if(image1->begin(), image1->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[8])));
92         should(image1_->end() == std::find_if(image1_->begin(), image1_->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[8])));
93 
94         /* Eine shallowCopy zeigt auf die selben Daten des kopierten Objektes
95         */
96         std::auto_ptr<Image> image1Copy(image1->shallowCopy());
97         should(equal(*image1Copy, *image1_));
98         should(&(*image1Copy) != &(*image1_));
99 
100         image1Copy->init(data[9]);
101         should(image1Copy->end() == std::find_if(image1Copy->begin(), image1Copy->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[9])));
102         should(image1_->end() == std::find_if(image1_->begin(), image1_->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[9])));
103         should(image1->end() == std::find_if(image1->begin(), image1->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[9])));
104 
105         std::auto_ptr<Image> image0(image0_->shallowCopy());
106         should(equal(*image0, *image0_));
107         should(&(*image0) != &(*image0_));
108 
109         (*image0_) = (*image1_);
110         should(equal(*image1_, *image0_));
111         should(!equal(*image1_, *image0));
112         should(!equal(*image0_, *image0));
113     }
114 
115     /** Testet die Methode actualSize(), die die Groesse des kompletten Bildes liefert und nicht der ROI
116     */
testActualSize()117     void testActualSize()
118     {
119         should(image1_->size() == image1_->actualSize());
120         image1_->setROI(Diff2D(1,1), Diff2D(1,3));
121         should(image1_->size() != image1_->actualSize());
122         should(image1_->size() == Diff2D(1,3));
123     }
124 
125     /** Testet die Methode actualWidth(), die die Breite des kompletten Bildes liefert und nicht der ROI
126     */
testActualWidth()127     void testActualWidth()
128     {
129         should(image1_->width() == image1_->actualWidth());
130         image1_->setROI(Diff2D(1,1), Diff2D(1,3));
131         should(image1_->width() == 1);
132         should(image1_->width() != image1_->actualWidth());
133     }
134 
135     /** Testet die Methode actualHeight(), die die Hoehe des kompletten Bildes liefert und nicht der ROI
136     */
testActualHeight()137     void testActualHeight()
138     {
139         should(image1_->height() == image1_->actualHeight());
140         image1_->setROI(Diff2D(1,1), Diff2D(1,3));
141         should(image1_->height() == 3);
142         should(image1_->height() != image1_->actualHeight());
143     }
144 
145     /** Testet die Methode actualBands(), die die Anzahl der Baender eines Bildes liefert
146     */
testActualBands()147     void testActualBands()
148     {
149         should(image1_->bands() == image1_->actualBands());
150     }
151 
152     /** Testet die Methode bands(), die die Anzahl der selektirerten Baender eines Bildes liefert.
153     * Die Anzahl der selektirerten Baender ist bei allen Bildern gleich dem Anzahl der Baender des Bildes,
154     * die Ausnahme bildet SelectBandImage dort ist immer nur ein Band selektiert.
155     */
testBands()156     void testBands()
157     {
158         should(image1_->bands() == image1_->actualBands());
159     }
160 
161     /** testet die Methode roiUpperLeft(), die die Koordinaten der linken
162     * oberen Ecke von ROI liefert.
163     */
testRoiUpperLeft()164     void testRoiUpperLeft()
165     {
166         should(image1_->roiUpperLeft() == Diff2D(0, 0));
167         image1_->setROI(Diff2D(1,1), Diff2D(1,3));
168         should(image1_->roiUpperLeft() == Diff2D(1, 1));
169         should((*image1_)[image1_->roiUpperLeft()] != (*image1_->upperLeft()));
170     }
171 
172     /** testet die Methode setROI(), die eine ROI auf einem Bild setzt.
173     */
testSetROI()174     void testSetROI()
175     {
176         std::auto_ptr<Image> image1_copy(image1_->shallowCopy());               //dient der Vergleichsmoeglichkeit
177         image1_->setROI(Diff2D(1,1), Diff2D(1,3));
178 
179         should(image1_->width() == (image1_->actualWidth() - 2));
180         should(image1_->height() == (image1_->actualHeight() - 2));
181         should(image1_->size() == (image1_->actualSize() - Diff2D(2, 2)));
182         should((*image1_copy)(1,1) == (*image1_)(0,0));
183 
184         /*  Differenz zweier ScanOrderIteratoren ist eine int_Zahl
185         */
186         should((image1_->end() - image1_->begin()) == 3);                       // Anzahl der Pixel in der ROI
187         should((image1_copy->end() - image1_copy->begin()) == 15);              // Anzahl der Pixel im Hauptbild
188 
189         /*  Erzeugt man eine shallowCopy eines Bildes an dem ROI gesetz ist, dann ist
190         *   die shallowCopy eine Copy des gesamten Bildes und nicht nur der ROI
191         *   dabei ist an der shallowCopy genau so die ROI gesetzt.
192         */
193         std::auto_ptr<Image> image1_ROI_copy(image1_->shallowCopy());
194 
195         should(!(image1_ROI_copy->size() == image1_ROI_copy->actualSize()));
196         should(image1_ROI_copy->size() == image1_->size());
197 
198         /*  Erzeugt man einen Clone eines Bildes an dem ROI gesetz ist, dann kriegt man ein Bild
199         *   mit der Groesse und Pixelinitialisierung der ROI
200         */
201         std::auto_ptr<typename Image::CloneType> image1_ROI_clone(image1_->clone());
202 
203         should(image1_ROI_clone->size() == image1_ROI_clone->actualSize());
204         should(image1_ROI_clone->size() == image1_->size());
205 
206         for(int x = 0; x < image1_ROI_clone->width(); x++)
207             for(int y = 0; y < image1_ROI_clone->height(); y++)
208                 should((*image1_ROI_clone)(x,y) == (*image1_copy)(x + 1,y + 1));
209 
210 
211         /*  Wenn man die Aenderungen an der ROI vornimmt, aendert sich auch die shallowCopy des Hauptbildes
212         *   aber verschoben um roiUpperLeft
213         */
214         image1_->init(data[7]);
215 
216         should(image1_->end() == std::find_if(image1_->begin(), image1_->end(), std::bind2nd(Pixels_not_equal_to<value_type>(), data[7])));
217 
218         for(int x = 0; x < image1_->width(); x++)
219             for(int y = 0; y < image1_->height(); y++)
220                 should((*image1_)(x,y) == static_cast<typename Policy::PixelType>(data[7]));
221 
222 
223         for(int x = 1; x < (image1_->width() + 1); x++)                                 //um 1 verschoben
224             for(int y = 1; y < (image1_->height() + 1); y++)                            //um 1 verschoben
225                 should((*image1_copy)(x,y) == static_cast<typename Policy::PixelType>(data[7]));
226 
227 
228         for(int x = 0; x < image1_->width(); x++)                                       //Verhalten einer ROI
229             for(int y = 0; y < image1_->height(); y++)
230                 should((*image1_ROI_copy)(x,y) == static_cast<typename Policy::PixelType>(data[7]));
231 
232 
233         /* Es wird ein neues Bild erzeugt mit unterschiedlichen Pixeldaten
234         */
235         std::auto_ptr<Image> image1_new(Policy::factory(3, 5));
236         typename Image::Accessor acc;
237         acc = image1_new->accessor();
238         scanOrderIter1_ = image1_new->begin();
239         for(unsigned int i = 0; i < data.size(); i++)
240             {
241                 acc.set(data[i], scanOrderIter1_);
242                 ++scanOrderIter1_;
243             }
244 
245         std::auto_ptr<Image> image1_new_copy(image1_new->shallowCopy());
246 
247         /*  Setzt man eine ROI auf der shallowCopy so ist sie auch nur in der Copy gesetzt.
248         *   Die Veraenderungen in der ROI sind aber in der Copie und im image1_new sichtbar,
249         *   im image1_new nur verschoben
250         */
251         image1_new_copy->setROI(Diff2D(1,1), Diff2D(1,3));
252 
253         should(image1_new->size() == image1_new->actualSize());
254         should(image1_new_copy->size() != image1_new_copy->actualSize());
255 
256         (*image1_new_copy)(0,0) = data[14];
257 
258         should((*image1_new_copy)(0,0) == static_cast<typename Policy::PixelType>(data[14]));
259         should((*image1_new)(1,1) == (*image1_new_copy)(0,0));
260 
261         /*  Von der ROI kann man in den negativen Bereich zurueckgreifen, da dort das Bild immernoch definiert ist
262         *   Vorsicht! der negative Zugrif darf nicht ausserhalb des eigentlichen Bildes erfolgen
263         */
264         should((image1_new_copy->upperLeft())[Diff2D(-1,-1)] == (*image1_new)(0,0));
265 
266         /*  Eine ROI ist auch auf die Groesse des Bildes ruecksetzbar
267         *   Vorsicht! Die Grenzueberschreitungen beachten!
268         */
269         image1_new_copy->setROI(Diff2D(-1,-1), image1_new_copy->actualSize());                      //Ruecksetzen
270 
271         should(image1_new_copy->size() == image1_new_copy->actualSize());
272         should((image1_new->upperLeft())[Diff2D(0,0)] == (*image1_new_copy)[image1_new_copy->roiUpperLeft()]);
273 
274 
275         /*  Setzt man die ROI mit neagtiven Werten in size so wird der negative Wert vom lowerRight des Bildes abgezogen
276         *   in unserem Falle sind Folgende ROIsetzungen gleich
277         */
278         image1_new_copy->setROI(Diff2D(1,1), Diff2D(-1,-1));
279         should((*image1_new_copy)(image1_new_copy->width() - 1, image1_new_copy->height() - 1) == (*image1_new)(1,3));
280         should(image1_new_copy->lowerRight()[Diff2D(0,0)] == (*image1_new)(image1_new->width() - 1,image1_new->height() - 1));
281         should(equalIteratorRun(image1_new_copy->upperLeft(), image1_new_copy->lowerRight(), image1_new_copy->begin()));
282 
283         image1_new_copy->setROI(Diff2D(-1,-1), image1_new_copy->actualSize());                      //Ruecksetzen
284         image1_new_copy->setROI(Diff2D(1,1), Diff2D(1,-1));                                         //neu setzen
285 
286         should((*image1_new_copy)(image1_new_copy->width() - 1, image1_new_copy->height() - 1) == (*image1_new)(1,3));
287         should(equalIteratorRun(image1_new_copy->upperLeft(), image1_new_copy->lowerRight(), image1_new_copy->begin()));
288         should(image1_new_copy->lowerRight()[Diff2D(0,0)] == (*image1_new)(image1_new->width() - 1,image1_new->height() - 1));
289 
290         image1_new_copy->resetROI();                                                                //Ruecksetzen
291         image1_new_copy->setROI(Diff2D(1,1), Diff2D(-1,3));                                         //neu setzen
292 
293         should((*image1_new_copy)(image1_new_copy->width() - 1, image1_new_copy->height() - 1) == (*image1_new)(1,3));
294         should(image1_new_copy->lowerRight()[Diff2D(0,0)] == (*image1_new)(image1_new->width() - 1,image1_new->height() - 1));
295         should(equalIteratorRun(image1_new_copy->upperLeft(), image1_new_copy->lowerRight(), image1_new_copy->begin()));
296      }//end of testSetRoi()
297 
298      /** testet die Methode resetROI(), die die gesetzte ROI wieder aufhebt
299      */
testResetROI()300      void testResetROI()
301      {
302         std::auto_ptr<typename Image::CloneType> image1(image1_->clone());
303         image1_->setROI(Diff2D(1,1), Diff2D(-1,3));
304         image1_->resetROI();
305         should(equal(*image1, *image1_));
306      }
307 
308      /** Testet die setROI(int band) Methode der Klasse SelectBandImage. Die Methode aendert den
309      * selektierten Band.
310      */
testSetROIBand()311      void testSetROIBand()
312      {
313         should(image1_->getSelectedBand() == Policy::n);
314         image1_->setROI(Policy::n == 0 ? 1 : (Policy::n - 1));
315         should(image1_->getSelectedBand() != Policy::n);
316         should(image1_->getSelectedBand() == Policy::n == 0 ? 1 : (Policy::n - 1));
317         testSetROI();
318      }
319 
320      /** Testet die getSelectedBand() Methode der Klasse SelectBandImage. Die Methode liefert den
321      * selektierten Band.
322      */
testGetSelectedBand()323      void testGetSelectedBand()
324      {
325         should(image1_->getSelectedBand() == Policy::n);
326         image1_->setROI(Policy::n == 0 ? 1 : (Policy::n - 1));
327         should(image1_->getSelectedBand() != Policy::n);
328         should(image1_->getSelectedBand() == Policy::n == 0 ? 1 : (Policy::n - 1));
329      }
330 
testIsInsideROI()331      void testIsInsideROI()
332      {
333         should(image1_->isInsideROI((image1_->actualSize())- Diff2D(1,1)));
334 
335         image1_->setROI(Diff2D(1,1), Diff2D(1,3));
336 
337         bool ergebnis = true;
338         for ( int i = 1 ; i < 2 ; i++)
339             for (int j = 1; j < 4; j ++)
340                 ergebnis &= image1_->isInsideROI(vigra::Diff2D(i,j));
341 
342         ergebnis &= !image1_->isInsideROI(vigra::Diff2D(0,0)) &&
343                      !image1_->isInsideROI(vigra::Diff2D(2,0)) &&
344                      !image1_->isInsideROI(vigra::Diff2D(0,4)) &&
345                      !image1_->isInsideROI(vigra::Diff2D(2,4)) &&
346                      !image1_->isInsideROI(vigra::Diff2D(2,2)) &&
347                      !image1_->isInsideROI(vigra::Diff2D(0,2)) &&
348                      !image1_->isInsideROI(vigra::Diff2D(2,0));
349 
350         should(ergebnis);
351      }
352 };// end of class ImageHierarchyTest
353 
354 template <class POLICY>
355 struct ImageHierarchyTestSuite
356 : public ImageTestSuite<POLICY>
357 {
ImageHierarchyTestSuiteImageHierarchyTestSuite358     ImageHierarchyTestSuite(const char * to_test_Image_name)
359     : ImageTestSuite<POLICY>(to_test_Image_name)
360     {
361         add( testCase( &ImageHierarchyTest<POLICY>::testInnerImageConstructor));
362         add( testCase( &ImageHierarchyTest<POLICY>::testClone));
363         add( testCase( &ImageHierarchyTest<POLICY>::testShallowCopy));
364         add( testCase( &ImageHierarchyTest<POLICY>::testSetROI));
365         add( testCase( &ImageHierarchyTest<POLICY>::testResetROI));
366         add( testCase( &ImageHierarchyTest<POLICY>::testActualSize));
367         add( testCase( &ImageHierarchyTest<POLICY>::testActualWidth));
368         add( testCase( &ImageHierarchyTest<POLICY>::testActualHeight));
369         add( testCase( &ImageHierarchyTest<POLICY>::testActualBands));
370         add( testCase( &ImageHierarchyTest<POLICY>::testBands));
371         add( testCase( &ImageHierarchyTest<POLICY>::testRoiUpperLeft));
372         add( testCase( &ImageHierarchyTest<POLICY>::testIsInsideROI));
373     }
374 };//end of struct ImageHierarchyTestSuite
375 #endif // IMAGEHIERARCHY_TEST_HXX
376