anas
Initial deployment of Raster2Seq floor plan vectorization API
fadb92b
# import lmdb
import pickle
import cv2
import numpy as np
import torch
from house import House
from numpy import genfromtxt
from torch.utils.data import Dataset
ROOM_NAMES = {
0: "Background",
1: "Outdoor",
2: "Wall",
3: "Kitchen",
4: "Living Room",
5: "Bed Room",
6: "Bath",
7: "Entry",
8: "Railing",
9: "Storage",
10: "Garage",
11: "Undefined",
}
ICON_NAMES = {
0: "No Icon",
1: "Window",
2: "Door",
3: "Closet",
4: "Electrical Applience",
5: "Toilet",
6: "Sink",
7: "Sauna Bench",
8: "Fire Place",
9: "Bathtub",
10: "Chimney",
}
class FloorplanSVG(Dataset):
def __init__(
self,
data_folder,
data_file,
is_transform=True,
augmentations=None,
img_norm=True,
format="txt",
original_size=False,
lmdb_folder="cubi_lmdb/",
):
self.img_norm = img_norm
self.is_transform = is_transform
self.augmentations = augmentations
self.get_data = None
self.original_size = original_size
self.image_file_name = "/F1_scaled.png"
self.org_image_file_name = "/F1_original.png"
self.svg_file_name = "/model.svg"
if format == "txt":
self.get_data = self.get_txt
# if format == 'lmdb':
# self.lmdb = lmdb.open(data_folder+lmdb_folder, readonly=True,
# max_readers=8, lock=False,
# readahead=True, meminit=False)
# self.get_data = self.get_lmdb
# self.is_transform = False
self.data_folder = data_folder
# Load txt file to list
self.folders = genfromtxt(data_folder + data_file, dtype="str")
def __len__(self):
"""__len__"""
return len(self.folders)
def __getitem__(self, index):
sample = self.get_data(index)
if self.augmentations is not None:
sample = self.augmentations(sample)
if self.is_transform:
sample = self.transform(sample)
return sample
def get_txt(self, index):
fplan = cv2.imread(self.data_folder + self.folders[index] + self.image_file_name)
fplan = cv2.cvtColor(fplan, cv2.COLOR_BGR2RGB) # correct color channels
height, width, nchannel = fplan.shape
fplan = np.moveaxis(fplan, -1, 0)
# Getting labels for segmentation and heatmaps
house = House(self.data_folder + self.folders[index] + self.svg_file_name, height, width)
# Combining them to one numpy tensor
label = torch.tensor(house.get_segmentation_tensor().astype(np.float32))
heatmaps = house.get_heatmap_dict()
room_polygons, room_types, icon_polygons, icon_types = house.get_coords_and_labels()
coef_width = 1
if self.original_size:
fplan = cv2.imread(self.data_folder + self.folders[index] + self.org_image_file_name)
fplan = cv2.cvtColor(fplan, cv2.COLOR_BGR2RGB) # correct color channels
height_org, width_org, nchannel = fplan.shape
fplan = np.moveaxis(fplan, -1, 0)
label = label.unsqueeze(0)
label = torch.nn.functional.interpolate(label, size=(height_org, width_org), mode="nearest")
label = label.squeeze(0)
coef_height = float(height_org) / float(height)
coef_width = float(width_org) / float(width)
for key, value in heatmaps.items():
heatmaps[key] = [(int(round(x * coef_width)), int(round(y * coef_height))) for x, y in value]
new_room_polygons = []
for poly in room_polygons:
new_room_polygons.append([(int(round(x * coef_width)), int(round(y * coef_height))) for x, y in poly])
room_polygons = new_room_polygons
new_icon_polygons = []
for poly in icon_polygons:
new_icon_polygons.append([(int(round(x * coef_width)), int(round(y * coef_height))) for x, y in poly])
icon_polygons = new_icon_polygons
img = torch.tensor(fplan.astype(np.float32))
sample = {
"image": img,
"label": label,
"folder": self.folders[index],
"heatmaps": heatmaps,
"scale": coef_width,
"room_polygon": room_polygons,
"room_type": room_types,
"icon_polygon": icon_polygons,
"icon_type": icon_types,
}
return sample
def get_lmdb(self, index):
key = self.folders[index].encode()
with self.lmdb.begin(write=False) as f:
data = f.get(key)
sample = pickle.loads(data)
return sample
def transform(self, sample):
fplan = sample["image"]
# Normalization values to range -1 and 1
fplan = 2 * (fplan / 255.0) - 1
sample["image"] = fplan
return sample