Beispiel #1
0
def _delaunayMapFromData(nodePositions, edgeData, imageSize, sigmaOrbits = None):
    if sigmaOrbits:
        sys.stderr.write(
            "TODO: re-use Delaunay sigma orbits instead of re-sorting!\n")
    edges = [startEnd and
             (startEnd[0], startEnd[1],
              [nodePositions[startEnd[0]], nodePositions[startEnd[1]]])
             for startEnd in edgeData]
    result = GeoMap(nodePositions, edges, imageSize)
    result.initializeMap(initLabelImage = False)
    return result
Beispiel #2
0
def _delaunayMapFromData(nodePositions, edgeData, imageSize, sigmaOrbits = None):
    if sigmaOrbits:
        sys.stderr.write(
            "TODO: re-use Delaunay sigma orbits instead of re-sorting!\n")
    edges = [startEnd and
             (startEnd[0], startEnd[1],
              [nodePositions[startEnd[0]], nodePositions[startEnd[1]]])
             for startEnd in edgeData]
    result = GeoMap(nodePositions, edges, imageSize)
    result.initializeMap(initLabelImage = False)
    return result
Beispiel #3
0
 def max_likelihood(c_param, alpha, c_mass, coords_list, ncoords_list):
     f_sum = 0
     eps = np.finfo(float).eps
     for pcoord in coords_list:
         dist = GeoMap.distance(c_mass, pcoord)
         if dist:
             f_sum += np.log(c_param * dist**(-alpha))
     for ncoord in ncoords_list:
         dist = GeoMap.distance(c_mass, ncoord)
         prob = c_param * dist**(-alpha)
         if prob > 1:
             f_sum += np.log(eps)
         else:
             f_sum += np.log(1 - prob)
     return f_sum
Beispiel #4
0
import numpy as np

from geomap import GeoMap


map_fac = 1.5

width = 1112
height = 609

zoom_level = 13
LAT = 41.159593802241154
LON = -8.60452651977539

longs = [LON]
lats = [LAT]

gm = GeoMap(LAT, LON, zoom_level, width, height)
xpix, ypix = gm.to_point(longs, lats)

