Blender V5.0
libmv/libmv/image/sample.h
Go to the documentation of this file.
1// Copyright (c) 2007, 2008 libmv authors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"), to
5// deal in the Software without restriction, including without limitation the
6// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7// sell copies of the Software, and to permit persons to whom the Software is
8// furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in
11// all copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19// IN THE SOFTWARE.
20
21#ifndef LIBMV_IMAGE_SAMPLE_H_
22#define LIBMV_IMAGE_SAMPLE_H_
23
24#include "libmv/image/image.h"
25
26namespace libmv {
27
29template <typename T>
30inline T SampleNearest(const Array3D<T>& image, float y, float x, int v = 0) {
31 const int i = int(round(y));
32 const int j = int(round(x));
33 return image(i, j, v);
34}
35
36inline void LinearInitAxis(float x, int size, int* x1, int* x2, float* dx) {
37 const int ix = static_cast<int>(x);
38 if (ix < 0) {
39 *x1 = 0;
40 *x2 = 0;
41 *dx = 1.0;
42 } else if (ix > size - 2) {
43 *x1 = size - 1;
44 *x2 = size - 1;
45 *dx = 1.0;
46 } else {
47 *x1 = ix;
48 *x2 = ix + 1;
49 *dx = *x2 - x;
50 }
51}
52
54template <typename T>
55inline T SampleLinear(const Array3D<T>& image, float y, float x, int v = 0) {
56 int x1, y1, x2, y2;
57 float dx, dy;
58
59 LinearInitAxis(y, image.Height(), &y1, &y2, &dy);
60 LinearInitAxis(x, image.Width(), &x1, &x2, &dx);
61
62 const T im11 = image(y1, x1, v);
63 const T im12 = image(y1, x2, v);
64 const T im21 = image(y2, x1, v);
65 const T im22 = image(y2, x2, v);
66
67 return T(dy * (dx * im11 + (1.0 - dx) * im12) +
68 (1 - dy) * (dx * im21 + (1.0 - dx) * im22));
69}
70
73template <typename T>
74inline void SampleLinear(const Array3D<T>& image, float y, float x, T* sample) {
75 int x1, y1, x2, y2;
76 float dx, dy;
77
78 LinearInitAxis(y, image.Height(), &y1, &y2, &dy);
79 LinearInitAxis(x, image.Width(), &x1, &x2, &dx);
80
81 for (int i = 0; i < image.Depth(); ++i) {
82 const T im11 = image(y1, x1, i);
83 const T im12 = image(y1, x2, i);
84 const T im21 = image(y2, x1, i);
85 const T im22 = image(y2, x2, i);
86
87 sample[i] = T(dy * (dx * im11 + (1.0 - dx) * im12) +
88 (1 - dy) * (dx * im21 + (1.0 - dx) * im22));
89 }
90}
91
92// Downsample all channels by 2. If the image has odd width or height, the last
93// row or column is ignored.
94// FIXME(MatthiasF): this implementation shouldn't be in an interface file
96 int height = in.Height() / 2;
97 int width = in.Width() / 2;
98 int depth = in.Depth();
99
100 out->Resize(height, width, depth);
101
102 // 2x2 box filter downsampling.
103 for (int r = 0; r < height; ++r) {
104 for (int c = 0; c < width; ++c) {
105 for (int k = 0; k < depth; ++k) {
106 // clang-format off
107 (*out)(r, c, k) = (in(2 * r, 2 * c, k) +
108 in(2 * r + 1, 2 * c, k) +
109 in(2 * r, 2 * c + 1, k) +
110 in(2 * r + 1, 2 * c + 1, k)) / 4.0f;
111 // clang-format on
112 }
113 }
114 }
115}
116
117// Sample a region centered at x,y in image with size extending by half_width
118// from x,y. Channels specifies the number of channels to sample from.
119inline void SamplePattern(const FloatImage& image,
120 double x,
121 double y,
122 int half_width,
123 int channels,
124 FloatImage* sampled) {
125 sampled->Resize(2 * half_width + 1, 2 * half_width + 1, channels);
126 for (int r = -half_width; r <= half_width; ++r) {
127 for (int c = -half_width; c <= half_width; ++c) {
128 for (int i = 0; i < channels; ++i) {
129 (*sampled)(r + half_width, c + half_width, i) =
130 SampleLinear(image, y + r, x + c, i);
131 }
132 }
133 }
134}
135
136} // namespace libmv
137
138#endif // LIBMV_IMAGE_SAMPLE_H_
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
3D array (row, column, channel).
Definition array_nd.h:332
void Resize(int height, int width, int depth=1)
Definition array_nd.h:341
int Depth() const
Definition array_nd.h:347
int Height() const
Definition array_nd.h:345
int Width() const
Definition array_nd.h:346
#define in
#define out
#define round
#define T
T SampleNearest(const Array3D< T > &image, float y, float x, int v=0)
Nearest neighbor interpolation.
Array3Df FloatImage
T SampleLinear(const Array3D< T > &image, float y, float x, int v=0)
Linear interpolation.
Array3D< float > Array3Df
Definition array_nd.h:373
void DownsampleChannelsBy2(const Array3Df &in, Array3Df *out)
void LinearInitAxis(float x, int size, int *x1, int *x2, float *dx)
void SamplePattern(const FloatImage &image, double x, double y, int half_width, int channels, FloatImage *sampled)
i
Definition text_draw.cc:230