Blender  V2.93
ImagePyramid.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
22 #include <iostream>
23 
24 #include "GaussianFilter.h"
25 #include "Image.h"
26 #include "ImagePyramid.h"
27 
28 using namespace std;
29 
30 namespace Freestyle {
31 
32 #if 0
33 ImagePyramid::ImagePyramid(const GrayImage &level0, unsigned nbLevels)
34 {
35  BuildPyramid(level0, nbLevels);
36 }
37 #endif
38 
39 ImagePyramid::ImagePyramid(const ImagePyramid & /*iBrother*/)
40 {
41  if (!_levels.empty()) {
42  for (vector<GrayImage *>::iterator im = _levels.begin(), imend = _levels.end(); im != imend;
43  ++im) {
44  _levels.push_back(new GrayImage(**im));
45  }
46  }
47 }
48 
49 ImagePyramid::~ImagePyramid()
50 {
51  if (!_levels.empty()) {
52  for (vector<GrayImage *>::iterator im = _levels.begin(), imend = _levels.end(); im != imend;
53  ++im) {
54  delete (*im);
55  }
56  _levels.clear();
57  }
58 }
59 
60 GrayImage *ImagePyramid::getLevel(int l)
61 {
62  return _levels[l];
63 }
64 
65 float ImagePyramid::pixel(int x, int y, int level)
66 {
67  GrayImage *img = _levels[level];
68  if (0 == level) {
69  return img->pixel(x, y);
70  }
71  unsigned int i = 1 << level;
72  unsigned int sx = x >> level;
73  unsigned int sy = y >> level;
74  if (sx >= img->width()) {
75  sx = img->width() - 1;
76  }
77  if (sy >= img->height()) {
78  sy = img->height() - 1;
79  }
80 
81  // bilinear interpolation
82  float A = i * (sx + 1) - x;
83  float B = x - i * sx;
84  float C = i * (sy + 1) - y;
85  float D = y - i * sy;
86 
87  float P1(0), P2(0);
88  P1 = A * img->pixel(sx, sy);
89  if (sx < img->width() - 1) {
90  if (x % i != 0) {
91  P1 += B * img->pixel(sx + 1, sy);
92  }
93  }
94  else {
95  P1 += B * img->pixel(sx, sy);
96  }
97  if (sy < img->height() - 1) {
98  if (y % i != 0) {
99  P2 = A * img->pixel(sx, sy + 1);
100  if (sx < img->width() - 1) {
101  if (x % i != 0) {
102  P2 += B * img->pixel(sx + 1, sy + 1);
103  }
104  }
105  else {
106  P2 += B * img->pixel(sx, sy + 1);
107  }
108  }
109  }
110  else {
111  P2 = P1;
112  }
113  return (1.0f / (float)(1 << (2 * level))) * (C * P1 + D * P2);
114 }
115 
116 int ImagePyramid::width(int level)
117 {
118  return _levels[level]->width();
119 }
120 
121 int ImagePyramid::height(int level)
122 {
123  return _levels[level]->height();
124 }
125 
126 GaussianPyramid::GaussianPyramid(const GrayImage &level0, unsigned nbLevels, float iSigma)
127 {
128  _sigma = iSigma;
129  BuildPyramid(level0, nbLevels);
130 }
131 
132 GaussianPyramid::GaussianPyramid(GrayImage *level0, unsigned nbLevels, float iSigma)
133 {
134  _sigma = iSigma;
135  BuildPyramid(level0, nbLevels);
136 }
137 
138 GaussianPyramid::GaussianPyramid(const GaussianPyramid &iBrother) : ImagePyramid(iBrother)
139 {
140  _sigma = iBrother._sigma;
141 }
142 
143 void GaussianPyramid::BuildPyramid(const GrayImage &level0, unsigned nbLevels)
144 {
145  GrayImage *pLevel = new GrayImage(level0);
146  BuildPyramid(pLevel, nbLevels);
147 }
148 
149 void GaussianPyramid::BuildPyramid(GrayImage *level0, unsigned nbLevels)
150 {
151  GrayImage *pLevel = level0;
152  _levels.push_back(pLevel);
154  // build the nbLevels:
155  unsigned w = pLevel->width();
156  unsigned h = pLevel->height();
157  if (nbLevels != 0) {
158  for (unsigned int i = 0; i < nbLevels; ++i) { // soc
159  w = pLevel->width() >> 1;
160  h = pLevel->height() >> 1;
161  GrayImage *img = new GrayImage(w, h);
162  for (unsigned int y = 0; y < h; ++y) {
163  for (unsigned int x = 0; x < w; ++x) {
164  float v = gf.getSmoothedPixel<GrayImage>(pLevel, 2 * x, 2 * y);
165  img->setPixel(x, y, v);
166  }
167  }
168  _levels.push_back(img);
169  pLevel = img;
170  }
171  }
172  else {
173  while ((w > 1) && (h > 1)) {
174  w = pLevel->width() >> 1;
175  h = pLevel->height() >> 1;
176  GrayImage *img = new GrayImage(w, h);
177  for (unsigned int y = 0; y < h; ++y) {
178  for (unsigned int x = 0; x < w; ++x) {
179  float v = gf.getSmoothedPixel<GrayImage>(pLevel, 2 * x, 2 * y);
180  img->setPixel(x, y, v);
181  }
182  }
183  _levels.push_back(img);
184  pLevel = img;
185  }
186  }
187 }
188 
189 } /* namespace Freestyle */
#define D
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
Class to perform gaussian filtering operations on an image.
Class to represent a pyramid of images.
#define C
Definition: RandGen.cpp:39
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert * v
#define A
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
float getSmoothedPixel(Map *map, int x, int y)
virtual void BuildPyramid(const GrayImage &level0, unsigned nbLevels)
float pixel(unsigned x, unsigned y) const
void setPixel(unsigned x, unsigned y, float v)
std::vector< GrayImage * > _levels
Definition: ImagePyramid.h:38
#define B
inherits from class Rep
Definition: AppCanvas.cpp:32
static unsigned x[3]
Definition: RandGen.cpp:87