im = plt.imread("./mapstack_v2.png")
plt.figure(figsize=(map_fac * 9.98, map_fac * 6.7))
plt.imshow(np.flipud(im))
plt.plot(xpix, ypix, 'ro', markersize=5, markeredgecolor='none')
plt.xlim([0, width])
plt.ylim([0, height])
plt.axis('off')
plt.title('taxis running in the city of Porto, in Porugal')
plt.tight_layout()
plt.savefig('test.png')
Beispiel #5
0
def catMap(delaunayMap,
           rectified = True,
           includeTerminalPositions = False):
    """catMap(delaunayMap,
           rectified = True,
           includeTerminalPositions = False)

    Extract a CAT (chordal axis transform) from a GeoMap object
    containing a Delaunay Triangulation.  Implements the rectified
    version (from L.Prasad's DGCI'05 article), which also works for
    GeoMaps with non-triangular Faces.

    Expects outer faces of the delaunayMap to be marked with the
    OUTER_FACE flag (in order to skip these faces and work only on the
    inner parts of the shapes), and edges which belong to the
    constrained segments of the CDT to be marked with the
    CONTOUR_SEGMENT flag (i.e. an edge is a chord iff
    'not edge.flag(CONTOUR_SEGMENT)')

    Usually, you will do sth. along:

    >>> del1 = delaunay.faceCDTMap(map1.face(173), map1.imageSize())
    >>> cat1 = delaunay.catMap(del1, rectified = False)

    The optional parameter `rectified` has been set to False here to
    use the original definition of junction node positions (using the
    circumcenter if possible) which works only for triangulations (and
    is therefore disabled by default).

    For triangulations, it is also possible to include the opposite
    vertex of the terminal triangles into the skeleton by setting
    `includeTerminalPositions` to True.

    If you want to use the rectified CAT (with weak chords being
    suppressed), you would use removeWeakChords before calling catMap:

    >>> del2 = copy.copy(del1) # if you want to keep the original
    >>> removeWeakChords(del2)
    >>> rcat2 = delaunay.catMap(del2)

    The resulting map will have additional attributes that relate the
    skeleton with the original boundary:

    subtendedLengths:
      This is a list mapping edge labels of the skeleton to the
      accumulated lengths of all contour segments within the contours
      of the sleeve- and terminal-faces that comprise the sleeve
      represented by that skeleton edge.

    shapeWidths:
      This is a list mapping edge labels of the skeleton to lists of
      shape widths at each support point of the polygon (may be None
      at the ends).  In theory, this allows to reconstruct the
      original boundary and thus makes the CAT fully reversible (see
      Prasad's papers).

    nodeChordLabels:
      This is a list mapping node labels of the skeleton to lists of
      (sleeveLabel, chordLabel) pairs, where sleeveLabel is the label
      of a skeleton edge and chordLabel is the dart label of the first
      chord from the `delaunayMap` within that sleeve.  (This is
      needed for later corrections of the junction node positions
      after pruning.)"""

    if rectified:
        junctionPos = rectifiedJunctionNodePosition
        assert not includeTerminalPositions, \
               "includeTerminalPositions is not supported for the rectified CAT!"
    else:
        junctionPos = junctionNodePosition

    result = GeoMap(delaunayMap.imageSize())
    result.subtendedLengths = [0] # unused Edge 0
    result.shapeWidths = [None]
    result.nodeChordLabels = []

    faceChords = [None] * delaunayMap.maxFaceLabel()
    boundaryLength = [None] * delaunayMap.maxFaceLabel()
    faceType = [None] * delaunayMap.maxFaceLabel()
    nodeLabel = [None] * delaunayMap.maxFaceLabel()

    for face in delaunayMap.faceIter(skipInfinite = True):
        if face.flag(OUTER_FACE):
            continue

        assert face.holeCount() == 0

        chords = []
        bl = 0.0
        for dart in face.contour().phiOrbit():
            if not dart.edge().flag(CONTOUR_SEGMENT):
                chords.append(dart)
            else:
                bl += dart.edge().length()

        boundaryLength[face.label()] = bl
        faceChords[face.label()] = chords

        # classify into terminal, sleeve, and junction triangles:
        if len(chords) < 2:
            faceType[face.label()] = "T"
            if chords:
                nodePos = middlePoint(chords[0]) # (may be changed later)
        elif len(chords) == 2:
            faceType[face.label()] = "S"
        else:
            faceType[face.label()] = "J"
            nodePos = junctionPos(chords)

        # add nodes for non-sleeve triangles:
        if faceType[face.label()] != "S" and chords:
            nodeLabel[face.label()] = result.addNode(nodePos).label()
            result.nodeChordLabels.append([])

    for face in delaunayMap.faceIter(skipInfinite = True):
        if face.flag(OUTER_FACE):
            continue

        if faceType[face.label()] != "S":
            #print faceType[face.label()] + "-triangle", face.label()
            for dart in faceChords[face.label()]:
                #print "following limb starting with", dart

                startNode = result.node(nodeLabel[face.label()])
                startDart = dart.clone()
                edgePoints = []
                subtendedBoundaryLength = 0.0
                shapeWidth = []

                if faceType[face.label()] == "T":
                    subtendedBoundaryLength += boundaryLength[face.label()]
                    if includeTerminalPositions:
                        # include opposite position
                        startNode.setPosition((dart.clone().nextPhi())[-1])

                while True:
                    edgePoints.append(middlePoint(dart))
                    shapeWidth.append(dart.edge().length())
                    dart.nextAlpha()
                    nextFace = dart.leftFace()
                    if faceType[nextFace.label()] == "S":
                        subtendedBoundaryLength += boundaryLength[nextFace.label()]
                        # continue with opposite dart:
                        if dart == faceChords[nextFace.label()][0]:
                            dart = faceChords[nextFace.label()][1]
                        else:
                            dart = faceChords[nextFace.label()][0]
                    else:
                        faceChords[nextFace.label()].remove(dart)
                        break

                endNode = result.node(nodeLabel[nextFace.label()])

                if faceType[nextFace.label()] == "T":
                    subtendedBoundaryLength += boundaryLength[nextFace.label()]
                    if includeTerminalPositions:
                        endNode.setPosition((dart.clone().nextPhi())[-1])

                flags = 0
                if not edgePoints or edgePoints[0] != startNode.position():
                    edgePoints.insert(0, startNode.position())
                    shapeWidth.insert(0, None)
                    flags |= START_NODE_ADDED
                if edgePoints[-1] != endNode.position():
                    edgePoints.append(endNode.position())
                    shapeWidth.append(None)
                    flags |= END_NODE_ADDED

                if len(edgePoints) < 2:
                    # don't add edges with only 1 point (two adjacent
                    # T-triangles) - may fail for J-faces?!
                    # but J-faces should not have nodes on their borders
                    assert endNode.position() == startNode.position() and \
                           endNode.isIsolated() and startNode.isIsolated()
                    nodeLabel[nextFace.label()] = nodeLabel[face.label()]
                    result.removeIsolatedNode(endNode)
                    continue

                sleeve = result.addEdge(
                    startNode, endNode, edgePoints)
                sleeve.setFlag(flags)

                result.subtendedLengths.append(subtendedBoundaryLength)
                result.shapeWidths.append(shapeWidth)
                if faceType[face.label()] == "J":
                    result.nodeChordLabels[startNode.label()].append(
                        (sleeve.label(), startDart.label()))
                if faceType[nextFace.label()] == "J":
                    result.nodeChordLabels[endNode.label()].append(
                        (sleeve.label(), dart.label()))

    result.initializeMap(initLabelImage = False)

    return result
