Ejemplo n.º 1
0
def put_tile(request: HttpRequest,
             project_id=None,
             stack_id=None) -> HttpResponse:
    """ Store labels to HDF5 """

    if not tile_loading_enabled:
        raise ConfigurationError("HDF5 tile loading is currently disabled")

    scale = float(request.POST.get('scale', '0'))
    height = int(request.POST.get('height', '0'))
    width = int(request.POST.get('width', '0'))
    x = int(request.POST.get('x', '0'))
    y = int(request.POST.get('y', '0'))
    z = int(request.POST.get('z', '0'))
    col = request.POST.get('col', 'y')
    row = request.POST.get('row', 'x')
    image = request.POST.get('image', 'x')

    fpath = os.path.join(settings.HDF5_STORAGE_PATH,
                         f'{project_id}_{stack_id}.hdf')

    with closing(h5py.File(fpath, 'a')) as hfile:
        hdfpath = '/labels/scale/' + str(int(scale)) + '/data'
        image_from_canvas = np.asarray(
            Image.open(BytesIO(base64.decodestring(image))))
        hfile[hdfpath][y:y + height, x:x + width, z] = image_from_canvas[:, :,
                                                                         0]

    return HttpResponse("Image pushed to HDF5.", content_type="plain/text")
Ejemplo n.º 2
0
def get_tile(request: HttpRequest,
             project_id=None,
             stack_id=None) -> HttpResponse:

    if not tile_loading_enabled:
        raise ConfigurationError("HDF5 tile loading is currently disabled")

    scale = float(request.GET.get('scale', '0'))
    height = int(request.GET.get('height', '0'))
    width = int(request.GET.get('width', '0'))
    x = int(request.GET.get('x', '0'))
    y = int(request.GET.get('y', '0'))
    z = int(request.GET.get('z', '0'))
    col = request.GET.get('col', 'y')
    row = request.GET.get('row', 'x')
    file_extension = request.GET.get('file_extension', 'png')
    basename = request.GET.get('basename', 'raw')

    # need to know the stack name
    fpath = os.path.join(
        settings.HDF5_STORAGE_PATH,
        '{0}_{1}_{2}.hdf'.format(project_id, stack_id, basename))

    if not os.path.exists(fpath):
        data = np.zeros((height, width))
        pilImage = Image.frombuffer('RGBA', (width, height), data, 'raw', 'L',
                                    0, 1)
        response = HttpResponse(content_type="image/png")
        pilImage.save(response, "PNG")
        return response
        # return HttpResponse(json.dumps({'error': 'HDF5 file does not exists: {0}'.format(fpath)}))

    with closing(h5py.File(fpath, 'r')) as hfile:
        #import math
        #zoomlevel = math.log(int(scale), 2)
        hdfpath = '/' + str(int(scale)) + '/' + str(z) + '/data'
        if not str(int(scale)) in hfile['/'].keys():
            data = np.zeros((height, width))
            pilImage = Image.frombuffer('RGBA', (width, height), data, 'raw',
                                        'L', 0, 1)
            response = HttpResponse(content_type="image/png")
            pilImage.save(response, "PNG")
            return response
            # return HttpResponse(json.dumps({'error': 'HDF5 file does not contain scale: {0}'.format(str(int(scale)))}))
        image_data = hfile[hdfpath]
        data = image_data[y:y + height, x:x + width]
        pilImage = Image.frombuffer('RGBA', (width, height), data, 'raw', 'L',
                                    0, 1)
        response = HttpResponse(content_type="image/png")
        pilImage.save(response, "PNG")
        return response

    return response
