18 #include <unordered_map>
30 using signature_decoder_t =
31 std::pair<std::string,
32 std::function<bool(
const std::string &, geometry::Image &)>>;
33 static const std::array<signature_decoder_t, 2> signature_decoder_list{
36 static constexpr uint8_t MAX_SIGNATURE_LEN = 8;
38 static const std::unordered_map<
40 std::function<bool(
const std::string &,
const geometry::Image &,
int)>>
41 file_extension_to_image_write_function{
50 auto image = std::make_shared<geometry::Image>();
56 std::string signature_buffer(MAX_SIGNATURE_LEN, 0);
57 std::ifstream file(
filename, std::ios::binary);
58 file.read(&signature_buffer[0], MAX_SIGNATURE_LEN);
61 err_msg =
"Read geometry::Image failed for file {}. I/O error.";
64 for (
const auto &signature_decoder : signature_decoder_list) {
65 if (signature_buffer.compare(0, signature_decoder.first.size(),
66 signature_decoder.first) == 0) {
71 "Read geometry::Image failed for file {}. Unknown file "
72 "signature, only PNG and JPG are supported.";
82 std::string filename_ext =
84 if (filename_ext.empty()) {
86 "Write geometry::Image failed: unknown file extension.");
89 auto map_itr = file_extension_to_image_write_function.find(filename_ext);
90 if (map_itr == file_extension_to_image_write_function.end()) {
92 "Write geometry::Image failed: file extension {} unknown.",
101 const char comment_prefix =
'%';
102 const int skip_first_n_lines = 5;
104 if (!file.
Open(noise_model_path,
"r")) {
108 std::vector<float> data;
109 const char *line_buffer;
110 for (
int i = 0; i < skip_first_n_lines; ++i) {
111 if (!(line_buffer = file.
ReadLine())) {
113 "Read depth model failed: file {} is less than {} "
115 noise_model_path, skip_first_n_lines);
118 while ((line_buffer = file.
ReadLine())) {
119 std::string line(line_buffer);
120 line.erase(std::find(line.begin(), line.end(), comment_prefix),
123 std::istringstream iss(line);
125 while (iss >> value) {
126 data.push_back(value);
135 for (
int y = 0; y < 80; ++y) {
136 for (
int x = 0; x < 80; ++x) {
137 int idx = (y * 80 + x) * 23 + 3;
138 bool all_less_than_8000 =
true;
139 for (
int i = 0; i < 5; ++i) {
140 if (data[idx + i] >= 8000) {
141 all_less_than_8000 =
false;
145 if (all_less_than_8000) {
149 for (
int i = 0; i < 5; ++i) {
150 *model_indexer.GetDataPtr<
float>(i, x, y) =
162 if (depth_scale != 1.0) {
164 "Depth scale is ignored when input depth is float32.");
167 if (depth_scale <= 0.0) {
212 float x_noise = deterministic_debug_mode_ ? 0 : gen_coord();
213 float y_noise = deterministic_debug_mode_ ? 0 : gen_coord();
220 float d = *src_indexer.
GetDataPtr<
float>(x - x % 2, y - y % 2);
223 int i2 =
static_cast<int>((d + 1) / 2);
225 float a_ = (d - (i1 * 2 + 1)) / 2;
226 int x_ =
static_cast<int>(x / 8);
227 int y_ =
static_cast<int>(y / 6);
228 float model_val0 = *model_indexer.
GetDataPtr<
float>(
230 float model_val1 = *model_indexer.
GetDataPtr<
float>(
232 float f = (1 - a_) * model_val0 + a_ * model_val1;
244 float d_noise = deterministic_debug_mode_ ? 0 : gen_depth();
245 dst_d = 35.130 * 8 / round((35.130 / d + d_noise) * 8);
253 im_dst_tensor = im_dst_tensor.
To(original_device);
#define CLOUDVIEWER_DEVICE
std::shared_ptr< core::Tensor > image
std::string ToString() const
Tensor Contiguous() const
static Tensor Zeros(const SizeVector &shape, Dtype dtype, const Device &device=Device("CPU:0"))
Create a tensor fill with zeros.
Device GetDevice() const override
Tensor Clone() const
Copy Tensor to the same device.
Tensor To(Dtype dtype, bool copy=false) const
The Image class stores image with customizable rows, cols, channels, dtype and device.
core::Dtype GetDtype() const
Get dtype of the image.
core::Tensor AsTensor() const
Returns the underlying Tensor of the Image.
int64_t GetChannels() const
Get the number of channels of the image.
int64_t GetCols() const
Get the number of columns of the image.
int64_t GetRows() const
Get the number of rows of the image.
CLOUDVIEWER_HOST_DEVICE void WorkloadToCoord(index_t workload, index_t *x_out, index_t *y_out) const
Workload => 2D coordinate.
CLOUDVIEWER_HOST_DEVICE void * GetDataPtr() const
DepthNoiseSimulator(const std::string &noise_model_path)
Constructor.
geometry::Image Simulate(const geometry::Image &im_src, float depth_scale=1000.0)
Apply noise model to a depth image.
bool Open(const std::string &filename, const std::string &mode)
Open a file.
void ParallelFor(const Device &device, int64_t n, const func_t &func)
void To(const core::Tensor &src, core::Tensor &dst, double scale, double offset)
bool ReadImageFromPNG(const std::string &filename, geometry::Image &image)
bool ReadImage(const std::string &filename, geometry::Image &image)
bool WriteImageToPNG(const std::string &filename, const geometry::Image &image, int quality)
std::shared_ptr< geometry::Image > CreateImageFromFile(const std::string &filename)
bool WriteImage(const std::string &filename, const geometry::Image &image, int quality)
bool WriteImageToJPG(const std::string &filename, const geometry::Image &image, int quality)
bool ReadImageFromJPG(const std::string &filename, geometry::Image &image)
std::string GetFileExtensionInLowerCase(const std::string &filename)
Generic file read and write utility for python interface.