views:

7019

answers:

5

I am currently developing a piece of software using opencv and qt that plots data points. I need to be able fill in an image from incomplete data. I want to interpolate between the points I have. Can anyone recommend a library or function that could help me. I thought maybe the opencv reMap method but I can't seem to get that to work.

The data is a 2-d matrix of intensity values. I want to create an image of some sort. Its a school project.

+3  A: 

Phew! Big subject.

The "right" answer depends a lot on your problem domain and various details of what you're doing.

Interpolating in more than 1 dimension requires making some choices. I'll assume that you are plotting on a regular grid, but that some of your grid points have no data. Big question: are the missing points sparse, or do they make big blobs?

You can't add information, so you're just trying to establish something that will look OK.

Conceptually simple suggestion (but the implementation may be some work):

For each region on missing data, identify all the edge points. That is find the x's in this figure

oooxxooo
oox..xoo 
oox...xo
ox..xxoo
oox.xooo
oooxoooo

where the .'s are the points missing data, and the x's and o's have data (for a single missing point, this will be the four nearest neighbors). Fill in each missing data point with an average over the edge points around this blob. To make it smooth, weight each point by 1/d where d is the taxidriver distance (delta x + delta y) between the two points..


From before we had any details:

In the absence of that kind of information, have you tried straight ahead linear interpolation? If your data is reasonably dense this might do it for you, and it is simple enough to code in-line when you need it.

Next step is usually a cubic spline, but for that you'll probably want to grab an existing implementation.


When I need something more powerful than a quick linear interpolation, I usually use ROOT (and pick one of the TSpline classes), but this may be more overhead than you need.

As noted in the comments, ROOT is big, and while it is fast, it does try to force you to do things the ROOT way, so it can have a big effect on your program.


A linear interpolation between (or indeed extrapolation from) two points (x1, y1) and (x2, y2) gives you

 y_i = (x_i-x1)*(y2-y1)/(x2-x1)
dmckee
Root is an UNHOLY amount of overhead. And doesn't most of it have to be run through the interpreter rather than actually being compiled?
James Matta
Lots of overhead: yes. Need to use cint: no (I prefer to compile stuff against it). And I'm a particle physicist, so I already have it installed and know it well...
dmckee
Your answer is pretty much exactly what I'm looking for, but i would rather not implement it myself, is there a c++ library that i could use to get this kind of result?
Sam
I don't know of one, but this isn't a task that I have to handle very often...
dmckee
+1  A: 

Are you sure you need to interpolate and not smooth the data using an approximation curve? Assuming a sequential connectivity of the data, like a time signal. Without any prior knowledge of the nature of the data a linear interpolation is the best in many ways.

A linear interpolation though is not smooth. How smooth should the interpolant be, i.e. how differentiable? A cubic interpolant has continuous derivatives up to the second derivative. For a linear function F(), only F() itself is continuous, none of its' derivatives.

What about the end points, if there are any? Do you want the data to connect to any other data? If so, how smoothly?

jeffD
A: 

if I understand that your need is as follows.

I think you have a subset of x,y,Intensity for a dimension of L by W and you want to fill for all X ranging from 0 to L and Y ranging from 0 to W.

If this is your question, then solution is to get other intensities by using Filters.

I think Bayer filter or Gaussian filter would do the job for you.

You can google these filters and you will get answers to implement.

Best of luck.

lakshmanaraj
+3  A: 

Interpolation is a complex subject. There are infinitely many ways to interpolate a set of points, and this assuming that you truly do wish to do interpolation, and not smoothing of any sort. (An interpolant reproduces the original data points exactly.) And of course, the 2-d nature of this problem makes things more difficult.

There are several common schemes for interpolation of scattered data in 2-d. Actually, for those who have access to it, a very nice paper is available (Richard Franke, "Scattered data interpolation: Tests of some methods", Mathematics of Computation, 1982.)

Perhaps the most common method used is based on a triangulation of your data. Merely build a triangulation of the domain from your data points. Then any point inside the convex hull of the data must lie inside exactly one of the triangles, or it will be on a shared edge. This allows you to interpolate linearly inside the triangle. If you are using MATLAB, then the function griddata is available for this express purpose.)

The problem when trying to populate a complete rectangular image from scattered points is that very likely the data does not extend to the 4 corners of the array. In that event, a triangulation based scheme will fail, since the corners of the array do not lie inside the convex hull of the scattered points. An alternative then is to use "radial basis functions" (often abbreviated RBF). There are many such schemes to be found, including Kriging, when used by the geostatistics community.

http://en.wikipedia.org/wiki/Kriging

Finally, inpainting is the name for a scheme of interpolation where elements are given in an array, but where there are missing elements. The name obviously refers to that done by an art conservator who needs to repair a tear or rip in a valuable piece of artwork.

http://en.wikipedia.org/wiki/Inpainting

The idea behind inpainting is typically to formulate a boundary value problem. That is, define a partial differential equation on the region where there is a hole. Using the known boundary values, fill in the hole by solving the PDE for the unknown elements. This can be computationally intensive if there are a huge number of unknown elements, since it typically requires the solution of at least a massive sparse system of linear equations. If the PDE is a nonlinear one, then it becomes a more intensive problem yet. A simple, reasonably good choice for the PDE is the Laplacian, which results in a linear system that extrapolates well. Again, I can offer a solution for a MATLAB user.

http://www.mathworks.com/matlabcentral/fileexchange/4551

Better choices for the PDE may come from nonlinear PDEs. Once such is the Navier/Stokes equation. It is well suited to modeling the types of surfaces typically seen, but it is also more difficult to deal with. As in many facets of life, you get what you pay for.

woodchips
A: 

Considering this is a simple school project, probably the easiest interpolation technique to implement is the "Nearest Neighbors"

For each missing data point you find the nearest "filled" data point and use that as the value.

If you want to improve the retults a little bit more, then you can lets say, find K nearest data points, and use their weighted average as the value of your missing data point.

the weight could be proportional to the distance of the point from the missing data point.

There are zillion other techniques, but nearest neighbor is probably the easiest to implement.

Yogi