IntegralImage.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ALVAR, A Library for Virtual and Augmented Reality.
3  *
4  * Copyright 2007-2012 VTT Technical Research Centre of Finland
5  *
6  * Contact: VTT Augmented Reality Team <alvar.info@vtt.fi>
7  * <http://www.vtt.fi/multimedia/alvar.html>
8  *
9  * ALVAR is free software; you can redistribute it and/or modify it under the
10  * terms of the GNU Lesser General Public License as published by the Free
11  * Software Foundation; either version 2.1 of the License, or (at your option)
12  * any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
17  * for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with ALVAR; if not, see
21  * <http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html>.
22  */
23 
24 #include "IntegralImage.h"
25 
26 namespace alvar {
27 
29  next_step = step;
31  if (estep >= steps) {
32  estep -= steps;
33  next_step++;
34  }
35 }
36 
37 IntIndex::IntIndex(int _res, int _steps) {
38  res = _res;
39  steps = _steps;
40  operator=(0);
41 }
42 int IntIndex::operator=(int v) {
43  index = 0;
44  step = res / steps;
46  estep = 0;
48  while ((index+next_step-1) < v) next();
49  return index;
50 }
52  index += next_step;
54  return index;
55 }
56 int IntIndex::get() const {
57  return index;
58 }
60  return next_step;
61 }
62 int IntIndex::end() const {
63  return res;
64 }
65 
67  sum = 0;
68 }
70  if (sum) cvReleaseImage(&sum);
71 }
72 void IntegralImage::Update(IplImage *gray) {
73  if ((sum == 0) ||
74  (sum->height != gray->width+1) ||
75  (sum->width != gray->height+1))
76  {
77  if (sum) cvReleaseImage(&sum);
78  // TODO: Now we assume 'double' - is it ok?
79  sum = cvCreateImage(cvSize(gray->width+1, gray->height+1), IPL_DEPTH_64F, 1);
80  }
81  cvIntegral(gray, sum);
82 }
83 double IntegralImage::GetSum(CvRect &rect, int *count /*=0*/) {
84  int x1 = rect.x;
85  int x2 = rect.x + rect.width; // Note, not -1
86  int y1 = rect.y;
87  int y2 = rect.y + rect.height;
88  //cout<<x1<<","<<y1<<"-"<<x2<<","<<y2<<endl;
89  /*
90  double v = +cvGet2D(sum, y2, x2).val[0]
91  -cvGet2D(sum, y2, x1).val[0]
92  -cvGet2D(sum, y1, x2).val[0]
93  +cvGet2D(sum, y1, x1).val[0];
94  */
95  double v = +((double *)sum->imageData)[y2*sum->width+x2]
96  -((double *)sum->imageData)[y2*sum->width+x1]
97  -((double *)sum->imageData)[y1*sum->width+x2]
98  +((double *)sum->imageData)[y1*sum->width+x1];
99 
100  if (count) *count = rect.width*rect.height;
101  return v;
102 }
103 double IntegralImage::GetAve(CvRect &rect) {
104  int count=1;
105  return GetSum(rect, &count)/count;
106 }
107 void IntegralImage::GetSubimage(const CvRect &rect, IplImage *sub) {
108  int yi=0;
109  for (IntIndex yy(rect.height, sub->height); yy.get() != yy.end(); yy.next(),yi++) {
110  int xi=0;
111  for (IntIndex xx(rect.width, sub->width); xx.get() != xx.end(); xx.next(),xi++) {
112  //cout<<"res: "<<sum->height<<","<<sum->width<<" - ";
113  //cout<<xi<<","<<yi<<": "<<rect.x<<","<<rect.y<<": "<<xx.get()<<","<<yy.get()<<endl;
114  CvRect r = {
115  rect.x+xx.get(),
116  rect.y+yy.get(),
117  xx.get_next_step(),
118  yy.get_next_step()
119  };
120  double ave = GetAve(r);
121 
122  //cvSet2D(sub, yi, xi, cvScalar(ave));
123  // TODO: Now we assume 8-bit gray
124  sub->imageData[yi*sub->widthStep+xi] = (char)ave;
125  }
126  }
127 }
129  int width = gray->width-1;
130  int height = gray->height-1;
131  if ((normalx == 0) ||
132  (normalx->width != width) ||
133  (normalx->height != height))
134  {
135  if (normalx) cvReleaseImage(&normalx);
136  if (normaly) cvReleaseImage(&normaly);
137  normalx = cvCreateImage(cvSize(width, height), IPL_DEPTH_64F, 1);
138  normaly = cvCreateImage(cvSize(width, height), IPL_DEPTH_64F, 1);
139  }
140  for (int j=0; j<height; j++) {
141  for (int i=0; i<width; i++) {
142  /*
143  // As we assume top-left coordinates we have these reverse compared to Donahue1992
144  double a4 = cvGet2D(gray, j, i+1).val[0];
145  double a3 = cvGet2D(gray, j, i).val[0];
146  double a2 = cvGet2D(gray, j+1, i).val[0];
147  double a1 = cvGet2D(gray, j+1, i+1).val[0];
148  // Normal vectors;
149  double nx = (-a1+a2+a3-a4)/4;
150  double ny = (-a1-a2+a3+a4)/4;
151  cvSet2D(normalx, j, i, cvScalar(nx));
152  cvSet2D(normaly, j, i, cvScalar(ny));
153  */
154  // As we assume top-left coordinates we have these reverse compared to Donahue1992
155  // TODO: Now we assume 8-bit gray
156  double a4 = (unsigned char)gray->imageData[(j)*gray->widthStep+(i+1)];
157  double a3 = (unsigned char)gray->imageData[(j)*gray->widthStep+(i)];
158  double a2 = (unsigned char)gray->imageData[(j+1)*gray->widthStep+(i)];
159  double a1 = (unsigned char)gray->imageData[(j+1)*gray->widthStep+(i+1)];
160  // Normal vectors;
161  double nx = (-a1+a2+a3-a4)/4;
162  double ny = (-a1-a2+a3+a4)/4;
163  ((double *)normalx->imageData)[j*normalx->width+i] = nx;
164  ((double *)normaly->imageData)[j*normaly->width+i] = ny;
165  }
166  }
167 }
169  normalx = 0;
170  normaly = 0;
171 }
173  if (normalx) cvReleaseImage(&normalx);
174  if (normaly) cvReleaseImage(&normaly);
175 }
177  CalculatePointNormals(gray);
178  integx.Update(normalx);
179  integy.Update(normaly);
180 }
181 void IntegralGradient::GetGradient(CvRect &rect, double *dirx, double *diry, int *count /*=0*/) {
182  CvRect r = {rect.x, rect.y, rect.width-1, rect.height-1};
183  if (count) *dirx = integx.GetSum(r, count);
184  else *dirx = integx.GetSum(r);
185  *diry = integy.GetSum(r);
186 }
187 void IntegralGradient::GetAveGradient(CvRect &rect, double *dirx, double *diry) {
188  int count=1;
189  GetGradient(rect, dirx, diry, &count);
190  *dirx /= count;
191  *diry /= count;
192 }
193 
194 } // namespace alvar
Main ALVAR namespace.
Definition: Alvar.h:174
void Update(IplImage *gray)
Update integral image for the given image.
This file implements integral image and integral gradient computations.
double GetAve(CvRect &rect)
Calculate the average for the given rectangular area in the image.
Class for calculating "evenly spaced" integer indices for data sequence.
Definition: IntegralImage.h:55
int height
Definition: GlutViewer.cpp:160
int end() const
For testing have we reached the end.
void CalculatePointNormals(IplImage *gray)
void GetAveGradient(CvRect &rect, double *dirx, double *diry)
Calculate the average gradient for the given rectangular area in the image.
void Update(IplImage *gray)
Update intermediate images for calculating the gradients to the given image.
int width
Definition: GlutViewer.cpp:159
cv::Mat gray
int get_next_step() const
How much the index will be increased with the next next()
int get() const
Get the index value.
IntIndex(int _res, int _steps)
Create IntIndex for indexing _res elements in predefined amount of _steps .
double GetSum(CvRect &rect, int *count=0)
Calculate the sum for the given rectangular area in the image.
void GetGradient(CvRect &rect, double *dirx, double *diry, int *count=0)
Calculate the gradient for the given rectangular area in the image.
int next()
Take the next integer index step.
r
int operator=(int v)
Set the integer index to the "grid" value nearest to v .
void GetSubimage(const CvRect &rect, IplImage *sub)
Get a sub-image using integral image representation.


ar_track_alvar
Author(s): Scott Niekum
autogenerated on Thu Jun 6 2019 19:27:23