What's the format of boost.serialization's output - serialization

I tried to serialize a vector and a map container and output their value by cout. However, it is hard for me to get the meaning of boost's output. My code looks like this:
#include <iostream>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/map.hpp>
#include <boost/assign.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <sstream>
#include <fstream>
using namespace std;
int main()
{
vector<int> v = boost::assign::list_of(1)(3)(5);
map<int, string> m = boost::assign::map_list_of(1,"one")(2,"two");
std::stringstream ss;
boost::archive::text_oarchive oa(ss);
oa<<v<<m;
vector<int> v_;
map<int,string> m_;
boost::archive::text_iarchive ia(ss);
ia>>v_>>m_;
boost::archive::text_oarchive ib(cout);
ib<<v_<<m_;
return 0;
}
The output looks like this:
22 serialization::archive 9 3 0 1 3 5 0 0 2 0 0 0 1 3 one 2 3 two
What's the meaning of the numbers 9 3 0 before the value 1 3 5 I compose? How about the 0 0 2 0 0 0 ? Does the '3' between '1' and 'one' mean there are 3 characters ?

I'm not sure about some zeros in the map (maybe some version number or tracking levels) but for the rest :
22 (length of the signature)
serialization::archive (signature)
9 (archive version, 10 on boost 1.53)
3 (vector size)
0 (item version)
1 3 5 (vector items)
0 (map class tracking level ?)
0 (map class version ?)
2 (map size)
0 (item class tracking _level ?)
0 (item class version ?)
0 (item version)
1 (key) 3 (value length) one (value)
2 (key) 3 (value length) two (value)
Note that the content and format of the text output is Boost's internal business and may change with future Boost revisions, so your application shouldn't rely on the internal archive contents.

If you put these lines at the end of your code, you will obtain a human readable XML version of the archive.
boost::archive::xml_oarchive ib(cout);
ib<< boost::serialization::make_nvp("v", v_) << boost::serialization::make_nvp("m", m_); // ib<<v_<<m_;
return 0;
you will get this output, which describes it self:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="10">
<v>
<count>3</count>
<item_version>0</item_version>
<item>1</item>
<item>3</item>
<item>5</item>
</v>
<m class_id="1" tracking_level="0" version="0">
<count>2</count>
<item_version>0</item_version>
<item class_id="2" tracking_level="0" version="0">
<first>1</first>
<second>one</second>
</item>
<item>
<first>2</first>
<second>two</second>
</item>
</m>
</boost_serialization>
So #zacinter is correct and the three 0 after the 2 are: 1) item_version (of std::pair, the value type of the map) 2) tracking_level of std::pair and 3) version of std::pair.

22 is the length of the text "serialization::archive".
Every text that is archived has such a text-length-number in front of it I believe.

