28#if defined(__CUDACC__)
30#elif defined(SYCL_LANGUAGE_VERSION)
43#define LINEAR_SATURATE(elem_t, calc_t) \
44 elem_t limits[2] = {std::numeric_limits<elem_t>::min(), \
45 std::numeric_limits<elem_t>::max()}; \
46 calc_t c_scale = static_cast<calc_t>(scale); \
47 calc_t c_offset = static_cast<calc_t>(offset); \
48 DISPATCH_DTYPE_TO_TEMPLATE(src.GetDtype(), [&]() { \
50 src.GetDevice(), indexer.NumWorkloads(), \
51 [=] OPEN3D_DEVICE(int64_t workload_idx) { \
53 indexer.GetInputPtr<scalar_t>(0, workload_idx); \
54 auto dst_ptr = indexer.GetOutputPtr<elem_t>(workload_idx); \
55 calc_t out = static_cast<calc_t>(*src_ptr) * c_scale + \
57 out = out < limits[0] ? limits[0] : out; \
58 out = out > limits[1] ? limits[1] : out; \
59 *dst_ptr = static_cast<elem_t>(out); \
87#if defined(__CUDACC__)
89#elif defined(SYCL_LANGUAGE_VERSION)
103 int64_t rows = src.GetShape(0);
104 int64_t cols = dst.GetShape(1);
105 int64_t n = rows * cols;
108 core::ParallelFor(src.GetDevice(), n,
109 [=] OPEN3D_DEVICE(int64_t workload_idx) {
110 int64_t y = workload_idx / cols;
111 int64_t x = workload_idx % cols;
113 float in = static_cast<float>(
114 *src_indexer.GetDataPtr<scalar_t>(x, y));
115 float out = in / scale;
116 out = out <= min_value ? clip_fill : out;
117 out = out >= max_value ? clip_fill : out;
118 *dst_indexer.GetDataPtr<float>(x, y) = out;
125#if defined(__CUDACC__)
127#elif defined(SYCL_LANGUAGE_VERSION)
135 float invalid_fill) {
142 int rows_down = dst_indexer.
GetShape(0);
143 int cols_down = dst_indexer.
GetShape(1);
144 int n = rows_down * cols_down;
148 const int gkernel_size = 5;
149 const int gkernel_size_2 = gkernel_size / 2;
150 const float gweights[3] = {0.375f, 0.25f, 0.0625f};
159 src.GetDevice(), n, [=]
OPEN3D_DEVICE(int64_t workload_idx) {
160 int y = workload_idx / cols_down;
161 int x = workload_idx % cols_down;
166 float v_center = *src_indexer.
GetDataPtr<
float>(x_src, y_src);
167 if (v_center == invalid_fill) {
172 int x_min = max(0, x_src - gkernel_size_2);
173 int y_min = max(0, y_src - gkernel_size_2);
175 int x_max = min(cols - 1, x_src + gkernel_size_2);
176 int y_max = min(rows - 1, y_src + gkernel_size_2);
180 for (
int yk = y_min; yk <= y_max; ++yk) {
181 for (
int xk = x_min; xk <= x_max; ++xk) {
182 float v = *src_indexer.
GetDataPtr<
float>(xk, yk);
183 int dy = abs(yk - y_src);
184 int dx = abs(xk - x_src);
186 if (v != invalid_fill &&
187 abs(v - v_center) < depth_diff) {
188 float w = gweights[dx] * gweights[dy];
196 w_sum == 0 ? invalid_fill : v_sum / w_sum;
202#if defined(SYCL_LANGUAGE_VERSION)
209 utility::LogError(
"SYCL bilateral filter does not support dtype {}.",
216 const int rows = src_indexer.GetShape(0);
217 const int cols = src_indexer.GetShape(1);
218 const int radius = kernel_size / 2;
219 const float inv_value_sigma_squared = 0.5f / (value_sigma * value_sigma);
220 const float inv_dist_sigma_squared = 0.5f / (dist_sigma * dist_sigma);
225 src.GetDevice(), static_cast<int64_t>(rows) * cols,
226 [=] OPEN3D_DEVICE(int64_t workload_idx) {
227 const int y = workload_idx / cols;
228 const int x = workload_idx % cols;
229 const float center = static_cast<float>(
230 *src_indexer.GetDataPtr<scalar_t>(x, y));
231 float value_sum = 0.0f;
232 float weight_sum = 0.0f;
234 for (int dy = -radius; dy <= radius; ++dy) {
235 const int sample_y = y + dy;
236 if (sample_y < 0 || sample_y >= rows) continue;
237 for (int dx = -radius; dx <= radius; ++dx) {
238 const int sample_x = x + dx;
239 if (sample_x < 0 || sample_x >= cols) continue;
240 const float sample = static_cast<float>(
241 *src_indexer.GetDataPtr<scalar_t>(
242 sample_x, sample_y));
243 const float spatial_distance =
244 static_cast<float>(dx * dx + dy * dy);
245 const float value_distance = sample - center;
246 const float weight = exp(
247 -spatial_distance * inv_dist_sigma_squared -
248 value_distance * value_distance *
249 inv_value_sigma_squared);
250 value_sum += weight * sample;
251 weight_sum += weight;
254 *dst_indexer.GetDataPtr<scalar_t>(x, y) =
255 static_cast<scalar_t>(value_sum / weight_sum);
261template <
typename scalar_t,
typename output_t>
270 const int rows = src_indexer.
GetShape(0);
271 const int cols = src_indexer.
GetShape(1);
272 const int radius = kernel_size / 2;
273 const float derivative_3[3] = {-1.0f, 0.0f, 1.0f};
274 const float smoothing_3[3] = {1.0f, 2.0f, 1.0f};
275 const float derivative_5[5] = {-1.0f, -2.0f, 0.0f, 2.0f, 1.0f};
276 const float smoothing_5[5] = {1.0f, 4.0f, 6.0f, 4.0f, 1.0f};
279 src.
GetDevice(),
static_cast<int64_t
>(rows) * cols,
281 const int y = workload_idx / cols;
282 const int x = workload_idx % cols;
283 float value_dx = 0.0f;
284 float value_dy = 0.0f;
286 for (
int ky = -radius; ky <= radius; ++ky) {
288 std::max(0, std::min(rows - 1,
y + ky));
289 for (
int kx = -radius; kx <= radius; ++kx) {
291 std::max(0, std::min(cols - 1,
x + kx));
292 const float sample =
static_cast<float>(
295 const int ix = kx + radius;
296 const int iy = ky + radius;
297 const float* derivative_coefficients =
298 kernel_size == 3 ? derivative_3 : derivative_5;
299 const float* smoothing_coefficients =
300 kernel_size == 3 ? smoothing_3 : smoothing_5;
301 value_dx += sample * derivative_coefficients[ix] *
302 smoothing_coefficients[iy];
303 value_dy += sample * smoothing_coefficients[ix] *
304 derivative_coefficients[iy];
308 static_cast<output_t
>(value_dx);
310 static_cast<output_t
>(value_dy);
314#if defined(SYCL_LANGUAGE_VERSION)
320 FilterSobelSYCLImpl<float, float>(src, dst_dx, dst_dy, kernel_size);
322 FilterSobelSYCLImpl<uint8_t, int16_t>(src, dst_dx, dst_dy, kernel_size);
324 utility::LogError(
"SYCL Sobel filter does not support dtype {}.",
330#if defined(SYCL_LANGUAGE_VERSION)
331template <
typename scalar_t>
332void FilterGaussianSYCLImpl(
const core::Tensor& src,
336 NDArrayIndexer src_indexer(src, 2);
337 NDArrayIndexer dst_indexer(dst, 2);
338 const int rows = src_indexer.GetShape(0);
339 const int cols = src_indexer.GetShape(1);
340 const int radius = kernel_size / 2;
343 src.GetDevice(),
static_cast<int64_t
>(rows) * cols,
345 const int y = workload_idx / cols;
346 const int x = workload_idx % cols;
347 float value_sum = 0.0f;
348 float weight_sum = 0.0f;
349 for (
int ky = -radius; ky <= radius; ++ky) {
351 std::max(0, std::min(rows - 1,
y + ky));
352 for (
int kx = -radius; kx <= radius; ++kx) {
354 std::max(0, std::min(cols - 1,
x + kx));
355 const float distance =
356 static_cast<float>(kx * kx + ky * ky);
358 exp(-distance / (2.0f * sigma * sigma));
361 *src_indexer.GetDataPtr<scalar_t>(
362 sample_x, sample_y));
366 *dst_indexer.GetDataPtr<scalar_t>(
x,
y) =
367 static_cast<scalar_t
>(value_sum / weight_sum);
371void FilterGaussianSYCL(
const core::Tensor& src,
376 FilterGaussianSYCLImpl<float>(src, dst, kernel_size, sigma);
378 FilterGaussianSYCLImpl<uint8_t>(src, dst, kernel_size, sigma);
380 FilterGaussianSYCLImpl<uint16_t>(src, dst, kernel_size, sigma);
382 utility::LogError(
"SYCL Gaussian filter does not support dtype {}.",
383 src.GetDtype().ToString());
387template <
typename scalar_t>
388void ResizeNearestSYCLImpl(
const core::Tensor& src,
390 float sampling_rate) {
393 const int src_rows = src_indexer.GetShape(0);
394 const int src_cols = src_indexer.GetShape(1);
395 const int dst_rows = dst_indexer.GetShape(0);
396 const int dst_cols = dst_indexer.GetShape(1);
399 src.GetDevice(),
static_cast<int64_t
>(dst_rows) * dst_cols,
401 const int y = workload_idx / dst_cols;
402 const int x = workload_idx % dst_cols;
403 const int source_y = std::min(
404 src_rows - 1,
static_cast<int>(
y / sampling_rate));
405 const int source_x = std::min(
406 src_cols - 1,
static_cast<int>(
x / sampling_rate));
407 *dst_indexer.GetDataPtr<scalar_t>(
x,
y) =
408 *src_indexer.GetDataPtr<scalar_t>(source_x, source_y);
412void ResizeNearestSYCL(
const core::Tensor& src,
414 float sampling_rate) {
416 ResizeNearestSYCLImpl<float>(src, dst, sampling_rate);
418 ResizeNearestSYCLImpl<uint8_t>(src, dst, sampling_rate);
420 ResizeNearestSYCLImpl<uint16_t>(src, dst, sampling_rate);
422 utility::LogError(
"SYCL nearest resize does not support dtype {}.",
423 src.GetDtype().ToString());
428#if defined(__CUDACC__)
429void CreateVertexMapCUDA
430#elif defined(SYCL_LANGUAGE_VERSION)
431void CreateVertexMapSYCL
438 float invalid_fill) {
444 int64_t rows = src.GetShape(0);
445 int64_t cols = src.GetShape(1);
446 int64_t n = rows * cols;
454 src.GetDevice(), n, [=]
OPEN3D_DEVICE(int64_t workload_idx) {
456 if (isinf(invalid_fill))
return isinf(v);
457 if (isnan(invalid_fill))
return isnan(v);
458 return v == invalid_fill;
461 int64_t
y = workload_idx / cols;
462 int64_t
x = workload_idx % cols;
467 if (!is_invalid(d)) {
468 ti.
Unproject(
static_cast<float>(
x),
static_cast<float>(
y),
469 d, vertex + 0, vertex + 1, vertex + 2);
471 vertex[0] = invalid_fill;
472 vertex[1] = invalid_fill;
473 vertex[2] = invalid_fill;
477#if defined(__CUDACC__)
478void CreateNormalMapCUDA
479#elif defined(SYCL_LANGUAGE_VERSION)
480void CreateNormalMapSYCL
488 int64_t rows = src_indexer.
GetShape(0);
489 int64_t cols = src_indexer.
GetShape(1);
490 int64_t n = rows * cols;
493 src.GetDevice(), n, [=]
OPEN3D_DEVICE(int64_t workload_idx) {
494 int64_t
y = workload_idx / cols;
495 int64_t
x = workload_idx % cols;
499 if (
y < rows - 1 &&
x < cols - 1) {
504 if ((v00[0] == invalid_fill && v00[1] == invalid_fill &&
505 v00[2] == invalid_fill) ||
506 (v01[0] == invalid_fill && v01[1] == invalid_fill &&
507 v01[2] == invalid_fill) ||
508 (v10[0] == invalid_fill && v10[1] == invalid_fill &&
509 v10[2] == invalid_fill)) {
510 normal[0] = invalid_fill;
511 normal[1] = invalid_fill;
512 normal[2] = invalid_fill;
516 float dx0 = v01[0] - v00[0];
517 float dy0 = v01[1] - v00[1];
518 float dz0 = v01[2] - v00[2];
520 float dx1 = v10[0] - v00[0];
521 float dy1 = v10[1] - v00[1];
522 float dz1 = v10[2] - v00[2];
524 normal[0] = dy0 * dz1 - dz0 * dy1;
525 normal[1] = dz0 * dx1 - dx0 * dz1;
526 normal[2] = dx0 * dy1 - dy0 * dx1;
528 constexpr float EPSILON = 1e-5f;
530 sqrt(normal[0] * normal[0] + normal[1] * normal[1] +
531 normal[2] * normal[2]);
532 normal_norm = std::max(normal_norm, EPSILON);
533 normal[0] /= normal_norm;
534 normal[1] /= normal_norm;
535 normal[2] /= normal_norm;
537 normal[0] = invalid_fill;
538 normal[1] = invalid_fill;
539 normal[2] = invalid_fill;
544#if defined(__CUDACC__)
545void ColorizeDepthCUDA
546#elif defined(SYCL_LANGUAGE_VERSION)
547void ColorizeDepthSYCL
559 int64_t rows = src.GetShape(0);
560 int64_t cols = dst.GetShape(1);
561 int64_t n = rows * cols;
563 float inv_interval = 255.0f / (max_value - min_value);
566 src.GetDevice(), n, [=] OPEN3D_DEVICE(int64_t workload_idx) {
567 int64_t y = workload_idx / cols;
568 int64_t x = workload_idx % cols;
570 float in = static_cast<float>(
571 *src_indexer.GetDataPtr<scalar_t>(x, y));
572 float out = in / scale;
573 out = out <= min_value ? min_value : out;
574 out = out >= max_value ? max_value : out;
577 static_cast<int>(inv_interval * (out - min_value));
578 uint8_t* out_ptr = dst_indexer.GetDataPtr<uint8_t>(x, y);
579 out_ptr[0] = turbo_srgb_bytes[idx][0];
580 out_ptr[1] = turbo_srgb_bytes[idx][1];
581 out_ptr[2] = turbo_srgb_bytes[idx][2];
#define OPEN3D_DEVICE
Definition CUDAUtils.h:44
#define DISPATCH_DTYPE_TO_TEMPLATE(DTYPE,...)
Definition Dispatch.h:30
std::shared_ptr< core::Tensor > image
Definition FilamentRenderer.cpp:347
#define LINEAR_SATURATE(elem_t, calc_t)
Real weight
Definition SurfaceReconstructionPoisson.cpp:270
double t
Definition SurfaceReconstructionPoisson.cpp:175
Indexer indexer
Definition UnaryEWSYCL.cpp:35
std::string ToString() const
Definition Dtype.h:64
Device GetDevice() const override
Definition Tensor.cpp:1556
static Tensor Eye(int64_t n, Dtype dtype, const Device &device)
Create an identity matrix of size n x n.
Definition Tensor.cpp:417
Dtype GetDtype() const
Definition Tensor.h:1223
Definition GeometryIndexer.h:160
OPEN3D_HOST_DEVICE void * GetDataPtr() const
Definition GeometryIndexer.h:314
OPEN3D_HOST_DEVICE index_t GetShape(int i) const
Definition GeometryIndexer.h:310
const Dtype UInt32
Definition Dtype.cpp:50
const Dtype Int64
Definition Dtype.cpp:47
const Dtype UInt16
Definition Dtype.cpp:49
const Dtype Int32
Definition Dtype.cpp:46
const Dtype Int16
Definition Dtype.cpp:45
const Dtype UInt8
Definition Dtype.cpp:48
void ParallelFor(const Device &device, int64_t n, const func_t &func)
Definition ParallelFor.h:190
const Dtype Float64
Definition Dtype.cpp:43
const Dtype UInt64
Definition Dtype.cpp:51
const Dtype Int8
Definition Dtype.cpp:44
const Dtype Float32
Definition Dtype.cpp:42
void ClipTransformCPU(const core::Tensor &src, core::Tensor &dst, float scale, float min_value, float max_value, float clip_fill=0.0f)
Definition ImageImpl.h:94
void CreateNormalMapCPU(const core::Tensor &src, core::Tensor &dst, float invalid_fill)
Definition ImageImpl.h:484
void ColorizeDepthCPU(const core::Tensor &src, core::Tensor &dst, float scale, float min_value, float max_value)
Definition ImageImpl.h:551
void CreateVertexMapCPU(const core::Tensor &src, core::Tensor &dst, const core::Tensor &intrinsics, float invalid_fill)
Definition ImageImpl.h:435
void PyrDownDepthCPU(const core::Tensor &src, core::Tensor &dst, float diff_threshold, float invalid_fill)
Definition ImageImpl.h:132
void ToCPU(const core::Tensor &src, core::Tensor &dst, double scale, double offset)
Definition ImageImpl.h:35
void FilterSobelSYCLImpl(const core::Tensor &src, core::Tensor &dst_dx, core::Tensor &dst_dy, int kernel_size)
Definition ImageImpl.h:262
TArrayIndexer< int64_t > NDArrayIndexer
Definition GeometryIndexer.h:359
Definition PinholeCameraIntrinsic.cpp:16