Beispiel #6
0
 def __init__(self, db_addr='localhost:27017', punfile="punctation.txt", stopfile="stopwords.txt"):
     self.citi_dict = {}
     self.geo_map = GeoMap(CityStats.poland_latitude[0], CityStats.poland_latitude[1],
                           CityStats.poland_longitude[0], CityStats.poland_longitude[1], precision=2)
     self.mn_db = MongoBase(db_addr)
     self.word_stats = WordStats(punfile=punfile, stopfile=stopfile)
Beispiel #7
0
class CityStats(object):

    poland_latitude = (54.83, 49.0)
    poland_longitude = (14.12, 24.15)

    def __init__(self, db_addr='localhost:27017', punfile="punctation.txt", stopfile="stopwords.txt"):
        self.citi_dict = {}
        self.geo_map = GeoMap(CityStats.poland_latitude[0], CityStats.poland_latitude[1],
                              CityStats.poland_longitude[0], CityStats.poland_longitude[1], precision=2)
        self.mn_db = MongoBase(db_addr)
        self.word_stats = WordStats(punfile=punfile, stopfile=stopfile)

    # get tweets from specified city
    def get_json_list(self, basename, city):
        db_cur = self.mn_db.get_dataset(basename, find_arg={"user.location": city})
        return db_cur

    # Create list of cities base on cities.txt file
    # content
    @staticmethod
    def get_cities_list(city_path):
        cities = []
        with open(city_path, 'r') as citi_file:
            for line in citi_file:
                cities.append(line[:-1])
        return cities

    def get_word_freq(self, city):
        db_cur = self.get_json_list('location', city)
        res = self.word_stats.word_counter(db_cur)
        res = {key: value for (key, value) in res.iteritems() if value > 1}
        return res

    @staticmethod
    def repr_dict(d):
        return '{%s}' % ',\n'.join("'%s': '%s'" % pair for pair in d.iteritems())

    # Count tweet words for specified location
    def count_citywords(self, city_path="cities.txt", stjson_path="words_statistic.json"):
        words_found = []
        cities = self.get_cities_list(city_path)
        for city in cities:
            res = self.get_word_freq(city)
            words_found.append(res)
            print city, self.repr_dict(res)
        citi_dict = dict(zip(cities, words_found))
        with open(stjson_path, 'w') as fp:
            json.dump(citi_dict, fp)
        return citi_dict

    @staticmethod
    def get_words(stjson_path="words_statistic.json", citi_dict=None):
        word_list = []
        # If city dictionary passed as value do nothing
        if not citi_dict:
            # Read words dictionary from json file
            with open(stjson_path) as data_file:
                citi_dict = json.load(data_file)
        for city, value in citi_dict.iteritems():
            for word, ntimes in value.iteritems():
                word_list.append(word)
        word_list = set(word_list)
        return word_list, citi_dict

    @staticmethod
    def max_likelihood(c_param, alpha, c_mass, coords_list, ncoords_list):
        f_sum = 0
        eps = np.finfo(float).eps
        for pcoord in coords_list:
            dist = GeoMap.distance(c_mass, pcoord)
            if dist:
                f_sum += np.log(c_param * dist**(-alpha))
        for ncoord in ncoords_list:
            dist = GeoMap.distance(c_mass, ncoord)
            prob = c_param * dist**(-alpha)
            if prob > 1:
                f_sum += np.log(eps)
            else:
                f_sum += np.log(1 - prob)
        return f_sum

    def find_parameters(self, start, end, c_mass, coords_list, ncoords_list, precision):
        f_list = []
        start = [int(x / precision) for x in start]
        end = [int(y / precision) for y in end]
        for i in range(start[0], end[0]):
            c = i * precision
            for j in range(start[1], end[1]):
                alpha = j * precision
                f_like = CityStats.max_likelihood(c, alpha, c_mass, coords_list, ncoords_list)
                f_list.append((f_like, c, alpha))
        f_only = [tpl[0] for tpl in f_list]
        max_val = max(f_only)
        word_params = f_list[f_only.index(max_val)]
        return word_params
        # if c_mass[0] == 164:
        #     self.geo_map.multi_exp(c_mass, word_params[1], word_params[2])

    def local_words(self, stjson="words_statistic.json"):
        # Read word list
        words, citi_dict = self.get_words(stjson_path=stjson)
        param_file = open('../data/local_params.dat', 'a+')
        # Iterate over words
        for word in words:
            word_params = self.word_prediction_params(word, citi_dict)
            if word_params:
                print word
                print word_params
                param_file.write(str(word_params[0]) + ';' +
                                 str(word_params[1].tolist()))
        param_file.close()

    def word_prediction_params(self, word, citi_dict):
        matched_freqs = []
        coords_list = []
        ncoords_list = []
        self.geo_map.clean()
        for city, value in citi_dict.iteritems():
            coords = self.geo_map.citi2idx(city)
            if coords:
                list_element = [freq for match, freq
                                in value.iteritems() if match == word
                                ]
                if list_element:
                    # self.geo_map.set_position(coords, value[word])
                    coords_list.append(coords)
                    matched_freqs.append(list_element[0])
                else:
                    ncoords_list.append(coords)
        # If matched frequencies not empty
        if matched_freqs:
            # if word == "targi":
            #     surf(self.geo_map.country_map)
            c_mass = np.sum([(coord[0] * freq, coord[1] * freq)
                             for coord, freq in zip(coords_list, matched_freqs)],
                            axis=0)
            c_mass /= np.sum(matched_freqs, axis=0)
            start = [0.1, 0.1]
            end = [2.0, 2.0]
            if len(coords_list) > 5:
                word_params = self.find_parameters(start, end, c_mass,
                                                   coords_list, ncoords_list, 0.1)
                return word_params, c_mass
            return None
