[GRASS-SVN] r58137 - in grass-addons/grass7/imagery: . i.segment.hierarchical

svn_grass at osgeo.org svn_grass at osgeo.org
Fri Nov 1 05:42:50 PDT 2013


Author: zarch
Date: 2013-11-01 05:42:50 -0700 (Fri, 01 Nov 2013)
New Revision: 58137

Added:
   grass-addons/grass7/imagery/i.segment.hierarchical/
   grass-addons/grass7/imagery/i.segment.hierarchical/Makefile
   grass-addons/grass7/imagery/i.segment.hierarchical/i.segment.hierarchical.html
   grass-addons/grass7/imagery/i.segment.hierarchical/i.segment.hierarchical.py
   grass-addons/grass7/imagery/i.segment.hierarchical/isegpatch.py
Log:
Add i.segment.hierarchical

Added: grass-addons/grass7/imagery/i.segment.hierarchical/Makefile
===================================================================
--- grass-addons/grass7/imagery/i.segment.hierarchical/Makefile	                        (rev 0)
+++ grass-addons/grass7/imagery/i.segment.hierarchical/Makefile	2013-11-01 12:42:50 UTC (rev 58137)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../..
+
+PGM = i.segment.hierarchical
+
+ETCFILES = isegpatch
+
+include $(MODULE_TOPDIR)/include/Make/Script.make
+include $(MODULE_TOPDIR)/include/Make/Python.make
+
+default: script