I'm aware that one should normally not try to parse the text_oarchive format of boost::serialization because the format is subject to change and should only ever be consumed by boost itself. In my case though, the software producing this output is a proprietary binary blob that uses messages on TCP and UDP encoded with boost::serialization. My (FOSS) client needs to be able to talk to it without having boost available. So I needed to figure out how all of this works and this SO question was the most useful I've found so far on this platform. So for any other poor souls in a similar situation, I wanted to share some more discoveries I made about the text_oarchive format.
I'll talk about an example as it would typically be produced by the proprietary application I need to inferface with. So here is some code with dummy classes A1, A2, A3, A4 and A5. A1 is the base class and all of the following classes are sub-classes inheriting from the one before.
#include "boost/serialization/export.hpp"
#include "boost/serialization/extended_type_info.hpp"
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <iostream>
#include <sstream>
class A1 {
public:
A1(void) {}
virtual ~A1(void) {}
private:
unsigned int mem1 = 101;
friend class boost::serialization::access;
template <class Archive> void serialize(Archive & ar, const unsigned int version) {
ar & BOOST_SERIALIZATION_NVP(mem1);
}
};
BOOST_CLASS_EXPORT_KEY(A1);
class A2 : public A1 {
public:
A2(void) {}
private:
unsigned int mem2 = 102;
friend class boost::serialization::access;
template <class Archive> void serialize(Archive & ar, const unsigned int version) {
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(A1);
ar & BOOST_SERIALIZATION_NVP(mem2);
}
};
BOOST_CLASS_EXPORT_KEY(A2);
class A3 : public A2 {
public:
A3(void) {}
private:
virtual void foo() = 0;
unsigned int mem3 = 103;
friend class boost::serialization::access;
template <class Archive> void serialize(Archive & ar, const unsigned int version) {
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(A2);
ar & BOOST_SERIALIZATION_NVP(mem3);
}
};
BOOST_CLASS_EXPORT_KEY(A3);
class A4 : public A3 {
public:
A4(void) {}
private:
void foo() {}
unsigned int mem4 = 104;
friend class boost::serialization::access;
template <class Archive> void serialize(Archive & ar, const unsigned int version) {
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(A3);
ar & BOOST_SERIALIZATION_NVP(mem4);
}
};
BOOST_CLASS_EXPORT_KEY(A4);
class A5 : public A4 {
public:
A5(void) {}
private:
unsigned int mem5 = 105;
friend class boost::serialization::access;
template <class Archive> void serialize(Archive & ar, const unsigned int version) {
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(A4);
ar & BOOST_SERIALIZATION_NVP(mem5);
}
};
BOOST_CLASS_EXPORT_KEY(A5);
BOOST_CLASS_EXPORT_IMPLEMENT(A1);
BOOST_CLASS_EXPORT_IMPLEMENT(A2);
BOOST_CLASS_EXPORT_IMPLEMENT(A3);
BOOST_CLASS_EXPORT_IMPLEMENT(A4);
BOOST_CLASS_EXPORT_IMPLEMENT(A5);
BOOST_CLASS_VERSION(A1, 11)
BOOST_CLASS_VERSION(A2, 12)
BOOST_CLASS_VERSION(A3, 13)
BOOST_CLASS_VERSION(A4, 14)
BOOST_CLASS_VERSION(A5, 15)
void func(const A1 * const packet) {
std::string outpacket;
std::ostringstream stream;
boost::archive::xml_oarchive oa_xml(stream);
oa_xml << BOOST_SERIALIZATION_NVP(packet);
boost::archive::text_oarchive oa_text(stream);
oa_text << BOOST_SERIALIZATION_NVP(packet);
outpacket = stream.str();
std::cout << outpacket << std::endl;
}
int main() {
auto data = new A5();
func(data);
}
At the end, the main() function creates an A5 object and passes it to the function called func which is able to handle arguments of type A1 of which A5 is a sub-class. This is important as the boost::serialization output would be different if func took A5 as input directly.
Another important bit is the virtual destructor of A1. This one is required as well or otherwise one will not get the expected output for reasons that I do not yet understand.
To be able to better understand the text format, func encodes the data as XML as well as in the text format. To be able to use the XML output, BOOST_SERIALIZATION_BASE_OBJECT_NVP and BOOST_SERIALIZATION_NVP are applied wherever necessary. This does not seem to inferfere with the text output at all, which does not need these.
Each of the classes A1 to A5 has a member called mem1 to mem5, respectively. These are filled with the values 101 to 105, respectively, to better debug which integer in the text output stands for what.
To understand the output even better, BOOST_CLASS_VERSION is used to give all classes a unique class version. This helps because by default the class version is zero and then it's not clear what all the zeroes in the output stand for.
Without further ado, this is the output of compiling and running above code:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="18">
<packet class_id="1" class_name="A5" tracking_level="1" version="15" object_id="_0">
<A4 class_id="2" tracking_level="1" version="14" object_id="_1">
<A3 class_id="3" tracking_level="0" version="13">
<A2 class_id="4" tracking_level="1" version="12" object_id="_2">
<A1 class_id="0" tracking_level="1" version="11" object_id="_3">
<mem1>101</mem1>
</A1>
<mem2>102</mem2>
</A2>
<mem3>103</mem3>
</A3>
<mem4>104</mem4>
</A4>
<mem5>105</mem5>
</packet>
22 serialization::archive 18 1 2 A5 1 15
0 1 14
1 0 13 1 12
2 1 11
3 101 102 103 104 105
Some general observations:
in general, the values in the XML output seem to be in the same order as in the text output when reading the xml sequentially from top to bottom and left to right
consequently, the member variables of each of the sub-classes are bundled together all at the end of the output
class A3, which is the only class with a virtual function, is the only one with tracking level 0 (all the others are tracking level 1) and without an object id
I do not understand where the newlines in front of the object-ids come from in the text output but boost seems to be able to parse a message with newlines replaced by spaces just the same, so they do not seem to have any semantic meaning
Lets look at the values one-by-one by having each of them in their own line:
22 -- length of the string "serialization::archive"
serialization::archive -- BOOST_ARCHIVE_SIGNATURE defined in src/basic_archive.cpp
18 -- BOOST_ARCHIVE_VERSION as defined in src/basic_archive.cpp
1 -- class-id of A5
2 -- length of class name "A5"
A5 -- class name of A5
1 -- tracking level of A5
15 -- class version of A5
0 -- object-id of A5
1 -- tracking level of A4
14 -- class version of A4
1 -- object-id of A4
0 -- tracking level of A3 (the only "0" tracking level -- A3 is abstract class)
13 -- class version of A3 (notice the absence of object-id for abstract class A3 as well)
1 -- tracking level of A2
12 -- class version of A2
2 -- object-id of A2
1 -- tracking level of A1
11 -- class version of A1
3 -- object-id of A1
101 -- member of A1
102 -- member of A2
103 -- member of A3
104 -- member of A4
105 -- member of A5

