Blender V4.3
COM_KuwaharaAnisotropicStructureTensorOperation.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
6
7#include "BLI_math_base.hh"
8#include "BLI_math_vector.h"
9#include "BLI_math_vector.hh"
11
12namespace blender::compositor {
13
20
21/* Computes the structure tensor of the image using a Dirac delta window function as described in
22 * section "3.2 Local Structure Estimation" of the paper:
23 *
24 * Kyprianidis, Jan Eric. "Image and video abstraction by multi-scale anisotropic Kuwahara
25 * filtering." 2011.
26 *
27 * The structure tensor should then be smoothed using a Gaussian function to eliminate high
28 * frequency details. */
30 MemoryBuffer *output, const rcti &area, Span<MemoryBuffer *> inputs)
31{
33 MemoryBuffer *image = inputs[0];
34 const int width = image->get_width();
35 const int height = image->get_height();
36
37 /* The weight kernels of the filter optimized for rotational symmetry described in section
38 * "3.2.1 Gradient Calculation". */
39 const float corner_weight = 0.182f;
40 const float center_weight = 1.0f - 2.0f * corner_weight;
41
42 for (BuffersIterator<float> it = output->iterate_with(inputs, area); !it.is_end(); ++it) {
43 const int x = it.x;
44 const int y = it.y;
45
46 float3 input_color;
47 float3 x_partial_derivative = float3(0.0f);
48 input_color = float3(image->get_elem(max(0, x - 1), min(height - 1, y + 1)));
49 x_partial_derivative += input_color * -corner_weight;
50 input_color = float3(image->get_elem(max(0, x - 1), y));
51 x_partial_derivative += input_color * -center_weight;
52 input_color = float3(image->get_elem(max(0, x - 1), max(0, y - 1)));
53 x_partial_derivative += input_color * -corner_weight;
54 input_color = float3(image->get_elem(min(width - 1, x + 1), min(height - 1, y + 1)));
55 x_partial_derivative += input_color * corner_weight;
56 input_color = float3(image->get_elem(min(width - 1, x + 1), y));
57 x_partial_derivative += input_color * center_weight;
58 input_color = float3(image->get_elem(min(width - 1, x + 1), max(0, y - 1)));
59 x_partial_derivative += input_color * corner_weight;
60
61 float3 y_partial_derivative = float3(0.0f);
62 input_color = float3(image->get_elem(max(0, x - 1), min(height - 1, y + 1)));
63 y_partial_derivative += input_color * corner_weight;
64 input_color = float3(image->get_elem(x, min(height - 1, y + 1)));
65 y_partial_derivative += input_color * center_weight;
66 input_color = float3(image->get_elem(min(width - 1, x + 1), min(height - 1, y + 1)));
67 y_partial_derivative += input_color * corner_weight;
68 input_color = float3(image->get_elem(max(0, x - 1), max(0, y - 1)));
69 y_partial_derivative += input_color * -corner_weight;
70 input_color = float3(image->get_elem(x, max(0, y - 1)));
71 y_partial_derivative += input_color * -center_weight;
72 input_color = float3(image->get_elem(min(width - 1, x + 1), max(0, y - 1)));
73 y_partial_derivative += input_color * -corner_weight;
74
75 /* We encode the structure tensor in a float4 using a column major storage order. */
76 float4 structure_tensor = float4(dot(x_partial_derivative, x_partial_derivative),
77 dot(x_partial_derivative, y_partial_derivative),
78 dot(x_partial_derivative, y_partial_derivative),
79 dot(y_partial_derivative, y_partial_derivative));
80 copy_v4_v4(it.out, structure_tensor);
81 }
82}
83
84} // namespace blender::compositor
MINLINE void copy_v4_v4(float r[4], const float a[4])
void update_memory_buffer_partial(MemoryBuffer *output, const rcti &area, Span< MemoryBuffer * > inputs) override
a MemoryBuffer contains access to the data
const int get_width() const
get the width of this MemoryBuffer
void add_output_socket(DataType datatype)
void add_input_socket(DataType datatype, ResizeMode resize_mode=ResizeMode::Center)
typename BuffersIteratorBuilder< T >::Iterator BuffersIterator
T dot(const QuaternionBase< T > &a, const QuaternionBase< T > &b)
T min(const T &a, const T &b)
T max(const T &a, const T &b)
VecBase< float, 4 > float4
VecBase< float, 3 > float3
#define min(a, b)
Definition sort.c:32
float max