41 #include <visp3/core/vpConfig.h>
43 #if defined(VISP_HAVE_THREADS) && (defined(VISP_HAVE_X11) || defined(VISP_HAVE_GDI))
44 #include <condition_variable>
50 #include <visp3/core/vpImageConvert.h>
51 #include <visp3/core/vpIoException.h>
52 #include <visp3/core/vpIoTools.h>
53 #include <visp3/gui/vpDisplayGDI.h>
54 #include <visp3/gui/vpDisplayX.h>
55 #include <visp3/gui/vpDisplayPCL.h>
56 #include <visp3/io/vpImageIo.h>
57 #include <visp3/io/vpParseArgv.h>
58 #include <visp3/io/vpVideoWriter.h>
60 #if defined(VISP_HAVE_PCL)
61 #include <pcl/pcl_config.h>
62 #if defined(VISP_HAVE_PCL_COMMON)
63 #include <pcl/point_types.h>
64 #include <pcl/point_cloud.h>
66 #if defined(VISP_HAVE_PCL_IO)
67 #include <pcl/io/pcd_io.h>
71 #if defined(VISP_HAVE_MINIZ) && defined(VISP_HAVE_WORKING_REGEX)
72 #define GETOPTARGS "ci:e:jbzodh"
74 #define GETOPTARGS "ci:e:jbodh"
77 #ifdef ENABLE_VISP_NAMESPACE
84 void usage(
const char *name,
const char *badparam)
86 std::cout <<
"\nNAME " << std::endl
88 <<
" - Read data acquired with a Realsense device." << std::endl
90 <<
"SYNOPSIS " << std::endl
92 <<
" [-i <directory>]"
93 <<
" [-e <filename pattern (e.g. %04d)>]"
97 #if defined(VISP_HAVE_MINIZ) && defined(VISP_HAVE_WORKING_REGEX)
104 std::cout <<
"\nOPTIONS " << std::endl
105 <<
" -i <directory>" << std::endl
106 <<
" Input folder that contains the data to read." << std::endl
108 <<
" -e <pattern>" << std::endl
109 <<
" Filename pattern, e.g. %04d." << std::endl
111 <<
" -c" << std::endl
112 <<
" Flag to display data in step by step mode triggered by a user click." << std::endl
114 <<
" -j" << std::endl
115 <<
" Image data are saved in JPEG format, otherwise in PNG." << std::endl
117 <<
" -b" << std::endl
118 <<
" Depth and Pointcloud streams are saved in binary format." << std::endl
120 #if defined(VISP_HAVE_MINIZ) && defined(VISP_HAVE_WORKING_REGEX)
121 <<
" -z" << std::endl
122 <<
" Pointcloud stream is saved in NPZ format." << std::endl
125 <<
" -o" << std::endl
126 <<
" Save color images in PNG format (lossless) in a new folder." << std::endl
128 <<
" -d" << std::endl
129 <<
" Display depth in color." << std::endl
131 <<
" --help, -h" << std::endl
132 <<
" Display this helper message." << std::endl
136 std::cout <<
"\nERROR: Bad parameter " << badparam << std::endl;
140 bool getOptions(
int argc,
const char *argv[], std::string &input_directory, std::string &pattern,
bool &click,
141 bool &force_binary_format,
bool &read_jpeg,
bool &read_npz,
bool &save_video,
bool &color_depth)
144 const char **argv1 = (
const char **)argv;
150 input_directory = optarg;
162 force_binary_format =
true;
164 #if defined(VISP_HAVE_MINIZ) && defined(VISP_HAVE_WORKING_REGEX)
179 usage(argv[0],
nullptr);
184 usage(argv[0], optarg);
190 if ((c == 1) || (c == -1)) {
192 usage(argv[0],
nullptr);
193 std::cerr <<
"ERROR: " << std::endl;
194 std::cerr <<
" Bad argument " << optarg << std::endl << std::endl;
201 bool readData(
int cpt,
const std::string &input_directory,
const std::string &pattern,
vpImage<vpRGBa> &I_color,
202 vpImage<uint16_t> &I_depth_raw,
bool force_binary_format,
bool read_jpeg,
bool read_npz
203 #
if defined(VISP_HAVE_PCL) && defined(VISP_HAVE_PCL_COMMON)
204 , pcl::PointCloud<pcl::PointXYZ>::Ptr point_cloud
208 std::string image_filename_ext = read_jpeg ?
".jpg" :
".png";
209 std::string depth_filename_ext = force_binary_format ?
".bin" :
".npz";
210 char buffer[FILENAME_MAX];
211 std::stringstream ss;
212 ss << input_directory <<
"/color_image_" << pattern << image_filename_ext;
213 snprintf(buffer, FILENAME_MAX, ss.str().c_str(), cpt);
214 std::string filename_color = buffer;
217 ss << input_directory <<
"/depth_image_" << pattern << depth_filename_ext;
218 snprintf(buffer, FILENAME_MAX, ss.str().c_str(), cpt);
219 std::string filename_depth = buffer;
222 ss << input_directory <<
"/point_cloud_" << pattern << (force_binary_format ?
".bin" :
223 (read_npz ?
".npz" :
".pcd"));
224 snprintf(buffer, FILENAME_MAX, ss.str().c_str(), cpt);
225 std::string filename_pointcloud = buffer;
229 std::cerr <<
"End of sequence." << std::endl;
240 if (force_binary_format) {
241 std::ifstream file_depth(filename_depth.c_str(), std::ios::in | std::ios::binary);
242 if (file_depth.is_open()) {
243 unsigned int height = 0, width = 0;
246 I_depth_raw.
resize(height, width);
248 uint16_t depth_value = 0;
249 for (
unsigned int i = 0; i < height; i++) {
250 for (
unsigned int j = 0; j < width; j++) {
252 I_depth_raw[i][j] = depth_value;
257 #if defined(VISP_HAVE_MINIZ) && defined(VISP_HAVE_WORKING_REGEX)
267 uint16_t *depth_data_ptr = arr_depth_data.
data<uint16_t>();
268 assert(arr_depth_data.
shape.size() == 3);
269 assert(arr_depth_data.
shape[2] == 1);
271 unsigned int height =
static_cast<unsigned int>(arr_depth_data.
shape[0]);
272 unsigned int width =
static_cast<unsigned int>(arr_depth_data.
shape[1]);
273 const bool copyData =
true;
285 #if defined(VISP_HAVE_PCL)
287 if (force_binary_format) {
288 std::ifstream file_pointcloud(filename_pointcloud.c_str(), std::ios::in | std::ios::binary);
289 if (!file_pointcloud.is_open()) {
290 std::cerr <<
"Cannot read pointcloud file: " << filename_pointcloud << std::endl;
293 uint32_t height = 0, width = 0;
294 const char is_dense = 1;
297 file_pointcloud.read((
char *)(&is_dense),
sizeof(is_dense));
299 point_cloud->width = width;
300 point_cloud->height = height;
301 point_cloud->is_dense = (is_dense != 0);
302 point_cloud->resize((
size_t)width * height);
304 float x = 0.0f, y = 0.0f, z = 0.0f;
305 for (uint32_t i = 0; i < height; i++) {
306 for (uint32_t j = 0; j < width; j++) {
311 point_cloud->points[(size_t)(i * width + j)].x = x;
312 point_cloud->points[(size_t)(i * width + j)].y = y;
313 point_cloud->points[(size_t)(i * width + j)].z = z;
317 #if defined(VISP_HAVE_MINIZ) && defined(VISP_HAVE_WORKING_REGEX)
327 float *pcl_data_ptr = arr_pcl_data.
data<
float>();
328 assert(arr_pcl_data.
shape.size() == 3);
329 assert(arr_pcl_data.
shape[2] == 3);
331 uint32_t height = arr_pcl_data.
shape[0], width = arr_pcl_data.
shape[1];
332 const char is_dense = 1;
334 point_cloud->width = width;
335 point_cloud->height = height;
336 point_cloud->is_dense = (is_dense != 0);
337 point_cloud->resize((
size_t)width * height);
339 for (uint32_t i = 0; i < height; i++) {
340 for (uint32_t j = 0; j < width; j++) {
341 point_cloud->points[(size_t)(i * width + j)].x = pcl_data_ptr[(size_t)(i * width + j)*3 + 0];
342 point_cloud->points[(size_t)(i * width + j)].y = pcl_data_ptr[(size_t)(i * width + j)*3 + 1];
343 point_cloud->points[(size_t)(i * width + j)].z = pcl_data_ptr[(size_t)(i * width + j)*3 + 2];
349 #if defined(VISP_HAVE_PCL_IO)
350 if (pcl::io::loadPCDFile<pcl::PointXYZ>(filename_pointcloud, *point_cloud) == -1) {
351 std::cerr <<
"Cannot read PCD: " << filename_pointcloud << std::endl;
364 int main(
int argc,
const char *argv[])
366 std::string input_directory =
"";
367 std::string pattern =
"%04d";
369 bool force_binary_format =
false;
370 bool save_video =
false;
371 bool color_depth =
false;
372 bool read_jpeg =
false;
373 bool read_npz =
false;
376 if (!getOptions(argc, argv, input_directory, pattern, click, force_binary_format, read_jpeg, read_npz,
377 save_video, color_depth)) {
390 bool init_display =
false;
392 #if defined(VISP_HAVE_PCL)
394 pcl::PointCloud<pcl::PointXYZ>::Ptr pointcloud(
new pcl::PointCloud<pcl::PointXYZ>());
395 #if defined(VISP_HAVE_PCL_VISUALIZATION)
405 writer.
setFileName(output_directory +
"/" + pattern +
".png");
412 #if defined(VISP_HAVE_PCL) && defined(VISP_HAVE_PCL_COMMON)
414 std::lock_guard<std::mutex> lock(mutex);
415 quit = !readData(cpt_frame, input_directory, pattern, I_color, I_depth_raw, force_binary_format, read_jpeg,
416 read_npz, pointcloud);
419 quit = !readData(cpt_frame, input_directory, pattern, I_color, I_depth_raw, force_binary_format, read_jpeg,
430 d1.init(I_color, 0, 0,
"Color image");
432 d2.init(I_depth_color, I_color.
getWidth() + 10, 0,
"Depth image");
435 d2.init(I_depth, I_color.
getWidth() + 10, 0,
"Depth image");
437 #if defined(VISP_HAVE_PCL) && defined(VISP_HAVE_PCL_VISUALIZATION)
438 if (pointcloud->size() > 0) {
441 pcl_viewer.
startThread(std::ref(mutex), pointcloud);
452 std::stringstream ss;
453 ss <<
"Frame: " << cpt_frame;
505 std::cerr <<
"Enable C++11 or higher (cmake -DUSE_CXX_STANDARD=11) and install X11 or GDI!" << std::endl;
Display for windows using GDI (available on any windows 32 platform).
void setPosition(int posx, int posy)
void startThread(std::mutex &mutex, pcl::PointCloud< pcl::PointXYZ >::Ptr pointcloud)
void setWindowName(const std::string &window_name)
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static void display(const vpImage< unsigned char > &I)
static void flush(const vpImage< unsigned char > &I)
static void displayText(const vpImage< unsigned char > &I, const vpImagePoint &ip, const std::string &s, const vpColor &color)
static void createDepthHistogram(const vpImage< uint16_t > &src_depth, vpImage< vpRGBa > &dest_rgba)
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
static void read(vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
unsigned int getWidth() const
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
void insert(const vpImage< Type > &src, const vpImagePoint &topLeft)
unsigned int getSize() const
unsigned int getHeight() const
Error that can be emitted by the vpIoTools class and its derivatives.
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Class that enables to write easily a video file or a sequence of images.
void saveFrame(vpImage< vpRGBa > &I)
void setFileName(const std::string &filename)
void open(vpImage< vpRGBa > &I)
VISP_EXPORT npz_t npz_load(std::string fname)
std::map< std::string, NpyArray > npz_t
VISP_EXPORT int wait(double t0, double t)
VISP_EXPORT std::string getDateTime(const std::string &format="%Y/%m/%d %H:%M:%S")
VISP_EXPORT double measureTimeMs()
std::shared_ptr< std::vector< char > > data_holder
std::vector< size_t > shape