Related

Microblaze How to use AXI Stream?

I have a microblaze instantiated with 16 stream interfaces with a custom IP attached to two. What is the correct header file or function to communicate over these interfaces in Vitis (Not HLS)?
Based on the full example that you can find here, I am going to provide a general idea:
Include the mb_interface.h in your C source
Use the putfsl and getfsl macros to write and read from the stream.
Such macros are wrapper around special assembly instructions that the microblaze will execute by writing the data on the axi stream interface. The ìd is the stream id. Here you can find all the possible functions and here you can explore the ISA.
#define putfsl(val, id) asm volatile ("put\t%0,rfsl" stringify(id) :: "d" (val))
The fundamental issue is that
#include "mb_interface.h"
/*
* Write 4 32-bit words.
*/
static void inline write_axis(volatile unsigned int *a)
{
register int a0, a1, a2, a3;
a3 = a[3]; a1 = a[1]; a2 = a[2]; a0 = a[0];
putfsl(a0, 0); putfsl(a1, 0); putfsl(a2, 0); putfsl(a3, 0);
}
int main()
{
volatile unsigned int outbuffer[BUFFER_SIZE] = { 0x0, 0x1, 0x2, 0x3 }
};
/* Perform transfers */
write_axis(outbuffer);
return 0;
}

Change color of mesh displayed by the function CGAL::draw()

