-
-
Notifications
You must be signed in to change notification settings - Fork 715
Open
Labels
type:EnhancementImprovement of existing methods or implementationImprovement of existing methods or implementation
Description
As identified in:
Description
The sobel operator is only supported in 2D.
Expected behavior
Sobel should provide an ND implementation.
Actual behavior
Compiler failures when instantiating N ! in [2,3]
Additional Information
AI Generated guess "write a c++ function that creates the n dimensional Sobel kernels?"
#include <vector>
#include <cstddef>
#include <stdexcept>
// Create N-dimensional Sobel kernels (one per axis).
// Each kernel is size 3^N, stored in row-major order with the last dimension varying fastest.
// Standard Sobel definition: derivative = [-1, 0, 1], smoothing = [1, 2, 1].
// Kernel for axis a is: K_a(x) = d[x_a] * Π_{j != a} s[x_j], with x_j ∈ {-1,0,1}.
inline std::vector<std::vector<int>> make_nd_sobel_kernels(std::size_t N)
{
if (N == 0) {
throw std::invalid_argument("Sobel kernels: N must be >= 1");
}
constexpr int d[3] = {-1, 0, 1};
constexpr int s[3] = { 1, 2, 1};
// total size = 3^N
std::size_t total = 1;
for (std::size_t i = 0; i < N; ++i) total *= 3;
// Precompute strides for row-major flattening (last dim fastest)
std::vector<std::size_t> stride(N, 1);
for (std::size_t i = 1; i < N; ++i) {
stride[N - 1 - i] = stride[N - i] * 3;
}
// Allocate one kernel per axis
std::vector<std::vector<int>> kernels(N, std::vector<int>(total, 0));
// Iterate over all N-D indices in {0,1,2}^N (mapping to {-1,0,1})
std::vector<int> idx(N, 0);
for (std::size_t linear = 0; linear < total; ++linear)
{
// Convert linear index -> base-3 digits (idx[0..N-1])
std::size_t t = linear;
for (std::size_t j = 0; j < N; ++j) {
idx[N - 1 - j] = static_cast<int>(t % 3);
t /= 3;
}
// For each axis, compute Sobel value at this point
for (std::size_t axis = 0; axis < N; ++axis)
{
int val = d[idx[axis]];
if (val == 0) { // derivative center => whole product is 0
kernels[axis][linear] = 0;
continue;
}
for (std::size_t j = 0; j < N; ++j) {
if (j == axis) continue;
val *= s[idx[j]];
}
kernels[axis][linear] = val;
}
}
return kernels;
}Metadata
Metadata
Assignees
Labels
type:EnhancementImprovement of existing methods or implementationImprovement of existing methods or implementation