5

Let's assume I have a raster image consisting of 0's and several donut-shaped rings of 1's. This raster could for example be the result of classifying a satellite image with ponds and lakes in it into two classes: 1) pond shoreline, pixel value 1 and 2) other, pixel value 0. See image for impression.

Donuts

My challenge is to fill each donut hole, creating full circles with pixel value 1. For this I have access to ArcGIS with all common functionality, as well as ENVI and Python with gdal bindings. See second image for impression of the desired outcome.I guess a majority filter will work to some extent, except when the donut holes are large.

Any suggestions on transforming donuts to circles are welcome. Bonus points for making it work with unclosed donuts as well.

Filled donuts

11

What you are looking for is a Mathematical Morphology application, Closing to be precise.

If you use GDAL to read your image into a numpy array there is a number of libraries that support this operation. scipy.ndimage is one of them and has a function for binary hole filling.

In python for a fictional binary dataset as you outlined this would transform the donuts to circles:

from osgeo import gdal
from scipy.ndimage.morphology import binary_fill_holes

donut_array = gdal.Open("input.tif").ReadAsArray()

filled_array = binary_fill_holes(donut_array, structure=np.ones((3,3)))

This method also works with open donuts, depending on the structure you use for filling. I made a example notebook as a proof of concept and a blog post showing a more real world example.

enter image description here

  • Hi Kersten, thanks for your extensive reply. I'd never heard of Mathematical Morphology before, but it makes for some interesting reading! Will your method work for any donut-hole size? Or should the structure size be increased beyond 3x3 for larger holes? – HDR Dec 17 '15 at 8:46
  • The structure needs to be adapted to the size of your holes. In a real world scenario I'd interate from small to large structures until all holes are filled. – Kersten Dec 17 '15 at 8:56
2

Convert raster to polygons. Do not simplify edges. enter image description here

Select donut like polygons using

How to find if polygon has a hole using field calculator in ArcGIS

Run field calculator expression on field Shape

def outer(shp):
 boundary=shp.boundary()
 part=boundary.getPart(0)
 pgon=arcpy.Polygon(arcpy.Array(part))
 return pgon

To call it use:

outer( !Shape! )

Result:

enter image description here

Convert polygons to raster

2

If you want to fill closed donut only and don't want to test several structuring elements like for the mathematical morphology, here is an alternative :

1) Use "region group" to assign an unique value to each set of connected pixels

2) Use the raster calculator to set all but the value of your background to one.

1

For an ArcGIS, you can use Block statistics using statistics type Majority. May be a bit of trial and error with the neighborhood statistics is needed. For example you can try circle or irregular options with different radii to specifically keep the filling within the donuts.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.