Пример #1
0
    def build_superworld(world, new_size):
        p = int(
            math.log2(len(world))
        ) + 1  # 2^p is number of points along each dimention of the space
        hc = HilbertCurve(p, 2)
        node_seq_coords = [(hc.distance_from_coordinates(n[1]['coords']), n[0])
                           for n in world.nodes(data=True)]
        node_seq_coords.sort()
        chunks = np.array_split(node_seq_coords, new_size)
        center_nodes = [chunk[len(chunk) // 2][1] for chunk in chunks]
        node_mapping = nx.voronoi_cells(world, center_nodes)

        new_nodes = []
        i = 0
        for center_node in center_nodes:
            new_nodes.append((i, {"nodes": node_mapping[center_node]}))
            for n in node_mapping[center_node]:
                world.nodes[n]['supernode'] = i
            i += 1
        superworld = nx.Graph(
        )  # we always use graph to simplify training, for both world and superworld
        superworld.add_nodes_from(new_nodes)
        # we assume all areas are approximately the same size, so we add edges in superworld of the same length
        edges = set()
        for e in world.edges():
            n1 = world.nodes[e[0]]['supernode']
            n2 = world.nodes[e[1]]['supernode']
            if n1 != n2 and (n1, n2) not in edges:
                edges.add((n1, n2))
        superworld.add_edges_from(list(edges))

        return superworld
Пример #2
0
class S3DISDataset(Dataset):
    def __init__(self, data_label, num_features=9, augment=False):
        self.augment = augment
        self.num_features = num_features
        self.data, self.label = data_label
        self.p = 7

        # compute hilbert order for voxelized space
        logging.info('Computing hilbert distances...')
        self.hilbert_curve = HilbertCurve(self.p, 3)

    def __len__(self):
        return self.data.shape[0]

    def __getitem__(self, item):
        pointcloud = self.data[item, ...]
        label = self.label[item, ...]

        if self.augment:
            points = pointcloud[:, :3]
            points = rotate_points(points)
            points = scale_points(points)
            points = add_noise_points(points)

            pointcloud[:, :3] = points

        # get coordinates
        coordinates = pointcloud[:, :3] - pointcloud[:, :3].min(axis=0)

        # compute hilbert order
        points_norm = pointcloud[:, :3] - pointcloud[:, :3].min(axis=0)
        points_norm /= points_norm.max(axis=0) + 1e-23

        # order points in hilbert order
        points_voxel = np.floor(points_norm * (2**self.p - 1))
        hilbert_dist = np.zeros(points_voxel.shape[0])
        for i in range(points_voxel.shape[0]):
            hilbert_dist[i] = self.hilbert_curve.distance_from_coordinates(
                points_voxel[i, :].astype(int))
        idx = np.argsort(hilbert_dist)

        # return appropriate number of features
        if self.num_features == 4:
            pointcloud = np.hstack(
                (pointcloud[:, 3:6], pointcloud[:, 2, np.newaxis]))
        elif self.num_features == 5:
            pointcloud = np.hstack((np.ones(
                (pointcloud.shape[0], 1)), pointcloud[:, 3:6],
                                    pointcloud[:, 2, np.newaxis]))
        elif self.num_features == 9:
            min_val = pointcloud[:, :3].min(axis=0)
            pointcloud = np.hstack((pointcloud[:, :3] - min_val,
                                    pointcloud[:, 3:6], pointcloud[:, 6:9]))
        else:
            raise ValueError(
                'Incorrect number of features provided. Values should be 4, 5, or 9, but {} provided'
                .format(self.num_features))

        return pointcloud[idx, :], coordinates[idx, :], label[idx]
Пример #3
0
def hilbert_sort(conf, D):
    hc = HilbertCurve(64, D)
    int_confs = (conf * 1000).astype(np.int64)
    dists = []
    for xyz in int_confs.tolist():
        dist = hc.distance_from_coordinates(xyz)
        dists.append(dist)
    perm = np.argsort(dists)
    return perm
Пример #4
0
def hilbert_distance(coordinates, iterations=5):
    count_entries, dims = coordinates.shape
    distances = np.zeros([count_entries])
    cells = 2**(iterations * dims)
    transform = HilbertCurve(iterations, dims)
    mm = MinMaxScaler((0, transform.max_x))
    normed_coords = np.rint(mm.fit_transform(coordinates)).astype('int')

    for i in range(len(coordinates)):
        distances[i] = transform.distance_from_coordinates(normed_coords[i])
    return distances
class ModelNet40(Dataset):
    def __init__(self, root_dir, phase='train', augment=False):
        self.phase = phase
        self.augment = augment
        self.data, self.label = load_data(root_dir=root_dir, phase=phase)
        self.p = 7  # hilbert iteration
        # by changing the value of p, we can control the level of hilbert curve.
        # this hyperparameter has to be careful and ideally, p should be different for each point cloud.
        # (because the density distribution is different

        # compute hilbert order for voxelized space
        logging.info('Computing hilbert distances...')
        self.hilbert_curve = HilbertCurve(self.p, 3)
        # different from voxelization, we are much more efficient

    def __len__(self):
        return self.data.shape[0]

    def __getitem__(self, item):
        pointcloud = self.data[item, ...]
        label = self.label[item]

        # augment data when requested
        if self.augment:
            pointcloud = rotate_pointcloud(pointcloud)
            # pointcloud = translate_pointcloud(pointcloud)
            pointcloud = scale_pointcloud(pointcloud)
            # pointcloud = shear_pointcloud(pointcloud)
            # todo: check if it is because of augmentation being too big.

        # normalize points
        points_norm = pointcloud - pointcloud.min(axis=0)
        points_norm /= points_norm.max(axis=0) + 1e-23

        # order points in hilbert order
        points_voxel = np.floor(points_norm * (2**self.p - 1))
        hilbert_dist = np.zeros(points_voxel.shape[0])

        # todo: we want to try two methods.
        # todo: 1. globally along with locally hilbert curve
        # todo: 2. multi-level of hilbert curve

        for i in range(points_voxel.shape[0]):
            # by doing the astype int, it will assign the same hilbert_dist to the points that belong to the same space
            # todo: check how much duplicates (multi-points in the same space).
            #  answer is no. p is 7, which partition the space very precise
            hilbert_dist[i] = self.hilbert_curve.distance_from_coordinates(
                points_voxel[i, :].astype(int))
        idx = np.argsort(hilbert_dist)

        return pointcloud[idx, :], label
Пример #6
0
def assign_hilbert_curve(normals: np.ndarray):
    dtype = np.uint32
    max_length_axis = 2**16 - 1
    bucket_normals = normals
    bucket_normals_xy = (azimuth_equidistant(bucket_normals) *
                         max_length_axis).astype(dtype)
    # print(bucket_normals_xy)
    hilbert_curve = HilbertCurve(16, 2)
    bucket_normals_hv = []
    for i in range(bucket_normals_xy.shape[0]):
        hv = hilbert_curve.distance_from_coordinates(bucket_normals_xy[i, :])
        bucket_normals_hv.append(hv)
    bucket_normals_hv = np.array(bucket_normals_hv)
    return bucket_normals_hv
Пример #7
0
 def encode_sfc(points, M=3, p=10):
     """
         points = [N, D, M]
     """
     hilbert_curve = HilbertCurve(p, M)
     num_points = 2 ** (M*p) - 1
     grid_size = 2**p - 1
     N = points.shape[0]
     D = points.shape[1]
     s = np.zeros((N, D))
     for i in range(N):
         for j in range(D):
             # change to integer
             coords = points[i, j, :] * grid_size + 0.5
             coords = coords.astype(int)
             dist = hilbert_curve.distance_from_coordinates(coords)
             s[i, j] = dist/num_points
     return s
def hilbert(df,
            iterations=12,
            dim=2,
            delete_temp_features=True,
            use_grouping=True):
    """iterations = 4: i.e. 256 cells (2^(p*n)). Frame cannot use multiindexing when use_grouping is true."""
    cells = 2**(iterations * dim)

    xy_transform = HilbertCurve(iterations, dim)
    mm = MinMaxScaler((0, xy_transform.max_x))
    minmax = lambda x: mm.fit_transform(np.rint(x.values.reshape(-1, 1)))
    df["_x_hnorm"] = minmax(np.rint(df.x))
    df["_y_hnorm"] = minmax(np.rint(df.y))
    unique_xy = df[["_x_hnorm", "_y_hnorm"]].drop_duplicates().values
    print("Found", len(unique_xy), "unique positions.")

    distance_by_xy = {}
    for i in unique_xy:
        distance_by_xy[tuple(i)] = xy_transform.distance_from_coordinates(
            [int(i[0]), int(i[1])])

    if use_grouping:
        import dask.dataframe as dd

        to_group = df  # [['_x_hnorm', '_y_hnorm']]
        grouped = to_group.groupby(["_x_hnorm", "_y_hnorm"])

        def do(group):
            first = group.iloc[0]
            coordinates = (first["_x_hnorm"], first["_y_hnorm"])
            group["hilbert_distance"] = distance_by_xy[coordinates]
            return group.reset_index(drop=True)

        df = grouped.apply(do)
    else:
        df["hilbert_distance"] = df[["_x_hnorm", "_y_hnorm"]].apply(
            lambda xy: distance_by_xy[tuple(xy)], axis=1)  # XXX: very slow

    df["hilbert_distance"] /= cells

    if delete_temp_features:
        df.drop(columns=["_x_hnorm", "_y_hnorm"], inplace=True)
    return df.reset_index(drop=True)
Пример #9
0
class S3DIS(Dataset):
    def __init__(self, data_label, augment=False):
        self.augment = augment
        self.data, self.label = data_label
        self.p = 7
        # compute hilbert order for voxelized space
        logging.info('Computing hilbert distances...')
        self.hilbert_curve = HilbertCurve(self.p, 3)

    def __len__(self):
        return self.data.shape[0]

    def __getitem__(self, item):
        pointcloud = self.data[item, ...]
        label = self.label[item, ...]
        # nns = self.adj[item, ...]

        if self.augment:
            pointcloud = utl.augment_point_cloud(pointcloud)

        # normalize points
        points_norm = pointcloud - pointcloud.min(axis=0)
        points_norm /= points_norm.max(axis=0) + 1e-23

        # order points in hilbert order
        points_voxel = np.floor(points_norm * (2**self.p - 1))
        hilbert_dist = np.zeros(points_voxel.shape[0])

        # todo: we want to try two methods.
        # todo: 1. globally along with locally hilbert curve
        # todo: 2. multi-level of hilbert curve

        for i in range(points_voxel.shape[0]):
            # by doing the astype int, it will assign the same hilbert_dist to the points that belong to the same space
            # todo: check how much duplicates (multi-points in the same space).
            #  answer is no. p is 7, which partition the space very precise
            hilbert_dist[i] = self.hilbert_curve.distance_from_coordinates(
                points_voxel[i, 0:3].astype(int))
        idx = np.argsort(hilbert_dist)

        return pointcloud[idx, :], label[
            idx]  # todo: label also need indexing.
class ModelNet40(Dataset):
    def __init__(self, root_dir, phase='train', augment=False):
        self.phase = phase
        self.augment = augment
        self.data, self.label = load_data(root_dir=root_dir, phase=phase)
        self.p = 7

        # compute hilbert order for voxelized space
        logging.info('Computing hilbert distances...')
        self.hilbert_curve = HilbertCurve(self.p, 3)

    def __len__(self):
        return self.data.shape[0]

    def __getitem__(self, item):
        pointcloud = self.data[item, ...]
        label = self.label[item]

        # augment data when requested
        if self.augment:
            pointcloud = rotate_pointcloud(pointcloud)
            # pointcloud = translate_pointcloud(pointcloud)
            pointcloud = scale_pointcloud(pointcloud)
            # pointcloud = shear_pointcloud(pointcloud)

        # normalize points
        points_norm = pointcloud - pointcloud.min(axis=0)
        points_norm /= points_norm.max(axis=0) + 1e-23

        # order points in hilbert order
        points_voxel = np.floor(points_norm * (2**self.p - 1))
        hilbert_dist = np.zeros(points_voxel.shape[0])
        for i in range(points_voxel.shape[0]):
            hilbert_dist[i] = self.hilbert_curve.distance_from_coordinates(
                points_voxel[i, :].astype(int))
        idx = np.argsort(hilbert_dist)

        return pointcloud[idx, :], label
Пример #11
0
def test_distance_from_coordinates(p, n):
    side_len = 2**p

    # build matrix of all possible coordinate
    coords = np.array(list(product(range(side_len), repeat=n)))

    # Compute distances as vector result
    vector_result = distances_from_coordinates(p, coords)

    # Compare with reference
    reference_hc = HilbertCurve(p, n)
    for i in range(coords.shape[0]):
        coord = coords[i, :]

        # Reference
        expected = reference_hc.distance_from_coordinates(coord)

        # Compute scalar distance and compare
        scalar_result = distance_from_coordinate(p, coord)
        assert scalar_result == expected

        # Compare with vector distance compute above
        assert vector_result[i] == expected
Пример #12
0
class Converter():
    def __init__(self,
                 method,
                 image_path,
                 max_freq=18000,
                 min_freq=30,
                 im=None,
                 resolution=16,
                 tone_length=1):

        # Paramters of Conversion
        self.method = method

        self.min_freq = min_freq
        self.max_freq = max_freq
        self.null_colour = "black"  #background colour
        self.force_null = False  #normalises colour to have lowest brightness = 0
        self.sample_rate = 44100.0
        self.max_vol = 1
        self.tone_length = tone_length  # in seconds

        self.resolution = resolution

        self.image_path = image_path  # for reading image (uploaded)
        self.audio_loc = "./audio/"  #  for saving audio

        # Doesn't have image path when live-streaming
        if image_path:
            # defines name for audio file
            self.audio_path = self.audio_loc + image_path.split("/")[-1].split(
                ".")[0] + ".wav"
            #reads image as greyscale
            self.im = imageio.imread(image_path,
                                     ignoregamma=True,
                                     as_gray=True)
        else:
            #When live streaming, images are fed in from camera
            self.im = im

        # Read image size
        self.image_size_x = len(self.im)
        self.image_size_y = len(self.im[0])

        #If still image and it's not the right format, reformat
        #For livestream images supplied are already right format, no need to check
        if not self.is_right_format() and self.image_path:
            self.reformat()

        # If hilbert is used, initialise the hilbert curve from library
        if self.method == "hilbert":
            #requires values p, N for initialisation

            #variable resolution hilbert curve
            p = int(np.log2(self.image_size_x))  # 2^(2p) pixels in image
            N = 2  # number of dimensions, for images always 2

            #initialise curve
            self.hilbert_curve = HilbertCurve(p, N)
            #get maximum distance from starting point on hilbert curve, this
            #acts as a reference point for conversion
            self.max_dist = self.hilbert_curve.distance_from_coordinates(
                [2**p - 1, 0])

        if self.method == "l2r":
            self.max_dist = self.image_size_x * self.image_size_y

        # logspace is needed because tones are logarithmically spaced for human hearing
        self.logspace = np.logspace(np.log2(min_freq),
                                    np.log2(self.max_freq),
                                    self.max_dist,
                                    base=2)

        # Phase of sin-waves are initially 0, keep track of this for video,
        # so that waves are continuous when new frame is calculated
        self.phase = {freq: 0 for freq in self.logspace}

        # Keeps track of previous volume to emphasize change
        self.prev_volume = {vol: 0 for vol in self.logspace}

        return

    def set_audio_path(self, audio_path):
        self.audio_loc = audio_path
        return

    def set_null_colour(self, colour):
        self.null_colour = colour
        return

    def is_right_format(self):
        return self.image_size_x == self.image_size_y and type(
            self.im[0][0]) == np.float

    def reformat(self):
        #makes image have the correct format by saving image and using PIL library
        im = PIL.Image.open(self.image_path)
        im_resized = im.resize((self.resolution, self.resolution),
                               PIL.Image.ANTIALIAS)
        new_name = ".".join(self.image_path.split(".")[0:-1]) + "_reduced.png"
        im_resized.save(new_name)
        self.im = imageio.imread(new_name, ignoregamma=True, as_gray=True)
        self.image_size_x = len(self.im)
        self.image_size_y = len(self.im[0])

    def coord_to_freq(self, x, y):
        '''
        Converts x,y position of pixel to corresponding frequency, wraps actual
        conversion functions
        --------------------------------------------------------------------
        Inputs:
            x, y: position of pixel
        --------------------------------------------------------------------
        Outputs:
            frequency
        '''
        if self.method == "hilbert":
            return self.get_hilbert_freq(x, y)
        elif self.method == "l2r":
            return self.get_l2r_freq(x, y)

    def get_l2r_freq(self, x, y):
        '''
        Converts x,y position of pixel to corresponding frequency using l2r
        method
        --------------------------------------------------------------------
        Inputs:
            x, y: position of pixel
        --------------------------------------------------------------------
        Outputs:
            frequency
        '''
        # calculates distance
        dist = y * self.image_size_x + x
        # checks that the distance is smaller than max
        assert (dist <= self.max_dist), "x = " + str(x) + " y = " + str(y)
        # returns logarithmically spaced frequency
        return self.logspace[dist - 1]

    def get_hilbert_freq(self, x, y):
        '''
        Converts x,y position of pixel to corresponding frequency using pseudo-
        hilbert-curve
        --------------------------------------------------------------------
        Inputs:
            x, y: position of pixel
        --------------------------------------------------------------------
        Outputs:
            frequency
        '''
        #calculates distance along our hilbert curve
        dist = self.hilbert_curve.distance_from_coordinates([x, y])
        #checks that the distance is smaller than max
        assert (dist <= self.max_dist), "x = " + str(x) + " y = " + str(y)
        # returns logarithmically spaced frequency
        return self.logspace[dist - 1]

    def brightness_to_volume(self, x, y):
        '''
        Converts pixel brightness at x,y position to volume through linear mapping.
        --------------------------------------------------------------------
        Inputs:
            x, y: position of pixel
        --------------------------------------------------------------------
        Outputs:
            volume (amplitude) could consider squared mapping for intensity as I~A^2
        '''
        # maximum brightness, white pixel has this value
        max_brightness = 255

        # for white background
        if self.null_colour == "white":
            #divides pixel brightness by max brightness to get relative brightness
            #multiplies by maximum volume.
            #This ensures that brightness 0   --> volume = 0
            #                  max brightness --> max volume
            return self.im[y][
                x] / max_brightness * self.max_vol  # USE THIS FOR 0 VOLUME = WHITE
        else:
            # for black background subtract 255 from brightness and multiply by -1
            #This ensures that white    --> volume = 0
            #                  black    --> max volume
            return -(
                self.im[y][x] - 255
            ) / max_brightness * self.max_vol  #use this for 0 volume = black

    def f2i(self, f):
        #maps frequency to corresponding index
        return int(self.tone_length * f)

    def complex_entry(self, mag, angle):
        # needed for fourier transform
        return mag * np.exp(1j * angle)

    def convert(self):
        '''
        Converts image to time-signal audio
        --------------------------------------------------------------------
        Inputs: (set by class)
        --------------------------------------------------------------------
        Returns:
            np.array() holding audio data at specified sample rate
        '''

        # set up initial frequency spectrum as zeros. Needs to have this length
        # to then have inverse fourier transform of desired SR, tone length
        spectrum = np.zeros(int(self.sample_rate * self.tone_length),
                            dtype=np.csingle)

        lowest_vol = 1  #is updated later

        if self.method != "spectrogram":
            # spectrogram, not yet implemented, has to be fundamentally differently calculated

            # loop through rows
            for y, row in enumerate(self.im):
                # every new row, update progress bar in gui, not really important
                self.progress = 80 * y / self.image_size_y  #80% of time taken by this

                #loop through pixels
                for x, pixel in enumerate(row):

                    # get volume
                    initial_volume = self.brightness_to_volume(x, y)
                    # get frequency
                    freq = self.coord_to_freq(x, y)
                    #set new phases
                    self.phase[
                        freq] = 2 * np.pi * freq * self.tone_length + self.phase[
                            freq]

                    #volume is driven by how much pixel changed, at least 0.01, at most 1
                    volume = max(
                        min(abs(self.prev_volume[freq] - initial_volume), 1),
                        0.01)

                    # spectrum is mostly empty, use f2i() to get correct index corresponding to right frequency
                    spectrum[self.f2i(freq)] = self.complex_entry(
                        volume, self.phase[freq])

                    # update lowest volume
                    lowest_vol = min(volume, lowest_vol)

                    #keep track of volume changes for next iteration
                    self.prev_volume[freq] = initial_volume

        if self.force_null:
            # if we force the lowest entry to be 0 (normalise), subtract lowest volume from all
            spectrum -= lowest_vol
        # now iFFT (inverse fast fourier transform) frequency spectrum to get audio signal
        self.audio = np.real(
            fft.ifft(spectrum, self.tone_length * self.sample_rate))
        self.audio = self.audio / max(
            self.audio)  #normalise audio to not be too loud/quiet

        return self.audio

    def rgb2gray(self):
        self.im = np.dot(self.im[..., :3], [0.2989, 0.5870, 0.1140])
        return

    def save_audio(self, audio=None):
        audio_path = self.audio_loc + self.image_path.split("/")[-1].split(
            ".")[0] + ".wav"
        if not audio:
            wavfile.write(self.audio_path, int(self.sample_rate), self.audio)
        else:
            wavfile.write(self.audio_path, int(self.sample_rate), audio)
        return os.path.abspath(audio_path)

    def set_phase(self, phase):
        self.phase = phase

    def set_prev_vol(self, vol):
        self.prev_volume = vol

    def save_wav(self, audio, file_name):
        wavfile.write(file_name, int(self.sample_rate), audio)
        return
Пример #13
0
def Hilbert_Mapping(x, p=8, dim=10):
    hilbert_curve = HilbertCurve(p, dim)
    aa = [int(xx) for xx in x * 2**p]
    h = hilbert_curve.distance_from_coordinates(aa)
    h = np.array(h / (2**(p * dim)))
    return h
import numpy as np
from hilbertcurve.hilbertcurve import HilbertCurve
from matplotlib.pyplot import *
import cv2

image = cv2.imread('suro.jpg')
dim = image.shape
center = round(dim[0] / 2)
start = center - 170
end = center + 86

reshaped_img = image[start:end, start:end, :]
p = 8
N = 3
hill_curve = HilbertCurve(p, N)

frequencies = []
for i in range(256 * 256):
    frequency = hill_curve.distance_from_coordinates(
        np.reshape(reshaped_img, (256 * 256, 3))[i])
    frequencies.append(frequency)
print(frequencies)

sampling_rate = 44100
# data = np.random.uniform(-1,1,44100) # 44100 random samples between -1 and 1
# scaled = np.int16(data/np.max(np.abs(data)) * 32767)
frequencies = np.asarray(frequencies)
frequencies = np.interp(frequencies, (frequencies.min(), frequencies.max()),
                        (2000, 20 * 1000))
write('test.wav', sampling_rate, frequencies)
Пример #15
0
class Hilbertize:
    """Transforms a batch of coordinates from Euclidean space to pseudo Hilbert distances space."""
    # angle that maximizes separation between two Hilbert distance measures
    ANGLE = np.deg2rad(45)

    def __init__(
        self, rotation_axis=((0, 1), (1, 2), (3, 0)), dimension_columns = ['x','y','z','t'], iterations=10
    ):
        # TODO: document rotation_axis
        self.rotation_axis = rotation_axis
        self.dimension_columns = dimension_columns
        self.dims = len(dimension_columns)
        self.dims_output =  1+ len(self.rotation_axis)
        self.cells = 2 ** (iterations * self.dims)
        self.transform = HilbertCurve(iterations, self.dims)
        self.scale_factor = self.transform.max_x
        self.edge_resolution = self.transform.max_x
        
    def _get_output_column_names(self):
        return [f"hilbert_{i}" for i in range(self.dims_output)]

    def __str__(self):
        return (
            f"Hilbertize from {self.dims}D, "
            f"resolution by edge: {self.edge_resolution+1}, "
            f"resolution by volume: {self.cells:.1e} cells."
        )

    def __call__(self, x:pd.DataFrame):
        coordinates = x[self.dimension_columns].values
        non_coordinates = x.drop(columns=self.dimension_columns)
        
        waveforms, dimensions = coordinates.shape
        assert dimensions == self.dims
        assert np.all(coordinates >= 0)
        assert np.all(coordinates <= 1)

        coordinates -= 0.5  # rotate around center of mass
        rotations = [coordinates] + [
            rotate_2d(coordinates, self.ANGLE, *ax) for ax in self.rotation_axis
        ]
        rotations = np.stack(rotations)

        # XXX: this also manipulates all axis that are not part of the rotations
        # this leads to a smaller parameter space, but I'm not sure if that's a bad thing
        rotation_in_01 = rotations / np.sqrt(2) + 0.5
        assert rotation_in_01.max() <= 1
        assert rotation_in_01.min() >= 0

        scaled_rot = rotation_in_01 * self.scale_factor
        scaled_rot = np.rint(scaled_rot).astype("int")

        distances = np.zeros([len(coordinates),self.dims_output])
        for r, coordinates in enumerate(scaled_rot):
            for c, coordinate in enumerate(coordinates):
                distances[c][r] = self.transform.distance_from_coordinates(coordinate)

        distances /= self.cells # scale distances to [0,1]
        
        transformed_x = non_coordinates
        for dim, key in enumerate(self._get_output_column_names()):
            transformed_x[key] = distances[:,dim]
        return transformed_x    
Пример #16
0
class Aceto:
    """ Interpreter object """
    def __init__(self, verbosity, flushness, allerr, encoding):
        self.stacks = defaultdict(list)
        self.sticky = set()
        self.sid = 0
        self.quick = ""
        self.verbosity = verbosity
        self.flushness = flushness
        self.allerr = allerr
        self.encoding = encoding
        # annotate this!
        self.commands = self.get_annotations()

    def get_annotations(self):
        cmds = {}
        d = type(self).__dict__
        for key in d:
            try:
                chars = d[key].__annotations__["return"]
                for c in chars:
                    cmds[c] = d[key]
            except KeyError:
                pass
            except AttributeError:
                pass
        return cmds

    def print_commands(self):
        cols, _ = shutil.get_terminal_size((80, 20))
        info = [f"{c} {f.__name__[1:]}" for c, f in self.commands.items()]
        info.sort()
        maxlen = max(len(x) for x in info) + 1
        columns = cols // maxlen
        iinfo = iter(info)
        end_character = "" if sys.stdout.isatty() else "\n"
        try:
            while True:
                for _ in range(columns):
                    item = next(iinfo)
                    # skip all numbers except for 0
                    while item.startswith(tuple("123456789")):
                        item = next(iinfo)
                    print(item.ljust(maxlen), end=end_character)
                if not end_character:
                    print()
        except StopIteration:
            print()

    @staticmethod
    def load_code_linear(fileobj):
        code_helper = defaultdict(lambda: defaultdict(str))
        chars = "".join(char for line in fileobj for char in line.strip())
        p = (ceil(len(chars)**0.5) - 1).bit_length()
        hilbert = HilbertCurve(p, 2)
        for step, char in enumerate(chars):
            y, x = hilbert.coordinates_from_distance(step)
            code_helper[x][y] = char
        return code_helper, p

    @staticmethod
    def load_code_hilbert(fileobj):
        code = []
        for line in reversed(fileobj.readlines()):
            code.append(list(line.rstrip("\n")))
        return code, (max(len(code), max(map(len, code))) - 1).bit_length()

    def load_code(self, filename, linear_mode=False):
        with open(filename, encoding=self.encoding) as f:
            if linear_mode:
                self.code, self.p = self.load_code_linear(f)
            else:
                self.code, self.p = self.load_code_hilbert(f)
        self.s = 2**self.p
        self.x, self.y = 0, 0
        self.timestamp = time.time()
        self.catch_mark = None
        self.dir = 1
        self.buf = ""
        self.mode = "command"
        self.previous_cmd = " "
        self.hilbert = HilbertCurve(self.p, 2)  # side length p, 2 dimensions

    def run(self):
        while True:
            try:
                self.step()
            except Exception as e:
                if self.catch_mark is not None and not self.allerr:
                    self.log(2, "Caught", e)
                    self.x, self.y = self.catch_mark
                else:
                    raise e

    def push(self, thing):
        self.stacks[self.sid].append(thing)

    def pushiter(self, iterable):
        self.stacks[self.sid].extend(iterable)

    def pop(self):
        try:
            x = self.stacks[self.sid][-1]
            if self.sid not in self.sticky:
                self.stacks[self.sid].pop()
            return x
        except IndexError:
            return 0

    def log(self, level, *pargs, **kwargs):
        if level <= self.verbosity:
            print(Colors.FAIL.value, file=sys.stderr, end="")
            print(*pargs, file=sys.stderr, **kwargs)
            print(Colors.ENDC.value, file=sys.stderr, end="", flush=True)

    def next_coord(self):
        """Return the next coordinate"""
        distance = self.hilbert.distance_from_coordinates([self.y, self.x])
        y, x = self.hilbert.coordinates_from_distance(distance + self.dir)
        return x, y

    def step_command_mode(self, cmd):
        method = self.commands.get(cmd, Aceto._nop)
        method(self, cmd)
        self.previous_cmd = cmd

    def step_string_mode(self, cmd):
        if cmd == '"' and self.mode == "string":
            self.push(self.buf)
            self.buf = ""
            self.mode = "command"
        elif cmd == "\\" and self.mode == "string":
            self.mode = "string-escape"
        elif self.mode == "string-escape" and cmd in "nt":
            self.buf += {"n": "\n", "t": "\t"}[cmd]
            self.mode = "string"
        else:
            self.buf += cmd
            self.mode = "string"
        self.move()

    def step_char_mode(self, cmd):
        if cmd == "\\" and self.mode == "char":
            self.mode = "char-escape"
        elif self.mode == "char-escape" and cmd in "nt":
            self.push({"n": "\n", "t": "\t"}[cmd])
            self.mode = "command"
        else:
            self.push(cmd)
            self.mode = "command"
        self.move()

    def step_escape_mode(self, cmd):
        self.move()
        self.mode = "command"

    def get_command(self):
        try:
            return self.code[self.x][self.y]
        except IndexError:
            return " "  # nop

    def step(self):
        cmd = self.get_command()
        if cmd != " ":
            self.log(1, cmd, end="")
            self.log(2, "\nActive stack:", self.stacks[self.sid])
        if self.mode == "command":
            self.step_command_mode(cmd)
        elif self.mode in ("string", "string-escape"):
            self.step_string_mode(cmd)
        elif self.mode in ("char", "char-escape"):
            self.step_char_mode(cmd)
        elif self.mode == "escape":
            self.step_escape_mode(cmd)
        else:
            raise CodeException("Invalid mode:", self.mode)

    def move(self, coords=None):
        if coords is not None:
            x, y = coords
        else:
            if self.dir == -1 and (0, 0) == (self.x, self.y):
                x, y = -1, -1
            else:
                try:
                    x, y = self.next_coord()
                except ValueError:
                    sys.exit()
        if x >= 2**self.p or y >= 2**self.p or x < 0 or y < 0:
            sys.exit()
        self.x, self.y = x, y

    def _nop(self, cmd) -> " ":
        self.move()

    def _left(self, cmd) -> "<W":
        if cmd == "W":
            self.code[self.x][self.y] = "N"
        self.move((self.x, (self.y - 1) % self.s))

    def _right(self, cmd) -> ">E":
        if cmd == "E":
            self.code[self.x][self.y] = "S"
        self.move((self.x, ((self.y + 1) % self.s)))

    def _down(self, cmd) -> "vS":
        if cmd == "S":
            self.code[self.x][self.y] = "W"
        self.log(
            2,
            f"{self.s} From {self.x},{self.y} to "
            f"{(self.x - 1) % self.s}, {self.y}",
        )
        self.move(((self.x - 1) % self.s, self.y))

    def _up(self, cmd) -> "^N":
        if cmd == "N":
            self.code[self.x][self.y] = "E"
        self.move(((self.x + 1) % self.s, self.y))

    def _numeric(self, cmd) -> "1234567890":
        self.push(int(cmd))
        self.move()

    def _plus(self, cmd) -> "+":
        x = self.pop()
        y = self.pop()
        try:
            self.push(y + x)
            self.move()
        except TypeError:
            raise CodeException(f"Can't add {x!r} to {y!r}")

    def _pow__find_char(self, cmd) -> "F":
        x = self.pop()
        y = self.pop()
        if isinstance(y, Number):
            try:
                self.push(y**x)
            except TypeError:
                raise CodeException(f"Can't raise {y!r} to the power of {x!r}")
        else:
            try:
                self.push(y[x])
            except IndexError:
                raise CodeException("Index out of range")
        self.move()

    def _minus__split1(self, cmd) -> "-":
        x = self.pop()
        if isinstance(x, Number):
            y = self.pop()
            try:
                self.push(y - x)
            except TypeError:
                raise CodeException(f"Can't subtract {x!r} from {y!r}")
        else:
            self.pushiter(reversed(x.split()))
        self.move()

    def _times(self, cmd) -> "*":
        x = self.pop()
        y = self.pop()
        try:
            self.push(y * x)
            self.move()
        except TypeError:
            raise CodeException(f"Can't multiply {x!r} with {y!r}")

    def _mod__re_replace(self, cmd) -> "%":
        x = self.pop()
        y = self.pop()
        if isinstance(x, Number):
            try:
                self.push(y % x)
            except TypeError:
                raise CodeException(f"Can't get modulo of {y!r} and {x!r}")
        else:
            z = self.pop()
            self.push(re.sub(y, z, x))
        self.move()

    def _div__re_matches(self, cmd) -> "/":
        x = self.pop()
        y = self.pop()
        if isinstance(x, Number):
            try:
                self.push(y // x)
            except ZeroDivisionError:
                raise CodeException("Zero division")
            except TypeError:
                raise CodeException(f"Can't idivide {y!r} by {x!r}")
        else:
            self.push(len(re.findall(y, x)))
        self.move()

    def _floatdiv__split2(self, cmd) -> ":":
        x = self.pop()
        if isinstance(x, Number):
            y = self.pop()
            try:
                self.push(y / x)
            except ZeroDivisionError:
                raise CodeException("Zero division")
            except TypeError:
                raise CodeException(f"Can't fdivide {y!r} by {x!r}")
        else:
            y = self.pop()
            self.pushiter(reversed(y.split(x)))
        self.move()

    def _equals(self, cmd) -> "=":
        x = self.pop()
        y = self.pop()
        self.log(2, f"Testing equality of {x!r} and {y!r}")
        self.push(y == x)
        self.move()

    def _print(self, cmd) -> "p":
        print(self.pop(), end="", flush=self.flushness)
        self.move()

    def _print_quick(self, cmd) -> "B":
        print(self.quick, end="", flush=self.flushness)
        self.move()

    def _sticky_mode_on(self, cmd) -> "k":
        self.sticky.add(self.sid)
        self.move()

    def _sticky_mode_off(self, cmd) -> "K":
        self.sticky.remove(self.sid)
        self.move()

    def _newline(self, cmd) -> "n":
        print()
        self.move()

    def _read(self, cmd) -> "r":
        self.push(input().rstrip("\n"))
        self.move()

    def _swap(self, cmd) -> "s":
        x = self.pop()
        y = self.pop()
        self.push(x)
        self.push(y)
        self.move()

    def _cast_int(self, cmd) -> "i":
        x = self.pop()
        try:
            self.push(int(x))
        except ValueError:
            raise CodeException(f"Can't cast {x!r} to int")
        self.move()

    def _cast_bool(self, cmd) -> "b":
        x = self.pop()
        try:
            self.push(bool(x))
        except ValueError:
            raise CodeException(f"Can't cast {x!r} to bool")
        self.move()

    def _cast_string(self, cmd) -> "∑":
        x = self.pop()
        try:
            self.push(str(x))
        except ValueError:
            raise CodeException(f"Can't cast {x!r} to string")
        self.move()

    def _increment(self, cmd) -> "I":
        x = self.pop()
        try:
            self.push(x + 1)
        except Exception:
            self.push(1)
        self.move()

    def _decrement(self, cmd) -> "D":
        x = self.pop()
        try:
            self.push(x - 1)
        except Exception:
            self.push(1)
        self.move()

    def _chr(self, cmd) -> "c":
        x = self.pop()
        try:
            self.push(chr(x))
        except Exception:
            self.push("\ufffd")
        self.move()

    def _ord(self, cmd) -> "o":
        x = self.pop()
        try:
            self.push(ord(x))
        except Exception:
            self.push(0)
        self.move()

    def _cast_float(self, cmd) -> "f":
        x = self.pop()
        try:
            self.push(float(x))
        except Exception:
            self.push(0)
        self.move()

    def _duplicate(self, cmd) -> "d":
        x = self.pop()
        self.push(x)
        self.push(x)
        self.move()

    def _head(self, cmd) -> "h":
        x = self.pop()
        self.stacks[self.sid] = []
        self.push(x)
        self.move()

    def _next_stack(self, cmd) -> ")":
        self.sid += 1
        self.move()

    def _prev_stack(self, cmd) -> "(":
        self.sid -= 1
        self.move()

    def _move_next_stack(self, cmd) -> "}":
        x = self.pop()
        self.sid += 1
        self.push(x)
        self.sid -= 1
        self.move()

    def _move_prev_stack(self, cmd) -> "{":
        x = self.pop()
        self.sid -= 1
        self.push(x)
        self.sid += 1
        self.move()

    def _move_go_next_stack(self, cmd) -> "]":
        x = self.pop()
        self.sid += 1
        self.push(x)
        self.move()

    def _move_go_prev_stack(self, cmd) -> "[":
        x = self.pop()
        self.sid -= 1
        self.push(x)
        self.move()

    def _negation(self, cmd) -> "!":
        self.push(not self.pop())
        self.move()

    def _die(self, cmd) -> "X":
        sys.exit()

    def _mirror_h(self, cmd) -> "|":
        cond = self.pop()
        if cond:
            new_pos = (self.x, 2**self.p - (self.y + 1))
            self.log(2, "Mirroring horizontally from", self.x, self.y, "to",
                     new_pos)
            self.move(new_pos)
        else:
            self.move()

    def _mirror_v(self, cmd) -> "_":
        cond = self.pop()
        if cond:
            new_pos = (2**self.p - (self.x + 1), self.y)
            self.log(2, "Mirroring vertically from", self.x, self.y, "to",
                     new_pos)
            self.move(new_pos)
        else:
            self.move()

    def _mirror_vh(self, cmd) -> "#":
        cond = self.pop()
        if cond:
            new_pos = (2**self.p - (self.x + 1), 2**self.p - (self.y + 1))
            self.log(2, "Mirroring (both) from", self.x, self.y, "to", new_pos)
            self.move(new_pos)
        else:
            self.move()

    def _reverse(self, cmd) -> "u":  # reverse direction
        self.dir *= -1
        self.move()

    def _reverse_stack(self, cmd) -> "U":  # reverse stack
        self.stacks[self.sid].reverse()
        self.move()

    def _string_literal(self, cmd) -> '"':
        self.mode = "string"
        self.move()

    def _char_literal(self, cmd) -> "'":
        self.mode = "char"
        self.move()

    def _escape(self, cmd) -> "\\":
        self.mode = "escape"
        self.move()

    def _cond_escape(self, cmd) -> "`":
        if not self.pop():
            self.mode = "escape"
        self.move()

    def _random_direction(self, cmd) -> "?":
        cmd_ = choice("v^<>")
        method = self.commands.get(cmd_, Aceto._nop)
        method(self, cmd)

    def _random_number(self, cmd) -> "R":
        self.push(random())
        self.move()

    def _pi(self, cmd) -> "P":
        self.push(pi)
        self.move()

    def _euler(self, cmd) -> "e":
        self.push(euler)
        self.move()

    def _invert(self, cmd) -> "~":
        x = self.pop()
        if isinstance(x, bool):
            self.push(not x)
        elif isinstance(x, Number):
            self.push(-x)
        elif isinstance(x, str):
            self.push(x[::-1])
        else:
            raise CodeException(f"Don't know how to invert {x!r}")
        self.move()

    def _bitwise_negate(self, cmd) -> "a":
        x = self.pop()
        if isinstance(x, Number):
            try:
                self.push(~x)
            except Exception:
                raise CodeException(f"Don't know how to invert {x!r}")
        else:
            y = self.pop()
            self.pushiter(reversed(re.findall(y, x)))
        self.move()

    def _restart(self, cmd) -> "O":
        if self.dir == 1:
            self.x, self.y = 0, 0
        else:
            length = 2**self.p
            self.x, self.y = 0, length - 1

    def _finalize(self, cmd) -> ";":
        if self.dir == -1:
            self.x, self.y = 0, 0
        else:
            length = 2**self.p
            self.x, self.y = 0, length - 1

    def _getch(self, cmd) -> ",":
        ch = getch()
        if ch == "\r":
            ch = ""
        self.push(ch)
        self.move()

    def _repeat(self, cmd) -> ".":
        method = self.commands.get(self.previous_cmd, Aceto._nop)
        method(self, self.previous_cmd)

    def _empty_stack(self, cmd) -> "ø":
        self.stacks[self.sid] = []
        self.move()

    def _jump(self, cmd) -> "j":
        steps = self.pop()
        distance = self.hilbert.distance_from_coordinates([self.y, self.x])
        y, x = self.hilbert.coordinates_from_distance(distance +
                                                      self.dir * steps)
        self.x, self.y = x, y

    def _goto(self, cmd) -> "§":
        distance = self.pop()
        # TODO: should take the direction (self.dir) into account.
        y, x = self.hilbert.coordinates_from_distance(distance)
        self.x, self.y = x, y

    def _join(self, cmd) -> "J":
        x, y = self.pop(), self.pop()
        self.push(str(x) + str(y))
        self.move()

    def _catch_mark(self, cmd) -> "@":
        self.catch_mark = self.x, self.y
        self.move()

    def _raise(self, cmd) -> "&":
        raise CodeException("Raised an &rror.")

    def _assert(self, cmd) -> "$":
        if self.pop():
            raise CodeException("A$$ertion failed")
        else:
            self.move()

    def _get_stopwatch(self, cmd) -> "t":
        self.push(time.time() - self.timestamp)
        self.move()

    def _set_stopwatch(self, cmd) -> "T":
        self.timestamp = time.time()
        self.move()

    def _get_datetime(self, cmd) -> "™τ":
        self.pushiter([*time.localtime()][:6][::-1])
        self.move()

    def _drop(self, cmd) -> "x":
        self.pop()
        self.move()

    def _contains(self, cmd) -> "C":
        x = self.pop()
        self.push(x in self.stacks[self.sid])
        self.move()

    def _length(self, cmd) -> "l":
        self.push(len(self.stacks[self.sid]))
        self.move()

    def _queue(self, cmd) -> "q":
        self.stacks[self.sid].insert(0, self.pop())
        self.move()

    def _unqueue(self, cmd) -> "Q":
        try:
            self.push(self.stacks[self.sid].pop(0))
        except IndexError:
            self.push(0)
        self.move()

    def _memorize_quick(self, cmd) -> "M":
        self.quick = self.pop()
        self.move()

    def _load_quick(self, cmd) -> "L":
        self.push(self.quick)
        self.move()

    def _more(self, cmd) -> "m":
        x = self.pop()
        y = self.pop()
        self.log(2, f"Testing if {y!r} > {x!r}")
        self.push(y > x)
        self.move()

    def _less_or_equal(self, cmd) -> "w":
        x = self.pop()
        y = self.pop()
        self.log(2, f"Testing if {y!r} <= {x!r}")
        self.push(y <= x)
        self.move()

    def _bitwise_and(self, cmd) -> "A":
        x = self.pop()
        y = self.pop()
        self.push(y & x)
        self.move()

    def _bitwise_or(self, cmd) -> "V":
        x = self.pop()
        y = self.pop()
        self.push(y | x)
        self.move()

    def _bitwise_xor(self, cmd) -> "H":
        x = self.pop()
        y = self.pop()
        self.push(y ^ x)
        self.move()

    def _range_down(self, cmd) -> "z":
        val = self.pop()
        if not isinstance(val, int) or val == 0:
            raise CodeException("Can only construct range with non-0 integer")
        step = -1 if val > 0 else 1
        self.pushiter(range(val, 0, step))
        self.move()

    def _range_up(self, cmd) -> "Z":
        val = self.pop()
        if not isinstance(val, int) or val == 0:
            raise CodeException("Can only construct range with non-0 integer")
        step = 1 if val > 0 else -1
        self.pushiter(range(step, val + step, step))
        self.move()

    def _order_up(self, cmd) -> "G":
        x = [self.pop(), self.pop()]
        x.sort()
        self.push(x.pop())
        self.push(x.pop())
        self.move()

    def _order_down(self, cmd) -> "g":
        x = [self.pop(), self.pop()]
        x.sort(reverse=True)
        self.push(x.pop())
        self.push(x.pop())
        self.move()

    def _shuffle(self, cmd) -> "Y":
        shuffle(self.stacks[self.sid])
        self.move()

    def _sign(self, cmd) -> "y":
        x = self.pop()
        self.push(1 if x > 0 else -1 if x < 0 else 0)
        self.move()

    def _bitwise_left(self, cmd) -> "«":
        x = self.pop()
        y = self.pop()
        self.push(y << x)
        self.move()

    def _bitwise_right(self, cmd) -> "»":
        x = self.pop()
        y = self.pop()
        self.push(y >> x)
        self.move()

    def _multiply_stack(self, cmd) -> "×":
        x = self.pop()
        self.stacks[self.sid] *= x
        self.move()

    def _abs(self, cmd) -> "±":
        x = self.pop()
        self.push(abs(x))
        self.move()

    def _explode_string(self, cmd) -> "€":
        x = self.pop()
        self.stacks[self.sid].extend(reversed(x))
        self.move()

    def _implode_string(self, cmd) -> "£¥":
        s = "".join(map(str, reversed(self.stacks[self.sid])))
        self.stacks[self.sid] = [s]
        self.move()
                        level=numeric_level)
    log_format = logging.Formatter('%(asctime)s [%(levelname)-5.5s] [%(filename)s:%(lineno)04d] %(message)s')
    logger = logging.getLogger()
    logger.setLevel(numeric_level)

    root_dir = args.root_dir
    phases = ['train', 'test']
    batch_size = 32
    category = 5

    # verify hilbert order.
    p = 7
    N = 2
    hilbert_curve = HilbertCurve(p, N)
    for coords in [[0, 0], [0, 1], [1, 1], [1, 0]]:
        dist = hilbert_curve.distance_from_coordinates(coords)
        print(f'distance(x={coords}) = {dist}')
    #
    datasets, dataloaders, num_classes = get_s3dis_dataloaders(root_dir=root_dir,
                                                               phases=phases,
                                                               batch_size=batch_size,
                                                               category=category)

    for phase in phases:
        print(phase.upper())
        print('\tDataset {} Dataloder {}'.format(len(datasets[phase]), len(dataloaders[phase])))
        for i, data in enumerate(dataloaders[phase]):
            print(data.pos.shape)
            x = torch.cat((data.pos, data.x), dim=2).transpose(1, 2)
            seg_label = data.y
            print('\tData {} Seg Label {}'.format(x.size(), seg_label.size()))
class S3DIS(InMemoryDataset):
    r"""The (pre-processed) Stanford Large-Scale 3D Indoor Spaces dataset from
    the `"3D Semantic Parsing of Large-Scale Indoor Spaces"
    <http://buildingparser.stanford.edu/images/3D_Semantic_Parsing.pdf>`_
    paper, containing point clouds of six large-scale indoor parts in three
    buildings with 12 semantic elements (and one clutter class).

    Args:
        root (string): Root directory where the dataset should be saved.
        test_area (int, optional): Which area to use for testing (1-6).
            (default: :obj:`6`)
        train (bool, optional): If :obj:`True`, loads the training dataset,
            otherwise the test dataset. (default: :obj:`True`)
        transform (callable, optional): A function/transform that takes in an
            :obj:`torch_geometric.data.Data` object and returns a transformed
            version. The data object will be transformed before every access.
            (default: :obj:`None`)
        pre_transform (callable, optional): A function/transform that takes in
            an :obj:`torch_geometric.data.Data` object and returns a
            transformed version. The data object will be transformed before
            being saved to disk. (default: :obj:`None`)
        pre_filter (callable, optional): A function that takes in an
            :obj:`torch_geometric.data.Data` object and returns a boolean
            value, indicating whether the data object should be included in the
            final dataset. (default: :obj:`None`)
    """

    url = ('https://shapenet.cs.stanford.edu/media/'
           'indoor3d_sem_seg_hdf5_data.zip')

    def __init__(self,
                 root,
                 test_area=5,
                 train=True,
                 transform=None,
                 pre_transform=None,
                 pre_filter=None,
                 hilbert_order=True,
                 hilbert_level=7):
        assert test_area >= 1 and test_area <= 6
        self.test_area = test_area
        self.p = hilbert_level
        self.hilbert_order = hilbert_order
        if self.hilbert_order:
            self.hilbert_curve = HilbertCurve(self.p, 3)
        super(S3DIS, self).__init__(root, transform, pre_transform, pre_filter)
        path = self.processed_paths[0] if train else self.processed_paths[1]
        self.data, self.slices = torch.load(path)

    @property
    def raw_file_names(self):
        return ['all_files.txt', 'room_filelist.txt']

    @property
    def processed_file_names(self):
        test_area = self.test_area
        return ['{}_{}.pt'.format(s, test_area) for s in ['train', 'test']]

    def download(self):
        path = download_url(self.url, self.root)
        extract_zip(path, self.root)
        os.unlink(path)
        shutil.rmtree(self.raw_dir)
        name = self.url.split(os.sep)[-1].split('.')[0]
        os.rename(osp.join(self.root, name), self.raw_dir)

    def process(self):
        with open(self.raw_paths[0], 'r') as f:
            filenames = [x.split('/')[-1] for x in f.read().split('\n')[:-1]]

        with open(self.raw_paths[1], 'r') as f:
            rooms = f.read().split('\n')[:-1]

        xs, ys = [], []
        for filename in filenames:
            f = h5py.File(osp.join(self.raw_dir, filename))
            # todo: check the data range
            xs += torch.from_numpy(f['data'][:]).unbind(0)
            ys += torch.from_numpy(f['label'][:]).to(torch.long).unbind(0)

        test_area = 'Area_{}'.format(self.test_area)
        train_data_list, test_data_list = [], []
        for i, (x, y) in enumerate(tqdm(zip(xs, ys), total=len(xs))):
            data = Data(pos=x[:, :3], x=x[:, 3:], y=y)

            if self.pre_filter is not None and not self.pre_filter(data):
                continue
            if self.pre_transform is not None:
                data = self.pre_transform(data)

            # Hilbert curve
            if self.hilbert_order:
                # order points in hilbert order
                # after normalizaiton, -1 to 1
                pos, x, y = data.pos, data.x, data.y
                point = (pos.numpy()+1)/2  # normalize to 0, 1
                points_voxel = np.floor(point * (2 ** self.p - 1)).astype(int)
                hilbert_dist = np.zeros(points_voxel.shape[0])

                # todo: we want to try two methods.
                # todo: 1. globally along with locally hilbert curve
                # todo: 2. multi-level of hilbert curve
                for point_idx in range(points_voxel.shape[0]):
                    hilbert_dist[point_idx] = self.hilbert_curve.distance_from_coordinates(points_voxel[point_idx, :])
                idx = np.argsort(hilbert_dist)
                pos = pos[idx, :]
                x = x[idx, :]
                y = y[idx]
                data = Data(pos=pos, x=x, y=y)

            if test_area not in rooms[i]:
                train_data_list.append(data)
            else:
                test_data_list.append(data)

        torch.save(self.collate(train_data_list), self.processed_paths[0])
        torch.save(self.collate(test_data_list), self.processed_paths[1])
Пример #19
0
class HilbertPalette(Palette):
    def __init__(self, sourceDirectory, file):
        super().__init__(sourceDirectory, file)
        self.hilbert_curve = HilbertCurve(255, 3)

    def MakeNewPalette(self):
        print("Collecting palette")
        colours = {}
        local = Path(__file__).resolve().parents[0]
        photos = local / self.sourceDirectory
        total = len(list(photos.iterdir()))
        with tqdm(total=total) as pbar:
            for photo in photos.iterdir():
                image = Image.open(photo)
                try:
                    colour = self.FindRegionColour(image)
                    dist = self.hilbert_curve.distance_from_coordinates(
                        np.rint(colour[:3]).astype(int).tolist())
                    colours[str(photo)] = dist
                except IndexError as e:
                    print(f"Error processing {photo}: {e}")
                pbar.update(1)
        print("Sorting")
        colours = {
            k: v
            for k, v in tqdm(sorted(colours.items(), key=lambda item: item[1]))
        }
        self.colours = colours
        self.colKeys = list(self.colours.keys())
        self.colValues = list(self.colours.values())

    def GetClosest(self, val1, val2, target):
        if (target - val1 >= val2 - target):
            return val2
        else:
            return val1

    def FindClosestIndex(self, arr, n, target):
        if (target <= arr[0]):
            return 0
        if (target >= arr[n - 1]):
            return n - 1

        i = 0
        j = n
        mid = 0
        while (i < j):
            mid = (i + j) // 2
            if (arr[mid] == target):
                return mid

            if (target < arr[mid]):

                if (mid > 0 and target > arr[mid - 1]):
                    if (self.GetClosest(arr[mid - 1], arr[mid],
                                        target) == mid):
                        return mid
                    else:
                        return mid - 1
                j = mid
            else:
                if (mid < n - 1 and target < arr[mid + 1]):
                    if (self.GetClosest(arr[mid], arr[mid + 1],
                                        target) == arr[mid]):
                        return mid
                    else:
                        return mid + 1
                i = mid + 1
        return mid

    def FindMatchingImage(self, RGB):
        rgbDist = self.hilbert_curve.distance_from_coordinates(list(RGB[:3]))
        matchIndex = self.FindClosestIndex(self.colValues, len(self.colValues),
                                           rgbDist)
        return self.colKeys[matchIndex]