示例#1
0
def siftImage(url):
    """
    """
    image = loadImage(url)
    
    handle, sift_filename = tempfile.mkstemp(prefix='decode-', suffix='.sift')
    os.close(handle)
        
    handle, pgm_filename = tempfile.mkstemp(prefix='decode-', suffix='.pgm')
    os.close(handle)
    
    try:
        # fit to 1000x1000
        scale = min(1., 1000. / max(image.size))
        
        # write the PGM
        pgm_size = int(image.size[0] * scale), int(image.size[1] * scale)
        image.convert('L').resize(pgm_size, PIL.Image.ANTIALIAS).save(pgm_filename)
        
        print >> sys.stderr, 'sift...', pgm_size,
        
        basedir = os.path.dirname(os.path.realpath(__file__)).replace(' ', '\ ')
        status, output = commands.getstatusoutput("%(basedir)s/bin/sift --peak-thresh=8 -o '%(sift_filename)s' '%(pgm_filename)s'" % locals())
        data = open(sift_filename, 'r')
        
        assert status == 0, 'Sift execution returned %s instead of 0' % status
        
        features = [matchup.row2feature(row) for row in data]
    
        print >> sys.stderr, len(features), 'features'
        
        return image, features, scale
    
    finally:
        os.unlink(sift_filename)
        os.unlink(pgm_filename)
示例#2
0
def main(scan_id, url, markers, apibase, password, qrcode_contents, do_sifting):
    """
    """
    scan_url_match = re.match(r'^http://.+/scans/([^/]+)/(.*)$', url, re.I)
    any_url_match = re.match(r'^http://.+/([^/]+)$', url, re.I)
    
    if scan_id and any_url_match:
        uploaded_file = any_url_match.group(1)
    
    elif scan_url_match:
        scan_id = scan_url_match.group(1)
        uploaded_file = scan_url_match.group(2)

    else:
        print >> sys.stderr, url, "doesn't match expected form"
        return

    # shorthand
    updateStepLocal = lambda step_number, extras: updateStep(apibase, password, scan_id, step_number, extras)
    
    try:
        if do_sifting:
            # sifting
            updateStepLocal(STEP_SIFTING, None)
            yield 60
            
            image, features, scale = siftImage(url)
            
            sifted_bytes = StringIO.StringIO()
            
            for feature in features:
                print >> sifted_bytes, matchup.feature2row(feature)
            
            sifted_name = 'sift.txt'
            sifted_bytes = sifted_bytes.getvalue()
            appendScanFile(scan_id, sifted_name, sifted_bytes, apibase, password)
            
            # finding needles
            updateStepLocal(STEP_FINDING_NEEDLES, None)
            yield 30
            
            # remove just the sticker from the markers dict
            stickers, sticker = [], markers.pop('Sticker', None)
            
            for marker in sticker.markersInFeatures(features):
                x, y = int(marker.anchor.x / scale), int(marker.anchor.y / scale)
                print >> sys.stderr, '->', (x, y)
        
                marker.anchor = Point(x, y)
                stickers.append(marker)
            
            for (name, marker) in markers.items():
                print >> sys.stderr, name, '...',
                marker.locateInFeatures(features)
        
                x, y = int(marker.anchor.x / scale), int(marker.anchor.y / scale)
                print >> sys.stderr, '->', (x, y)
        
                marker.anchor = Point(x, y)
        
        else:
            image = loadImage(url)
            stickers = False
        
        if qrcode_contents:
            print_id, north, west, south, east = interpretCode(qrcode_contents)

        else:
            # reading QR code
            updateStepLocal(STEP_READING_QR_CODE, None)
            yield 10
            
            qrcode = extractCode(image, markers)
            uploadScanCodeImage(apibase, password, scan_id, qrcode)
            
            print_id, north, west, south, east = readCode(qrcode)

        print 'code contents:', 'Print', print_id, (north, west, south, east)
        
        # tiling and uploading
        updateStepLocal(STEP_TILING_UPLOADING, None)
        yield 180

        gym = ModestMaps.OpenStreetMap.Provider()
        
        topleft = gym.locationCoordinate(ModestMaps.Geo.Location(north, west)).zoomTo(20)
        bottomright = gym.locationCoordinate(ModestMaps.Geo.Location(south, east)).zoomTo(20)
        
        print 'Coordinates:', topleft, bottomright
        print 'Mercator:', poorMansSphericalMercator(topleft), poorMansSphericalMercator(bottomright)

        uploadScanImages(apibase, password, scan_id, image)
        uploadGeoTiff(apibase, password, markers, scan_id, image, topleft, bottomright)
        
        if stickers:
            uploadScanStickers(apibase, password, scan_id, markers, stickers, topleft, bottomright)
        
        min_zoom, max_zoom = 20, 0
        
        renders = {}
        
        for zoom in range(20, 0, -1):
            localTopLeft = topleft.zoomTo(zoom)
            localBottomRight = bottomright.zoomTo(zoom)

            zoom_renders = tileZoomLevel(image, localTopLeft, localBottomRight, markers, renders)
            
            for (coord, tile_image) in zoom_renders:
                x, y, z = coord.column, coord.row, coord.zoom
                tile_name = '%(z)d/%(x)d/%(y)d.jpg' % locals()
                
                tile_bytes = StringIO.StringIO()
                tile_image.save(tile_bytes, 'JPEG')
                tile_bytes = tile_bytes.getvalue()

                appendScanFile(scan_id, tile_name, tile_bytes, apibase, password)
            
                renders[str(coord)] = tile_image
                
                min_zoom = min(coord.zoom, min_zoom)
                max_zoom = max(coord.zoom, max_zoom)
        
        print 'min:', topleft.zoomTo(min_zoom)
        print 'max:', bottomright.zoomTo(max_zoom)
        
        # finished!
        updateScan(apibase, password, scan_id, uploaded_file, print_id, bool(stickers), topleft.zoomTo(min_zoom), bottomright.zoomTo(max_zoom))
        updateStepLocal(STEP_FINISHED, None)

        yield ALL_FINISHED

    except CodeReadException:
        print 'Failed QR code, maybe will try again?'
    
        extras = [(name, marker.anchor) for (name, marker) in markers.items()]
        extras = [(name, {'x': anch.x, 'y': anch.y}) for (name, anch) in extras]
        extras = {'image_url': url, 'markers': dict(extras)}
        updateStepLocal(STEP_BAD_QRCODE, json.dumps(extras))
        
        yield ALL_FINISHED
    
    except UpdateScanException:
        print 'Giving up after many scan update attempts'
        yield ALL_FINISHED
    
    except KeyboardInterrupt, e:
        yield 1
        raise e