Other Useful Tools

namespace: tool

The tool module defines some of functions that other modules needs. At present, the tool contains basic image processing, control of console output color, Ply file reading and writing, timer, multithreading, etc.

ConsoleColor

Defines some controls for the console output color. The author hopes that the entire structure of OnePiece is clear and the output is as elegant as possible. 'Red', 'yellow', 'green' and 'blue' are defined in the header file. Red corresponds to Error, yellow corresponds to Warning, and green means things is running as expected, the blue color is to output some related information, which is good for debug. After including the ConsoleColor header file, you can change the output color by following operation:

//output error information
std::cout<<RED<<"[ERROR]::There is a error."<<RESET<<std::endl;

RESET will set the output color to the default white color.

ImageProcessing

ImageProcessing.himplements some image processing related content, encapsulates some OpenCV functions, including Gaussian filter, Sobel filter, creation of image pyramid and so on.

PLYManager

PLYManager implements the reading and writing of ply files based on tinyply. In addition to vertices, colors, normals, and triangular faces, PLYManager also supports to read and write arbitrary elements with properties, and comments. For additional elements you want to add, they need to be packaged in AdditionalElement to be correctly used by PLYManager:

struct AdditionalElement
{
    //Number of elements
    size_t count;
    //The total number of bytes occupied by data, which is equal to (count * sizeof(type) * element_property.size())
    size_t byte_size;
    //Name of elements
    std::string element_key;
    //name of elements' property
    std::vector<std::string> element_property;
    //type of property, which can be char, short, int, and unsigned version, float, double
    tinyply::Type type;
    //property can also be a list, this is the type of list's length
    tinyply::Type list_type = tinyply::Type::INVALID;
    //list'length
    size_t list_count = 0;
    //pointer to data
    unsigned char *data; 
};
//When reading additional elements, remember to delete the data pointer after conversion to the datatype you need.
bool ReadPLY(const std::string &filename, geometry::Point3List &points, geometry::Point3List &normals,
    geometry::Point3List &colors, geometry::Point3uiList &triangles, 
    std::vector<AdditionalElement> & additional_labels);
bool WritePLY(const std::string &filename, const geometry::Point3List&points, 
    const geometry::Point3List &normals, const geometry::Point3List &colors,
    const geometry::Point3uiList &triangles = geometry::Point3uiList(), 
    const std::vector<std::string> & comments = std::vector<std::string>(),
    const std::vector<AdditionalElement> & additional_labels = std::vector<AdditionalElement>(),
    bool use_ascii = false);

RPLYManager(Deleted)

OnePiece uses the RPLY library to read and write PLY and to read the point Cloud or triangle mesh. The loading and writing of 'geometry::PointCloud' and 'geometry::TriangleMesh' are encapsulation of this class.

OnePiece also supports reading or writing of other properties or labels of vertices(OnePiece supports int32, float, double, unchar, ushort currently). However, when you want to do this, you need to call some low-level functions implemented in RPLYManager.h.

//template function for reading the information of a certain label, you need to provide the label name, value type, and corresponding contained vector
//You can read the values of one label at a time.
template<typename T>
    bool ReadVertexLabelFromPLY(const std::string &filename, const std::string &label_name,
        std::vector<T> &vertex_labels);
//Write additional label information into ply. It's a little troublesome to write.
//You need to pack the information to be written into a container(vector), and the type of this vector is AdditionalLabel, which is a tuple type. It contains label_name, label_type, and a pointer to the data.
//You write multiple attributes at once
typedef std::tuple<std::string, e_ply_type, void *> AdditionalLabel;
bool WritePLY(const std::string &filename, const geometry::Point3List&points, 
    const geometry::Point3List &normals, const geometry::Point3List &colors,
    const std::vector<Eigen::Vector3i> &triangles, 
    const std::vector<AdditionalLabel> & additional_labels = std::vector<AdditionalLabel>(),
    bool use_ascii = true);

For reading and writing of labels or properties, you can check example/GetLabelUsingKDTree.cpp, which will perform reading and writing semantic information of meshes. Here OnePiece can pack Reading operation into the same form as Writing, but in fact Writing is more troublesome to call, and it also means to allocate space for void pointers (which needs to be released). This is more dangerous behavior, so OnePiece gave up this method.

OBJManager

OnePiece uses OBJManager to read and write OBJ file, which is an encapsulation of tinyobjloader.

MultiThreads

What you need to provide is the parameters, that is, the input, and the output container that needs to be changed, and the function to call. The input parameters and the return are stored in two std::vector. The function prototype is as follows:

template <class T1, class T2>
void MultiThreads(const std::vector<T1> &p1, std::vector<T2> &p2, std::function<void(const T1 &, T2&)> &f);

It is also very simple for to use this template. Put the input and output into two std::vectors, then use the std::function binding function, and pass them into the above functions together. The grid generation introduced later will have Examples of use.

The implementation here is still too simple, which means that there can only be one input and one output. This template is temporarily written to meet a certain function for the author needs.

MultiThreads does not care whether your loop can be parallelized, so it is the user's responsibility to ensure that the loop can be accelerated in parallel.

TickTock

TickTock is a timer, which is defined in class Timer. Timer can time multiple processes, as long as their names are different. Yes, to use Timer, you must define a unique name for the timing process. It is simple to use:

tool::Timer timer;
timer.TICK("My Process");
// code of process
timer.TOCK("My Process");
timer.Log("My Process");

Log is used to print the ellapsed time, The unit is milliseconds. You can use LogAll() to output all results. However, a warning will be output when 'Tick time' is larger than 'Tock time'. So try to use these tools correctly.

OpenNIReader

OpenNIReader encapsulates the interface of OpenNI to read depth and rgb, which needs to be improved.

KeyframeBasedSlam

A base class of the key frame-based slam system, example/BAFusion.cpp and example/FBAFusion.cpp are based on this class.

CPPExtension

CPPExtension.h implements some extensions of CPP. It currently includes the string slice operations Split and RSplit, and the template function ShuffleVector to randomly shuffle a std::vector.

IO

IO.h contains some IO operations of TUM dataset and Scannet dataset. AlignColorToDepth can be used to align color map and depth map, when the color camera and depth camera have different camera intrinsics( Generally, color camera has a high resolution).