def move_axis_aligned_box_to_wall(box2d, walls, cat_name, voxel_size): assert box2d.shape == (1,5) assert walls.shape[1] == 8 box2d0 = box2d.copy() max_thick = MAX_THICK_MAP[cat_name] / voxel_size thick_add_on_wall = int(THICK_GREATER_THAN_WALL[cat_name] / voxel_size) n = walls.shape[0] center = np.array(box2d[0,:2]) wall_lines = OBJ_REPS_PARSE.encode_obj( walls, 'XYXYSin2WZ0Z1', 'RoLine2D_2p' ).reshape(-1,2,2) walls_ = OBJ_REPS_PARSE.encode_obj(walls, 'XYXYSin2WZ0Z1', 'XYLgWsA') diss = vertical_dis_1point_lines(center, wall_lines, no_extend=False) angles_dif = walls_[:,-1] - box2d[:,-1] angles_dif = limit_period_np(angles_dif, 0.5, np.pi) invalid_mask = np.abs(angles_dif) > np.pi/4 diss[invalid_mask] = 1000 diss *= voxel_size if diss.min() > 0.3: return box2d the_wall_id = diss.argmin() the_wall = walls_[the_wall_id] thick_add_on_wall = int(THICK_GREATER_THAN_WALL[cat_name] / voxel_size) new_thick = min(the_wall[3] + thick_add_on_wall, max_thick) new_thick = max(new_thick, max_thick*0.7) box2d[0,3] = new_thick angle_dif = limit_period_np( the_wall[-1] - box2d[0,-1], 0.5, np.pi ) if abs(box2d[0,-1]) < np.pi/4: # long axis is x, move y move_axis = 1 else: move_axis = 0 # if the center of box2d is not inside the wall, do not move j = 1- move_axis inside_wall = box2d0[0,j] < the_wall[j]+the_wall[2]/2 and box2d0[0,j] > the_wall[j]-the_wall[2]/2 if inside_wall: move0 = the_wall[move_axis] - box2d0[0,move_axis] if abs(move0 * voxel_size) < 0.1: move = move0 else: move = abs(new_thick - box2d0[0,3]) * np.sign(move0) / 2 box2d[0,move_axis] += move print(f'move:{move}, move0:{move0}') #_show_3d_points_objs_ls( objs_ls=[ box2d0, box2d, the_wall[None]], obj_rep='XYLgWsA', obj_colors=['blue', 'red', 'black']) #_show_3d_points_objs_ls( objs_ls=[ box2d0, the_wall[None]], obj_rep='XYLgWsA', obj_colors=[ 'blue', 'black']) #_show_3d_points_objs_ls( objs_ls=[ box2d, the_wall[None]], obj_rep='XYLgWsA', obj_colors=[ 'red', 'black']) pass return box2d
def align_bboxes_with_wall(dets, walls, cat, obj_rep): assert cat in ['door', 'window'] assert obj_rep == 'XYZLgWsHA' new_dets = dets.copy() det_scores = dets[:,-1:] dets = dets[:,:-1] wall_scores = walls[:,-1:] walls = walls[:,:-1] ious = dsiou_rotated_3d_bbox_np(dets, walls, iou_w=1, size_rate_thres=0.2, ref='bboxes1') the_wall_ids = ious.argmax(1) max_ious = ious.max(1) ndet = dets.shape[0] #print(f'max_ious: {max_ious}') #_show_objs_ls_points_ls( (512,512), [dets, walls], obj_rep=obj_rep, obj_colors=['red', 'blue']) for i in range(ndet): if max_ious[i] > 0.5: the_wall = walls[the_wall_ids[i]] #_show_objs_ls_points_ls( (512,512), [dets[i:i+1], the_wall[None,:]], obj_rep=obj_rep, obj_colors=['red', 'blue']) angle_dif = np.abs( limit_period_np( dets[i,-1] - the_wall[-1] , 0.5, np.pi)) if angle_dif < np.pi/4: #new_dets[i, -1] = the_wall[-1] #new_dets[i, 4] = max(dets[i,4], the_wall[4]*1.5) new_dets[i,:7] = align_1_box_with_wall(new_dets[i,:7], the_wall[:7], obj_rep) #_show_objs_ls_points_ls( (512,512), [new_dets[i:i+1,:7], the_wall[None,:]], obj_rep=obj_rep, obj_colors=['red', 'blue']) pass pass return new_dets
def fix_box_cv2(box2d): box2d = np.array( box2d[0]+box2d[1]+(box2d[2],) )[None, :] # The original angle from cv2.minAreaRect denotes the rotation from ref-x # to body-x. It is it positive for clock-wise. # make x the long dim if box2d[0,2] < box2d[0,3]: box2d[:,[2,3]] = box2d[:,[3,2]] box2d[:,-1] = 90+box2d[:,-1] box2d[:,-1] *= np.pi / 180 box2d[:,-1] = limit_period_np(box2d[:,-1], 0.5, np.pi) # limit_period return box2d
def manual_rm_objs(bboxes0, obj_rep, all_colors, max_size=7): print(bboxes0[:,3] ) bboxes1 = OBJ_REPS_PARSE.encode_obj(bboxes0, obj_rep, 'XYZLgWsHA') #_show_3d_bboxes_ids(bboxes0, obj_rep) mask1 = bboxes1[:,3] < max_size angle_dif = np.abs(limit_period_np(bboxes1[:,6], 0.5, np.pi/2)) mask2 = angle_dif < 0.3 mask = mask1 * mask2 bboxes2 = bboxes1[mask] bboxes_out = OBJ_REPS_PARSE.encode_obj(bboxes2, 'XYZLgWsHA', obj_rep) all_colors = [all_colors[i] for i in range(len(mask)) if mask[i]] return bboxes_out, all_colors
def get_room_quality_scores(rooms, obj_rep): from obj_geo_utils.geometry_utils import limit_period_np assert obj_rep == 'XYZLgWsHA' assert rooms.shape[1] == 8 areas = rooms[:,3] * rooms[:,4] # smaller is better area_scores = 1 - areas / areas.mean() area_scores = np.clip(area_scores, a_min=0, a_max=None) rotations = limit_period_np( rooms[:,6], 0.5, np.pi/2) * 180 / np.pi # smaller is better align_scores = 1 - np.abs(rotations) / 45 det_scores = rooms[:,-1] final_scores = area_scores * 0.2 + align_scores * 0.5 + det_scores * 0.3 #_show_objs_ls_points_ls((512,512), [rooms[:,:-1]], obj_rep, obj_scores_ls=[final_scores]) return final_scores
def sort_rooms(rooms, obj_rep): ''' Small first, Align first ''' from obj_geo_utils.geometry_utils import limit_period_np assert rooms.shape[1] == 7+1 assert obj_rep == 'XYZLgWsHA' areas = rooms[:,3] * rooms[:,4] # smaller is better area_scores = 1 - areas / areas.mean() rotations = limit_period_np( rooms[:,6], 0.5, np.pi/2) * 180 / np.pi # smaller is better align_scores = 1 - np.abs(rotations) / 45 det_scores = rooms[:,-1] final_scores = area_scores * 0.4 + align_scores * 0.3 + det_scores * 0.3 ids = np.argsort(-final_scores) rooms_new = rooms[ids] return rooms_new
def connect_two_corner(corners, walls0, obj_rep): assert corners.shape == (2,2) assert walls0.shape[0] == 2 show = 0 c = walls0.shape[1] angle_dif = limit_period_np( walls0[0,6] - walls0[1,6], 0.5, np.pi) angle_dif = abs(angle_dif) if angle_dif > np.pi / 4: new_wall = intersect_2edges_by_add_new_wall( walls0[:,:7], obj_rep, corners ) walls1 = walls0[:,:7] else: new_wall = OBJ_REPS_PARSE.encode_obj(corners.reshape(1,4), 'RoLine2D_2p', obj_rep) walls1 = walls0[:,:7] if c==8: score = new_wall[:,0:1].copy() score[:] =1 new_wall = np.concatenate([new_wall, score ], 1) if show: _show_objs_ls_points_ls( (512, 512), [walls0[:,:7], walls1[:,:7], new_wall[:,:7]], obj_rep, obj_colors=['white', 'green', 'red'], obj_thickness=[4,1,1] ) import pdb; pdb.set_trace() # XXX BREAKPOINT pass return walls1, new_wall