47#include "./../include/image_writing.h"
48#include "../include/image_loading.h"
49#include "../include/Config.h"
55#include <opencv2/imgproc.hpp>
56#include <opencv2/imgcodecs.hpp>
62 using detail::ColorSpace;
63 using detail::g_color_space;
65 void write_raw(std::ofstream& stream, cv::Mat image)
67 CV_Assert(stream.good() && !image.empty() && image.isContinuous());
68 stream.write(
reinterpret_cast<char const*
>(image.data), image.size().area() * image.elemSize());
71 void write_color_YUV(std::string filepath, cv::Mat image,
int frame)
73 std::ofstream stream(filepath, frame
74 ? std::ios::binary | std::ios::app
76 if (!stream.is_open())
77 throw std::runtime_error(
"Failed to open YUV output image");
80 cv::split(image, dst);
82 cv::resize(dst[1], dst[1], cv::Size(), 0.5, 0.5, cv::INTER_CUBIC);
83 cv::resize(dst[2], dst[2], cv::Size(), 0.5, 0.5, cv::INTER_CUBIC);
85 write_raw(stream, dst[0]);
86 write_raw(stream, dst[1]);
87 write_raw(stream, dst[2]);
90 void write_depth_YUV(std::string filepath, cv::Mat image,
int frame, Parameters
const& parameters)
92 std::ofstream stream(filepath, frame
93 ? std::ios::binary | std::ios::app
95 if (!stream.is_open())
96 throw std::runtime_error(
"Failed to open YUV output image");
98 auto bit_depth = parameters.getDepthBitDepth();
99 auto neutral = bit_depth == 32
101 : 0.5 * (1 + max_level(bit_depth));
103 write_raw(stream, image);
105 if (parameters.getDepthColorFormat() == ColorFormat::YUV420) {
106 auto chroma = cv::Mat(image.size() / 2, image.type(), cv::Scalar::all(neutral));
107 write_raw(stream, chroma);
108 write_raw(stream, chroma);
112 void write_mask_YUV(std::string filepath, cv::Mat1b image,
int frame)
114 std::ofstream stream(filepath, frame
115 ? std::ios::binary | std::ios::app
117 if (!stream.is_open())
118 throw std::runtime_error(
"Failed to open YUV output image");
120 auto chroma = cv::Mat1b(image.size() / 2, 128);
122 write_raw(stream, image);
123 write_raw(stream, chroma);
124 write_raw(stream, chroma);
128 void write_color(std::string filepath, cv::Mat3f color,
int frame, Parameters
const& parameters)
131 auto color_space = filepath.substr(filepath.size() - 4, 4) ==
".yuv"
134 if (g_color_space == ColorSpace::YUV && color_space == ColorSpace::RGB) {
135 cv::cvtColor(color, color, cv::COLOR_YUV2BGR);
137 else if (g_color_space == ColorSpace::RGB && color_space == ColorSpace::YUV) {
138 cv::cvtColor(color, color, cv::COLOR_BGR2YUV);
142 auto bit_depth = parameters.getColorBitDepth();
144 if (bit_depth == 32 || color_space != ColorSpace::YUV) {
148 color.convertTo(image, cvdepth_from_bit_depth(bit_depth), max_level(bit_depth));
152 if (parameters.getPaddedSize() != parameters.getSize()) {
153 auto padded = cv::Mat(parameters.getPaddedSize(), image.type(), cv::Scalar::all(0.));
154 padded(parameters.getCropRegion()) = image;
159 if (color_space == ColorSpace::YUV) {
160 write_color_YUV(filepath, image, frame);
162 else if (frame == 0) {
164 cv::imwrite(filepath, image);
167 throw std::runtime_error(
"Writing multiple frames not (yet) supported for image files");
171 void write_depth(std::string filepath, cv::Mat1f depth,
int frame, Parameters
const& parameters)
173 write_maskedDepth(filepath, depth, cv::Mat1b(), frame, parameters);
176 void write_maskedDepth(std::string filepath, cv::Mat1f depth, cv::Mat1b mask,
int frame, Parameters
const& parameters)
179 depth = depth.clone();
181 auto bit_depth = parameters.getDepthBitDepth();
184 if (bit_depth == 32) {
189 auto near = parameters.getDepthRange()[0];
190 auto far = parameters.getDepthRange()[1];
194 depth = near / depth;
197 depth = (far * near / depth - near) / (far - near);
201 depth.setTo(0.f, mask);
203 depth.convertTo(image, cvdepth_from_bit_depth(bit_depth), max_level(bit_depth));
207 if (parameters.getPaddedSize() != parameters.getSize()) {
208 auto padded = cv::Mat(parameters.getPaddedSize(), image.type(), cv::Scalar::all(0.));
209 padded(parameters.getCropRegion()) = image;
214 if (filepath.substr(filepath.size() - 4, 4) ==
".yuv") {
215 write_depth_YUV(filepath, image, frame, parameters);
217 else if (frame == 0) {
218 cv::imwrite(filepath, image);
221 throw std::runtime_error(
"Writing multiple frames not (yet) supported for image files");
225 void write_mask(std::string filepath, cv::Mat1b mask,
int frame, Parameters
const& parameters)
227 mask.setTo(255, mask);
230 if (parameters.getPaddedSize() != parameters.getSize()) {
231 auto padded = cv::Mat(parameters.getPaddedSize(), mask.type(), cv::Scalar::all(0.));
232 padded(parameters.getCropRegion()) = mask;
237 if (filepath.substr(filepath.size() - 4, 4) ==
".yuv") {
238 write_mask_YUV(filepath, mask, frame);
240 else if (frame == 0) {
241 cv::imwrite(filepath, mask);
244 throw std::runtime_error(
"Writing multiple frames not (yet) supported for image files");