Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
TestFilterBase.hh
1 /* This file is part of the BIAS library (Basic ImageAlgorithmS).
2 
3  Copyright (C) 2003-2009 (see file CONTACT for details)
4  Multimediale Systeme der Informationsverarbeitung
5  Institut fuer Informatik
6  Christian-Albrechts-Universitaet Kiel
7 
8 
9  BIAS is free software; you can redistribute it and/or modify
10  it under the terms of the GNU Lesser General Public License as published by
11  the Free Software Foundation; either version 2.1 of the License, or
12  (at your option) any later version.
13 
14  BIAS is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public License
20  along with BIAS; if not, write to the Free Software
21  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/
22 #ifndef __TestFilterBase_hh__
23 #define __TestFilterBase_hh__
24 
25 #include <Base/Debug/Error.hh>
26 #include <Base/Image/Image.hh>
27 #include <Filter/FilterBase.hh>
28 #include <Filter/FilterMask.hh>
29 
30 #include <iostream>
31 /**
32  * @file TestFilterBase.hh
33  */
34 using namespace std;
35 
36 namespace BIAS {
37 
38  /** @class FilterTestPair
39  @brief struct holding ground truth data for filter testing\
40  @relates TestFilterBase
41  @author woelk 06/2008 (c) www.vision-n.de */
42  template <typename InputStorageType, typename OutputStorageType>
44  {
45  public:
47  const Image<OutputStorageType> output)
48  : Input(input), Output(output),
49  BorderHandling(FilterBase<InputStorageType,
50  OutputStorageType>::TBH_valid), Mask() {}
51 
52  Image<InputStorageType> Input; ///< input image
53  Image<OutputStorageType> Output; /// ground truth output
56  };
57 
58 
59 
60  /** @class TestFilterBase
61  @brief helper class for testing individual filters
62 
63  Instatiate this class with the approriat filter, add some grond truth
64  test data using the function AddTestData() and finally call
65  Test() to do some basic testing of the filter
66 
67  See TestFilterBinomial as an example
68 
69  @author woelk 06/2008 (c) www.vision-n.de */
70  template <template <typename, typename> class FILTER,
71  typename InputStorageType, typename OutputStorageType>
73  {
74  public:
76 
78 
79  bool Test();
80 
81  void AddTestData(const FilterTestPair<InputStorageType,
82  OutputStorageType> &data);
83 
84  protected:
85  // the filter to be tested
86  FILTER<InputStorageType, OutputStorageType> Filter_;
87  // the test data used for testing
88  std::vector<FilterTestPair<InputStorageType, OutputStorageType> > Data_;
89 
90  // checks all data sets from Data_
91  bool TestData_();
92 
93  // checks if bordr handling is correctly implemented
94  bool TestBorderHandling_();
95 
96  // compares the image header
97  bool CompareHeader_(const Image<InputStorageType> &src,
98  const Image<OutputStorageType> &dst) const;
99 
100  // compares the image data within ROI of dst
101  bool CompareImageData_(const Image<OutputStorageType> &gt,
102  const Image<OutputStorageType> &dst) const;
103 
104  }; // class
105 
106 
107 
108 
109 
110  ////////////////////////////////////////////////////////
111  // implementation
112  ////////////////////////////////////////////////////////
113 
114  template <template <typename, typename> class FILTER,
115  typename InputStorageType, typename OutputStorageType>
118  {
119  if (!TestBorderHandling_()) { return false; }
120 
121  if (!TestData_()) { return false; }
122 
123  return true;
124  }
125 
126 
127 
128  template <template <typename, typename> class FILTER,
129  typename InputStorageType, typename OutputStorageType>
132  {
133  // TODO: consistency check
134  Data_.push_back(data);
135  }
136 
137 
138 
139  template <template <typename, typename> class FILTER,
140  typename InputStorageType, typename OutputStorageType>
143  {
144  const int sze = 100, roioffs = 2;
145  BIASASSERT(2*roioffs<sze);
146  // prepare sourec image
147  Image<InputStorageType> src(sze, sze, 1);
149  src.FillImageWithConstValue((InputStorageType)0);
150  const unsigned src_roi[]={roioffs, roioffs, sze-roioffs, sze-roioffs};
151  src.SetROICorners(src_roi[0], src_roi[1], src_roi[2], src_roi[3]);
152  unsigned dst_roi[4];
153 
154  // check 'valid'
155  Filter_.SetBorderHandling(FilterBase<unsigned char, unsigned char>::
156  TBH_valid);
157  if (Filter_.Filter(src, dst)!=0){ BIASABORT; }
158  if (!CompareHeader_(src, dst)) { BIASABORT; }
159  dst.GetROICorners(dst_roi[0], dst_roi[1], dst_roi[2], dst_roi[3]);
160  int roi_offs[4]; // the offsets
161  Filter_.GetBorders(roi_offs[0], roi_offs[1]);
162  roi_offs[2] = -roi_offs[0]; roi_offs[3] = -roi_offs[1];
163  for (int i=0; i<4; i++){
164  //cout << "src_roi: "<<src_roi[i]<<"\tdst_roi: "<<dst_roi[i]
165  // <<"\troi_offs: "<<roi_offs[i]<<endl;
166  if ((int)src_roi[i] + roi_offs[i] != (int)dst_roi[i]){ BIASABORT; }
167  }
168 
169  // check 'same'
170  Filter_.SetBorderHandling(FilterBase<unsigned char, unsigned char>::
171  TBH_same);
172  if (Filter_.Filter(src, dst)!=0){ BIASABORT; }
173  if (!CompareHeader_(src, dst)) { BIASABORT; }
174  dst.GetROICorners(dst_roi[0], dst_roi[1], dst_roi[2], dst_roi[3]);
175  for (int i=0; i<4; i++){
176  if (src_roi[i] != dst_roi[i]){ BIASABORT; }
177  }
178 
179  return true;
180 
181  // boder handing full does not work so far
182 // Filter_.SetBorderHandling(FilterBase<unsigned char, unsigned char>::
183 // TBH_full);
184 // if (Filter_.Filter(src, dst)!=0){ BIASABORT; }
185  //if (!CompareHeader_(src, dst)) { BIASABORT; }
186  // return true;
187  }
188 
189 
190  template <template <typename, typename> class FILTER,
191  typename InputStorageType, typename OutputStorageType>
194  {
195  for (unsigned i=0; i<Data_.size(); i++){
197  Filter_.SetBorderHandling(Data_[i].BorderHandling);
198  if (Filter_.Filter(Data_[i].Input, dst)!=0){ BIASABORT; }
199  if (!CompareHeader_(Data_[i].Output, dst)) { BIASABORT; }
200  if (!CompareImageData_(Data_[i].Output, dst)) { BIASABORT; }
201  }
202  return true;
203  }
204 
205 
206  template <template <typename, typename> class FILTER,
207  typename InputStorageType, typename OutputStorageType>
210  const Image<OutputStorageType> &dst) const
211  {
212  if (src.GetWidth() != dst.GetWidth()){ BIASABORT; }
213  if (src.GetHeight() != dst.GetHeight()){ BIASABORT; }
214  if (src.GetChannelCount() != dst.GetChannelCount()){ BIASABORT; }
215  if (src.GetColorModel() != dst.GetColorModel()){ BIASABORT; }
216  if (src.IsInterleaved() != dst.IsInterleaved()){ BIASABORT; }
217  return true;
218  }
219 
220  template <template <typename, typename> class FILTER,
221  typename InputStorageType, typename OutputStorageType>
224  const Image<OutputStorageType> &dst) const
225  {
226  if (!gt.SamePixelAndChannelCount(dst)) { BIASABORT; }
227  unsigned gt_roi[4], dst_roi[4];
228  gt.GetROICorners(gt_roi[0], gt_roi[1], gt_roi[2], gt_roi[3]);
229  dst.GetROICorners(dst_roi[0], dst_roi[1], dst_roi[2], dst_roi[3]);
230  // for (int i=0; i<4; i++){
231 // if (gt_roi[i] < dst_roi[i]){ BIASABORT; }
232 // }
233  const OutputStorageType **dst_ida = dst.GetImageDataArray();
234  const OutputStorageType **gt_ida = gt.GetImageDataArray();
235  const unsigned cc = gt.GetChannelCount();
236  register unsigned x, y, c;
237  for (y=dst_roi[1]; y<dst_roi[3]; y++){
238  for (x=dst_roi[1]; x<dst_roi[3]; x++){
239  for (c=0; c<cc; c++){
240  if (!Equal(dst_ida[y][x*cc+c], gt_ida[y][x*cc+c])) {
241  cout << "y: "<<y<<"\tx: "<<x<<"\tcc: "<<cc<<"\tcc: "<<c<<endl
242  << "dst_ida[y][x*cc+c]: "<<(int)dst_ida[y][x*cc+c]
243  <<"\tgt_ida[y][x*cc+c]: "<<(int)gt_ida[y][x*cc+c]<<endl;
244  BIASABORT;
245  }
246  }
247  }
248  }
249 
250  return true;
251  }
252 
253 } // namespace
254 
255 
256 #endif // __TestFilterBase_hh__
struct holding ground truth data for filter testing\
FILTER< InputStorageType, OutputStorageType > Filter_
Image< InputStorageType > Input
input image
bool IsInterleaved() const
Definition: ImageBase.hh:491
virtual parent class for API definition of all (future) filters
Definition: FilterBase.hh:77
unsigned int GetWidth() const
Definition: ImageBase.hh:312
TBorderHandling
enum for border calculation, same meanings as in matlab:
Definition: FilterBase.hh:98
void GetROICorners(unsigned int &UpperLeftX, unsigned int &UpperLeftY, unsigned int &LowerRightX, unsigned int &LowerRightY) const
access region of interest rectangle JW
Definition: ImageBase.cpp:1067
std::vector< FilterTestPair< InputStorageType, OutputStorageType > > Data_
FilterTestPair(const Image< InputStorageType > input, const Image< OutputStorageType > output)
unsigned int GetChannelCount() const
returns the number of Color channels, e.g.
Definition: ImageBase.hh:382
unsigned int GetHeight() const
Definition: ImageBase.hh:319
void FillImageWithConstValue(StorageType Value)
fill grey images
Definition: Image.cpp:456
bool SamePixelAndChannelCount(const ImageBase &Image) const
checks if data area has same &quot;size&quot; as Image of other type
Definition: ImageBase.hh:73
bool Equal(const T left, const T right, const T eps)
comparison function for floating point values See http://www.boost.org/libs/test/doc/components/test_...
enum EColorModel GetColorModel() const
Definition: ImageBase.hh:407
Image< OutputStorageType > Output
helper class for testing individual filters
int SetROICorners(unsigned int UpperLeftX, unsigned int UpperLeftY, unsigned int LowerRightX, unsigned int LowerRightY)
Definition: ImageBase.cpp:1048
A filter mask (or a kernel) used for convolution.
Definition: FilterMask.hh:61
const StorageType ** GetImageDataArray() const
overloaded GetImageDataArray() from ImageBase
Definition: Image.hh:153