Problem descriptionI wonder if there is a way to change the color of mesh displayed by the function CGAL::draw(). I have a Surface_mesh, I want to draw it with CGAL. So I use the function CGAL::draw(), but the color of mesh is blue, which is not pretty in my view. I tried to change the code of CGAL to change the color. I found a functor called DefaultColorFunctorFaceGraph in a header file called draw_face_graoh.h, there is an annotation above the definition of DefaultColorFunctorFaceGraph, which says "// Default color functor; user can change it to have its own face color". I change the functor, in which I change the return value to CGAL::IO::gray(), but it doesn't work at all, the color of mesh is still blue.So can I change the color of mesh by changing the code of CGAL? Is it necessary to change lower level code such as some codes calling OpenGL?
Code
Here is an example about the way I use the function draw().
#include<iostream>
#include<fstream>
#include<CGAL/Surface_mesh.h>
#include<CGAL/draw_surface_mesh.h>
#include<CGAL/Exact_predicates_inexact_constructions_kernel.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel kernel;
typedef kernel::Point_3 point;
typedef CGAL::Surface_mesh<point> Mesh;
int main() {
std::ifstream fin("test.off");
Mesh mesh;
fin >> mesh;
CGAL::draw(mesh);
}
The file called test.off is as follws.
OFF
4 4 0
0 0 1
0 0 0
1 0 0
0 1 0
3 2 0 1
3 1 0 3
3 1 3 2
3 3 0 2
Here is the changed functor.
namespace CGAL
{
// Default color functor; user can change it to have its own face color
struct DefaultColorFunctorFaceGraph
{
template<typename Graph>
CGAL::IO::Color operator()(const Graph&,
typename boost::graph_traits<Graph>::face_descriptor fh) const
{
if (fh == boost::graph_traits<Graph>::null_face()) // use to get the mono color
//return CGAL::IO::Color(100,125,200); // R G B between 0-255
return CGAL::IO::gray();//Here changed
return get_random_color(CGAL::get_default_random());
}
};
Runtime environment
IDE: VS 2017
Solution configuration: Release x64
CGAL version: 5.3
Finally I found a struct named Basic_viewer_qt in a header file called Basic_viewer_qt.h. By changing the values of variables m_faces_mono_color and m_ambient_color in this struct, color of mesh can be changed.

Passing an inlined CArray in a CStruct to a shared library using NativeCall

This is a follow-up question to "How to declare native array of fixed size in Perl 6?".
In that question it was discussed how to incorporate an array of a fixed size into a CStruct. In this answer it was suggested to use HAS to inline a CArray in the CStruct. When I tested this idea, I ran into some strange behavior that could not be resolved in the comments section below the question, so I decided to write it up as a new question. Here is is my C test library code:
slib.c:
#include <stdio.h>
struct myStruct
{
int A;
int B[3];
int C;
};
void use_struct (struct myStruct *s) {
printf("sizeof(struct myStruct): %ld\n", sizeof( struct myStruct ));
printf("sizeof(struct myStruct *): %ld\n", sizeof( struct myStruct *));
printf("A = %d\n", s->A);
printf("B[0] = %d\n", s->B[0]);
printf("B[1] = %d\n", s->B[1]);
printf("B[2] = %d\n", s->B[2]);
printf("C = %d\n", s->C);
}
To generate a shared library from this i used:
gcc -c -fpic slib.c
gcc -shared -o libslib.so slib.o
Then, the Perl 6 code:
p.p6:
use v6;
use NativeCall;
class myStruct is repr('CStruct') {
has int32 $.A is rw;
HAS int32 #.B[3] is CArray is rw;
has int32 $.C is rw;
}
sub use_struct(myStruct $s) is native("./libslib.so") { * };
my $s = myStruct.new();
$s.A = 1;
$s.B[0] = 2;
$s.B[1] = 3;
$s.B[2] = 4;
$s.C = 5;
say "Expected size of Perl 6 struct: ", (nativesizeof(int32) * 5);
say "Actual size of Perl 6 struct: ", nativesizeof( $s );
say 'Number of elements of $s.B: ', $s.B.elems;
say "B[0] = ", $s.B[0];
say "B[1] = ", $s.B[1];
say "B[2] = ", $s.B[2];
say "Calling library function..";
say "--------------------------";
use_struct( $s );
The output from the script is:
Expected size of Perl 6 struct: 20
Actual size of Perl 6 struct: 24
Number of elements of $s.B: 3
B[0] = 2
B[1] = 3
B[2] = 4
Calling library function..
--------------------------
sizeof(struct myStruct): 20
sizeof(struct myStruct *): 8
A = 1
B[0] = 0 # <-- Expected 2
B[1] = 653252032 # <-- Expected 3
B[2] = 22030 # <-- Expected 4
C = 5
Questions:
Why does nativesizeof( $s ) give 24 (and not the expected value of 20)?
Why is the content of the array B in the structure not as expected when printed from the C function?
Note:
I am using Ubuntu 18.04 and Perl 6 Rakudo version 2018.04.01, but have also tested with version 2018.05
Your code is correct. I just fixed that bug in MoarVM, and added tests to rakudo, similar to your code:
In C:
typedef struct {
int a;
int b[3];
int c;
} InlinedArrayInStruct;
In Perl 6:
class InlinedArrayInStruct is repr('CStruct') {
has int32 $.a is rw;
HAS int32 #.b[3] is CArray;
has int32 $.c is rw;
}
See these patches:
https://github.com/MoarVM/MoarVM/commit/ac3d3c76954fa3c1b1db14ea999bf3248c2eda1c
https://github.com/rakudo/rakudo/commit/f8b79306cc1900b7991490eef822480f304a56d9
If you are not building rakudo (and also NQP and MoarVM) directly from latest source from github, you probably have to wait for the 2018.08 release that will appear here: https://rakudo.org/files

'boost::archive::archive_exception' what(): unsupported version

I cloned this repository:
https://github.com/srianant/computer_vision
built and ran,got this error:
OpenPose/DLIB Gesture, Action and Face Recognition.
resolution: 640x480
net_resolution: 656x368
handNetInputSize: 368x368
face_net_resolution: 368x368
cCamera Resolution set to: 640x480
Push following keys:
p for pause sample generation
f for generating face samples
t for train samples
c for continue camera feed
h for display key commands
q for quit program
terminate called after throwing an instance of 'boost::archive::archive_exception'
what(): unsupported version
And this exception thrown from this file:line:32
https://github.com/srianant/computer_vision/blob/master/openpose/src/openpose/user_code/pose_model.cpp
I think it is trying to deserialized this file:
https://github.com/srianant/computer_vision/blob/master/openpose/train_data/pose/pose.model
You're probably doing something wrong: have you checked your boost version? It could just be (very) old.
I can deserialize all the input archives that use boost.
The only use of boost is in openpose_recognition.cpp, and the only archives being read are text archives from the training data.
It is easy to create a standalone program to verify that these file can be deserialized.
Creating The Minimal Declarations
Extracted from pose_model.hpp:
// Timesteps per samples
const int timesteps = 5; // 5 frames per sample
// 2-dim data to store different postures
const int max_pose_count = 10;
const int max_pose_score_pair = 36; // 34 pairs for pose + 2 padding for multiples of 4
typedef std::array<std::string, max_pose_count> pose;
typedef std::array<double,max_pose_score_pair*timesteps> pose_sample_type;
// 2-dim data to store different hand actions
const int max_hand_count = 10;
const int max_hand_score_pair = 40; // 40 pairs for hand
typedef std::array<std::string,max_hand_count> hand;
typedef std::array<double,max_hand_score_pair*timesteps> hand_sample_type;
// 2-dim data to store different faces
const int max_face_count = 10;
const int max_face_score_pair = 96; // 96 pairs (94 + 2 pairs for padding for multiples of 4)
typedef std::array<std::string,max_face_count> face;
typedef std::array<double,max_face_score_pair*timesteps> face_sample_type;
Test Method:
All extractions follow the same pattern, let's add a debug_print method later:
template <typename T>
void read_and_verify(std::string name, T& into) {
std::ifstream ifs("/tmp/so/computer_vision/openpose/train_data/" + name);
boost::archive::text_iarchive ia(ifs);
ia >> into;
debug_print(name, into);
}
Note: Adjust the path to match your file locations
Reading All The Archives:
int main() {
{
pose pose_names;
std::vector<pose_sample_type> pose_samples; // vector of m_pose_sample vectors
std::vector<double> pose_labels; // vector of pose labels (eg. 1,2,3...)
read_and_verify("pose/pose_names.txt", pose_names);
read_and_verify("pose/pose_samples.txt", pose_samples);
read_and_verify("pose/pose_labels.txt", pose_labels);
}
{
face face_names; // vector of face emotions names (eg. normal, sad, happy...)
std::vector<face_sample_type> face_samples; // vector of m_face_sample vectors
std::vector<double> face_labels; // vector of face emotions labels (eg. 1,2,3...)
read_and_verify("face/face_names.txt", face_names);
read_and_verify("face/face_samples.txt", face_samples);
read_and_verify("face/face_labels.txt", face_labels);
}
{
hand hand_names; // vector of hand gesture names (eg. fist, victory, stop...);
std::vector<hand_sample_type> left_hand_samples; // vector of m_left_hand_sample vectors
std::vector<hand_sample_type> right_hand_samples; // vector of m_right_hand_sample vectors
std::vector<double> left_hand_labels; // vector of left hand labels (eg. 1,2,3...)
std::vector<double> right_hand_labels; // vector of right hand labels (eg. 1,2,3...)
read_and_verify("hand/hand_names.txt", hand_names);
read_and_verify("hand/left_hand_samples.txt", left_hand_samples);
read_and_verify("hand/right_hand_samples.txt", right_hand_samples);
read_and_verify("hand/left_hand_labels.txt", left_hand_labels);
read_and_verify("hand/right_hand_labels.txt", right_hand_labels);
}
}
Printing Debug Info:
We need only three different debug_print overloads, for names, samples and labels:
template <size_t N> // names
void debug_print(std::string name, std::array<std::string, N> const& data) {
std::cout << name << ": ";
for (auto& n : data)
if (!n.empty())
std::cout << n << " ";
std::cout << "\n";
}
// labels
void debug_print(std::string name, std::vector<double> const& data) {
std::cout << name << ": ";
for (auto& a : data)
std::cout << a << " ";
std::cout << "\n";
}
template <size_t N> // samples
void debug_print(std::string name, std::vector<std::array<double, N> > const& data) {
std::cout << name << ": ";
for (auto& a : data)
std::cout << "{" << a[0] << "...} ";
std::cout << "\n";
}
DEMO TIME
The complete program is here:
Live On Coliru
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/array.hpp>
#include <boost/serialization/vector.hpp>
#include <fstream>
#include <iostream>
///////////////// from pose_model.hpp
//
// Timesteps per samples
const int timesteps = 5; // 5 frames per sample
// 2-dim data to store different postures
const int max_pose_count = 10;
const int max_pose_score_pair = 36; // 34 pairs for pose + 2 padding for multiples of 4
typedef std::array<std::string, max_pose_count> pose;
typedef std::array<double,max_pose_score_pair*timesteps> pose_sample_type;
// 2-dim data to store different hand actions
const int max_hand_count = 10;
const int max_hand_score_pair = 40; // 40 pairs for hand
typedef std::array<std::string,max_hand_count> hand;
typedef std::array<double,max_hand_score_pair*timesteps> hand_sample_type;
// 2-dim data to store different faces
const int max_face_count = 10;
const int max_face_score_pair = 96; // 96 pairs (94 + 2 pairs for padding for multiples of 4)
typedef std::array<std::string,max_face_count> face;
typedef std::array<double,max_face_score_pair*timesteps> face_sample_type;
//
///////////////// end pose_model.hpp
template <size_t N> // names
void debug_print(std::string name, std::array<std::string, N> const& data) {
std::cout << name << ": ";
for (auto& n : data)
if (!n.empty())
std::cout << n << " ";
std::cout << "\n";
}
// labels
void debug_print(std::string name, std::vector<double> const& data) {
std::cout << name << ": ";
for (auto& a : data)
std::cout << a << " ";
std::cout << "\n";
}
template <size_t N> // samples
void debug_print(std::string name, std::vector<std::array<double, N> > const& data) {
std::cout << name << ": ";
for (auto& a : data)
std::cout << "{" << a[0] << "...} ";
std::cout << "\n";
}
template <typename T>
void read_and_verify(std::string name, T& into) {
std::ifstream ifs("/tmp/so/computer_vision/openpose/train_data/" + name);
boost::archive::text_iarchive ia(ifs);
ia >> into;
debug_print(name, into);
}
int main() {
{
pose pose_names;
std::vector<pose_sample_type> pose_samples; // vector of m_pose_sample vectors
std::vector<double> pose_labels; // vector of pose labels (eg. 1,2,3...)
read_and_verify("pose/pose_names.txt", pose_names);
read_and_verify("pose/pose_samples.txt", pose_samples);
read_and_verify("pose/pose_labels.txt", pose_labels);
}
{
face face_names; // vector of face emotions names (eg. normal, sad, happy...)
std::vector<face_sample_type> face_samples; // vector of m_face_sample vectors
std::vector<double> face_labels; // vector of face emotions labels (eg. 1,2,3...)
read_and_verify("face/face_names.txt", face_names);
read_and_verify("face/face_samples.txt", face_samples);
read_and_verify("face/face_labels.txt", face_labels);
}
{
hand hand_names; // vector of hand gesture names (eg. fist, victory, stop...);
std::vector<hand_sample_type> left_hand_samples; // vector of m_left_hand_sample vectors
std::vector<hand_sample_type> right_hand_samples; // vector of m_right_hand_sample vectors
std::vector<double> left_hand_labels; // vector of left hand labels (eg. 1,2,3...)
std::vector<double> right_hand_labels; // vector of right hand labels (eg. 1,2,3...)
read_and_verify("hand/hand_names.txt", hand_names);
read_and_verify("hand/left_hand_samples.txt", left_hand_samples);
read_and_verify("hand/right_hand_samples.txt", right_hand_samples);
read_and_verify("hand/left_hand_labels.txt", left_hand_labels);
read_and_verify("hand/right_hand_labels.txt", right_hand_labels);
}
}
Printing (lines truncated at 100 characters):
pose/pose_names.txt: unknown close_to_camera standing sitting
pose/pose_samples.txt: {204.658...} {196.314...} {210.322...} {191.529...} {192.8...} {187.155...} {...
pose/pose_labels.txt: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ...
face/face_names.txt: unknown normal happy sad surprise
face/face_samples.txt: {89.5967...} {93.7026...} {97.6529...} {91.7247...} {91.8048...} {91.3076...}...
face/face_labels.txt: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ...
hand/hand_names.txt: unknown fist pinch wave victory stop thumbsup
hand/left_hand_samples.txt: {0...} {0.000524104...} {0...} {0...} {0...} {0...} {0...} {0...} {0...}...
hand/right_hand_samples.txt: {0...} {0.00166845...} {0.00161618...} {0.00176376...} {0.00167096...} ...
hand/left_hand_labels.txt: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1...
hand/right_hand_labels.txt: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ...
BONUS:
I had to use a hack to circumvent the file-size limit on Coliru: I changed to code to read bzip2 compressed files:
#include <boost/iostreams/filter/bzip2.hpp>
#include <boost/iostreams/filtering_stream.hpp>
template <typename T>
void read_and_verify(std::string name, T& into) {
std::ifstream compressed("/tmp/so/computer_vision/openpose/train_data/" + name + ".bz2");
boost::iostreams::filtering_istream fs;
fs.push(boost::iostreams::bzip2_decompressor{});
fs.push(compressed);
boost::archive::text_iarchive ia(fs);
ia >> into;
debug_print(name, into);
}
Now you can actually see the output Live On Coliru
After replacing ::archive 14 with ::archive 12 in all txt files,this problem gone,#sehe thanks very much

VB.net API variables

I really hope someone can help me with this, I've searched everywhere and can't find anything on the matter.
I've got a SMART card printer that prints plastic cards and I've been given the API to interact with it directly from vb.net, I've managed to execute most of the functions but one of them refers to a
1 COLORREF
and a
1 WCHAR*
variable and I'm clueless as to what they want me to provide.
Below is the structure I've been given for context
01 int SmartComm_DrawBarcode(
02 HSMART hHandle,
03 BYTE page,
04 BYTE panel,
05 int x,
06 int y,
07 int cx,
08 int cy,
09 COLORREF col,
10 RECT* prcArea,
11 const WCHAR* szName,
12 int nSize,
13 const WCHAR* szData,
14 const WCHAR* szPost
15 );
Below is the code that I'm using to execute one of the functions and it works perfectly, I just can't get the barcode working:
1 Dim lclogo As String = "C:\acer\lclogo.png"
2 strImg_ptr = Marshal.StringToHGlobalUni(LunchcardLogo)
3 rcDraws_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(GetType(RECT)))
4 If nres = SM_SUCCESS Then
5 nres = SmartComm_DrawImage(hsmart, CByte(PAGE_FRONT), CByte(PANEL_BLACK), 606, 456, 405, 171, strImg_ptr, rcDraws_ptr)
6 End If
7
8 Marshal.FreeHGlobal(strImg_ptr)
9 Marshal.FreeHGlobal(rcDraws_ptr)
*I know that the original structure is in either c# or c++ but I can't for the life of me find the equivalent in vb.net.
Thanks guys.
A COLORREF is basically a 32bit integer value. You can define a struct to interact with it like this (see this link for details):
Structure COLORREF
Public R As Byte
Public G As Byte
Public B As Byte
Public Overrides Function ToString() As String
Return String.Format("({0},{1},{2})", R, G, B)
End Function
End Structure
WCHAR* is a pointer to a wide-character string. So you can use String as its data type and add the MarshalAs attribute:
WCHAR* szName
will be
<MarshalAs(UnmanagedType.LPWStr)> szName As String