7

I have photo images of galaxies. There are some unwanted data on these images (like stars or aeroplane streaks) that are masked out. I don't just want to fill the masked areas with some mean value, but to interpolate them according to surrounding data. How do i do that in python?

We've tried various functions in SciPy.interpolate package: RectBivariateSpline, interp2d, splrep/splev, map_coordinates, but all of them seem to work in finding new pixels between existing pixels, we were unable to make them fill arbitrary "hole" in data.

Michas
  • 8,534
  • 6
  • 38
  • 62
miceuz
  • 3,327
  • 5
  • 29
  • 33
  • 9
    Launch two or more probes into space in different directions. After their view is no longer obstructed by the object blocking your view from the Earth, have them take a picture of the section of space you are interested in. By combining the pictures with some form of interpolation, you can get a very good approximation of what that section of space would look like from the Earth if the view wasn't blocked. – Swiss Feb 28 '12 at 08:11
  • @Swiss lol... seriuosly? – neizod Feb 28 '12 at 08:13
  • 2
    @Swiss - post that as answer, if it gets accepted you'll be an internet hero forever. – Gleno Feb 28 '12 at 08:16
  • This might not be what you want but nearest neighbor interpolation can be done in two lines with scipy: see [this post](http://stackoverflow.com/questions/5551286/filling-gaps-in-a-numpy-array/9262129#9262129) for details. – Juh_ Aug 28 '13 at 13:04

3 Answers3

8

What you want is called Inpainting.
OpenCV has an inpaint() function that does what you want.

Adi Shavit
  • 16,743
  • 5
  • 67
  • 137
  • thanks for the right keyword - inpaint. openCV might not be the best option as astronomical images are 64bit - per pixel, when openCV allows 1 channel 8bit or 3 channel 8bit images (max 24bit per pixel). I've found a simple implementation of inpainting: https://github.com/gasagna/openpiv-python/blob/master/openpiv/src/lib.pyx – miceuz Feb 28 '12 at 09:31
  • @miceuz Mathematica has an Inpaint function which can operate on double precision images. – Matthias Odisio Feb 28 '12 at 12:51
  • Also see G'MIC for inpainting, http://gmic.eu. I've used it for NO_DATA areas with great success. `gmic -h -inpaint` – RobLabs Oct 17 '16 at 02:54
  • As @miceuz mentioned, the OpenCV version requires an 8 bit value. I tried converting my float 32 data set to 8bit using `cv2.convertScaleAbs`, but I'm not sure how to reconvert it back to the float32 or remap the filled in holes back into the original float 32 data. – CMCDragonkai Mar 20 '17 at 13:09
2

What you want is not interpolation at all. Interpolation depends on the assumption that data between known points is roughly contiguous. In any non-trivial image, this will not be the case.

You actually want something like the content-aware fill that is in Photoshop CS5. There is a free alternative available in The GIMP through the GIMP-resynthesize plugin. These filters are extremely advanced and to try to re-implement them is insane. A better choice would be to figure out how to use GIMP-resynthesize in your program instead.

Swiss
  • 5,556
  • 1
  • 28
  • 42
  • 4
    Actually, resynthesize was there before, so it's "there is a paying alternative available in CS5 via the content-aware fill"... – Kheldar Feb 28 '12 at 08:35
1

I made my first gimp python script that might help you: my scripts

It is called conditional filter as it is a matrix filter that fill all transparent pixels from an image according to the mean value of its 4 nearest neighbours that are not transparent. Be sure to use a RGBA image with only 0 and 255 transparent values.

Its is rough, simple, slow, unoptimized but bug free.

Christian
  • 11
  • 1