Conduct AngleAxisToRotationMatirx on part of a double arrray in Ceres? - eigen3

Nowadays I'm working with Ceres and Eigen. And I have a 6x3 = 18-d double array, let's call it xs, which is defined as:
double xs[6*3];
Basically xs contains the 6 rotations expressed in angle-axis format. And I need to turn each rotation of all 6 into rotation matrix format, then matrix multiplication will be conducted.
struct F1 {
template <typename T> bool operator()(const T* const xs,
T* residual) const {
Eigen::Map<const Eigen::Matrix<T,3,1> > m0(xs, 3);
T m[9], res[3];
ceres::AngleAxisToRotationMatrix(m0, m);
residual[0] = res[0];
residual[1] = res[1];
residual[2] = res[2];
}
Here in the example code I extract first 3 elements of xs via Eigen::Map, then I applied AngleAxisToRotationMatrix on it. But I keep receiving such errors:
error: no matching function for call to ‘AngleAxisToRotationMatrix(Eigen::Map<const Eigen::Matrix<ceres::Jet<double, 18>, 3, 1, 0, 3, 1>, 0, Eigen::Stride<0, 0> >&, ceres::Jet<double, 1> [9])’
Can somebody lend me a hand here? I'm pretty new to Ceres and Eigen, it really drove me almost to crazy.
Thanks!

ceres::AngleAxisToRotationMatrix expects raw pointers:
AngleAxisToRotationMatrix(xs, m);

Related

How to create an Eigen::Ref to a fixed-sized matrix row?

I would like to write something like foo4 similar to foo3 in the Eigen::Ref doc here :
#include <Eigen/Dense>
using namespace Eigen;
void foo3(Ref<VectorXf, 0, Eigen::InnerStride<> >){};
void foo4(Ref<Vector3f, 0, Eigen::InnerStride<> >){};
int main()
{
Eigen::Matrix3f fmat = Eigen::Matrix3f::Identity();
Eigen::MatrixXf dmat = Eigen::Matrix3f::Identity();
foo3(dmat.row(1)); // OK
foo3(fmat.row(1)); // Error : YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES
foo4(fmat.row(1)); // Error : YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES
}
I'm using Eigen version 3.3.7
You are getting size-mismatch errors, because you are trying to pass row-vectors where column vectors are expected.
There are two solutions:
Change the function to accept row-vectors:
void foo3(Ref<RowVectorXf, 0, Eigen::InnerStride<> >){};
void foo4(Ref<RowVector3f, 0, Eigen::InnerStride<> >){};
Explicitly transpose the vector you pass to the function:
foo3(fmat.row(1).transpose());
foo4(fmat.row(1).transpose());
Note that there are some cases where Eigen implicitly transposes row-vectors to column-vectors (like the following example). But generally, I would not rely on that and always explicitly transpose vectors to match the orientation:
Eigen::MatrixXd A(rows,cols);
Eigen::VectorXd v1 = A.row(0); // this works
Eigen::VectorXd v2 = A.row(0).transpose(); // more verbose, but what actually happens

Running Tensorflow session produces an empty tensor

I am trying to use the Tensorflow C API to run a session with the Deeplab graph. The frozen graph of Deeplab, pre-trained on Cityscapes, was downloaded from here:
http://download.tensorflow.org/models/deeplabv3_mnv2_cityscapes_train_2018_02_05.tar.gz
When I run with python, I get this segmentation output:
By printing out all of the graph's tensors via the python line: tensors = [n.values() for n in tf.get_default_graph().get_operations()]
, I found out that the dimensions of the input tensor are {1,?,?,3}, and the output tensor are {1,?,?}, and the data types of the input and output tensors are uint8 and int64, respectively. I used this information to write a C++ method to run the graph session:
int Deeplab::run_segmentation(image_t* img, segmap_t* seg) {
using namespace std;
// Allocate the input tensor
TF_Tensor* const input = TF_NewTensor(TF_UINT8, img->dims, 4, img->data_ptr, img->bytes, &free_tensor, NULL);
TF_Operation* oper_in = TF_GraphOperationByName(graph, "ImageTensor");
const TF_Output oper_in_ = {oper_in, 0};
// Allocate the output tensor
TF_Tensor* output = TF_NewTensor(TF_INT64, seg->dims, 3, seg->data_ptr, seg->bytes, &free_tensor, NULL);
TF_Operation* oper_out = TF_GraphOperationByName(graph, "SemanticPredictions");
const TF_Output oper_out_ = {oper_out, 0};
// Run the session on the input tensor
TF_SessionRun(session, nullptr, &oper_in_, &input, 1, &oper_out_, &output, 1, nullptr, 0, nullptr, status);
return TF_GetCode(status); // https://github.com/tensorflow/tensorflow/blob/master/tensorflow/c/tf_status.h#L42
}
Where the argument types image_t and segmap_t contain the parameters needed to call TF_NewTensor. They simply hold the pointers to the allocated buffer for the input/output tensors, the dimensions of the tensors, and the size in bytes:
typedef struct segmap {
const int64_t* dims;
size_t bytes;
int64_t* data_ptr;
} segmap_t;
typedef struct image {
const int64_t* dims;
size_t bytes;
uint8_t* data_ptr;
} image_t;
Then, I used OpenCV to fill an array with the street scene image (same one as above), and passed the image_t and segmap_t structs into the session run method :
// Allocate input image object
const int64_t dims_in[4] = {1, new_size.width, new_size.height, 3};
image_t* img_in = (image_t*)malloc(sizeof(image_t));
img_in->dims = &dims_in[0];
//img_in->data_ptr = (uint8_t*)malloc(new_size.width*new_size.height*3);
img_in->data_ptr = resized_image.data;
img_in->bytes = new_size.width*new_size.height*3*sizeof(uint8_t);
// Allocate output segmentation map object
const int64_t dims_out[3] = {1, new_size.width, new_size.height};
segmap_t* seg_out = (segmap_t*)malloc(sizeof(segmap_t));
seg_out->dims = &dims_out[0];
seg_out->data_ptr = (int64_t*)calloc(new_size.width*new_size.height, sizeof(int64_t));
seg_out->bytes = new_size.width*new_size.height*sizeof(int64_t);
But the resulting tensor (set_out->data_ptr) consisted of all 0s. The graph seemed to execute for about 5 seconds, the same amount of time as the working python implementation. Somehow, the graph is failing to dump the output tensor data in the buffer I allocated. What am I doing wrong?
There were two mistakes:
First, Deeplab's input tensor dimensions are {1, height, width, 3}, and the output tensor dimensions are {1, height, width}. So I had to swap height and width.
Also, for some reason, you have to fetch the data from the tensor with the TF_TensorData method. Creating the output tensor by doing TF_NewTensor(..., data_ptr, ...), then running TF_SessionRun, and finally accessing data_ptr does not work. You have to instead create the output tensor by calling TF_AllocateTensor(...), run TF_SessionRun, and access the tensor data with TF_TensorData(&tensor).

nanopb (Protocol Buffers library) repeated sub-messages encode

we are using the nanopb library as our Protocol Buffers library. We defined the following messages:
simple.proto:
syntax = "proto2";
message repField {
required float x = 1;
required float y = 2;
required float z = 3;
}
message SimpleMessage {
required float lucky_number = 1;
repeated repField vector = 2;
}
with simple.options
SimpleMessage.vector max_count:300
So we know the repField has a fixed size of 300 and thus defining it as such.
Parts of the generated one looks like:
simple.pb.c:
const pb_field_t repField_fields[4] = {
PB_FIELD( 1, FLOAT , REQUIRED, STATIC , FIRST, repField, x, x, 0),
PB_FIELD( 2, FLOAT , REQUIRED, STATIC , OTHER, repField, y, x, 0),
PB_FIELD( 3, FLOAT , REQUIRED, STATIC , OTHER, repField, z, y, 0),
PB_LAST_FIELD
};
const pb_field_t SimpleMessage_fields[3] = {
PB_FIELD( 1, FLOAT , REQUIRED, STATIC , FIRST, SimpleMessage, lucky_number, lucky_number, 0),
PB_FIELD( 2, MESSAGE , REPEATED, STATIC , OTHER, SimpleMessage, vector, lucky_number, &repField_fields),
PB_LAST_FIELD
};
and part of simple.pb.h:
/* Struct definitions */
typedef struct _repField {
float x;
float y;
float z;
/* ##protoc_insertion_point(struct:repField) */
} repField;
typedef struct _SimpleMessage {
float lucky_number;
pb_size_t vector_count;
repField vector[300];
/* ##protoc_insertion_point(struct:SimpleMessage) */
} SimpleMessage;
We try to encode the message by doing:
// Init message
SimpleMessage message = SimpleMessage_init_zero;
pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
// Fill in message
[...]
// Encode message
status = pb_encode(&stream, SimpleMessage_fields, &message);
// stream.bytes_written is wrong!
But the stream.bytes_written is wrong which means it is not encoded correctly, although status=1.
In the documentation for pb_encode() it says:
[...] However, submessages must be serialized twice: first to
calculate their size and then to actually write them to output. This
causes some constraints for callback fields, which must return the
same data on every call.
But, we are not sure how to interpret this sentence - what steps to follow exactly to achieve this.
So our question is:
What is the correct way to encode messages that contain fixed-size (repeated) submessages using the nanopb library?
Thank you!
You're not using callback fields here, so that quote doesn't matter for you. But if you were, it would just mean that in some situations your callback would be called multiple times.
Are you the same person as on the forum? Your stack overflow question does not show it, but the person on the forum has a similar problem that appears to be due to not setting vector_count. Then it will remain as 0 length array. So try adding:
message.vector_count = 300;
In the future, please wait a few days before posting the same question in multiple places. It's a waste of volunteer time to answer the same question multiple times.

making 3d array with arma::cube in Rcpp shows cube error

I am making a Rcpp code for Gibbs sampling. Inside the code, I first want to make a 3 dimensional array with row number= number of iteration (500), column number=number of parameter(4) and slice number= number of chain(3). I wrote it in this way:
#include <RcppArmadillo.h>
#include <math.h>
// [[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;
using namespace std;
using namespace arma;
//Gibbs sampling code starts here
Rcpp::List mcmc(const int iter,const int chains, const NumericVector data){
arma::cube posteriorC = arma::zeros(iter, 5, chains);
\\ rest of the codes
List out(Rcpp::List::create(Rcpp::Named("posteriorC") =posteriorC));
return out;
}
. While compelling it does not show any error. But when I want to run the code with:
res<- mcmc(iter=500,chains=2,data)
it shows the error:
Error: Cube::operator(): index out of bounds
. I want to know if there any mistake while making the 3D array. Please note that I want to get estimates of 5 parameters of my model.
You need to specify the template for arma::zeros to correctly fill an arma::cube, c.f. arma::zeros<template>
Generate a vector, matrix or cube with the elements set to zero
Usage:
vector_type v = zeros<vector_type>( n_elem )
matrix_type X = zeros<matrix_type>( n_rows, n_cols )
matrix_type Y = zeros<matrix_type>( size(X) )
cube_type Q = zeros<cube_type>( n_rows, n_cols, n_slices )
cube_type R = zeros<cube_type>( size(Q) )
Thus, in your case it would be:
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
Rcpp::List mcmc(const int iter, const int chains,
const Rcpp::NumericVector data){
arma::cube posteriorC = arma::zeros<arma::cube>(iter, 5, chains);
// --------------------------------- ^^^^^^^^
// Not Shown
Rcpp::List out = Rcpp::List::create(Rcpp::Named("posteriorC") =posteriorC);
return out;
}
Two final notes:
You explicitly state that the code as it stands now will create 4 columns to store 4 variables. However, you explicitly mention that you needed to estimate 5 parameters. You may need to increase this to prevent an out of bounds when saving into the arma::cube slices.
The way the Rcpp::List out is being created isn't quite correct. In general, the best way to create the list is to do: Rcpp::List out = Rcpp::List::create(Rcpp::Named("Blah"), Blah);

a simpler way to get variables from structs within structs

It's been over a year since I last used C, so I'm pretty much back to basics.
I have this code as part of a larger file:
typedef struct
{
float ix;
float iy;
float iz;
} InitialPosition;
typedef struct
{
InitialPosition init;
} Particle;
void particle()
{
Particle p1 =
{
.init = { .ix = 10, .iy = 10, .iz = 10 },
};
glPointSize(10);
glBegin(GL_POINTS);
glVertex3f(p1.init.ix,p1.init.iy,p1.init.iz);
//glVertex3f( 0, 0, 0 );
glEnd();
}
It works/appears correctly with my particle being plotted onto an axis, but it seems like there must be a quicker way to feed the variables from the struct into the glVertex3f method.
On the off-chance it makes any difference I'm using openGL & glut.
Should I also be using pointers? (If so an example of use would be great.) Like I said it has been a while so any help appreciated.
Functions that take three separate parameters require that you break each value out. If you're going to be using these calls a lot, you have two ways to make it more convenient.
1) make a helper function:
void myglVertexParticle(Particle * apoint) { glVertex3f(init->ix, init->iy, init->iz) ; }
myglVertexParticle( & (p1.init)) ;
2) use an expansion macro:
#define PARTICLE3f(uuu) uuu.ix, uuu.iy, uuu.iz
glVertex3f( PARTICLE3f( p1.init)) ;
Most people are probably going to frown on the second choice from a style point of view, and a good optimizing compiler should make the first case run nearly as quickly as the second.

Resources