Beispiel #8
0
def catMap(delaunayMap,
           rectified = True,
           includeTerminalPositions = False):
    """catMap(delaunayMap,
           rectified = True,
           includeTerminalPositions = False)

    Extract a CAT (chordal axis transform) from a GeoMap object
    containing a Delaunay Triangulation.  Implements the rectified
    version (from L.Prasad's DGCI'05 article), which also works for
    GeoMaps with non-triangular Faces.

    Expects outer faces of the delaunayMap to be marked with the
    OUTER_FACE flag (in order to skip these faces and work only on the
    inner parts of the shapes), and edges which belong to the
    constrained segments of the CDT to be marked with the
    CONTOUR_SEGMENT flag (i.e. an edge is a chord iff
    'not edge.flag(CONTOUR_SEGMENT)')

    Usually, you will do sth. along:

    >>> del1 = delaunay.faceCDTMap(map1.face(173), map1.imageSize())
    >>> cat1 = delaunay.catMap(del1, rectified = False)

    The optional parameter `rectified` has been set to False here to
    use the original definition of junction node positions (using the
    circumcenter if possible) which works only for triangulations (and
    is therefore disabled by default).

    For triangulations, it is also possible to include the opposite
    vertex of the terminal triangles into the skeleton by setting
    `includeTerminalPositions` to True.

    If you want to use the rectified CAT (with weak chords being
    suppressed), you would use removeWeakChords before calling catMap:
    
    >>> del2 = copy.copy(del1) # if you want to keep the original
    >>> removeWeakChords(del2)
    >>> rcat2 = delaunay.catMap(del2)

    The resulting map will have additional attributes that relate the
    skeleton with the original boundary:

    subtendedLengths:
      This is a list mapping edge labels of the skeleton to the
      accumulated lengths of all contour segments within the contours
      of the sleeve- and terminal-faces that comprise the sleeve
      represented by that skeleton edge.

    shapeWidths:
      This is a list mapping edge labels of the skeleton to lists of
      shape widths at each support point of the polygon (may be None
      at the ends).  In theory, this allows to reconstruct the
      original boundary and thus makes the CAT fully reversible (see
      Prasad's papers).

    nodeChordLabels:
      This is a list mapping node labels of the skeleton to lists of
      (sleeveLabel, chordLabel) pairs, where sleeveLabel is the label
      of a skeleton edge and chordLabel is the dart label of the first
      chord from the `delaunayMap` within that sleeve.  (This is
      needed for later corrections of the junction node positions
      after pruning.)"""

    if rectified:
        junctionPos = rectifiedJunctionNodePosition
        assert not includeTerminalPositions, \
               "includeTerminalPositions is not supported for the rectified CAT!"
    else:
        junctionPos = junctionNodePosition

    result = GeoMap(delaunayMap.imageSize())
    result.subtendedLengths = [0] # unused Edge 0
    result.shapeWidths = [None]
    result.nodeChordLabels = []

    faceChords = [None] * delaunayMap.maxFaceLabel()
    boundaryLength = [None] * delaunayMap.maxFaceLabel()
    faceType = [None] * delaunayMap.maxFaceLabel()
    nodeLabel = [None] * delaunayMap.maxFaceLabel()

    for face in delaunayMap.faceIter(skipInfinite = True):
        if face.flag(OUTER_FACE):
            continue

        assert face.holeCount() == 0

        chords = []
        bl = 0.0
        for dart in face.contour().phiOrbit():
            if not dart.edge().flag(CONTOUR_SEGMENT):
                chords.append(dart)
            else:
                bl += dart.edge().length()
        
        boundaryLength[face.label()] = bl
        faceChords[face.label()] = chords
        
        # classify into terminal, sleeve, and junction triangles:
        if len(chords) < 2:
            faceType[face.label()] = "T"
            if chords:
                nodePos = middlePoint(chords[0]) # (may be changed later)
        elif len(chords) == 2:
            faceType[face.label()] = "S"
        else:
            faceType[face.label()] = "J"
            nodePos = junctionPos(chords)

        # add nodes for non-sleeve triangles:
        if faceType[face.label()] != "S" and chords:
            nodeLabel[face.label()] = result.addNode(nodePos).label()
            result.nodeChordLabels.append([])

    for face in delaunayMap.faceIter(skipInfinite = True):
        if face.flag(OUTER_FACE):
            continue
        
        if faceType[face.label()] != "S":
            #print faceType[face.label()] + "-triangle", face.label()
            for dart in faceChords[face.label()]:
                #print "following limb starting with", dart

                startNode = result.node(nodeLabel[face.label()])
                startDart = dart.clone()
                edgePoints = []
                subtendedBoundaryLength = 0.0
                shapeWidth = []

                if faceType[face.label()] == "T":
                    subtendedBoundaryLength += boundaryLength[face.label()]
                    if includeTerminalPositions:
                        # include opposite position
                        startNode.setPosition((dart.clone().nextPhi())[-1])

                while True:
                    edgePoints.append(middlePoint(dart))
                    shapeWidth.append(dart.edge().length())
                    dart.nextAlpha()
                    nextFace = dart.leftFace()
                    if faceType[nextFace.label()] == "S":
                        subtendedBoundaryLength += boundaryLength[nextFace.label()]
                        # continue with opposite dart:
                        if dart == faceChords[nextFace.label()][0]:
                            dart = faceChords[nextFace.label()][1]
                        else:
                            dart = faceChords[nextFace.label()][0]
                    else:
                        faceChords[nextFace.label()].remove(dart)
                        break

                endNode = result.node(nodeLabel[nextFace.label()])

                if faceType[nextFace.label()] == "T":
                    subtendedBoundaryLength += boundaryLength[nextFace.label()]
                    if includeTerminalPositions:
                        endNode.setPosition((dart.clone().nextPhi())[-1])

                flags = 0
                if not edgePoints or edgePoints[0] != startNode.position():
                    edgePoints.insert(0, startNode.position())
                    shapeWidth.insert(0, None)
                    flags |= START_NODE_ADDED
                if edgePoints[-1] != endNode.position():
                    edgePoints.append(endNode.position())
                    shapeWidth.append(None)
                    flags |= END_NODE_ADDED

                if len(edgePoints) < 2:
                    # don't add edges with only 1 point (two adjacent
                    # T-triangles) - may fail for J-faces?!
                    # but J-faces should not have nodes on their borders
                    assert endNode.position() == startNode.position() and \
                           endNode.isIsolated() and startNode.isIsolated()
                    nodeLabel[nextFace.label()] = nodeLabel[face.label()]
                    result.removeIsolatedNode(endNode)
                    continue
                
                sleeve = result.addEdge(
                    startNode, endNode, edgePoints)
                sleeve.setFlag(flags)

                result.subtendedLengths.append(subtendedBoundaryLength)
                result.shapeWidths.append(shapeWidth)
                if faceType[face.label()] == "J":
                    result.nodeChordLabels[startNode.label()].append(
                        (sleeve.label(), startDart.label()))
                if faceType[nextFace.label()] == "J":
                    result.nodeChordLabels[endNode.label()].append(
                        (sleeve.label(), dart.label()))

    result.initializeMap(initLabelImage = False)

    return result