Added: grass-addons/grass7/imagery/i.segment.hierarchical/i.segment.hierarchical.html
===================================================================
Added: grass-addons/grass7/imagery/i.segment.hierarchical/i.segment.hierarchical.py
===================================================================
--- grass-addons/grass7/imagery/i.segment.hierarchical/i.segment.hierarchical.py	                        (rev 0)
+++ grass-addons/grass7/imagery/i.segment.hierarchical/i.segment.hierarchical.py	2013-11-01 12:42:50 UTC (rev 58137)
@@ -0,0 +1,260 @@
+#!/usr/bin/env python
+# -- coding: utf-8 --
+#
+############################################################################
+#
+# MODULE:	    i.segment.hierarchical
+#
+# AUTHOR(S):   Pietro Zambelli (University of Trento)
+#
+# COPYRIGHT:	(C) 2013 by the GRASS Development Team
+#
+#		This program is free software under the GNU General Public
+#		License (>=v2). Read the file COPYING that comes with GRASS
+#		for details.
+#
+#############################################################################
+
+#%Module
+#%  description: Hierarchical segmentation
+#%  keywords: imagery
+#%  keywords: segment
+#%  overwrite: yes
+#%End
+#%option G_OPT_I_GROUP
+#%  key: group
+#%  description: Name of input imagery group
+#%  required: yes
+#%end
+#%option
+#%  key: thresholds
+#%  type: double
+#%  multiple: yes
+#%  description: Segment thresholds
+#%  required: yes
+#%  answer: 0.02,0.05
+#%end
+#%option G_OPT_R_OUTPUT
+#%  key: output
+#%  description: Name of output sement raster map
+#%  required: yes
+#%end
+#%option
+#%  key: outputs_prefix
+#%  type: string
+#%  description: Name for output raster maps from segment
+#%  required: no
+#%  answer: seg__%.2f
+#%end
+#%option
+#%  key: method
+#%  type: string
+#%  description: Segmentation method
+#%  required: no
+#%  answer: region_growing
+#%  guisection: Segment
+#%end
+#%option
+#%  key: similarity
+#%  type: string
+#%  description: Similarity calculation method
+#%  required: no
+#%  answer: euclidean
+#%  guisection: Segment
+#%end
+#%option
+#%  key: minsizes
+#%  type: integer
+#%  description: Minimum number of cells in a segment
+#%  multiple: yes
+#%  required: no
+#%  guisection: Segment
+#%end
+#%option
+#%  key: memory
+#%  type: integer
+#%  description: Memory in MB
+#%  required: no
+#%  answer: 300
+#%  guisection: Segment
+#%end
+#%option
+#%  key: iterations
+#%  type: integer
+#%  description: Maximum number of iterations
+#%  required: no
+#%  answer: 20
+#%  guisection: Segment
+#%end
+#%option G_OPT_R_INPUT
+#%  key: seeds
+#%  description: Name for input raster map with starting seeds
+#%  required: no
+#%  guisection: Segment
+#%end
+#%option G_OPT_R_INPUT
+#%  key: bounds
+#%  description: Name of input bounding/constraining raster map
+#%  required: no
+#%  guisection: Segment
+#%end
+#%option
+#%  key: width
+#%  description: Tile width in pixels
+#%  type: integer
+#%  required: no
+#%  guisection: Grid
+#%end
+#%option
+#%  key: height
+#%  description: Tile height in pixels
+#%  type: integer
+#%  required: no
+#%  guisection: Grid
+#%end
+#%option
+#%  key: overlap
+#%  description: Tile overlap in pixels
+#%  type: integer
+#%  required: no
+#%  answer: 0
+#%  guisection: Grid
+#%end
+#%option
+#%  key: processes
+#%  description: Number of concurrent processes
+#%  type: integer
+#%  required: no
+#%  guisection: Grid
+#%end
+#%option
+#%  key: move
+#%  description: Path where move and copy the mapset
+#%  type: string
+#%  required: no
+#%  guisection: Grid
+#%end
+
+
+from __future__ import print_function
+import multiprocessing as mltp
+import time
+import sys
+
+from grass.script.core import parser
+from grass.pygrass.modules import Module
+from grass.pygrass.modules.grid import GridModule
+from grass.pygrass.modules.grid.grid import copy_rasters
+from grass.pygrass.modules.grid.split import split_region_tiles
+
+from grass.pygrass.gis import Location
+from grass.pygrass.functions import get_lib_path
+
+path = get_lib_path("i.segment.hierarchical", "")
+if path is None:
+    raise ImportError("Not able to find the path %s directory." % path)
+
+sys.path.append(path)
+from isegpatch import rpatch_map
+
+
+DEBUG = False
+
+
+class SegModule(GridModule):
+    """Extend the GridModule class, modifying the patch method."""
+
+    def __init__(self, *args, **kwargs):
+        self.memory = kwargs['memory']
+        super(SegModule, self).__init__(*args, **kwargs)
+
+    def patch(self):
+        """Patch the final results."""
+        # make all mapset in the location visible
+        loc = Location()
+        mset = loc[self.mset.name]
+        mset.current()
+        mset.visible.extend(loc.mapsets())
+        # patch all the outputs
+        bboxes = split_region_tiles(width=self.width, height=self.height)
+        inputs = self.module.inputs
+        print("Start patching the segments")
+        start = time.time()
+        rpatch_map(inputs.outputs_prefix % inputs.thresholds[-1],
+                   self.mset.name, self.msetstr, bboxes,
+                   self.module.flags.overwrite,
+                   self.start_row, self.start_col, self.out_prefix)
+        print("%s, required: %.2fs" % (OPTS['output'], time.time() - start))
+
+        # segment
+        print("Start running segment for the last time in the whole region")
+        start = time.time()
+        iseg = Module('i.segment')
+        threshold = self.module.inputs.thresholds[-1]
+        iseg(group=self.module.inputs.group,
+             output=self.module.outputs.output,
+             threshold=threshold,
+             method=self.module.inputs.method,
+             similarity=self.module.inputs.similarity,
+             minsize=self.module.inputs.minsizes[-1],
+             memory=self.memory,
+             iterations=3,
+             seeds=self.module.inputs.outputs_prefix % threshold)
+        print("%s, required: %.2fs" % (OPTS['output'], time.time() - start))
+
+        self.mset.current()
+        if self.move:
+            copy_rasters([self.module.outputs.output, ],
+                         self.gisrc_dst, self.gisrc_src)
+
+
+def segment(thresholds, minsizes, output='seg__%.2f', **opts):
+    """Call the i.segment module hierarchical"""
+    iseg = Module('i.segment')
+    seeds = opts['seeds'] if opts['seeds'] else None
+    for thr, msize in zip(thresholds, minsizes):
+        opts['threshold'] = thr
+        opts['minsize'] = msize
+        opts['seeds'] = seeds
+        opts['flags'] = FLAGS
+        opts['output'] = output % thr
+        start = time.time()
+        iseg(**opts)
+        print("%s, required: %.2fs" % (opts['output'], time.time() - start))
+        seeds = opts['output']  # update seeds
+
+
+if __name__ == "__main__":
+    OPTS, FLAGS = parser()
+    WIDTH = OPTS.pop('width')
+    HEIGHT = OPTS.pop('height')
+    OVERLAP = OPTS.pop('overlap')
+    MOVE = OPTS.pop('move')
+    MOVE = MOVE if MOVE else None
+    PROCESSES = OPTS.pop('processes')
+    PROCESSES = int(PROCESSES) if PROCESSES else mltp.cpu_count()
+    MEMORY = int(OPTS['memory'])
+    THRS = [float(thr) for thr in OPTS['thresholds'].split(',') if thr]
+    if OPTS['minsizes']:
+        MINSIZES = [int(m) for m in OPTS['minsizes'].split(',') if m]
+        if len(MINSIZES) != len(THRS):
+            MINSIZES = [int(MINSIZES[0]), ] * len(THRS)
+    else:
+        MINSIZES = [1, ] * len(THRS)
+
+    # define new cleaned parameters
+    OPTS['thresholds'] = THRS
+    OPTS['minsizes'] = MINSIZES
+    OPTS['iterations'] = int(OPTS['iterations'])
+    OPTS['memory'] = MEMORY / PROCESSES
+    if WIDTH and HEIGHT:
+        SEG = SegModule('i.segment.hierarchical',
+                        width=int(WIDTH), height=int(HEIGHT),
+                        overlap=int(OVERLAP),
+                        processes=PROCESSES, move=MOVE,
+                        debug=DEBUG, **OPTS)
+        SEG.run()
+    else:
+        OPTS.pop('output')
+        segment(OPTS.pop('thresholds'), OPTS.pop('minsizes'),
+                output=OPTS.pop('outputs_prefix'), **OPTS)


