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