Miguel,If you are trying to use automatic differentiation (which would be the reason to use the templated functor),then you cannot convert to double. Everything has to be done in terms of the type T, because this functor willbe evaluated using doubles and Jets to evaluate the derivatives automatically.The right thing to do here is to sayT yaw = x[3]Sameer
--
--
----------------------------------------
Ceres Solver Google Group
http://groups.google.com/group/ceres-solver?hl=en?hl=en
----------------------------------------
Ceres Solver Google Group
http://groups.google.com/group/ceres-solver?hl=en?hl=en
Hi Miguel,Sorry about my slow reply. I have integrated Ceres into Blender (www.blender.org) for motion tracking. There, I use mixed auto/numeric diff. I have some patches in the Blender fork of Ceres that will help with this. I am planning on adding this to upstream Ceres but haven't had time to do it yet and it probably won't make it into the 1.2.2 release tonight.Here's the Blender planar tracker, which relies on Ceres. Search for "Chain::Rule" to see the mixing of numeric/automatic derivatives:http://projects.blender.org/scm/viewvc.php/branches/soc-2011-tomato/extern/libmv/libmv/tracking/track_region.cc?view=markup&root=bf-blender
You can see the use of "Chain::Rule" that I placed in jet.h (not in upstream). Search for "ArgumentType" to find it.These need to get ported into Ceres proper, with better names and some other fixes.Let me know if you have further questions.Keir
On Sat, Jun 16, 2012 at 10:25 AM, Sameer Agarwal <sameer...@google.com> wrote:
Hi Miguel
,Instead of defining a functor, define a subclass of CostFunction instead.In that class you will be responsible for computing the derivatives, but you can use jets yourself and compute the derivatives using them. In that class you can cache whatever information you want.Keir may have some more suggestions. He has been playing with image derivatives and mixing automatic and numeric differentiation.Sameer
On Sat, Jun 16, 2012 at 3:33 AM, Miguel Algaba <miguel.algaba.borrego@gmail.com> wrote:
Hi again, I am trying to transform an image of double numbers into a matrix of numbers of type T so that I can apply auto-diferentiation (the idea I described in my previous comments). I have tried to use the Eigen::Matrix<T,480,640> type to represent an image of Jet numbers, but I would like to transform the image into the matrix representation only once and not each time the () operator is called. Can you give me some hints/recommendations to do this?Thanks in advance and best regards,Miguel Algaba.
The image is essentially a 2D (sampled) function whose derivatives are unkown 'a priori'. So, we need to compute and propagate the image gradients to 'substitute' the image derivatives with the image numerical gradients. This way we can compute Jet-error-functions that depend on non-Jet-functions (images for example) chaining the Jet-functions derivatives with a Jet representation of the numerical derivatives of the non-Jet-functions.
Now going back to my case; each pixel residual is calculated this way (in my previous post I wrote the error function in a wrong way)
T point3D[4] = obtain3DPointFromDepthImage(imgDepth0(i,j)) //3D point in homogeneous coordinates of first image [imgDepth0]
T warpedPoint3D[4] = Rt * point3D //Rt is a 4x4 translation and rotation matrix that depends on the (x,y,z,yaw,pitch,roll) state vector
T warpedPoint2D[2] = project3DPointTo2D(warpedPoint3D) //simply computes the projected 2D coordinates of the 3D point to the image plane
e(i,j) = imgIntensity1(warpedPoint2D[0], warpedPoint2D[1]) - imgIntensity0(i,j)
The warpedPoint2D depends on the (x,y,z,yaw,pitch,roll) state vector, so I have to compute its coordinates into an array of type T so the auto-diff can compute the derivatives of warpedPoint2D with respect to each parameter. Then, I have to compute the image numerical gradients and chain them to the warpedPoint2D derivatives to have a Jet representation of the whole error function.
// Sample the image at position (x, y) but use the gradient, if present, to
// propagate derivatives from x and y. This is needed to integrate the numeric
// image gradients with Ceres's autodiff framework.
template<typename T>
static T SampleWithDerivative(const FloatImage &image_and_gradient,
const T &x,
const T &y) {
float scalar_x = JetOps<T>::GetScalar(x);
float scalar_y = JetOps<T>::GetScalar(y);
// Note that sample[1] and sample[2] will be uninitialized in the scalar
// case, but that is not an issue because the Chain::Rule below will not read
// the uninitialized values.
float sample[3];
if (JetOps<T>::IsScalar()) {
// For the scalar case, only sample the image.
sample[0] = SampleLinear(image_and_gradient, scalar_y, scalar_x, 0);
} else {
// For the derivative case, sample the gradient as well.
SampleLinear(image_and_gradient, scalar_y, scalar_x, sample);
}
T xy[2] = { x, y };
return Chain<float, 2, T>::Rule(sample[0], sample + 1, xy);
}This does the sampling in the same way you need; e.g.Hi Miguel,
Wow! I wasn't expecting you to go to all the trouble of using libmv; it makes more sense for you to adapt the code to your existing image libraries. It should be straightforward to adapt it to your case.Either way, the libmv in upstream blender is considerably forked from the one on github. I am entirely to blame for this. If you take the sample.h from extern/libmv in blender, that should work. With that said, I don't advise this path; consider instead adapting the algorithms to your data structures.
Keir
Hi again Keir, I'm adapting the algorithms to use my data structures as you suggested me. Now, I'm implementing the image gradients computation, but I don't know exactly which kernel you use to convolve the intensity image. You use Sobel? Scharr? any other more precise?
--
Thanks a lot! Very useful information :)
2012/6/22 Keir Mierle <ke...@google.com>
Hi, running my program Eigen prints an execution error message:
/usr/include/eigen3/Eigen/src/Core/DenseStorage.h:69: Eigen::internal::plain_array<T, Size, MatrixOrArrayOptions, 16>::plain_array() [with T = double, int Size = 6, int MatrixOrArrayOptions = 0]: Assertion `(reinterpret_cast<size_t>(array) & 0xf) == 0 && "this assertion is explained here: " "http://eigen.tuxfamily.org/dox-devel/TopicUnalignedArrayAssert.html" " **** READ THIS WEB PAGE !!! ****"' failed.
I'm not using Eigen variables in my program, so I should be using the auto-diff framework in a wrong way. I imagine this problem is related to the fixed size of the residuals (is has 307200 elements). I have tried to use this constructor AutoDiffCostFunction(CostFunctor* functor, int num_residuals) to specify the number of residuals in runtime, but I must be missing something (it doesn't compile).
are you on a 32bit system or a 64 bit system?There is an issue filed against ceres about 32bit alignment stuff being broken.Eigen is used for implementing automatic differentiation. I am pretty sure thats where the error is coming from.
Sameer
Yes this is going to be a problem.I am going to look into it as soon as I can get my hands on a 32 bit system. Unfortunately I do not have access to one right now :/.I am not sure if the changes in 1.2.2 introduced this problem or its been there for a while.Two things will help me debug this.1. Can you get the stack trace by compiling ceres and your application in debug mode, running it in gdb and reporting the full stack trace back.2. can you check if you get the same error with ceres version 1.2.1 ?Sameer
here is the relevant issue to keep track of
If you wanted to share some results of the optimizations, we'd love to collect them together on a page showing off what people have done with Ceres.
Thanks again,
Keir
That would be fantastic!
Miguel,