Property changes on: grass-addons/grass7/imagery/i.segment.hierarchical/i.segment.hierarchical.py
___________________________________________________________________
Added: svn:executable
   + *

Added: grass-addons/grass7/imagery/i.segment.hierarchical/isegpatch.py
===================================================================
--- grass-addons/grass7/imagery/i.segment.hierarchical/isegpatch.py	                        (rev 0)
+++ grass-addons/grass7/imagery/i.segment.hierarchical/isegpatch.py	2013-11-01 12:42:50 UTC (rev 58137)
@@ -0,0 +1,81 @@
+# -*- coding: utf-8 -*-
+"""
+Created on Mon Oct 21 12:54:42 2013
+
+ at author: pietro
+"""
+import os
+import re
+
+import grass.lib.gis as libgis
+
+from grass.pygrass.modules.grid.patch import get_start_end_index
+from grass.pygrass.modules.grid.split import split_region_tiles
+from grass.pygrass.modules.grid.node import row_order
+from grass.pygrass.raster import RasterRow
+
+
+def rpatch_row(rast, rasts, bboxes, max_rasts):
+    """Patch a row of bound boxes."""
+    sei = get_start_end_index(bboxes)
+    # instantiate two buffer
+    buff = rasts[0][0]
+    rbuff = rasts[0][0]
+    r_start, r_end, c_start, c_end = sei[0]
+    for row in xrange(r_start, r_end):
+        for col, ras in enumerate(rasts):
+            r_start, r_end, c_start, c_end = sei[col]
+            buff = ras.get_row(row, buff)
+            rbuff[c_start:c_end] = buff[c_start:c_end] + max_rasts[col]
+        rast.put_row(rbuff)
+
+
+def rpatch_map(raster, mapset, mset_str, bbox_list, overwrite=False,
+               start_row=0, start_col=0, prefix=''):
+    """Patch raster using a bounding box list to trim the raster."""
+    # Instantiate the RasterRow input objects
+    rast = RasterRow(prefix + raster, mapset)
+    with RasterRow(name=raster, mapset=mset_str % (0, 0), mode='r') as rtype:
+        rast.open('w', mtype=rtype.mtype, overwrite=overwrite)
+    rasts = []
+    mrast = 0
+    nrows = len(bbox_list)
+    for row, rbbox in enumerate(bbox_list):
+        rrasts = []
+        max_rasts = []
+        for col in range(len(rbbox)):
+            libgis.G_percent(row, nrows, 1)
+            rrasts.append(RasterRow(name=raster,
+                                    mapset=mset_str % (start_row + row,
+                                                       start_col + col)))
+            rrasts[-1].open('r')
+            mrast += rrasts[-1].info.max + 1
+            max_rasts.append(mrast)
+        rasts.append(rrasts)
+        rpatch_row(rast, rrasts, rbbox, max_rasts)
+        for rst in rrasts:
+            rst.close()
+            del(rst)
+
+    rast.close()
+
+
+def node_patch(cmd, nwidth, nheight, out_regexp, overwrite=True):
+    from grass.lib.gis import G_tempfile
+    tmp, dummy = os.path.split(os.path.split(G_tempfile())[0])
+    tmpdir = os.path.join(cmd)
+    bboxes = split_region_tiles(width=nwidth, height=nheight)
+    for out in os.listdir(tmpdir):
+        outdir = os.path.join(tmpdir, out)
+        rasts = os.listdir(outdir)
+        rsts = row_order(rasts, bboxes)
+        rst = RasterRow(re.findall(out_regexp, rasts[0])[0])
+        rst.open('w', mtype=rsts[0][0].mtype, overwrite=overwrite)
+        for rrst, rbbox in zip(rsts, bboxes):
+            rpatch_row(rst, rrst, rbbox)
+
+        for rrst in rsts:
+            for r in rrst:
+                r.close()
+
+        rst.close()



More information about the grass-commit mailing list