I am trying to use cv::Rodrigues function in order to get a rotation matrix from a given vector of angles.
I already have these includes in my program:
#include "opencv2/video/tracking.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/videoio/videoio.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/core.hpp"
Without adding #include "opencv2/calib3d.hpp" everything compiles just fine.
But when I add it in order to be able to use cv::Rodrigues the compilation fails with many errors.
I won't add the whole error log because it will be long and useless. But it starts with this:
<command-line>:0:9: error: expected identifier before numeric constant
<command-line>:0:9: error: expected '}' before numeric constant
<command-line>:0:9: error: expected unqualified-id before numeric constant
And after that I have many error such as :
/usr/local/include/opencv2/features2d.hpp:1106:69: error: expected primary-expression before 'int'
const Scalar& color=Scalar::all(-1), int flags=DrawMatchesFlags::DEFAULT );
^
/usr/local/include/opencv2/features2d.hpp:1130:32: error: variable or field 'drawMatches' declared void
CV_EXPORTS_W void drawMatches( InputArray img1, const std::vector<KeyPoint>& keypoints1,
^
/usr/local/include/opencv2/features2d.hpp:1130:32: error: 'InputArray' was not declared in this scope
For completeness here is the part of the code that I would like to add:
void test(cv::Matx33f& rot_mat){
float x = 50 * (M_PI/180);
float y = -10 * (M_PI/180);
float z = 0 * (M_PI/180);
cv::Matx31f rot_vec(x,y,z);
//converts to a rotation matrix
cv::Rodrigues(rot_vec, rot_mat);
}
Note: I am working on Ubuntu 15.10 with OpenCV 3.1.0 and I did add -lopencv_calib3d to my makefile.
Related
I am trying to get a TensorFlow Lite example to run on a machine with an ARM Cortex-A72 processor. Unfortunately, I wasn't able to deploy a test model due to the lack of examples on how to use the C++ API. I will try to explain what I have achieved so far.
Create the tflite model
I have created a simple linear regression model and converted it, which should approximate the function f(x) = 2x - 1. I got this code snippet from some tutorial, but I am unable to find it anymore.
import tensorflow as tf
import numpy as np
from tensorflow import keras
from tensorflow.contrib import lite
model = keras.Sequential([keras.layers.Dense(units=1, input_shape=[1])])
model.compile(optimizer='sgd', loss='mean_squared_error')
xs = np.array([ -1.0, 0.0, 1.0, 2.0, 3.0, 4.0], dtype=float)
ys = np.array([ -3.0, -1.0, 1.0, 3.0, 5.0, 7.0], dtype=float)
model.fit(xs, ys, epochs=500)
print(model.predict([10.0]))
keras_file = 'linear.h5'
keras.models.save_model(model, keras_file)
converter = lite.TocoConverter.from_keras_model_file(keras_file)
tflite_model = converter.convert()
open('linear.tflite', 'wb').write(tflite_model)
This creates a binary called linear.tflite, which I should be able to load.
Compile TensorFlow Lite for my machine
TensorFlow Lite comes with a script for the compilation on machines with the aarch64 architecture. I followed the guide here to do this, even though I had to modify the Makefile slightly. Note that I compiled this natively on my target system. This created a static library called libtensorflow-lite.a.
Problem: Inference
I tried to follow the tutorial on the site here, and simply pasted the the code snippets from loading and running the model together, e.g.
class FlatBufferModel {
// Build a model based on a file. Return a nullptr in case of failure.
static std::unique_ptr<FlatBufferModel> BuildFromFile(
const char* filename,
ErrorReporter* error_reporter);
// Build a model based on a pre-loaded flatbuffer. The caller retains
// ownership of the buffer and should keep it alive until the returned object
// is destroyed. Return a nullptr in case of failure.
static std::unique_ptr<FlatBufferModel> BuildFromBuffer(
const char* buffer,
size_t buffer_size,
ErrorReporter* error_reporter);
};
tflite::FlatBufferModel model("./linear.tflite");
tflite::ops::builtin::BuiltinOpResolver resolver;
std::unique_ptr<tflite::Interpreter> interpreter;
tflite::InterpreterBuilder(*model, resolver)(&interpreter);
// Resize input tensors, if desired.
interpreter->AllocateTensors();
float* input = interpreter->typed_input_tensor<float>(0);
// Fill `input`.
interpreter->Invoke();
float* output = interpreter->typed_output_tensor<float>(0);
When trying to compile this via
g++ demo.cpp libtensorflow-lite.a
I get a load of errors. Log:
root#localhost:/inference# g++ demo.cpp libtensorflow-lite.a
demo.cpp:3:15: error: ‘unique_ptr’ in namespace ‘std’ does not name a template type
static std::unique_ptr<FlatBufferModel> BuildFromFile(
^~~~~~~~~~
demo.cpp:10:15: error: ‘unique_ptr’ in namespace ‘std’ does not name a template type
static std::unique_ptr<FlatBufferModel> BuildFromBuffer(
^~~~~~~~~~
demo.cpp:16:1: error: ‘tflite’ does not name a type
tflite::FlatBufferModel model("./linear.tflite");
^~~~~~
demo.cpp:18:1: error: ‘tflite’ does not name a type
tflite::ops::builtin::BuiltinOpResolver resolver;
^~~~~~
demo.cpp:19:6: error: ‘unique_ptr’ in namespace ‘std’ does not name a template type
std::unique_ptr<tflite::Interpreter> interpreter;
^~~~~~~~~~
demo.cpp:20:1: error: ‘tflite’ does not name a type
tflite::InterpreterBuilder(*model, resolver)(&interpreter);
^~~~~~
demo.cpp:23:1: error: ‘interpreter’ does not name a type
interpreter->AllocateTensors();
^~~~~~~~~~~
demo.cpp:25:16: error: ‘interpreter’ was not declared in this scope
float* input = interpreter->typed_input_tensor<float>(0);
^~~~~~~~~~~
demo.cpp:25:48: error: expected primary-expression before ‘float’
float* input = interpreter->typed_input_tensor<float>(0);
^~~~~
demo.cpp:28:1: error: ‘interpreter’ does not name a type
interpreter->Invoke();
^~~~~~~~~~~
demo.cpp:30:17: error: ‘interpreter’ was not declared in this scope
float* output = interpreter->typed_output_tensor<float>(0);
^~~~~~~~~~~
demo.cpp:30:50: error: expected primary-expression before ‘float’
float* output = interpreter->typed_output_tensor<float>(0);
I am relatively new to C++, so I may be missing something obvious here. It seems, however, that other people have trouble with the C++ API as well (look at this GitHub issue). Has anybody also stumbled across this and got it to run?
The most important aspects for me to cover would be:
1.) Where and how do I define the signature, so that the model knows what to treat as inputs and outputs?
2.) Which headers do I have to include?
Thanks!
EDIT
Thanks to #Alex Cohn, the linker was able to find the correct headers. I also realized that I probably do not need to redefine the flatbuffers class, so I ended up with this code (minor change is marked):
#include "tensorflow/lite/interpreter.h"
#include "tensorflow/lite/kernels/register.h"
#include "tensorflow/lite/model.h"
#include "tensorflow/lite/tools/gen_op_registration.h"
auto model = tflite::FlatBufferModel::BuildFromFile("linear.tflite"); //CHANGED
tflite::ops::builtin::BuiltinOpResolver resolver;
std::unique_ptr<tflite::Interpreter> interpreter;
tflite::InterpreterBuilder(*model, resolver)(&interpreter);
// Resize input tensors, if desired.
interpreter->AllocateTensors();
float* input = interpreter->typed_input_tensor<float>(0);
// Fill `input`.
interpreter->Invoke();
float* output = interpreter->typed_output_tensor<float>(0);
This reduces the number of errors greatly, but I am not sure how to resolve the rest:
root#localhost:/inference# g++ demo.cpp -I/tensorflow
demo.cpp:10:34: error: expected ‘)’ before ‘,’ token
tflite::InterpreterBuilder(*model, resolver)(&interpreter);
^
demo.cpp:10:44: error: expected initializer before ‘)’ token
tflite::InterpreterBuilder(*model, resolver)(&interpreter);
^
demo.cpp:13:1: error: ‘interpreter’ does not name a type
interpreter->AllocateTensors();
^~~~~~~~~~~
demo.cpp:18:1: error: ‘interpreter’ does not name a type
interpreter->Invoke();
^~~~~~~~~~~
How do I have to tackle these? It seems that I have to define my own resolver, but I have no clue on how to do that.
I finally got it to run. Considering my directory structure looks like this:
/(root)
/tensorflow
# whole tf repo
/demo
demo.cpp
linear.tflite
libtensorflow-lite.a
I changed demo.cpp to
#include <stdio.h>
#include "tensorflow/lite/interpreter.h"
#include "tensorflow/lite/kernels/register.h"
#include "tensorflow/lite/model.h"
#include "tensorflow/lite/tools/gen_op_registration.h"
int main(){
std::unique_ptr<tflite::FlatBufferModel> model = tflite::FlatBufferModel::BuildFromFile("linear.tflite");
if(!model){
printf("Failed to mmap model\n");
exit(0);
}
tflite::ops::builtin::BuiltinOpResolver resolver;
std::unique_ptr<tflite::Interpreter> interpreter;
tflite::InterpreterBuilder(*model.get(), resolver)(&interpreter);
// Resize input tensors, if desired.
interpreter->AllocateTensors();
float* input = interpreter->typed_input_tensor<float>(0);
// Dummy input for testing
*input = 2.0;
interpreter->Invoke();
float* output = interpreter->typed_output_tensor<float>(0);
printf("Result is: %f\n", *output);
return 0;
}
Also, I had to adapt my compile command (I had to install flatbuffers manually to make it work). What worked for me was:
g++ demo.cpp -I/tensorflow -L/demo -ltensorflow-lite -lrt -ldl -pthread -lflatbuffers -o demo
Thanks to #AlexCohn for getting me on the right track!
Here is the minimal set of includes:
#include "tensorflow/lite/interpreter.h"
#include "tensorflow/lite/kernels/register.h"
#include "tensorflow/lite/model.h"
#include "tensorflow/lite/tools/gen_op_registration.h"
These will include other headers, e.g. <memory> which defines std::unique_ptr.
I'm trying to use Eigen3 to compute some complex eigenvalues and sofar everything worked, but know I get a weird error:
g++ -I/usr/include/eigen3/ -Icubature/ -I/usr/include/boost/ cubature/hcubature.c main.cpp wavefunction.cpp -o main.x
main.cpp: In function ‘int main(int, char**)’:
main.cpp:103:2: error: ‘ComplexEigenSolver’ was not declared in this scope
ComplexEigenSolver<MatrixXcd> ces;
^~~~~~~~~~~~~~~~~~
main.cpp:103:2: note: suggested alternative:
In file included from /usr/include/eigen3/Eigen/Eigenvalues:35:0,
from /usr/include/eigen3/Eigen/Dense:7,
from main.cpp:4:
/usr/include/eigen3/Eigen/src/Eigenvalues/ComplexEigenSolver.h:45:38: note: ‘Eigen::ComplexEigenSolver’
template<typename _MatrixType> class ComplexEigenSolver
^~~~~~~~~~~~~~~~~~
main.cpp:103:30: error: expected primary-expression before ‘>’ token
ComplexEigenSolver<MatrixXcd> ces;
^
main.cpp:103:32: error: ‘ces’ was not declared in this scope
ComplexEigenSolver<MatrixXcd> ces;
^~~
make: *** [Makefile:2: all] Error 1
Here are my includes:
#include <iostream>
#include <vector>
#include <Eigen/Core>
#include <Eigen/Dense>
#include <Eigen/Eigenvalues>
#include "wavefunction.cpp"
#include "cubature.h"
using Eigen::MatrixXcd;
This is the routine where the error occurs:
MatrixXcd hop(5,5);
for(int m1 = -2; m1 <= 2; m1++){
for(int m2 = -2; m2 <= 2; m2++){
hop(m1+2, m2+2) = ....;
}
}
ComplexEigenSolver<MatrixXcd> ces;
Everything works fine, only the last line doesn't work. I don't see the difference between my code and the example given at the Eigen website.
What am I doing wrong?
Following code:
#include <iostream>
#include <armadillo>
using namespace std;
using namespace arma;
int main()
{
sp_mat A = speye<sp_mat>(5,5);
rowvec s1 = max(A,0);
return 0;
}
gives the following compile time error:
benchmark.cpp: In function ‘int main()’:
benchmark.cpp:11:21: error: conversion from ‘arma::enable_if2<true, const arma::SpOp<arma::SpMat<double>, arma::spop_max> >::result {aka const arma::SpOp<arma::SpMat<double>, arma::spop_max>}’ to non-scalar type ‘arma::rowvec {aka arma::Row<double>}’ requested
rowvec s1 = max(A,0);
^
make: *** [all] Error 1
Same for min, sum and other operations on sparse matrices, while they work perfectly well for dense matrices.
Am I doing something wrong here?
The max operation on a sparse matrix will result in a sparse matrix.
Change your code to:
sp_mat A = speye<sp_mat>(5,5);
sp_mat s1 = max(A,0);
To calculate the sum of each row, I've used matrix multiplication:
sp_mat A = sprandu<sp_mat>(5, 5);
mat sumRows = A * ones(A.n_cols, 1);
I'm trying to compile the examples found here:
http://www.netlib.org/lapack/lapacke.html#_examples
Specifically, I'm trying to get the "Calling CGEQRF and the CBLAS" example to work. The code is like so:
#include <stdio.h>
#include <stdlib.h>
#include <lapacke.h>
#include <cblas.h>
int main (int argc, const char * argv[])
{
lapack_complex_float *a,*tau,*r,one,zero;
lapack_int info,m,n,lda;
int i,j;
float err=0.0;
m = 10; n = 5; lda = m;
one = lapack_make_complex_float(1.0,0.0);
zero= lapack_make_complex_float(0.0,0.0);
a = calloc(m*n,sizeof(lapack_complex_float));
r = calloc(n*n,sizeof(lapack_complex_float));
tau = calloc(m,sizeof(lapack_complex_float));
for(j=0;j<n;j++)
for(i=0;i<m;i++)
a[i+j*m] = lapack_make_complex_float(i+1,j+1);
info = LAPACKE_cgeqrf(LAPACK_COL_MAJOR,m,n,a,lda,tau);
info = LAPACKE_cungqr(LAPACK_COL_MAJOR,m,n,n,a,lda,tau);
for(j=0;j<n;j++)
for(i=0;i<n;i++)
r[i+j*n]=(i==j)?-one:zero;
cblas_cgemm(CblasColMajor,CblasConjTrans,CblasNoTrans,
n,n,m,&one,a,lda,a,lda,&one,r,n );
for(i=0;i<n;i++)
for(j=0;j<n;j++)
err=MAX(err,cabs(r[i+j*n]));
printf("error=%e\n",err);
free(tau);
free(r);
free(a);
return(info);
}
If I save the file as a .cpp (perhaps this is my first mistake?) and compile using
g++ lapacketest.cpp -llapack
I get the following compile errors:
3_20_2.cpp:14:7: error: assigning to '_Complex float *' from incompatible type 'void *'
a = calloc(m*n,sizeof(lapack_complex_float));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3_20_2.cpp:15:7: error: assigning to '_Complex float *' from incompatible type 'void *'
r = calloc(n*n,sizeof(lapack_complex_float));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3_20_2.cpp:16:9: error: assigning to '_Complex float *' from incompatible type 'void *'
tau = calloc(m,sizeof(lapack_complex_float));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3_20_2.cpp:29:25: error: use of undeclared identifier 'cabs'
err=MAX(err,cabs(r[i+j*n]));
I tried changing to .c and compiling with gcc, but I got other strange errors. Any thoughts? I'm slowly trying transition from Matlab to c++ for scientific computing and so far it's just been a giant headache.
It looks like calloc(m*n,sizeof(lapack_complex_float)); is not returning a pointer to an object of type lapack_complex_float.
I could compile it but you have to change the line
#include <lapacke.h>
to
#include <lapacke_utils.h>
You find at http://www.netlib.org/lapack/explore-html/da/d8e/lapacke__utils_8h_source.html. After you download it and put in the same directory of your program or use the tags -L -I to locate the library on your system during the compilation.
To compile use:
gcc CGEQRF_CUNGQR.c -llapacke -lblas -lm
I'm trying to write a simple program to calculate numerical approximations with Euler's method and every complier I've used hasn't printed anything. Codeblocks is running an error but I think that is because the compiler isn't set up right. xCode will build it but nothing happens. When I run g++ Euler.cpp I get:
Euler.cpp:1: error: expected constructor, destructor, or type conversion before ‘<’ token
Euler.cpp: In function ‘int main()’:
Euler.cpp:13: error: ‘cin’ was not declared in this scope
Euler.cpp:19: error: ‘cout’ was not declared in this scope
Euler.cpp:19: error: ‘endl’ was not declared in this scope
I usually never have problems with simple c++ programs and fear it's something very obvious.
//
// Euler.cpp
// Numerical Approximations (Euler's Method)
//
// Created by XXXXXXXXXXXX on 6/18/12.
// Copyright (c) 2012 University of Kansas Department of Mathematics. All rights reserved.
//
#include <iostream>
using namespace std;
int main ()
{
int N=4;
//cout<<"Number of steps (N):";
//cin>>t;
float h=0.1;
//cout<<endl<<" Step size (h):";
cin>>h;
float y0=1;
//cout<<endl<<"y(0)=";
//cin>>y0;
cout<<"test!"<<endl;
float data[N][4];
int n=0;
data[0][2] = y0;
while (n<N){
data[n][0]=n;
if(n>0){
data[n][2]=data[n-1][3];
}
data[n][1]=h*n;
data[n][3] = data[n][2] + ((3 + data[n][1] - data[n][2])*h);
n++;
cout<<"n="<<n<<". tn="<<data[n][1]<<". y(n)="<<data[n][2]<<". y(n+1)="<<data[n][3] <<"."<<endl;
}
return 0;
}
It's probably something obvious but I don't see it.
It's not finding the iostream header. Do you see an error message reading something like "couldn't find header iostream" ?