Ejemplo n.º 3
0
def get_hdf5_tile(project_id, stack_id, scale, height, width, x, y, z, col,
                  row, file_extension, basename):
    if not tile_loading_enabled:
        raise ConfigurationError("HDF5 tile loading is currently disabled")
    # need to know the stack name
    fpath = os.path.join(settings.HDF5_STORAGE_PATH,
                         f'{project_id}_{stack_id}_{basename}.hdf')

    if not os.path.exists(fpath):
        data = np.zeros((height, width))
        pilImage = Image.frombuffer('RGBA', (width, height), data, 'raw', 'L',
                                    0, 1)
        response = HttpResponse(content_type="image/png")
        pilImage.save(response, "PNG")
        return response

    with closing(h5py.File(fpath, 'r')) as hfile:
        # import math
        # zoomlevel = math.log(int(scale), 2)
        hdfpath = '/' + str(int(scale)) + '/' + str(z) + '/data'
        if not str(int(scale)) in hfile['/'].keys():
            data = np.zeros((height, width))
            pilImage = Image.frombuffer('RGBA', (width, height), data, 'raw',
                                        'L', 0, 1)
            response = HttpResponse(content_type="image/png")
            pilImage.save(response, "PNG")
            return response
        image_data = hfile[hdfpath]
        data = image_data[y:y + height, x:x + width]
        pilImage = Image.frombuffer('RGBA', (width, height), data, 'raw', 'L',
                                    0, 1)
        response = HttpResponse(content_type="image/png")
        pilImage.save(response, "PNG")
        return response

    return response
Ejemplo n.º 4
0
def get_cloudvolume_tile(project_id,
                         stack_id,
                         scale,
                         height,
                         width,
                         x,
                         y,
                         z,
                         col,
                         row,
                         file_extension='png',
                         basename=None,
                         fill_missing=False,
                         cache=True,
                         upscale=False):
    if not cv_tile_loading_enabled:
        raise ConfigurationError(
            "CloudVolume tile loading is currently disabled")

    if upscale:
        mip = math.ceil(abs(math.log(scale) / math.log(2)))
    else:
        mip = math.floor(abs(math.log(scale) / math.log(2)))
    scale_to_fit = False
    effective_scale = 1.0
    voxel_offset = (0, 0, 0)
    try:
        cv = cloudvolume.CloudVolume(basename,
                                     use_https=True,
                                     parallel=False,
                                     cache=cache,
                                     mip=mip,
                                     bounded=False,
                                     fill_missing=fill_missing)
        cutout = cv[x:(x + width), y:(y + height), z]
    except cloudvolume.exceptions.ScaleUnavailableError as e:
        logger.info(
            f'Need to use extra scaling, because mip level {mip} is not available: {e}'
        )
        cv_test = cloudvolume.CloudVolume(basename,
                                          use_https=True,
                                          parallel=False,
                                          cache=cache,
                                          bounded=False,
                                          fill_missing=fill_missing)
        # Find mip closest to the request
        min_mip = None
        min_mip_dist = float('infinity')
        for ex_mip in cv_test.available_mips:
            if abs(mip - ex_mip) < min_mip_dist:
                min_mip = ex_mip
                min_mip_dist = abs(mip - ex_mip)

        if min_mip is None:
            raise ValueError('No fitting scale level found')

        # Get volume with best fit
        cv = cloudvolume.CloudVolume(basename,
                                     use_https=True,
                                     parallel=False,
                                     cache=cache,
                                     mip=min_mip,
                                     bounded=False,
                                     fill_missing=fill_missing)
        effective_scale = 2**mip / 2**min_mip

        # TODO: Correctly walk downsample factors / scale levels in each
        # dimensions for exact scaling in non power-of-two scale pyramids.
        scale_to_fit = True
        x, y = math.floor(x * effective_scale), math.floor(y * effective_scale)
        width, height = math.ceil(width * effective_scale), math.ceil(
            height * effective_scale)

    cutout = cv[(x + cv.voxel_offset[0]):(x + cv.voxel_offset[0] + width),
                (y + cv.voxel_offset[1]):(y + cv.voxel_offset[1] + height), z]

    if cutout is None:
        data = np.zeros((height, width))
    else:
        data = np.transpose(cutout[:, :, 0, 0])

    img = Image.frombuffer('RGBA', (width, height), data, 'raw', 'L', 0, 1)

    if scale_to_fit:
        img = img.resize((math.ceil(width / effective_scale),
                          math.ceil(height / effective_scale)))

    response = HttpResponse(content_type=f"image/{file_extension.lower()}")
    img.save(response, file_extension.upper())
    return response