36 const float truncation_factor = 0.004f;
40 int width = lround(2 * precisehalfwidth);
45 kernel->resize(width);
46 derivative->resize(width);
48 derivative->setZero();
49 int halfwidth = width / 2;
50 for (
int i = -halfwidth; i <= halfwidth; ++i) {
51 (*kernel)(i + halfwidth) =
Gaussian(i, sigma);
60 for (
int i = -halfwidth; i <= halfwidth; ++i) {
61 factor -= i * (*derivative)(i + halfwidth);
63 *derivative /= factor;
66template <
int size,
bool vertical>
75 double coefficients[2 * size + 1];
76 for (
int k = 0; k < 2 * size + 1; ++k) {
77 coefficients[k] = kernel(2 * size - k);
80 for (
int y = 0; y < height; ++
y) {
81 for (
int x = 0; x < width; ++
x) {
83 for (
int k = -size; k <=
size; ++k) {
85 if (y + k >= 0 && y + k < height) {
86 sum += src[k * src_line_stride] * coefficients[k +
size];
89 if (x + k >= 0 && x + k < width) {
90 sum += src[k * src_stride] * coefficients[k +
size];
94 dst[0] =
static_cast<float>(
sum);
101template <
bool vertical>
106 int width = in.Width();
107 int height = in.Height();
114 assert(kernel.size() % 2 == 1);
115 assert(&in != out_pointer);
117 int src_line_stride = in.Stride(0);
118 int src_stride = in.Stride(1);
119 int dst_stride = out.Stride(1);
120 const float* src = in.Data();
121 float* dst = out.Data() + plane;
125 int half_width = kernel.size() / 2;
126 switch (half_width) {
127#define static_convolution(size) \
129 FastConvolve<size, vertical>(kernel, \
141#undef static_convolution
142 default :
int dynamic_size = kernel.size() / 2;
143 for (
int y = 0; y < height; ++
y) {
144 for (
int x = 0; x < width; ++
x) {
147 for (
int k = -dynamic_size; k <= dynamic_size; ++k) {
149 if (y + k >= 0 && y + k < height) {
150 sum += src[k * src_line_stride] *
151 kernel(2 * dynamic_size - (k + dynamic_size));
154 if (x + k >= 0 && x + k < width) {
155 sum += src[k * src_stride] *
156 kernel(2 * dynamic_size - (k + dynamic_size));
160 dst[0] =
static_cast<float>(
sum);
183 Vec kernel, derivative;
195 Vec kernel, derivative;
213 Vec kernel, derivative;
236 assert(in.Depth() == 1);
238 Vec kernel, derivative;
244 blurred_and_gradxy->
Resize(in.Height(), in.Width(), 3);
260 int half_width = (window_size - 1) / 2;
262 for (
int k = 0; k < in.Depth(); ++k) {
263 for (
int i = 0; i < in.Height(); ++i) {
266 for (
int j = 0; j < half_width; ++j) {
270 for (
int j = 0; j < half_width + 1; ++j) {
271 sum += in(i, j + half_width, k);
275 for (
int j = half_width + 1; j < in.Width() - half_width; ++j) {
276 sum -= in(i, j - half_width - 1, k);
277 sum += in(i, j + half_width, k);
281 for (
int j = in.Width() - half_width; j < in.Width(); ++j) {
282 sum -= in(i, j - half_width - 1, k);
294 int half_width = (window_size - 1) / 2;
296 for (
int k = 0; k < in.Depth(); ++k) {
297 for (
int j = 0; j < in.Width(); ++j) {
300 for (
int i = 0; i < half_width; ++i) {
304 for (
int i = 0; i < half_width + 1; ++i) {
305 sum += in(i + half_width, j, k);
309 for (
int i = half_width + 1; i < in.Height() - half_width; ++i) {
310 sum -= in(i - half_width - 1, j, k);
311 sum += in(i + half_width, j, k);
315 for (
int i = in.Height() - half_width; i < in.Height(); ++i) {
316 sum -= in(i - half_width - 1, j, k);
334 for (
int y = 1; y < height - 1; y++) {
335 for (
int x = 1; x < width - 1; x++) {
336 const unsigned char* s = &src[y * width +
x];
337 int l = 128 + s[-width - 1] + s[-width] + s[-width + 1] + s[1] -
338 8 * s[0] + s[1] + s[width - 1] + s[width] + s[width + 1];
339 int d = ((256 - strength) * s[0] + strength *
l) / 256;
346 dst[y * width +
x] = d;
ATTR_WARN_UNUSED_RESULT const BMLoop * l
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
static T sum(const btAlignedObjectArray< T > &items)
3D array (row, column, channel).
void Resize(int height, int width, int depth=1)
void ResizeLike(const ArrayND< D, N > &other)
#define static_convolution(size)
void BoxFilterVertical(const Array3Df &in, int window_size, Array3Df *out_pointer)
void ImageDerivatives(const Array3Df &in, double sigma, Array3Df *gradient_x, Array3Df *gradient_y)
void ConvolveHorizontal(const Array3Df &in, const Vec &kernel, Array3Df *out_pointer, int plane)
void ConvolveVertical(const Array3Df &in, const Vec &kernel, Array3Df *out_pointer, int plane)
void LaplaceFilter(unsigned char *src, unsigned char *dst, int width, int height, int strength)
double GaussianDerivative(double x, double sigma)
double NormalizeL1(TVec *x)
void BoxFilterHorizontal(const Array3Df &in, int window_size, Array3Df *out_pointer)
void BlurredImageAndDerivativesChannels(const Array3Df &in, double sigma, Array3Df *blurred_and_gradxy)
double Gaussian(double x, double sigma)
void FastConvolve(const Vec &kernel, int width, int height, const float *src, int src_stride, int src_line_stride, float *dst, int dst_stride)
double GaussianInversePositive(double y, double sigma)
void ConvolveGaussian(const Array3Df &in, double sigma, Array3Df *out_pointer)
void Convolve(const Array3Df &in, const Vec &kernel, Array3Df *out_pointer, int plane)
void ComputeGaussianKernel(double sigma, Vec *kernel, Vec *derivative)
void BoxFilter(const Array3Df &in, int box_width, Array3Df *out)
void BlurredImageAndDerivatives(const Array3Df &in, double sigma, Array3Df *blurred_image, Array3Df *gradient_x, Array3Df *gradient_y)