Spaces:
Build error
Build error
Download util/lua/representation_utils.lua~ from rawanessam/FloorPlanTransformation: direct link, hf CLI and curl.
- Browser
- Download file 35.8 kB
-
https://huggingface.co/spaces/rawanessam/FloorPlanTransformation/resolve/main/util/lua/representation_utils.lua~
- Command line
-
hf download 'hf://spaces/rawanessam/FloorPlanTransformation/util/lua/representation_utils.lua~'
-
curl -L -o 'representation_utils.lua~' 'https://huggingface.co/spaces/rawanessam/FloorPlanTransformation/resolve/main/util/lua/representation_utils.lua~'
35.8 kB
| require 'csvigo' | |
| require 'image' | |
| local pl = require 'pl.import_into' () | |
| local utils = {} | |
| function utils.roomTypeMap() | |
| local roomTypeMap = {} | |
| roomTypeMap[1] = 'living_room' | |
| roomTypeMap[2] = 'kitchen' | |
| roomTypeMap[3] = 'bedroom' | |
| roomTypeMap[4] = 'bathroom' | |
| roomTypeMap[5] = 'restroom' | |
| roomTypeMap[6] = 'balcony' | |
| roomTypeMap[7] = 'closet' | |
| roomTypeMap[8] = 'corridor' | |
| roomTypeMap[9] = 'stairs' | |
| roomTypeMap[10] = 'PS' | |
| return roomTypeMap | |
| end | |
| function utils.keyMap() | |
| local roomTypeMap = utils.roomTypeMap() | |
| local keyMap = {} | |
| keyMap['b'] = {'icons', 'bathtub'} | |
| keyMap['c'] = {'icons', 'cooking_counter'} | |
| keyMap['t'] = {'icons', 'toilet'} | |
| keyMap['s'] = {'icons', 'special'} | |
| keyMap['e'] = {'icons', 'entrance'} | |
| keyMap['w'] = {'icons', 'washing_basin'} | |
| for i = 1, 10 do | |
| keyMap[tostring(i % 10)] = {'labels', roomTypeMap[i]} | |
| end | |
| keyMap['a'] = {'walls', 'wall'} | |
| keyMap['d'] = {'doors', 'door'} | |
| return keyMap | |
| end | |
| function utils.classMap() | |
| local classMap = {} | |
| classMap.labels = {} | |
| classMap.labels['living_room'] = 1 | |
| classMap.labels['kitchen'] = 2 | |
| classMap.labels['bedroom'] = 3 | |
| classMap.labels['bathroom'] = 4 | |
| classMap.labels['restroom'] = 5 | |
| classMap.labels['balcony'] = 6 | |
| classMap.labels['closet'] = 7 | |
| classMap.labels['corridor'] = 8 | |
| classMap.labels['stairs'] = 9 | |
| classMap.labels['PS'] = 10 | |
| classMap.icons = {} | |
| classMap.icons['bathtub'] = 1 | |
| classMap.icons['cooking_counter'] = 2 | |
| classMap.icons['toilet'] = 3 | |
| classMap.icons['entrance'] = 4 | |
| classMap.icons['washing_basin'] = 5 | |
| classMap.icons['special'] = 6 | |
| return classMap | |
| end | |
| function utils.modeMap() | |
| local modeMap = {} | |
| local keyMap = utils.keyMap() | |
| for _, modeNamePair in pairs(keyMap) do | |
| modeMap[modeNamePair[2]] = modeNamePair[1] | |
| end | |
| return modeMap | |
| end | |
| function utils.numItemsPerCell() | |
| local numItemsPerCell = {} | |
| numItemsPerCell.points = 2 | |
| numItemsPerCell.doors = 2 | |
| numItemsPerCell.icons = 2 | |
| numItemsPerCell.labels = 2 | |
| return numItemsPerCell | |
| end | |
| function utils.numFeaturesPerItem() | |
| local numFeaturesPerItem = {} | |
| numFeaturesPerItem.points = 5 | |
| numFeaturesPerItem.doors = 5 | |
| numFeaturesPerItem.icons = 5 | |
| numFeaturesPerItem.labels = 5 | |
| return numFeaturesPerItem | |
| end | |
| function utils.offsetsBB() | |
| local numItemsPerCell = utils.numItemsPerCell() | |
| local numFeaturesPerItem = utils.numFeaturesPerItem() | |
| local offsetsBB = {} | |
| offsetsBB.points = 0 | |
| offsetsBB.doors = offsetsBB.points + numFeaturesPerItem.points * numItemsPerCell.points | |
| offsetsBB.icons = offsetsBB.doors + numFeaturesPerItem.doors * numItemsPerCell.doors | |
| offsetsBB.labels = offsetsBB.icons + numFeaturesPerItem.icons * numItemsPerCell.icons | |
| return offsetsBB | |
| end | |
| function utils.numFeaturesBB() | |
| local numItemsPerCell = utils.numItemsPerCell() | |
| local offsetsBB = utils.offsetsBB() | |
| local numFeaturesPerItem = utils.numFeaturesPerItem() | |
| local numFeaturesBB = offsetsBB.labels + numFeaturesPerItem.labels * numItemsPerCell.labels | |
| return numFeaturesBB | |
| end | |
| function utils.offsetsClass() | |
| local numItemsPerCell = utils.numItemsPerCell() | |
| local numFeaturesPerItem = utils.numFeaturesPerItem() | |
| local numFeaturesBB = utils.numFeaturesBB() | |
| local offsetsClass = {} | |
| offsetsClass.points = numFeaturesBB | |
| offsetsClass.doors = offsetsClass.points + numItemsPerCell.points | |
| offsetsClass.icons = offsetsClass.doors + numItemsPerCell.doors | |
| offsetsClass.labels = offsetsClass.icons + numItemsPerCell.icons | |
| return offsetsClass | |
| end | |
| function utils.numFeaturesClass() | |
| local numItemsPerCell = utils.numItemsPerCell() | |
| local numFeaturesClass = numItemsPerCell.points + numItemsPerCell.doors + numItemsPerCell.icons + numItemsPerCell.labels | |
| return numFeaturesClass | |
| end | |
| function utils.lineDim(line) | |
| if math.abs(line[1][1] - line[2][1]) > math.abs(line[1][2] - line[2][2]) and math.abs(line[1][2] - line[2][2]) <= 1 then | |
| return 1 | |
| elseif math.abs(line[1][2] - line[2][2]) > math.abs(line[1][1] - line[2][1]) and math.abs(line[1][1] - line[2][1]) <= 1 then | |
| return 2 | |
| else | |
| return 0 | |
| end | |
| end | |
| function utils.cutoffRange(range, max) | |
| local lowerBound = math.max(range[1], 1) | |
| local upperBound = math.min(range[2], max) | |
| if lowerBound > upperBound then | |
| return {} | |
| else | |
| return {lowerBound, upperBound} | |
| end | |
| end | |
| function utils.drawLineMask(width, height, lines, lineDim, lineWidth) | |
| local lineMask = torch.zeros(width, height) | |
| local size = {width, height} | |
| for _, line in pairs(lines) do | |
| if utils.lineDim(line) == lineDim then | |
| local fixedDim = 3 - lineDim | |
| local fixedValue = (line[1][fixedDim] + line[2][fixedDim]) / 2 | |
| local fixedRange = utils.cutoffRange({fixedValue - lineWidth, fixedValue + lineWidth}, size[fixedDim]) | |
| if #fixedRange > 0 then | |
| local lineRange = utils.cutoffRange({line[1][lineDim] - lineWidth, line[2][lineDim] + lineWidth}, size[lineDim]) | |
| if lineDim == 1 then | |
| lineMask[{{lineRange[1], lineRange[2]}, {fixedRange[1], fixedRange[2]}}] = 1 | |
| else | |
| lineMask[{{fixedRange[1], fixedRange[2]}, {lineRange[1], lineRange[2]}}] = 1 | |
| end | |
| end | |
| end | |
| end | |
| end | |
| function utils.sortLines(lines) | |
| for lineIndex, line in pairs(lines) do | |
| local lineDim = utils.lineDim(line) | |
| if lineDim > 0 and line[1][lineDim] > line[2][lineDim] then | |
| local temp = lines[lineIndex][1][lineDim] | |
| lines[lineIndex][1][lineDim] = lines[lineIndex][2][lineDim] | |
| lines[lineIndex][2][lineDim] = temp | |
| end | |
| end | |
| return lines | |
| end | |
| function utils.calcDistance(point_1, point_2) | |
| return math.sqrt(math.pow(point_1[1] - point_2[1], 2) + math.pow(point_1[2] - point_2[2], 2)) | |
| end | |
| function utils.findNearestEndPointPair(line_1, line_2, gap) | |
| local nearestPair | |
| local minDistance | |
| for index_1 = 1, 2 do | |
| for index_2 = 1, 2 do | |
| local distance = utils.calcDistance(line_1[index_1], line_2[index_2]) | |
| if minDistance == nil or distance < minDistance then | |
| nearestPair = {index_1, index_2} | |
| minDistance = distance | |
| end | |
| end | |
| end | |
| if minDistance > gap then | |
| local lineDim_1 = utils.lineDim(line_1) | |
| local lineDim_2 = utils.lineDim(line_2) | |
| local fixedValue_1 = (line_1[1][3 - lineDim_1] + line_1[2][3 - lineDim_1]) / 2 | |
| local fixedValue_2 = (line_2[1][3 - lineDim_2] + line_2[2][3 - lineDim_2]) / 2 | |
| if lineDim_1 + lineDim_2 == 3 then | |
| if line_2[1][lineDim_2] < fixedValue_1 and line_2[2][lineDim_2] > fixedValue_1 then | |
| for index = 1, 2 do | |
| local distance = math.abs(line_1[index][lineDim_1] - fixedValue_2) | |
| if distance < minDistance then | |
| nearestPair = {index, 0} | |
| minDistance = distance | |
| end | |
| end | |
| end | |
| if line_1[1][lineDim_1] < fixedValue_2 and line_1[2][lineDim_1] > fixedValue_2 then | |
| for index = 1, 2 do | |
| local distance = math.abs(line_2[index][lineDim_2] - fixedValue_1) | |
| if distance < minDistance then | |
| nearestPair = {0, index} | |
| minDistance = distance | |
| end | |
| end | |
| end | |
| end | |
| end | |
| if #line_1 >= 3 and line_1[3][2] == 2 and line_2[3][2] == 1 then | |
| nearestPair[2] = 0 | |
| end | |
| if #line_2 >= 3 and line_2[3][2] == 2 and line_1[3][2] == 1 then | |
| nearestPair[1] = 0 | |
| end | |
| return nearestPair, minDistance | |
| end | |
| function utils.stitchLines(lines, gap) | |
| for lineIndex_1, line_1 in pairs(lines) do | |
| local lineDim_1 = utils.lineDim(line_1) | |
| if lineDim_1 > 0 then | |
| local fixedValue_1 = (line_1[1][3 - lineDim_1] + line_1[2][3 - lineDim_1]) / 2 | |
| for lineIndex_2, line_2 in pairs(lines) do | |
| if lineIndex_2 > lineIndex_1 then | |
| local lineDim_2 = utils.lineDim(line_2) | |
| if lineDim_2 > 0 then | |
| local fixedValue_2 = (line_2[1][3 - lineDim_2] + line_2[2][3 - lineDim_2]) / 2 | |
| local nearestPair, minDistance = utils.findNearestEndPointPair(line_1, line_2, gap) | |
| --print(minDistance .. ' ' .. lineDim_1 .. ' ' .. lineDim_2) | |
| if minDistance <= gap and lineDim_1 + lineDim_2 == 3 then | |
| local pointIndex_1 = nearestPair[1] | |
| local pointIndex_2 = nearestPair[2] | |
| --print(lineIndex_1 .. ' ' .. lineIndex_2) | |
| if pointIndex_1 > 0 and pointIndex_2 > 0 then | |
| lines[lineIndex_1][pointIndex_1][lineDim_1] = fixedValue_2 | |
| lines[lineIndex_2][pointIndex_2][lineDim_2] = fixedValue_1 | |
| elseif pointIndex_1 > 0 and pointIndex_2 == 0 then | |
| lines[lineIndex_1][pointIndex_1][lineDim_1] = fixedValue_2 | |
| elseif pointIndex_1 == 0 and pointIndex_2 > 0 then | |
| lines[lineIndex_2][pointIndex_2][lineDim_2] = fixedValue_1 | |
| end | |
| end | |
| end | |
| end | |
| end | |
| end | |
| end | |
| return lines | |
| end | |
| function utils.gridPoint(width, height, gridWidth, gridHeight, point) | |
| local cellWidth = width / gridWidth | |
| local cellHeight = height / gridHeight | |
| local gridX = math.floor((point[1] - 1) / cellWidth) + 1 | |
| local gridY = math.floor((point[2] - 1) / cellHeight) + 1 | |
| local cellX = ((point[1] - 1) - (gridX - 1) * cellWidth) / (cellWidth - 1) | |
| local cellY = ((point[2] - 1) - (gridY - 1) * cellHeight) / (cellHeight - 1) | |
| return {{gridX, gridY}, {cellX, cellY}} | |
| end | |
| function utils.gridRectangle(width, height, gridWidth, gridHeight, point_1, point_2) | |
| if point_2 == nil then | |
| local rectangle = utils.gridPoint(width, height, gridWidth, gridHeight, point_1) | |
| table.insert(rectangle, {0, 0}) | |
| return rectangle | |
| end | |
| local center = utils.gridPoint(width, height, gridWidth, gridHeight, {(point_1[1] + point_2[1]) / 2, (point_1[2] + point_2[2]) / 2}) | |
| local rectangle = center | |
| table.insert(rectangle, {(point_2[1] - point_1[1] + 1) / width, (point_2[2] - point_1[2] + 1) / height}) | |
| return rectangle | |
| end | |
| function utils.imageRectangle(width, height, gridWidth, gridHeight, rectangle) | |
| local cellWidth = width / gridWidth | |
| local cellHeight = height / gridHeight | |
| local centerX = (rectangle[1][1] - 1) * cellWidth + rectangle[2][1] * (cellWidth - 1) + 1 | |
| local centerY = (rectangle[1][2] - 1) * cellHeight + rectangle[2][2] * (cellHeight - 1) + 1 | |
| return {{centerX - (rectangle[3][1] * width - 1) / 2, centerY - (rectangle[3][2] * height - 1) / 2}, {centerX + (rectangle[3][1] * width - 1) / 2, centerY + (rectangle[3][2] * height - 1) / 2}} | |
| end | |
| function utils.convertRepresentation(width, height, representationGeneral, representationType, gap) | |
| local representation = {} | |
| if representationType == 'P' then | |
| local points = {} | |
| local usedLinePointMask = {} | |
| for lineIndex, line in pairs(representationGeneral.walls) do | |
| usedLinePointMask[lineIndex] = {false, false} | |
| end | |
| for lineIndex_1, line_1 in pairs(representationGeneral.walls) do | |
| local lineDim_1 = utils.lineDim(line_1) | |
| if lineDim_1 > 0 then | |
| local fixedValue_1 = (line_1[1][3 - lineDim_1] + line_1[2][3 - lineDim_1]) / 2 | |
| for lineIndex_2, line_2 in pairs(representationGeneral.walls) do | |
| if lineIndex_2 > lineIndex_1 then | |
| local lineDim_2 = utils.lineDim(line_2) | |
| if lineDim_2 > 0 then | |
| local fixedValue_2 = (line_2[1][3 - lineDim_2] + line_2[2][3 - lineDim_2]) / 2 | |
| local nearestPair, minDistance = utils.findNearestEndPointPair(line_1, line_2, gap) | |
| if minDistance <= gap and lineDim_1 + lineDim_2 == 3 then | |
| local pointIndex_1 = nearestPair[1] | |
| local pointIndex_2 = nearestPair[2] | |
| if pointIndex_1 > 0 and pointIndex_2 > 0 then | |
| local point = {} | |
| point[lineDim_1] = fixedValue_2 | |
| point[lineDim_2] = fixedValue_1 | |
| local side = {} | |
| side[lineDim_1] = line_1[3 - pointIndex_1][lineDim_1] - fixedValue_2 | |
| side[lineDim_2] = line_2[3 - pointIndex_2][lineDim_2] - fixedValue_1 | |
| if side[1] < 0 and side[2] < 0 then | |
| table.insert(points, {point, {'point', 2, 1}}) | |
| elseif side[1] > 0 and side[2] < 0 then | |
| table.insert(points, {point, {'point', 2, 2}}) | |
| elseif side[1] > 0 and side[2] > 0 then | |
| table.insert(points, {point, {'point', 2, 3}}) | |
| elseif side[1] < 0 and side[2] > 0 then | |
| table.insert(points, {point, {'point', 2, 4}}) | |
| end | |
| usedLinePointMask[lineIndex_1][pointIndex_1] = true | |
| usedLinePointMask[lineIndex_2][pointIndex_2] = true | |
| elseif (pointIndex_1 > 0 and pointIndex_2 == 0) or (pointIndex_1 == 0 and pointIndex_2 > 0) then | |
| local lineDim | |
| local pointIndex | |
| local fixedValue | |
| local pointValue | |
| if pointIndex_1 > 0 then | |
| lineDim = lineDim_1 | |
| pointIndex = pointIndex_1 | |
| fixedValue = fixedValue_2 | |
| pointValue = line_1[pointIndex_1][3 - lineDim_1] | |
| usedLinePointMask[lineIndex_1][pointIndex_1] = true | |
| else | |
| lineDim = lineDim_2 | |
| pointIndex = pointIndex_2 | |
| fixedValue = fixedValue_1 | |
| pointValue = line_2[pointIndex_2][3 - lineDim_2] | |
| usedLinePointMask[lineIndex_2][pointIndex_2] = true | |
| end | |
| local point = {} | |
| point[lineDim] = fixedValue | |
| point[3 - lineDim] = pointValue | |
| if pointIndex == 1 then | |
| if lineDim == 1 then | |
| table.insert(points, {point, {'point', 3, 4}}) | |
| else | |
| table.insert(points, {point, {'point', 3, 1}}) | |
| end | |
| else | |
| if lineDim == 1 then | |
| table.insert(points, {point, {'point', 3, 2}}) | |
| else | |
| table.insert(points, {point, {'point', 3, 3}}) | |
| end | |
| end | |
| elseif line_1[1][lineDim_1] < fixedValue_2 and line_1[2][lineDim_1] > fixedValue_2 and line_2[1][lineDim_2] < fixedValue_1 and line_2[2][lineDim_2] > fixedValue_1 then | |
| local point = {} | |
| point[lineDim_1] = fixedValue_2 | |
| point[lineDim_2] = fixedValue_1 | |
| table.insert(points, {point, {'point', 4, 1}}) | |
| end | |
| --print(lineIndex_1 .. '\t' .. lineIndex_2) | |
| --print(nearestPair[1] .. '\t' .. nearestPair[2] .. '\t' .. minDistance) | |
| --local point = points[#points] | |
| --print(#points .. '\t' .. point[1][1] .. '\t' .. point[1][2] .. '\t' .. point[2][2]) | |
| end | |
| end | |
| end | |
| end | |
| end | |
| end | |
| --for _, point in pairs(points) do | |
| --print(point[1][1] .. '\t' .. point[1][2] .. '\t' .. point[2][2]) | |
| --end | |
| --os.exit(1) | |
| for lineIndex, pointMask in pairs(usedLinePointMask) do | |
| local lineDim = utils.lineDim(representationGeneral.walls[lineIndex]) | |
| for pointIndex = 1, 2 do | |
| if pointMask[pointIndex] == false then | |
| local point = {representationGeneral.walls[lineIndex][pointIndex][1], representationGeneral.walls[lineIndex][pointIndex][2]} | |
| if pointIndex == 1 then | |
| if lineDim == 1 then | |
| table.insert(points, {point, {'point', 1, 4}}) | |
| else | |
| table.insert(points, {point, {'point', 1, 1}}) | |
| end | |
| else | |
| if lineDim == 1 then | |
| table.insert(points, {point, {'point', 1, 2}}) | |
| else | |
| table.insert(points, {point, {'point', 1, 3}}) | |
| end | |
| end | |
| end | |
| end | |
| end | |
| representation.points = points | |
| representation.doors = representationGeneral.doors | |
| representation.icons = representationGeneral.icons | |
| representation.labels = representationGeneral.labels | |
| end | |
| --[[ | |
| print('from') | |
| for mode, items in pairs(representationGeneral) do | |
| print(mode .. '\t' .. #items) | |
| end | |
| print('to') | |
| for mode, items in pairs(representation) do | |
| print(mode .. '\t' .. #items) | |
| end | |
| ]]-- | |
| return representation | |
| end | |
| function utils.convertRepresentationToTensor(width, height, gridWidth, gridHeight, representationGlobal) | |
| local representation = {} | |
| representation.points = {} | |
| for _, point in pairs(representationGlobal.points) do | |
| local newPoint = utils.gridRectangle(width, height, gridWidth, gridHeight, point[1]) | |
| table.insert(newPoint, point[2]) | |
| if newPoint[1][1] >= 1 and newPoint[1][1] <= gridWidth and newPoint[1][2] >= 1 and newPoint[1][2] <= gridHeight then | |
| table.insert(representation.points, newPoint) | |
| end | |
| end | |
| representation.doors = {} | |
| for _, door in pairs(representationGlobal.doors) do | |
| local newRectangle = utils.gridRectangle(width, height, gridWidth, gridHeight, door[1], door[2]) | |
| table.insert(newRectangle, door[3]) | |
| if newRectangle[1][1] >= 1 and newRectangle[1][1] <= gridWidth and newRectangle[1][2] >= 1 and newRectangle[1][2] <= gridHeight then | |
| table.insert(representation.doors, newRectangle) | |
| end | |
| end | |
| representation.icons = {} | |
| for _, icon in pairs(representationGlobal.icons) do | |
| local newRectangle = utils.gridRectangle(width, height, gridWidth, gridHeight, icon[1], icon[2]) | |
| table.insert(newRectangle, icon[3]) | |
| if newRectangle[1][1] >= 1 and newRectangle[1][1] <= gridWidth and newRectangle[1][2] >= 1 and newRectangle[1][2] <= gridHeight then | |
| table.insert(representation.icons, newRectangle) | |
| end | |
| end | |
| representation.labels = {} | |
| for _, label in pairs(representationGlobal.labels) do | |
| local newPoint = utils.gridRectangle(width, height, gridWidth, gridHeight, label[1], label[2]) | |
| --table.remove(newPoint) | |
| table.insert(newPoint, label[3]) | |
| if newPoint[1][1] >= 1 and newPoint[1][1] <= gridWidth and newPoint[1][2] >= 1 and newPoint[1][2] <= gridHeight then | |
| table.insert(representation.labels, newPoint) | |
| end | |
| end | |
| local offsetsBB = utils.offsetsBB() | |
| local offsetsClass = utils.offsetsClass() | |
| local numFeaturesBB = utils.numFeaturesBB() | |
| local numFeaturesClass = utils.numFeaturesClass() | |
| local classMap = utils.classMap() | |
| local numItemsPerCell = utils.numItemsPerCell() | |
| local numFeaturesPerItem = utils.numFeaturesPerItem() | |
| local representationTensor = torch.zeros(numFeaturesBB + numFeaturesClass, gridHeight, gridWidth) | |
| local gridItems = {} | |
| for y = 1, gridHeight do | |
| gridItems[y] = {} | |
| for x = 1, gridWidth do | |
| gridItems[y][x] = {} | |
| for mode, offset in pairs(offsetsBB) do | |
| gridItems[y][x][mode] = {} | |
| end | |
| end | |
| end | |
| for mode, items in pairs(representation) do | |
| for __, item in pairs(items) do | |
| --if gridItems[item[1][2]][item[1][1]][mode] ~= nil then | |
| table.insert(gridItems[item[1][2]][item[1][1]][mode], item) | |
| --end | |
| end | |
| end | |
| for x = 1, gridWidth do | |
| for y = 1, gridHeight do | |
| for mode, items in pairs(gridItems[y][x]) do | |
| local numFeatures = numFeaturesPerItem[mode] | |
| local sortedItems = {} | |
| for _, item in pairs(items) do | |
| table.insert(sortedItems, {item[2][1] + item[2][2], item}) | |
| end | |
| table.sort(sortedItems, function(a, b) return a[1] < b[1] end) | |
| for i = numItemsPerCell[mode] + 1, #sortedItems do | |
| table.remove(sortedItems) | |
| end | |
| local offsetBB = offsetsBB[mode] | |
| for itemIndex, item in pairs(sortedItems) do | |
| item = item[2] | |
| local itemTensor = representationTensor[{{offsetBB + (itemIndex - 1) * numFeatures + 1, offsetBB + (itemIndex - 1) * numFeatures + numFeatures}, y, x}] | |
| itemTensor[1] = item[2][1] | |
| itemTensor[2] = item[2][2] | |
| itemTensor[3] = item[3][1] | |
| itemTensor[4] = item[3][2] | |
| itemTensor[5] = 1 | |
| end | |
| local offsetClass = offsetsClass[mode] | |
| for itemIndex, item in pairs(sortedItems) do | |
| item = item[2] | |
| local class | |
| if mode == 'points' then | |
| class = (item[4][2] - 1) * 4 + item[4][3] | |
| elseif mode == 'doors' then | |
| class = item[4][2] | |
| elseif mode == 'icons' then | |
| class = classMap[mode][item[4][1]] | |
| elseif mode == 'labels' then | |
| class = classMap[mode][item[4][1]] | |
| end | |
| --print(mode) | |
| --print(item[4][1]) | |
| --print(class) | |
| representationTensor[{offsetClass + itemIndex, y, x}] = class | |
| end | |
| end | |
| end | |
| end | |
| return representationTensor | |
| end | |
| function utils.convertTensorToRepresentation(width, height, representationTensor, confidenceThreshold) | |
| local offsetsBB = utils.offsetsBB() | |
| local offsetsClass = utils.offsetsClass() | |
| local numItemsPerCell = utils.numItemsPerCell() | |
| local numFeaturesPerItem = utils.numFeaturesPerItem() | |
| local representation = {} | |
| representation.points = {} | |
| representation.doors = {} | |
| representation.icons = {} | |
| representation.labels = {} | |
| local gridWidth = representationTensor:size(3) | |
| local gridHeight = representationTensor:size(2) | |
| local confidenceThreshold = confidenceThreshold or 0.5 | |
| for x = 1, gridWidth do | |
| for y = 1, gridHeight do | |
| for mode, numItems in pairs(numItemsPerCell) do | |
| local offsetBB = offsetsBB[mode] | |
| local offsetClass = offsetsClass[mode] | |
| local numFeatures = numFeaturesPerItem[mode] | |
| for itemIndex = 1, numItems do | |
| local item = representationTensor[{{offsetBB + (itemIndex - 1) * numFeatures + 1, offsetBB + (itemIndex - 1) * numFeatures + numFeatures}, y, x}] | |
| local class = representationTensor[{offsetClass + itemIndex, y, x}] | |
| --if torch.max(item) > 0 then | |
| --print(mode) | |
| --print(item) | |
| --end | |
| if item[5] > confidenceThreshold then | |
| if mode == 'points' then | |
| table.insert(representation[mode], {{x, y}, {item[1], item[2]}, {item[3], item[4]}, {'point', math.floor((class - 1) / 4) + 1, (class - 1) % 4 + 1}}) | |
| elseif mode == 'doors' then | |
| table.insert(representation[mode], {{x, y}, {item[1], item[2]}, {item[3], item[4]}, {'door', 1, 1}}) | |
| elseif mode == 'icons' then | |
| table.insert(representation[mode], {{x, y}, {item[1], item[2]}, {item[3], item[4]}, {'icon', 1, 1}}) | |
| elseif mode == 'labels' then | |
| table.insert(representation[mode], {{x, y}, {item[1], item[2]}, {item[3], item[4]}, {'label', 1, 1}}) | |
| end | |
| end | |
| end | |
| end | |
| end | |
| end | |
| return representation | |
| end | |
| function utils.cropRepresentation(representation, startX, startY, endX, endY) | |
| local newRepresentation = {} | |
| for mode, items in pairs(representation) do | |
| newRepresentation[mode] = {} | |
| for _, item in pairs(items) do | |
| if (item[1][1] + item[2][1]) / 2 <= endX and (item[1][2] + item[2][2]) / 2 <= endY then | |
| for pointIndex = 1, 2 do | |
| item[pointIndex][1] = item[pointIndex][1] - startX | |
| item[pointIndex][2] = item[pointIndex][2] - startY | |
| end | |
| --[[ | |
| print(mode) | |
| for i = 1, 3 do | |
| print(item[i][1] .. ' ' .. item[i][2]) | |
| end | |
| ]]-- | |
| table.insert(newRepresentation[mode], item) | |
| end | |
| end | |
| end | |
| return newRepresentation | |
| end | |
| function utils.scaleRepresentation(representation, width, height, newWidth, newHeight) | |
| local newRepresentation = {} | |
| for mode, items in pairs(representation) do | |
| newRepresentation[mode] = {} | |
| for _, item in pairs(items) do | |
| for pointIndex = 1, 2 do | |
| item[pointIndex][1] = torch.round((item[pointIndex][1] - 1) / (width - 1) * (newWidth - 1) + 1) | |
| item[pointIndex][2] = torch.round((item[pointIndex][2] - 1) / (height - 1) * (newHeight - 1) + 1) | |
| end | |
| table.insert(newRepresentation[mode], item) | |
| end | |
| end | |
| return newRepresentation | |
| end | |
| function utils.rotateRepresentation(representation, width, height, orientation) | |
| if orientation == 1 then | |
| return representation | |
| end | |
| local newRepresentation = {} | |
| for mode, items in pairs(representation) do | |
| newRepresentation[mode] = {} | |
| for _, item in pairs(items) do | |
| for pointIndex = 1, 2 do | |
| local x = item[pointIndex][1] | |
| local y = item[pointIndex][2] | |
| if orientation == 2 then | |
| item[pointIndex][1] = height - y | |
| item[pointIndex][2] = x | |
| elseif orientation == 3 then | |
| item[pointIndex][1] = width - x | |
| item[pointIndex][2] = height - y | |
| else | |
| item[pointIndex][1] = y | |
| item[pointIndex][2] = width - x | |
| end | |
| end | |
| table.insert(newRepresentation[mode], item) | |
| end | |
| end | |
| newRepresentation.walls = utils.sortLines(newRepresentation.walls) | |
| newRepresentation.doors = utils.sortLines(newRepresentation.doors) | |
| return newRepresentation | |
| end | |
| function utils.drawRepresentationImage(width, height, gridWidth, gridHeight, floorplan, representation, representationType, renderingType, lineWidth) | |
| representationType = representationType or 'P' | |
| renderingType = renderingType or 'P' | |
| if representationType == 'P' and renderingType == 'P' then | |
| local colorMap = {} | |
| colorMap[1] = {255, 0, 0} | |
| colorMap[2] = {0, 255, 0} | |
| colorMap[3] = {0, 0, 255} | |
| colorMap[4] = {255, 255, 0} | |
| colorMap[5] = {0, 255, 255} | |
| colorMap[6] = {255, 0, 255} | |
| colorMap[7] = {128, 0, 0} | |
| colorMap[8] = {0, 128, 0} | |
| colorMap[9] = {0, 0, 128} | |
| local representationImage = floorplan | |
| for mode, items in pairs(representation) do | |
| if mode == 'points' or mode == 'doors' or mode == 'icons' or mode == 'labels' then | |
| for __, item in pairs(items) do | |
| local rectangle = utils.imageRectangle(width, height, gridWidth, gridHeight, item) | |
| local center = {(rectangle[2][1] + rectangle[1][1]) / 2, (rectangle[2][2] + rectangle[1][2]) / 2} | |
| local rectangleWidth = math.max(rectangle[2][1] - rectangle[1][1] + 1, 10) | |
| local rectangleHeight = math.max(rectangle[2][2] - rectangle[1][2] + 1, 10) | |
| local color = colorMap[item[4][2]] | |
| lineWidth = 2 | |
| if mode == 'points' then | |
| lineWidth = 10 | |
| end | |
| --[[ | |
| print(mode) | |
| print(width .. ' ' .. height) | |
| print(center[1] .. ' ' .. center[2]) | |
| print(rectangleWidth .. ' ' .. rectangleHeight) | |
| print(#representationImage) | |
| print(math.max(center[1] - rectangleWidth / 2, 1) .. ' ' .. math.max(center[2] - rectangleHeight / 2, 1) .. ' ' .. math.min(center[1] + rectangleWidth / 2, width) .. ' ' .. math.min(center[2] + rectangleHeight / 2, height)) | |
| ]]-- | |
| --representationImage = image.drawRect(representationImage, math.max(center[1] - rectangleWidth / 2, 1), math.max(center[2] - rectangleHeight / 2, 1), math.min(center[1] + rectangleWidth / 2, width), math.min(center[2] + rectangleHeight / 2, height), {lineWidth = lineWidth, color = color}) | |
| success, newRepresentationImage = pcall(function() return image.drawRect(representationImage, math.max(center[1] - rectangleWidth / 2, 1), math.max(center[2] - rectangleHeight / 2, 1), math.min(center[1] + rectangleWidth / 2, width), math.min(center[2] + rectangleHeight / 2, height), {lineWidth = lineWidth, color = color}) end) | |
| if success then | |
| representationImage = newRepresentationImage | |
| else | |
| --[[ | |
| print('Fail to draw rectangle') | |
| print(#representationImage) | |
| print(center[1] .. '\t' .. center[2] .. '\t' .. rectangleWidth .. '\t' .. rectangleHeight .. '\t' .. lineWidth) | |
| ]]-- | |
| end | |
| end | |
| end | |
| end | |
| return representationImage | |
| elseif representationType == 'P' and renderingType == 'L' then | |
| local representationImage = torch.ones(#floorplan) | |
| local usedPointLineMask = {} | |
| local pointOrientations = {} | |
| for pointIndex, point in pairs(representation.points) do | |
| usedPointLineMask[pointIndex] = {true, true, true, true} | |
| local orientations = {} | |
| local orientation = point[3][3] | |
| if point[3][2] == 1 then | |
| table.insert(orientations, (orientation + 2 - 1) % 4 + 1) | |
| elseif point[3][2] == 2 then | |
| table.insert(orientations, orientation) | |
| table.insert(orientations, (orientation + 3 - 1) % 4 + 1) | |
| elseif point[3][2] == 3 then | |
| for i = 1, 4 do | |
| if i ~= orientation then | |
| table.insert(orientations, i) | |
| end | |
| end | |
| else | |
| for i = 1, 4 do | |
| table.insert(orientations, i) | |
| end | |
| end | |
| pointOrientations[pointIndex] = orientations | |
| for _, orientation in pairs(orientations) do | |
| usedPointLineMask[orientation] = false | |
| end | |
| end | |
| for pointIndex, point in pairs(representation.points) do | |
| local orientations = pointOrientations[pointIndex] | |
| local x = point[1][1] | |
| local y = point[1][2] | |
| for _, orientation in pairs(orientations) do | |
| if usedPointLineMask[pointIndex][orientation] == false then | |
| local min_x, max_x, min_y, max_y | |
| if orientation == 1 or orientation == 3 then | |
| min_x = x - lineWidth | |
| max_x = x - lineWidth | |
| if orientation = 1 then | |
| min_y = 1 | |
| max_y = y | |
| else | |
| min_y = y | |
| max_y = height | |
| end | |
| else | |
| min_y = y - lineWidth | |
| max_y = y - lineWidth | |
| if orientation = 2 then | |
| min_x = x | |
| max_x = width | |
| else | |
| min_x = 1 | |
| max_x = x | |
| end | |
| end | |
| local orientationOpposite = (orientation + 2 - 1) % 4 + 1 | |
| for otherPointIndex, otherPoint in pairs(representation.points) do | |
| if otherPointIndex ~= pointIndex and usedPointLineMask[otherPoint][orientationOpposite] == false then | |
| for mode, items in pairs(representation) do | |
| if mode == 'points' or mode == 'doors' or mode == 'icons' or mode == 'labels' then | |
| for __, item in pairs(items) do | |
| local rectangle = utils.imageRectangle(width, height, gridWidth, gridHeight, item) | |
| local center = {(rectangle[2][1] + rectangle[1][1]) / 2, (rectangle[2][2] + rectangle[1][2]) / 2} | |
| local rectangleWidth = math.max(rectangle[2][1] - rectangle[1][1] + 1, 10) | |
| local rectangleHeight = math.max(rectangle[2][2] - rectangle[1][2] + 1, 10) | |
| local color = colorMap[item[4][2]] | |
| lineWidth = 2 | |
| if mode == 'points' then | |
| lineWidth = 10 | |
| end | |
| success, newRepresentationImage = pcall(function() return image.drawRect(representationImage, math.max(center[1] - rectangleWidth / 2, 1), math.max(center[2] - rectangleHeight / 2, 1), math.min(center[1] + rectangleWidth / 2, width), math.min(center[2] + rectangleHeight / 2, height), {lineWidth = lineWidth, color = color}) end) | |
| if success then | |
| representationImage = newRepresentationImage | |
| else | |
| --[[ | |
| print('Fail to draw rectangle') | |
| print(#representationImage) | |
| print(center[1] .. '\t' .. center[2] .. '\t' .. rectangleWidth .. '\t' .. rectangleHeight .. '\t' .. lineWidth) | |
| ]]-- | |
| end | |
| end | |
| end | |
| end | |
| return representationImage | |
| end | |
| end | |
| function utils.loadRepresentation(filename) | |
| local representationExists, representationInfo = pcall(function() | |
| return csvigo.load({path=filename, mode="large", header=false, separator='\t', verbose=false}) | |
| end) | |
| if representationExists and representationInfo ~= nil then | |
| local representation = {} | |
| representation.walls = {} | |
| representation.doors = {} | |
| representation.icons = {} | |
| representation.labels = {} | |
| local modeMap = utils.modeMap() | |
| for _, item in pairs(representationInfo) do | |
| local itemMode = modeMap[item[5]] | |
| local itemInfo = {{tonumber(item[1]), tonumber(item[2])}, {tonumber(item[3]), tonumber(item[4])}, {item[5], tonumber(item[6]), tonumber(item[7])}} | |
| table.insert(representation[itemMode], itemInfo) | |
| end | |
| return representation | |
| else | |
| return nil | |
| end | |
| end | |
| function utils.finalizeRepresentation(representation) | |
| representation.walls = utils.stitchLines(utils.sortLines(representation.walls), 5) | |
| representation.doors = utils.sortLines(representation.doors) | |
| return representation | |
| end | |
| function utils.saveRepresentation(filename, representation) | |
| --local representationExists, representationFile = pcall(function() | |
| --return io.open(filename, 'r') | |
| --end) | |
| --local override = false | |
| --if representationExists then | |
| --end | |
| print('save representation') | |
| representation = utils.finalizeRepresentation(representation) | |
| pl.dir.makepath(filename:match('(.+)/(.+)')) | |
| local representationFile = io.open(filename, 'w') | |
| for itemMode, items in pairs(representation) do | |
| for _, item in pairs(items) do | |
| for __, field in pairs(item) do | |
| if __ <= 3 then | |
| for ___, value in pairs(field) do | |
| representationFile:write(value .. '\t') | |
| end | |
| end | |
| end | |
| representationFile:write('\n') | |
| end | |
| end | |
| representationFile:close() | |
| end | |
| --[[ | |
| lines = {} | |
| table.insert(lines, {{1, 1}, {1, 10}}) | |
| table.insert(lines, {{1, 11}, {20, 11}}) | |
| print(lines) | |
| print(stitchLines(lines, 5)) | |
| ]]-- | |
| return utils | |