Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ConstantRegionDetector.cpp
1 /*
2  This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4  Copyright (C) 2003-2009 (see file CONTACT for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 
10  BIAS is free software; you can redistribute it and/or modify
11  it under the terms of the GNU Lesser General Public License as published by
12  the Free Software Foundation; either version 2.1 of the License, or
13  (at your option) any later version.
14 
15  BIAS is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  GNU Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with BIAS; if not, write to the Free Software
22  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23  */
24 
25 #include "ConstantRegionDetector.hh"
26 #include <Base/Image/ImageIO.hh>
27 #include <Filter/Median.hh>
28 #include <algorithm>
29 
30 using namespace std;
31 using namespace BIAS;
32 
33 
34 //////////////////////////////////////////////////////////////////////////
35 // implementation
36 //////////////////////////////////////////////////////////////////////////
37 
38 
39 template<class StorageType, class CalculationType>
41  threshold_ = (CalculationType)1;
42  halfWinSize_ = 2;
43  maxNumFeatures_ = -1;
44  maskImg_ = Image<unsigned char>(0, 0, 1);
45  minDistance_ = -1;
46 }
47 
48 template<class StorageType, class CalculationType>
50 }
51 
52 template<class StorageType, class CalculationType> int ConstantRegionDetector<
53  StorageType, CalculationType>::Detect(Image<StorageType>& src, std::vector<
54  HomgPoint2D>& points2d, vector<Vector3<StorageType> >& colors,
55  bool useMedian){
56 
57  if (useMedian) {
58  Image<StorageType> imMed;
60  median.SetSize(3, 3);
61  median.FilterColorImg(src, imMed);
62  src = imMed;
63  }
64 
65  points2d.clear();
66  colors.clear();
67  featureList_.clear();
68 
69  bool checkMask = false;
70  cout << "mask? " << maskImg_.GetWidth() << " " << maskImg_.GetHeight() << endl;
71  if(maskImg_.GetWidth() == src.GetWidth() && maskImg_.GetHeight() == src.GetHeight()){
72  checkMask = true;
73  }
74 
75  StorageType** imageData = src.GetImageDataArray();
76  unsigned char** maskData = maskImg_.GetImageDataArray();
77  int imgWidth = (int)src.GetWidth();
78  int imgHeight = (int)src.GetHeight();
79 
80  for (int i = halfWinSize_; i < (imgWidth - halfWinSize_); i++) {
81  for (int j = halfWinSize_; j < (imgHeight - halfWinSize_); j++) {
82 
83  // check if mask image is set and if pixel is to be omitted
84  if(checkMask && (maskData[j][i] > (unsigned char)0)){
85  continue;
86  }
87 
88  CalculationType sqrDiffR = 0;
89  CalculationType sqrDiffG = 0;
90  CalculationType sqrDiffB = 0;
91  for (int ii = -halfWinSize_; ii <= halfWinSize_; ii++) {
92  for (int jj = -halfWinSize_; jj <= halfWinSize_; jj++) {
93  sqrDiffR = sqrDiffR + (CalculationType) pow((float) imageData[j][i*3+0]
94  - (float) imageData[j+jj][(i+ii)*3+0], 2.0f);
95  sqrDiffG = sqrDiffG + (CalculationType) pow((float) imageData[j][i*3+1]
96  - (float) imageData[j+jj][(i+ii)*3+1], 2.0f);
97  sqrDiffB = sqrDiffB + (CalculationType) pow((float) imageData[j][i*3+2]
98  - (float) imageData[j+jj][(i+ii)*3+2], 2.0f);
99  }
100  }
101  float numMeasurements = (halfWinSize_ * 2.0f + 1.0f) * (halfWinSize_ * 2.0f + 1.0f) * 3.0f;
102  sqrDiffR = CalculationType((float)sqrDiffR / numMeasurements);
103  sqrDiffG = CalculationType((float)sqrDiffG / numMeasurements);
104  sqrDiffB = CalculationType((float)sqrDiffB / numMeasurements);
105 
106  CalculationType qual = sqrDiffR + sqrDiffG + sqrDiffB;
107 
108  if (qual < threshold_) {
109  ColFeat<StorageType> feature;
110  feature.x = i;
111  feature.y = j;
112  feature.val = qual;
113  feature.col = Vector3<StorageType> (imageData[j][i*3+0], imageData[j][i*3+1], imageData[j][i*3+2]);
114  featureList_.push_back(feature);
115  points2d.push_back(HomgPoint2D(i, j, 1.0));
116  colors.push_back(Vector3<StorageType> (imageData[j][i*3+0], imageData[j][i*3+1], imageData[j][i*3+2]));
117 
118  }
119 
120  } // end for j
121  } // end for i
122 
123  // enforce min distance
124  if(minDistance_ != -1){
125  sort(featureList_.begin(), featureList_.end());
126 
127  Image<unsigned char> regionMap(imgWidth, imgHeight, 1);
128  regionMap.SetZero();
129  unsigned char** regionMapData = regionMap.GetImageDataArray();
130 
131  unsigned int numRegions = featureList_.size();
132 
133  int xcoor, ycoor, winCoorX, winCoorY;
134 
135  points2d.clear();
136  colors.clear();
137  vector<ColFeat<StorageType> > tempList;
138 
139  for(unsigned int i=0; i < numRegions; i++){
140  xcoor = featureList_[i].x;
141  ycoor = featureList_[i].y;
142  if(regionMapData[ycoor][xcoor]==(unsigned char)0){ // no region yet -- draw and add to final list
143  for(int xx = -minDistance_; xx <= minDistance_; xx++){
144  for(int yy=-minDistance_; yy <= minDistance_; yy++){
145  winCoorX = xcoor + xx;
146  winCoorY = ycoor + yy;
147  if(winCoorX >= 0 && winCoorX < imgWidth && winCoorY >= 0 && winCoorY < imgHeight){
148  regionMapData[winCoorY][winCoorX] = (unsigned char)1;
149  }
150  }
151  } // end for xx (drawing forbidden region in regionMap image
152  // adding region to be kept to output data structures
153  tempList.push_back(featureList_[i]);
154  points2d.push_back(HomgPoint2D(xcoor, ycoor, 1.0));
155  colors.push_back(Vector3<StorageType>(imageData[ycoor][xcoor*3+0], imageData[ycoor][xcoor*3+1], imageData[ycoor][xcoor*3+2]));
156  }
157 
158  }
159 
160  featureList_ = tempList;
161 
162  } // end if min Distance != -1
163 
164 
165  if(maxNumFeatures_ != -1){
166  sort(featureList_.begin(), featureList_.end());
167 
168  points2d.clear();
169  colors.clear();
170  ColFeat<StorageType> featureTmp;
171  for(int i = 0; i < maxNumFeatures_; i++){
172  featureTmp = featureList_.back();
173  featureList_.pop_back();
174  points2d.push_back(HomgPoint2D(featureTmp.x, featureTmp.y, 1.0));
175  colors.push_back(featureTmp.col);
176  }
177 
178  }
179 
180 
181  return 0;
182 }
183 
184 
185 
186 //////////////////////////////////////////////////////////////////////////
187 // instantiation
188 //////////////////////////////////////////////////////////////////////////
189 
190 //template class ColFeat<unsigned char>;
191 //template class ColFeat<float>;
192 namespace BIAS{
195 
196 // fill in instances as required
197 #ifdef BUILD_IMAGE_INT
199 #endif
200 #ifdef BUILD_IMAGE_CHAR
202 #endif
203 #ifdef BUILD_IMAGE_SHORT
204 #endif
205 #ifdef BUILD_IMAGE_USHORT
207 #ifdef BUILD_IMAGE_INT
209 #endif
210 #endif
211 #ifdef BUILD_IMAGE_UINT
212 #endif
213 #ifdef BUILD_IMAGE_DOUBLE
214 #endif
215 }
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
Definition: HomgPoint2D.hh:67
unsigned int GetWidth() const
Definition: ImageBase.hh:312
Implements a 2D median filter for images.
Definition: Median.hh:39
int FilterColorImg(const Image< InputStorageType > &src, Image< OutputStorageType > &dst)
Definition: Median.cpp:1030
unsigned int GetHeight() const
Definition: ImageBase.hh:319
void SetSize(int newsize, int secondsize=-1)
Definition: Median.hh:140
detects regions with close to zero gradients in images, works on color images only ...
internal class for feature (with color) passing only
BIAS::Vector3< StorageType > col
const StorageType ** GetImageDataArray() const
overloaded GetImageDataArray() from ImageBase
Definition: Image.hh:153