Beispiel #9
0
def pyCrackEdgeGraph(labelImage,
                     eightConnectedRegions=True,
                     progressHook=None):
    result = GeoMap(labelImage.size())

    cc = crackConnectionImage(labelImage)

    if eightConnectedRegions:
        for y in range(1, cc.height() - 1):
            for x in range(1, cc.width() - 1):
                if cc[x, y] == CONN_ALL4:
                    if labelImage[x, y] == labelImage[x - 1, y - 1]:
                        cc[x, y] += CONN_DIAG_UPLEFT
                    if labelImage[x - 1, y] == labelImage[x, y - 1]:
                        cc[x, y] += CONN_DIAG_UPRIGHT

                    # crossing regions?
                    if cc[x,
                          y] == CONN_ALL4 + CONN_DIAG_UPLEFT + CONN_DIAG_UPRIGHT:
                        # preserve connectedness of higher label:
                        if labelImage[x, y - 1] > labelImage[x - 1, y - 1]:
                            cc[x, y] -= CONN_DIAG_UPLEFT
                        else:
                            cc[x, y] -= CONN_DIAG_UPRIGHT

    for y in range(cc.height()):
        for x in range(cc.width()):
            conn = int(cc[x, y])
            if degree[conn] > 2:
                cc[x, y] = conn | CONN_NODE
            elif conn & CONN_ALL4 == (CONN_RIGHT | CONN_DOWN):
                cc[x, y] = conn | CONN_MAYBE_NODE
            if conn & CONN_DIAG:
                cc[x, y] = conn | CONN_MAYBE_NODE

    nodeImage = ScalarImage(cc.size())
    # nodeImage encoding: each pixel's higher 28 bits encode the
    # (label + 1) of a node that has been inserted into the resulting
    # GeoMap at the corresponding position (+1 because zero is a valid
    # node label), while the lower 4 bits encode the four CONN_
    # directions in which a GeoMap edge is already connected to this
    # node

    progressHook = progressHook and progressHook.rangeTicker(cc.height())

    for startAt in (CONN_NODE, CONN_MAYBE_NODE):
        for y in range(cc.height()):
            if progressHook:
                progressHook()
            for x in range(cc.width()):
                nodeConn = int(cc[x, y])
                if nodeConn & startAt:
                    startNodeInfo = int(nodeImage[x, y])
                    if startNodeInfo:
                        startNode = result.node((startNodeInfo >> 4) - 1)
                    else:
                        startNode = result.addNode((x - 0.5, y - 0.5))
                        nodeImage[x, y] = startNodeInfo = \
                                          (startNode.label() + 1) << 4

                    for direction, startConn in enumerate(connections):
                        if nodeConn & startConn and not startNodeInfo & startConn:
                            edge, endPos, endConn = followEdge(
                                cc, (x, y), direction)
                            endNodeInfo = int(nodeImage[endPos])
                            if not endNodeInfo:
                                endNode = result.addNode(
                                    (endPos[0] - 0.5, endPos[1] - 0.5))
                                endNodeInfo = (endNode.label() + 1) << 4
                            else:
                                assert not endNodeInfo & endConn, "double connection?"
                                endNode = result.node((endNodeInfo >> 4) - 1)

                            edge = result.addEdge(startNode, endNode, edge)

                            startNodeInfo |= startConn
                            if edge.isLoop():
                                startNodeInfo |= endConn
                                nodeImage[x, y] = startNodeInfo
                            else:
                                nodeImage[x, y] = startNodeInfo
                                nodeImage[endPos] = endNodeInfo | endConn

    return result
