DynamicScene/DynamicGeneration
8
1import numpy as np2import random3import copy4 5 6PRIVATE_OBJECT_LIST = ["AlarmClock", "CellPhone", "Cloth", "CreditCard", "HandTower", "KeyChain", "Laptop", "Pillow", "TeddyBear", "Towel", "Watch"]7COMMONLY_USED_OBJECT_LIST = ['Book', 'CD', 'Newspaper']8FILTER_TYPE = [9 "AlarmClock",10 "BaseballBat",11 "BasketBall",12 "Bowl",13 "Book"14 "CellPhone",15 "Cloth",16 "CreditCard",17 'Cup',18 'DishSponge',19 'Fork',20 'KeyChain',21 "Laptop",22 'Knife',23 "Mug",24 "Newspaper",25 'Pen', 26 'Pencil',27 'Pillow',28 'Plate',29 'Spoon', 30 'SprayBottle',31 'Vase', 32 'Watch',33 ]34PICKUPABLE_OBJECT_LIST = ['AlarmClock', 'AluminumFoil', 'Apple', 'AppleSliced', 'BaseballBat', 35 'BasketBall', 'Book', 'Boots', 'Bottle', 'Bowl', 'Box', 'Bread', 36 'BreadSliced', 'ButterKnife', 'Candle', 'CD', 'CellPhone', 'Cloth', 37 'CreditCard', 'Cup', 'DishSponge', 'Dumbbell', 'Egg', 'EggCracked', 38 'Fork', 'HandTowel', 'Kettle', 'KeyChain', 'Knife', 'Ladle', 'Laptop', 39 'Lettuce', 'LettuceSliced', 'Mug', 'Newspaper', 'Pan', 'PaperTowelRoll', 40 'Pen', 'Pencil', 'PepperShaker', 'Pillow', 'Plate', 'Plunger', 'Pot', 'Potato', 41 'PotatoSliced', 'RemoteControl', 'SaltShaker', 'ScrubBrush', 'SoapBar', 'SoapBottle', 42 'Spatula', 'Spoon', 'SprayBottle', 'Statue', 'TableTopDecor', 'TeddyBear', 'TennisRacket', 43 'TissueBox', 'ToiletPaper', 'Tomato', 'TomatoSliced', 'Towel', 'Vase', 'Watch', 'WateringCan', 'WineBottle']44RECEPTACLE_LIST = ['ArmChair', 'Bathtub', 'BathtubBasin', 'Bed', 'Bowl', 'Box', 'Cabinet', 'Chair', 'CoffeeMachine', 'CoffeeTable', 45 'CounterTop', 'Cup', 'Desk', 'DiningTable', 'Drawer', 'Dresser', 'Fridge', 'GarbageCan', 'HandTowelHolder', 46 'LaundryHamper', 'Microwave', 'Mug', 'Ottoman', 'Pan', 'Plate', 'Pot', 'Safe', 'Shelf', 'SideTable', 'Sink', 47 'SinkBasin', 'Sofa', 'StoveBurner', 'Toaster', 'Toilet', 'ToiletPaperHanger', 'TowelHolder', 'TVStand']48 49def get_obj_type(obj_id):50 return obj_id.split('|')[0]51 52def get_obj_belong_type(obj_id):53 obj_type = get_obj_type(obj_id)54 belong_type = "public"55 if obj_type in PRIVATE_OBJECT_LIST:56 belong_type = "private"57 elif obj_type in COMMONLY_USED_OBJECT_LIST:58 belong_type = "part_public"59 return belong_type60 61class Sampler():62 def __init__(self):63 self.schedules = []64 self.activity_base = {}65 self.character = []66 self.character_specific = {}67 self.scene_layout = {}68 self.object_prior = {}69 70 def clear_character_specific(self):71 self.character_specific = {}72 for c in self.character:73 self.character_specific[c] = {}74 self.character_specific[c]['room'] = {}75 self.character_specific[c]['related_object'] = []76 77 def set_activity(self, character_info, activity_base, schedules):78 self.activity_base = activity_base79 self.character_info = character_info80 self.character = [c['name'] for c in self.character_info]81 self.schedules = schedules82 self.clear_character_specific()83 84 def set_scene_layout(self, scene_layout):85 self.scene_layout = scene_layout86 self.clear_character_specific()87 88 def get_character_group(self):89 result = [[c] for c in self.character]90 return result91 92 def object_allocation(self):93 rooms = self.scene_layout['room']94 bedrooms = [room for room in rooms if room['roomType'] == 'Bedroom']95 bathrooms = [room for room in rooms if room['roomType'] == 'Bathroom']96 character_group = self.get_character_group()97 bedroom_stack = copy.deepcopy(bedrooms)98 bathroom_stack = copy.deepcopy(bathrooms)99 for cg in character_group:100 if len(bedroom_stack) > 0:101 cd_bedroom = bedroom_stack[-1]102 bedroom_stack.pop(-1)103 else:104 cd_bedroom = bedrooms[0]105 if len(bathroom_stack) > 0:106 cd_bathroom = bathroom_stack[-1]107 bathroom_stack.pop(-1)108 else:109 cd_bathroom = bathrooms[0]110 111 for c in cg:112 self.character_specific[c]['room'] = {113 'Bedroom':cd_bedroom['roomId'],114 'Bathroom':cd_bathroom['roomId']115 }116 117 #object118 pickup_objects = self.scene_layout['pickupable object']119 for pobj in pickup_objects:120 pobj_type = get_obj_type(pobj)121 #private122 if pobj_type in PRIVATE_OBJECT_LIST:123 for character in self.character_specific:124 private_objects = self.character_specific[character]['related_object']125 exist = False126 for o in private_objects:127 if get_obj_type(o) == pobj_type:128 exist = True129 break130 if not exist:131 self.character_specific[character]['related_object'].append(pobj)132 break133 134 #common used (not all characters)135 elif pobj_type in COMMONLY_USED_OBJECT_LIST:136 if len(self.character) >= 2:137 selected_characters = random.sample(self.character, 2)138 else:139 selected_characters = self.character140 for sc in selected_characters:141 self.character_specific[sc]['related_object'].append(pobj)142 143 144 def sample_schedules(self, id=0):145 character = self.character[id]146 schedules = self.schedules[id]147 activity_base = self.activity_base[id]148 results = {}149 for day in schedules:150 day_schedule = []151 for activity in schedules[day]:152 153 154 activity_name = activity['activity']155 #character = activity['character']156 if activity_name not in activity_base:157 continue158 activity_content = activity_base[activity_name]159 160 #sample room161 rooms = list(activity_content.keys())162 room_probs = np.array([activity_content[room]['room_prob'] for room in activity_content])163 if not room_probs.sum() == 1:164 room_probs = room_probs / room_probs.sum()165 166 choose_ids = [i for i in range(len(rooms))]167 choose_id = np.random.choice(choose_ids, p=room_probs.ravel())168 room = rooms[choose_id]169 170 #room ground to scene171 final_rooms = []172 #卧室和厕所找分配173 if (room == 'Bedroom' or room == 'Bathroom'):174 175 final_room_id = self.character_specific[character]['room'][room]176 for r in self.scene_layout['room']:177 if r['roomId'] == final_room_id:178 final_room = r179 break180 else:181 for scene_room in self.scene_layout['room']:182 if scene_room['roomType'] == room:183 final_rooms.append(scene_room)184 #final_room = final_rooms[0]185 final_room = np.random.choice(final_rooms)186 187 #sample object188 object_effect = activity_content[room]['object_effect']189 sample_objects = []190 191 192 for obj in object_effect:193 object_prob = float(object_effect[obj]['object_prob'])194 random_num = random.random()195 if random_num < object_prob:196 sample_objects.append(obj)197 198 199 #sample receptacle200 sample_receptacles = []201 for obj in sample_objects:202 #除去房间中没有的receptacle,并重新归一化203 possible_receptacles_init = object_effect[obj]['receptacles']204 possible_receptacles = []205 for pr in possible_receptacles_init:206 for child in final_room['children']:207 if pr[0] == child.split('|')[0] and pr[0]!='Fridge':208 possible_receptacles.append(pr)209 break210 if len(possible_receptacles) == 0:211 continue212 prob_sum = 0213 for pr in possible_receptacles:214 prob_sum += pr[1]215 for i in range(len(possible_receptacles)):216 possible_receptacles[i][1] = possible_receptacles[i][1] / prob_sum217 218 receptacle_probs = np.array([recep[1] for recep in possible_receptacles])219 choose_ids = [i for i in range(len(receptacle_probs))]220 choose_id = np.random.choice(choose_ids, p=receptacle_probs.ravel())221 receptacle = possible_receptacles[choose_id][0]222 sample_receptacles.append([obj, receptacle])223 224 final_sample = []225 for type_sample in sample_receptacles:226 obj_type = type_sample[0]227 receptacle_type = type_sample[1]228 final_obj = ""229 final_recep = ""230 231 related_objs = self.character_specific[character]['related_object']232 if obj_type in PRIVATE_OBJECT_LIST:233 234 for ro in related_objs:235 if get_obj_type(ro) == obj_type:236 final_obj = ro237 break238 239 else:240 exist = False241 for ro in related_objs:242 if get_obj_type(ro) == obj_type:243 exist = True244 final_obj = ro245 break246 if not exist:247 #从全部找248 cand_final_obj = []249 for pick_obj in self.scene_layout['pickupable object']:250 if pick_obj.split("|")[0] == obj_type:251 #final_obj = pick_obj252 cand_final_obj.append(pick_obj)253 if len(cand_final_obj) > 0:254 final_obj = np.random.choice(cand_final_obj)255 256 for recep in final_room['children']:257 if recep.split('|')[0] == receptacle_type:258 final_recep = recep259 break260 261 if len(final_obj)>0 and len(final_recep) > 0:262 final_sample.append({263 'object':final_obj,264 'receptacle':final_recep265 })266 267 day_schedule.append({268 'activity':activity_name,269 'character':character,270 'start_time':activity['start_time'],271 'end_time':activity['end_time'],272 'room':final_room['roomId'],273 'room_type':final_room['roomType'],274 'content':final_sample,275 })276 277 results[day] = day_schedule 278 279 return results 280 281 def sample(self):282 self.object_allocation()283 sample_schedules = {}284 keys = list(self.schedules[0].keys())285 for key in keys:286 sample_schedules[key] = []287 for i in range(len(self.character)):288 schedule = self.sample_schedules(i)289 for key in keys:290 sample_schedules[key].extend(schedule[key])291 292 def compare_time(item):293 return item['start_time']294 295 for key in keys:296 sample_schedules[key] = sorted(sample_schedules[key], key=compare_time)297 return sample_schedules, None, None298 299def get_layout(house_info):300 objects = house_info['objects']301 rooms = house_info['rooms']302 room_info = []303 receptacle_info = []304 pickupable_object_info = []305 306 for room in rooms:307 room_info.append({308 'roomId':room['id'],309 'roomType':room['roomType'],310 'roomPolygon':room['floorPolygon'],311 'children':[],312 })313 314 def isIn(obj, room):315 pos = obj['position']316 room_polygon = room['roomPolygon']317 polygon_n = len(room_polygon)318 j = polygon_n - 1319 res = False320 for i in range(polygon_n):321 if ((room_polygon[i]['z']>pos['z'])!=(room_polygon[j]['z']>pos['z']) and \322 pos['x']< (room_polygon[j]['x'] - room_polygon[i]['x']) * (pos['z'] - room_polygon[i]['z'])/(room_polygon[j]['z'] - room_polygon[i]['z']) + room_polygon[i]['x'] ):323 res = not res324 j = i325 326 return res327 328 def get_type(oid):329 return oid.split('|')[0]330 331 def get_receptacle_info(obj):332 rinfo = {333 'id':obj['id'],334 }335 if 'children' in obj:336 rc = []337 for child in obj['children']:338 rc.append(child['id'])339 if get_type(child['id']) in PICKUPABLE_OBJECT_LIST:340 pickupable_object_info.append(child['id'])341 if get_type(child['id']) in RECEPTACLE_LIST:342 get_receptacle_info(child)343 344 if len(rc) >0:345 rinfo['children'] = rc346 347 receptacle_info.append(rinfo)348 349 for obj in objects: 350 for room in room_info:351 if isIn(obj, room):352 room['children'].append(obj['id'])353 #print("{} in {}".format(obj['id'], room['roomType']))354 break355 if get_type(obj['id']) in RECEPTACLE_LIST:356 get_receptacle_info(obj)357 if get_type(obj['id']) in PICKUPABLE_OBJECT_LIST:358 pickupable_object_info.append(obj['id'])359 360 for r in room_info:361 del r['roomPolygon']362 363 layout_info = {364 'room':room_info,365 'receptacle': receptacle_info,366 'pickupable object' : pickupable_object_info367 }368 return layout_info369 