Blender  V3.3
ImagePyramid.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
8 #include <iostream>
9 
10 #include "GaussianFilter.h"
11 #include "Image.h"
12 #include "ImagePyramid.h"
13 
14 using namespace std;
15 
16 namespace Freestyle {
17 
18 #if 0
19 ImagePyramid::ImagePyramid(const GrayImage &level0, unsigned nbLevels)
20 {
21  BuildPyramid(level0, nbLevels);
22 }
23 #endif
24 
25 ImagePyramid::ImagePyramid(const ImagePyramid & /*iBrother*/)
26 {
27  if (!_levels.empty()) {
28  for (vector<GrayImage *>::iterator im = _levels.begin(), imend = _levels.end(); im != imend;
29  ++im) {
30  _levels.push_back(new GrayImage(**im));
31  }
32  }
33 }
34 
35 ImagePyramid::~ImagePyramid()
36 {
37  if (!_levels.empty()) {
38  for (vector<GrayImage *>::iterator im = _levels.begin(), imend = _levels.end(); im != imend;
39  ++im) {
40  delete (*im);
41  }
42  _levels.clear();
43  }
44 }
45 
46 GrayImage *ImagePyramid::getLevel(int l)
47 {
48  return _levels[l];
49 }
50 
51 float ImagePyramid::pixel(int x, int y, int level)
52 {
53  GrayImage *img = _levels[level];
54  if (0 == level) {
55  return img->pixel(x, y);
56  }
57  unsigned int i = 1 << level;
58  unsigned int sx = x >> level;
59  unsigned int sy = y >> level;
60  if (sx >= img->width()) {
61  sx = img->width() - 1;
62  }
63  if (sy >= img->height()) {
64  sy = img->height() - 1;
65  }
66 
67  // bilinear interpolation
68  float A = i * (sx + 1) - x;
69  float B = x - i * sx;
70  float C = i * (sy + 1) - y;
71  float D = y - i * sy;
72 
73  float P1(0), P2(0);
74  P1 = A * img->pixel(sx, sy);
75  if (sx < img->width() - 1) {
76  if (x % i != 0) {
77  P1 += B * img->pixel(sx + 1, sy);
78  }
79  }
80  else {
81  P1 += B * img->pixel(sx, sy);
82  }
83  if (sy < img->height() - 1) {
84  if (y % i != 0) {
85  P2 = A * img->pixel(sx, sy + 1);
86  if (sx < img->width() - 1) {
87  if (x % i != 0) {
88  P2 += B * img->pixel(sx + 1, sy + 1);
89  }
90  }
91  else {
92  P2 += B * img->pixel(sx, sy + 1);
93  }
94  }
95  }
96  else {
97  P2 = P1;
98  }
99  return (1.0f / (float)(1 << (2 * level))) * (C * P1 + D * P2);
100 }
101 
102 int ImagePyramid::width(int level)
103 {
104  return _levels[level]->width();
105 }
106 
107 int ImagePyramid::height(int level)
108 {
109  return _levels[level]->height();
110 }
111 
112 GaussianPyramid::GaussianPyramid(const GrayImage &level0, unsigned nbLevels, float iSigma)
113 {
114  _sigma = iSigma;
115  BuildPyramid(level0, nbLevels);
116 }
117 
118 GaussianPyramid::GaussianPyramid(GrayImage *level0, unsigned nbLevels, float iSigma)
119 {
120  _sigma = iSigma;
121  BuildPyramid(level0, nbLevels);
122 }
123 
124 GaussianPyramid::GaussianPyramid(const GaussianPyramid &iBrother) : ImagePyramid(iBrother)
125 {
126  _sigma = iBrother._sigma;
127 }
128 
129 void GaussianPyramid::BuildPyramid(const GrayImage &level0, unsigned nbLevels)
130 {
131  GrayImage *pLevel = new GrayImage(level0);
132  BuildPyramid(pLevel, nbLevels);
133 }
134 
135 void GaussianPyramid::BuildPyramid(GrayImage *level0, unsigned nbLevels)
136 {
137  GrayImage *pLevel = level0;
138  _levels.push_back(pLevel);
140  // build the nbLevels:
141  unsigned w = pLevel->width();
142  unsigned h = pLevel->height();
143  if (nbLevels != 0) {
144  for (unsigned int i = 0; i < nbLevels; ++i) { // soc
145  w = pLevel->width() >> 1;
146  h = pLevel->height() >> 1;
147  GrayImage *img = new GrayImage(w, h);
148  for (unsigned int y = 0; y < h; ++y) {
149  for (unsigned int x = 0; x < w; ++x) {
150  float v = gf.getSmoothedPixel<GrayImage>(pLevel, 2 * x, 2 * y);
151  img->setPixel(x, y, v);
152  }
153  }
154  _levels.push_back(img);
155  pLevel = img;
156  }
157  }
158  else {
159  while ((w > 1) && (h > 1)) {
160  w = pLevel->width() >> 1;
161  h = pLevel->height() >> 1;
162  GrayImage *img = new GrayImage(w, h);
163  for (unsigned int y = 0; y < h; ++y) {
164  for (unsigned int x = 0; x < w; ++x) {
165  float v = gf.getSmoothedPixel<GrayImage>(pLevel, 2 * x, 2 * y);
166  img->setPixel(x, y, v);
167  }
168  }
169  _levels.push_back(img);
170  pLevel = img;
171  }
172  }
173 }
174 
175 } /* namespace Freestyle */
#define D
_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
_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
Class to perform gaussian filtering operations on an image.
Class to represent a pyramid of images.
#define C
Definition: RandGen.cpp:25
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:24
ccl_gpu_kernel_postfix ccl_global float int int sy
ccl_gpu_kernel_postfix ccl_global float int sx
#define B
inherits from class Rep
Definition: AppCanvas.cpp:18
static unsigned x[3]
Definition: RandGen.cpp:73