Beispiel #10
0
    return numpy.array((x, y))
Size2D = Vector2

from geomap import GeoMap, contourPoly
#from map import GeoMap
execfile("testSPWS")

# --------------------------------------------------------------------
# 				flowline map creation / face.contains
# --------------------------------------------------------------------

# The following data contains edges that run out of the image range,
# which ATM leads to overlapping edges after border closing. That
# violates some assumptions and would lead to errors if we actually
# worked with that Map.
map = GeoMap(maxima2, [], Size2D(39, 39))
maputils.addFlowLinesToMap(flowlines2, map)
assert map.checkConsistency(), "graph inconsistent"
map.sortEdgesEventually(stepDist = 0.2, minDist = 0.05)
map.splitParallelEdges()
map.initializeMap()
assert map.checkConsistency(), "map inconsistent"
assert maputils.checkLabelConsistency(map), "map.labelImage() inconsistent"

# merge faces so that survivor has a hole:
hole = map.faceAt((16,17))
assert hole.contains((16,17))
assert contourPoly(hole.contour()).contains((16,17))

dart = hole.contour()
while True:
Beispiel #11
0
Size2D = Vector2

from geomap import GeoMap, contourPoly
#from map import GeoMap
execfile("testSPWS")

# --------------------------------------------------------------------
# 				flowline map creation / face.contains
# --------------------------------------------------------------------

