CoolFace
Apppublic

DynamicScene/DynamicGeneration

sourceHugging Faceupdated 2y agoView on Hugging Face
8likes
dynamic_utils.py369 linesDownload Raw Back to root
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