Performing Raster Noise Reduction and Edge Smoothing?

The morphological operations Expand and Shrink were created for this kind of processing. Use ArcGIS (or GRASS or Mathematica) because R's "raster" library is too slow.


Often it helps to experiment a little with the parameters: you have to decide how much expanding and shrinking is needed to clean an image; and usually you want to do as little as possible, because each operation tends to smooth out some of the sharp details. Here is a sequence that works well to eliminate much of the apparent "noise" while maintaining most of the detail in the "entities". "Expand" and "shrink" are both with reference to the white cells, so that expanding causes them to grow outwards and shrinking causes the black cells to encroach into white regions.

Table of images

The "difference" column uses color to highlight differences between the start and end image at each step: blue for black that turned to white, and orange for white that turned to black.

If the larger remaining pieces need to be removed, that might best be done with RegionGroup to identify them, after which they can be obliterated through reclassification. This was an option at the outset, but a little initial cleaning with Expand and Shrink reduces the work and provides the desired smoothing.


Incidentally, I chose to make the eight images in this illustration with Mathematica commands because they are so simple, easy, and fast to execute:

i = Import["http://i.stack.imgur.com/umDg7.png"];
l = Dilation[k = Erosion[j = Dilation[i, 2], 3], 1];      (* This does all the work *)
delta = ColorCombine /@ {{i, j}, {j, k}, {k, l}, {i, l}}; (* Compares images *)

The workflow in ArcGIS is the same but the syntax will be lengthier. If you really want to use R, load the "raster" library and exploit focalFilter to create functions to do the expanding and shrinking. Then wait about a minute each to execute the operations... .


Using the Spatial Analyst Extension, you can use some of the Generalization tools. Some of them perform similar tasks, so you might need to play around with a few to get the results to be how you want them. But, I would have a look at the Majority Filter tool and the Boundary Clean tool.

Here is a page on the concepts of these two tools.

I'm not sure how to perform these tasks in R, but here is a post on how to perform a Majority Filter using GRASS GIS.


This is basically a variant to @whuber's answer and uses Euclidian Distance to expand and shrink the raster boundaries to smooth the sharp corners of the raster which is exaggrated by expand-shrink process which utilises the number of cells to grow/encroach. Although Euclidian Distance imitates Expand, it is not possible to introduce negative value to encroach/shrink. The trick is to develop an iterative process to take the negative of Euclidian Distance raster and grow it. Below are the steps for the given sample imagery and the snapshots for clarification.

  1. Reclassify raster to keep only 1s (white cells)

  2. Apply euclidian distance for two-cell distance (60 metres in this case) to the reclassified raster

  3. Take the negative of the expanded raster by using Reclassify (the cells with the value will get NODATA and NODATA will be turned to 1) or Raster Calculator's Con and IsNull operators

  4. Apply Euclidian Distance once more to this negative raster with the same distance (60 m)

  5. Take the negative of this by following the same process given above

  6. Use Raster Calculator or Reclassify to assign NODATA cells to 0 in this raster to return back to original values of the sample raster

Expand Shrink vs. Euclidian Distance

Expand and shrinkEuclidian distance

Note: Green shows the processed cells (white cells in the questions)

The advantage of Euclidian Distance is that, it takes the proper distance from each cell through the hypotenuse extents which smooths otherwise sharp edges. The number of cell parameter of expand and shrink tools, on the other hand, process the same number of cells for all direction, which yields bounding-box like edges, therefore overly generalises the edges/corners.

The main issue, though, it does not remove the noise as successfully as expand/shrink and it is a bit longer than the answer.