7

I have a binary raster containing boundary pixels with the value 1 (white) and no-boundary pixels with the value 0 (black):

enter image description here

I would like to vectorize the raster by keeping one center line trough the boundary pixels. However, most polygonize methods I tried (e.g., gdalogr:polygonize, result in two lines around the outline of the boundary pixels (red lines) or no output (saga:gridskeletonization): enter image description here

Did I miss any method with which this can be easily done? Or do I have to vectorize the raster first to a vector layer containing two parallel lines and find a way from there to skeletonize/centerline the two lines?

4

GRASS GIS is able do this.

You need two steps:

  1. r.thin

Thins non-null cells that denote linear features in a raster map layer.

  1. r.to.vect

Converts a raster map into a vector map.

  • Works for me after setting a nodata value to the raster with gdal_translate -a_nodata. – AndreJ Aug 8 '17 at 14:02
  • @RoVo s solution didn't entirely work for me. I was able to start r.thin after converting the binary raster with gdal_translate -ot INT32 src_dataset dst_dataset. It seems that similar conversions are often required before applying r.thin to avoid the error ERROR: Input raster must be of type CELL [see following link] (gis.stackexchange.com/questions/197145/…). However, when running r.to.vect on the raster created with r.thin, GRASS always stops working even when applied to small extents of the raster. – Sophie Crommelinck Sep 12 '17 at 7:30
  • That seems to be a different problem. – pLumo Sep 14 '17 at 15:47
  • Now it worked for me as @RoVo suggested. The problem were the no-data values. I changed these not with gdal_translate as @AndreJ suggests, but with mapcalc. I will post my answer containing the modules I used as a separate answer below. – Sophie Crommelinck Sep 19 '17 at 12:23
  • Came here with this issue some time later, having tried various centerline processes - but this GRASS solution worked PERFECTLY - thanks @RoVo – AlecZ Nov 21 '17 at 20:14
1

Now it worked for me as @RoVo suggested before. The problem were the no-data values in my input raster. I changed these not with gdal_translate as @AndreJ suggests (in comments of answer above), but with GRASS r.mapcalc. Here the modules that I used:

Replace all no data values:

processing.runalg('grass:r.mapcalculator',
                  {"amap": gPb_rlayer,
                   "formula": "if(A>0, 1, null())",
                   "GRASS_REGION_PARAMETER": "%f,%f,%f,%f" % (xmin, xmax, ymin, ymax),
                   "GRASS_REGION_CELLSIZE_PARAMETER": 1,
                   "outfile": mapcalc})

Thin raster layer to thin non-null cells:

processing.runalg('grass7:r.thin',
                  {"input": mapcalc,
                   "GRASS_REGION_PARAMETER": "%f,%f,%f,%f" % (xmin, xmax, ymin, ymax),
                   "output": thinned})

Raster to vector conversion:

processing.runalg('grass7:r.to.vect',
                  {"input": thinned,
                   "type": 0,
                   "GRASS_OUTPUT_TYPE_PARAMETER": 2,
                   "GRASS_REGION_PARAMETER": "%f,%f,%f,%f" % (xmin, xmax, ymin, ymax),
                   "output": centerlines})

enter image description here

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.