# The following data contains edges that run out of the image range,
# which ATM leads to overlapping edges after border closing. That
# violates some assumptions and would lead to errors if we actually
# worked with that Map.
map = GeoMap(maxima2, [], Size2D(39, 39))
maputils.addFlowLinesToMap(flowlines2, map)
assert map.checkConsistency(), "graph inconsistent"
map.sortEdgesEventually(stepDist=0.2, minDist=0.05)
map.splitParallelEdges()
map.initializeMap()
assert map.checkConsistency(), "map inconsistent"
assert maputils.checkLabelConsistency(map), "map.labelImage() inconsistent"

# merge faces so that survivor has a hole:
hole = map.faceAt((16, 17))
assert hole.contains((16, 17))
assert contourPoly(hole.contour()).contains((16, 17))

dart = hole.contour()
while True:
Beispiel #12
0
def pyCrackEdgeGraph(labelImage, eightConnectedRegions = True,
                   progressHook = None):
    result = GeoMap(labelImage.size())

    cc = crackConnectionImage(labelImage)

    if eightConnectedRegions:
        for y in range(1, cc.height()-1):
          for x in range(1, cc.width()-1):
            if cc[x,y] == CONN_ALL4:
                if labelImage[x,y] == labelImage[x-1,y-1]:
                    cc[x,y] += CONN_DIAG_UPLEFT
                if labelImage[x-1,y] == labelImage[x,y-1]:
                    cc[x,y] += CONN_DIAG_UPRIGHT

                # crossing regions?
                if cc[x,y] == CONN_ALL4 + CONN_DIAG_UPLEFT + CONN_DIAG_UPRIGHT:
                    # preserve connectedness of higher label:
                    if labelImage[x,y-1] > labelImage[x-1,y-1]:
                        cc[x,y] -= CONN_DIAG_UPLEFT
                    else:
                        cc[x,y] -= CONN_DIAG_UPRIGHT

    for y in range(cc.height()):
        for x in range(cc.width()):
            conn = int(cc[x,y])
            if degree[conn] > 2:
                cc[x,y] = conn | CONN_NODE
            elif conn & CONN_ALL4 == (CONN_RIGHT | CONN_DOWN):
                cc[x,y] = conn | CONN_MAYBE_NODE
            if conn & CONN_DIAG:
                cc[x,y] = conn | CONN_MAYBE_NODE
    
    nodeImage = ScalarImage(cc.size())
    # nodeImage encoding: each pixel's higher 28 bits encode the
    # (label + 1) of a node that has been inserted into the resulting
    # GeoMap at the corresponding position (+1 because zero is a valid
    # node label), while the lower 4 bits encode the four CONN_
    # directions in which a GeoMap edge is already connected to this
    # node

    progressHook = progressHook and progressHook.rangeTicker(cc.height())

    for startAt in (CONN_NODE, CONN_MAYBE_NODE):
     for y in range(cc.height()):
      if progressHook:
          progressHook()
      for x in range(cc.width()):
        nodeConn = int(cc[x, y])
        if nodeConn & startAt:
            startNodeInfo = int(nodeImage[x, y])
            if startNodeInfo:
                startNode = result.node((startNodeInfo >> 4) - 1)
            else:
                startNode = result.addNode((x - 0.5, y - 0.5))
                nodeImage[x, y] = startNodeInfo = \
                                  (startNode.label() + 1) << 4

            for direction, startConn in enumerate(connections):
                if nodeConn & startConn and not startNodeInfo & startConn:
                    edge, endPos, endConn = followEdge(
                        cc, (x, y), direction)
                    endNodeInfo = int(nodeImage[endPos])
                    if not endNodeInfo:
                        endNode = result.addNode((endPos[0] - 0.5, endPos[1] - 0.5))
                        endNodeInfo = (endNode.label() + 1) << 4
                    else:
                        assert not endNodeInfo & endConn, "double connection?"
                        endNode = result.node((endNodeInfo >> 4) - 1)

                    edge = result.addEdge(startNode, endNode, edge)

                    startNodeInfo |= startConn
                    if edge.isLoop():
                        startNodeInfo |= endConn
                        nodeImage[x, y] = startNodeInfo
                    else:
                        nodeImage[x, y] = startNodeInfo
                        nodeImage[endPos] = endNodeInfo | endConn

    return result