ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
ImageWarpingField.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
9 
10 #include <Logging.h>
11 #include <json/json.h>
12 
13 namespace cloudViewer {
14 namespace pipelines {
15 namespace color_map {
16 using namespace cloudViewer;
17 
18 ImageWarpingField::ImageWarpingField() { InitializeWarpingFields(0, 0, 0); }
19 
21  int height,
22  int number_of_vertical_anchors) {
23  InitializeWarpingFields(width, height, number_of_vertical_anchors);
24 }
25 
27  int width, int height, int number_of_vertical_anchors) {
28  anchor_h_ = number_of_vertical_anchors;
29  anchor_step_ = double(height) / (anchor_h_ - 1);
30  anchor_w_ = int(std::ceil(double(width) / anchor_step_) + 1);
31  flow_ = Eigen::VectorXd(anchor_w_ * anchor_h_ * 2);
32  for (int i = 0; i <= (anchor_w_ - 1); i++) {
33  for (int j = 0; j <= (anchor_h_ - 1); j++) {
34  int baseidx = (i + j * anchor_w_) * 2;
35  flow_(baseidx) = i * anchor_step_;
36  flow_(baseidx + 1) = j * anchor_step_;
37  }
38  }
39 }
40 
41 Eigen::Vector2d ImageWarpingField::QueryFlow(int i, int j) const {
42  int baseidx = (i + j * anchor_w_) * 2;
43  // exceptional case: quried anchor index is out of pre-defined space
44  if (baseidx < 0 || baseidx >= anchor_w_ * anchor_h_ * 2)
45  return Eigen::Vector2d(0.0, 0.0);
46  else
47  return Eigen::Vector2d(flow_(baseidx), flow_(baseidx + 1));
48 }
49 
50 Eigen::Vector2d ImageWarpingField::GetImageWarpingField(double u,
51  double v) const {
52  int i = (int)(u / anchor_step_);
53  int j = (int)(v / anchor_step_);
54  double p = (u - i * anchor_step_) / anchor_step_;
55  double q = (v - j * anchor_step_) / anchor_step_;
56  return (1 - p) * (1 - q) * QueryFlow(i, j) +
57  (1 - p) * (q)*QueryFlow(i, j + 1) +
58  (p) * (1 - q) * QueryFlow(i + 1, j) +
59  (p) * (q)*QueryFlow(i + 1, j + 1);
60 }
61 
62 bool ImageWarpingField::ConvertToJsonValue(Json::Value &value) const {
63  value["class_name"] = "ImageWarpingField";
64  value["version_major"] = 1;
65  value["version_minor"] = 0;
66  value["anchor_w"] = anchor_w_;
67  value["anchor_h"] = anchor_h_;
68  Json::Value flow_array;
69  for (int i = 0; i < anchor_w_ * anchor_h_ * 2; i++) {
70  flow_array.append(flow_[i]);
71  }
72  value["flow"] = flow_array;
73  return true;
74 }
75 
76 bool ImageWarpingField::ConvertFromJsonValue(const Json::Value &value) {
77  if (!value.isObject()) {
79  "ImageWarpingField read JSON failed: unsupported json "
80  "format.");
81  return false;
82  }
83  if (value.get("class_name", "").asString() != "ImageWarpingField" ||
84  value.get("version_major", 1).asInt() != 1 ||
85  value.get("version_minor", 0).asInt() != 0) {
87  "ImageWarpingField read JSON failed: unsupported json "
88  "format.");
89  return false;
90  }
91  anchor_w_ = value.get("anchor_w", 1).asInt();
92  anchor_h_ = value.get("anchor_h", 1).asInt();
93 
94  const Json::Value flow_array = value["flow"];
95  if (flow_array.empty() ||
96  int(flow_array.size()) != (anchor_w_ * anchor_h_ * 2)) {
98  "ImageWarpingField read JSON failed: invalid flow.");
99  return false;
100  }
101  flow_.resize(anchor_w_ * anchor_h_ * 2, 1);
102  for (int i = 0; i < anchor_w_ * anchor_h_ * 2; i++) {
103  flow_(i) = flow_array[i].asDouble();
104  }
105  return true;
106 }
107 
108 } // namespace color_map
109 } // namespace pipelines
110 } // namespace cloudViewer
int width
int height
void InitializeWarpingFields(int width, int height, int number_of_vertical_anchors)
bool ConvertFromJsonValue(const Json::Value &value) override
bool ConvertToJsonValue(Json::Value &value) const override
Eigen::Vector2d GetImageWarpingField(double u, double v) const
#define LogWarning(...)
Definition: Logging.h:72
MiniVec< float, N > ceil(const MiniVec< float, N > &a)
Definition: MiniVec.h:89
Generic file read and write utility for python interface.