PCL Incrementally registering clouds - point-cloud-library

in the provided PCL example for how to incrementally register pairs of clouds with ICP, they describe and show the process.
They register a pair of clouds getting the transformation and an output cloud (but they don't do anything with the output cloud because it is the source cloud transformed to the target cloud). Then they take the source->target transformation and invert it to get the target->source transformation and accumulate it in a global transformation. Next, they apply the target->source transformation on the target cloud to get it into the source form and add the source to it. finally they apply the global transform to transform the transformed target + source.
So my question is, instead of gathering source->target transforms and inverting them, why not do target->source transforms to save inversion and not using output clouds from initial .align() steps?

Related

OpenMDAO generating coloring files twice

I'm wondering if this is correct. Most of the Implicit and Explicit components I have created use the line:
self.declare_coloring(wrt='*', method='cs', tol=1.0E-12, show_sparsity=True)
Then when I get to the file that runs the driver I use:
p.driver.declare_coloring()
And in my /coloring_files directory I have a 'col' and a 'disc' for each component.
coloring_traj_phases_phase0_rhs_col_brakeThrottle.pkl coloring_traj_phases_phase0_rhs_disc_implicitOutputs.pkl
coloring_traj_phases_phase0_rhs_col_implicitOutputs.pkl coloring_traj_phases_phase0_rhs_disc_powerTrain.pkl
coloring_traj_phases_phase0_rhs_col_powerTrain.pkl coloring_traj_phases_phase0_rhs_disc_spin.pkl
coloring_traj_phases_phase0_rhs_col_spin.pkl coloring_traj_phases_phase0_rhs_disc_timeAdder.pkl
coloring_traj_phases_phase0_rhs_col_timeAdder.pkl coloring_traj_phases_phase0_rhs_disc_timeSpace.pkl
coloring_traj_phases_phase0_rhs_col_timeSpace.pkl coloring_traj_phases_phase0_rhs_disc_tracking.pkl
coloring_traj_phases_phase0_rhs_col_tracking.pkl coloring_traj_phases_phase0_rhs_disc_tyreConstraint.pkl
coloring_traj_phases_phase0_rhs_col_tyreConstraint.pkl coloring_traj_phases_phase0_rhs_disc_tyre.pkl
coloring_traj_phases_phase0_rhs_col_tyre.pkl total_coloring.pkl
coloring_traj_phases_phase0_rhs_disc_brakeThrottle.pkl
Are both sets of files needed or am I repeating an operation twice? Also I'm wondering if declaring coloring with the driver is using a method other than CS? I do intent on using the total_coloring.pkl for static coloring.
Dymos can use one of two methods for transcription: The Radau Pseudospectral Method or the high-order GaussLobatto method.
The GaussLobatto method is a two-step process:
The ODE is evaluated at the "discretization" nodes.
The values and rates at the discretization nodes are used to interpolate the state and state rates to the "collocation" nodes.
The ODE is evaluated a second time at the collocation nodes using the interpolated state values from step 2.
The interpolated rates are compared to the rates output by the ODE at the collocation nodes (these are called the defects) - if they're tiny, then the physics are assumed to be accurate.
The Radau transcription follows a similar process, except the collocation nodes are a subset of the discretization nodes, so interpolation isn't necessary, and the ODE only needs to be evaluated once.
If you change your transcription from dymos.GaussLobatto to dymos.Radau, then you'll only have one partial-coloring file for each of your ODE components. Otherwise, both need to have their coloring worked out separately.

IterativeClosestPoint with pcl does not give expected results

I got two point clouds. To match them I try to do a registration with ICP. The point cloud's are not super similar but I want to at least get them very near together.
When using IterativeClosestPoint from the pcl library this works when I use my pointCloud A as a source and pointCloud B as a target. But it doesn't work when I use B as source and A as target. In the latter case it even increases the distance between my both clouds.
Does anyone know what I am doing wrong? Why should there be a difference in performance when changing the source/target?
This is my code:
pcl::IterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> icp;
icp.setInputSource(A);
icp.setInputTarget(B);
icp.setMaximumIterations(50);
icp.setTransformationEpsilon(1e-8);
icp.setEuclideanFitnessEpsilon(1);
icp.setMaxCorrespondenceDistance(0.5); // 50cm
icp.setRANSACOutlierRejectionThreshold(0.03);
icp.align(aligned_model_cloud);
I am happy for any ideas and input.
Edit: here are the two clouds
Cloud A
Cloud B
Update:
I tried my code using Cloud A as source and Cloud A* as target. Where Cloud A* is a copy of Cloud A with just a translation on the x-axis. I did the same experiment with Cloud B and both were able to successfully converge in icp.
But as soon as I use Cloud B as source and Cloud A as target, it doesn't work anymore and converges after moving the cloud only a tiny bit (even the wrong direction). I checked the convergecriteria and found that it is CONVERGENCE_CRITERIA_REL_MSE (when transfromationEpslion is almost zero). I tried reducing the relative MSE with
icp.getConvergeCriteria()->setRelativeMSE(1e-15) but this didn't succeed. When checking the value of the relativeMSE after converging I get something like this: -124034642 which doesn't make any sense at all for me.
Update2: I moved the clouds quite near together first without ICP. When doing this ICP works fine.
Update3: I am doing an FPFH for a first estimation and afterwards ICP. Doing it like this works too.
This question is old and OP has already found a solution, but I'll just explain in case OP and someone find it useful.
First, ICP works by iteratively estimating correspondences between the two clouds and then minimize the overall distances between them. And ICP estimates correspondences using closest point data association (hence the name Iterative Closest Point).
And as you may know, closest neigbor graph is directed. That is to say, if point A has B as its closest neighbor, point B might not have A as its closest neighbor since C is closer to B than A!
Now that ICP uses closest point data association to estimate correspondences between the two clouds, specifying A as source will get a different correspondence set from specifying B. That explains the differences you observed.
Usually the difference is small and you may not notice after ICP. But in your case, I found the two clouds you provided are too different (one is extra large and the other small) and the relation becomes too asymmetric.
If you want to ensure the result is symmetric, you can just change the data association step (PCL might provide the option to do that) to make closest point correspondences come from both cloud (and this is just a variant of the classic ICP. For more information you can see my other answer).

Is the ParMetis generating any information about neighbors of a processor?

I am working on a parallel finite element method on moving meshes.
So I will need to call ParMETIS_V3_AdaptiveRepart from ParMetis to perform re-partitioning every time I re-mesh.
When successful, the function only generates the partitioning information, i.e. the elements on the processors.
However, the neighbors of a process are important as well, in order to construct the ghost layers of a sub-mesh.
So I am wondering if there is any efficient way to get the information about shared (overlapped) entities and neighbors, or does the ParMetis actually provide this information?
ParMetis is the function ParMETIS_V3_AdaptiveRepart does more or less the smae thing as ParMETIS_V3_PartKway
The ouput of ParMETIS_V3_PartKway is part "an array of size equal to the number of locally-stored vertices. Upon successful completion the
partition vector of the locally-stored vertices is written to this array."
It also returns the number of edges that are cut. (which is only a part of what you want).
But METIS does not provide a way to create the "ghost layers" as you elegantly say.
However since you have the created the graph you know how to find each neighbour for each element. And you can check if your neighbour element is in your current process's graph and if part[element]==part[neighbour_element]. If the neighbour element is not in your current process you will have to do a bit of MPI.

In chainer, How to write BPTT updater using multiple GPUs?

I don't find example because existing example only extends training.StandardUpdater, thus only use One GPU.
I assume that you are talking about the BPTTUpdater of the ptb example of Chainer.
It's not straight forward to make the customized updater support learning on multiple GPUs. The MultiprocessParallelUpdater hard code the way to compute the gradient (only the target link implementation is customizable), so you have to copy the overall implementation of MultiprocessParallelUpdater and modify the gradient computation parts. What you have to copy and edit is chainer/training/updaters/multiprocess_parallel_updater.py.
There are two parts in this file that compute gradient; one in _Worker.run, which represents a worker process task, and the other in MultiprocessParallelUpdater.update_core, which represents the master process task. You have to make these code do BPTT by modifying the code starting from _calc_loss to backward in each of these two parts:
# Change self._master into self.model for _Worker.run code
loss = _calc_loss(self._master, batch)
self._master.cleargrads()
loss.backward()
It should be modified by inserting the code of BPTTUpdater.update_core.
You also have to take care on the data iterators. MultiprocessParallelUpdater accept the set of iterators that will be distributed to master/worker processes. Since the ptb example uses a customized iterator (ParallelSequentialIterator), you have to make sure that these iterators iterate over different portions of the dataset or using different initial offsets of word positions. It may require customization to ParalellSequentialIterator as well.

Cheat sheet for caffe / pycaffe?

Does anyone know whether there is a cheat sheet for all important pycaffe commands?
I was so far using caffe only via Matlab interface and terminal + bash scripts.
I wanted to shift towards using ipython and work through the ipython notebook examples. However I find it hard to get an overview of all the functions that are inside the caffe module for python. (I'm also quite new to python).
The pycaffe tests and this file are the main gateway to the python coding interface.
First of all, you would like to choose whether to use Caffe with CPU or GPU. It is sufficient to call caffe.set_mode_cpu() or caffe.set_mode_gpu(), respectively.
Net
The main class that the pycaffe interface exposes is the Net. It has two constructors:
net = caffe.Net('/path/prototxt/descriptor/file', caffe.TRAIN)
which simply create a Net (in this case using the Data Layer specified for training), or
net = caffe.Net('/path/prototxt/descriptor/file', '/path/caffemodel/weights/file', caffe.TEST)
which creates a Net and automatically loads the weights as saved in the provided caffemodel file - in this case using the Data Layer specified for testing.
A Net object has several attributes and methods. They can be found here. I will cite just the ones I use more often.
You can access the network blobs by means of Net.blobs. E.g.
data = net.blobs['data'].data
net.blobs['data'].data[...] = my_image
fc7_activations = net.blobs['fc7'].data
You can access the parameters (weights) too, in a similar way. E.g.
nice_edge_detectors = net.params['conv1'].data
higher_level_filter = net.params['fc7'].data
Ok, now it's time to actually feed the net with some data. So, you will use backward() and forward() methods. So, if you want to classify a single image
net.blobs['data'].data[...] = my_image
net.forward() # equivalent to net.forward_all()
softmax_probabilities = net.blobs['prob'].data
The backward() method is equivalent, if one is interested in computing gradients.
You can save the net weights to subsequently reuse them. It's just a matter of
net.save('/path/to/new/caffemodel/file')
Solver
The other core component exposed by pycaffe is the Solver. There are several types of solver, but I'm going to use only SGDSolver for the sake of clarity. It is needed in order to train a caffe model.
You can instantiate the solver with
solver = caffe.SGDSolver('/path/to/solver/prototxt/file')
The Solver will encapsulate the network you are training and, if present, the network used for testing. Note that they are usually the same network, only with a different Data Layer. The networks are accessible with
training_net = solver.net
test_net = solver.test_nets[0] # more than one test net is supported
Then, you can perform a solver iteration, that is, a forward/backward pass with weight update, typing just
solver.step(1)
or run the solver until the last iteration, with
solver.solve()
Other features
Note that pycaffe allows you to do more stuff, such as specifying the network architecture through a Python class or creating a new Layer type.
These features are less often used, but they are pretty easy to understand by reading the test cases.
Please note that the answer by Flavio Ferrara has a litte problem which may cause you waste a lot of time:
net.blobs['data'].data[...] = my_image
net.forward()
The code above is noneffective if your first layer is a Data type layer, because when net.forward() is called, it will begin from the first layer, and then your inserted data my_image will be covered. So it will show no error but give you totally irrelevant output. The correct way is to assign the start and end layer, for example:
net.forward(start='conv1', end='fc')
Here is a Github repository of Face Verification Experiment on LFW Dataset, using pycaffe and some matlab code. I guess it could help a lot, especially the caffe_ftr.py file.
https://github.com/AlfredXiangWu/face_verification_experiment
Besides, here are some short example code of using pycaffe for image classification:
http://codrspace.com/Jaleyhd/caffe-python-tutorial/
http://prog3.com/sbdm/blog/u011762313/article/details/48342495

Resources