오늘 작성한 코드이고, 자세한 내용은 따로 포스팅 할 예정이다
def _tf_decode(x, y):
img_side = tf.shape(x)[0]
grid_size = tf.shape(y)[0]
point_count = tf.shape(y)[2]
attr_len = tf.shape(y)[3]
g = tf.stack(tf.meshgrid(
tf.range(0,grid_size),
tf.range(0,grid_size)
), axis=-1)
pad_g = tf.zeros((grid_size,grid_size,attr_len-2), tf.int32)
g = tf.concat([g,pad_g], axis=-1)
g = tf.expand_dims(g, -2)
g = tf.tile(g, tf.convert_to_tensor([1, 1, point_count, 1]))
coord = tf.ones((1,1,1,2)) * tf.cast(img_side/grid_size, tf.float32)
size = tf.ones((1,1,1,2)) * tf.cast(img_side, tf.float32)
others = tf.ones((1,1,1,attr_len-4))
info = tf.concat([coord, size, others], axis=-1)
ty = tf.identity(y)
ty = ty + tf.cast(g, tf.float32)
ty = ty * info
return ty
def _tf_encode(x, y, bboxes):
# Get grid coords, sizes
img_side = tf.shape(x)[0]
grid_side = tf.shape(y)[0]
point_count = tf.shape(y)[2]
attr_count = tf.shape(y)[3]
to_grid_coord = tf.convert_to_tensor([[img_side/grid_side, img_side/grid_side]], tf.float32)
to_glob_size = tf.convert_to_tensor([[img_side, img_side]], tf.float32)
pad = tf.ones((1,attr_count-4), tf.float32)
to_grid = tf.concat([to_grid_coord, to_glob_size, pad], axis=-1)
g_bboxes = bboxes / to_grid
glob_grid_coords = g_bboxes[:,:2]
local_grid_coords = g_bboxes[:,:2] - tf.floor(glob_grid_coords)
glob_grid_coords = tf.cast(glob_grid_coords, tf.int32)
# Get point order
enc_coord = glob_grid_coords[:,0]*grid_side + glob_grid_coords[:,1]
uni, indices = tf.unique(enc_coord)
point_order = tf.zeros_like(indices, tf.int32)
cnts = tf.zeros_like(uni, tf.int32)
# < Example >
# [0 1 0 2 1] --> [0,0,1,0,1]
ind_dp = tf.shape(indices)[0]
cnt_dp = tf.shape(cnts)[0]
for i in range(ind_dp):
v = indices[i]
c = cnts[v]
ind_idx = tf.one_hot(i, ind_dp, dtype=tf.int32)
cnt_idx = tf.one_hot(v, cnt_dp, dtype=tf.int32)
point_order = point_order + ind_idx * c
cnts = cnts + cnt_idx
point_order = tf.expand_dims(point_order, -1)
point_order = tf.minimum(point_order, point_count)
# Create indices
indices = tf.concat([glob_grid_coords[...,::-1], point_order], -1)
# Scatter bboxes
encoded_bbox = tf.concat([local_grid_coords, g_bboxes[:,2:]], axis=-1)
plane_shape = tf.shape(y)
encoded_bboxes = tf.scatter_nd(indices, encoded_bbox, plane_shape)
return encoded_bboxes
def _rotate_bbox(x, y, degree):
img_side = tf.shape(x)[0]
img_side = tf.cast(img_side, tf.float32)
bboxes = y[y[...,4]==1]
box_count = tf.shape(bboxes)[0]
pi = tf.math.acos(0.0)*2
radian = -degree * pi / 180.
cos = tf.math.cos([radian])
sin = tf.math.sin([radian])
rotate_matrix = tf.concat([cos, -sin, sin, cos], axis=-1)
rotate_matrix = tf.reshape(rotate_matrix, (1,2,2))
cx = bboxes[:,0:1]
cy = bboxes[:,1:2]
w = bboxes[:,2:3]
h = bboxes[:,3:4]
left = cx - w/2
right = cx + w/2
top = cy - h/2
bottom = cy + h/2
coord = tf.concat([left, right, top, bottom], axis=-1)
coord = tf.reshape(coord, (-1,2,2))
coord = coord - tf.convert_to_tensor([[img_side/2, img_side/2], [img_side/2, img_side/2]])
rot_coord = rotate_matrix @ coord
rot_coord = rot_coord + tf.convert_to_tensor([[img_side/2, img_side/2],[img_side/2, img_side/2]])
rot_coord = tf.clip_by_value(rot_coord, 0.0, img_side-1)
lt = rot_coord[...,0]
rb = rot_coord[...,1]
w = rb[...,0:1] - lt[...,0:1]
h = rb[...,1:2] - lt[...,1:2]
cx = lt[...,0:1] + w/2
cy = lt[...,1:2] + h/2
result = tf.concat([cx, cy, w, h, bboxes[...,4:]], axis=-1)
return result
def _tf_decode(x, y):
img_side = tf.shape(x)[0]
Grid_size = tf.shape(y)[0]
point_count = tf.shape(y)[2]
attr_len = tf.shape(y)[3]
g = tf.stack(tf.meshgrid(
tf.range(0,grid_size),
tf.range(0,grid_size)
), 축=-1)
pad_g = tf.zeros((grid_size,grid_size,attr_len-2), tf.int32)
g = tf.concat([g,pad_g], 축=-1)
g = tf.expand_dims(g, -2)
g = tf.tile(g, tf.convert_to_tensor([1, 1, point_count, 1]))
좌표 = tf.ones((1,1,1,2)) * tf.cast(img_side/grid_size, tf.float32)
크기 = tf.ones((1,1,1,2)) * tf.cast(img_side, tf.float32)
기타 = tf.ones((1,1,1,attr_len-4))
info = tf.concat([좌표, 크기, 기타], 축=-1)
ty = tf.identity(y)
ty = ty + tf.cast(g, tf.float32)
ty = ty * 정보
타이를 반환
def _tf_encode(x, y, bboxes):
# 그리드 좌표, 크기를 얻습니다
img_side = tf.shape(x)[0]
Grid_side = tf.shape(y)[0]
point_count = tf.shape(y)[2]
attr_count = tf.shape(y)[3]
to_grid_coord = tf.convert_to_tensor([[img_side/grid_side, img_side/grid_side]], tf.float32)
to_glob_size = tf.convert_to_tensor([[img_side, img_side]], tf.float32)
패드 = tf.ones((1,attr_count-4), tf.float32)
to_grid = tf.concat([to_grid_coord, to_glob_size, pad], 축=-1)
g_bboxes = bboxes / to_grid
glob_grid_coords = g_bboxes[:,:2]
local_grid_coords = g_bboxes[:,:2] - tf.floor(glob_grid_coords)
glob_grid_coords = tf.cast(glob_grid_coords, tf.int32)
# 포인트 주문 받기
enc_coord = glob_grid_coords[:,0]*grid_side + glob_grid_coords[:,1]
유니, 인덱스 = tf.unique(enc_coord)
point_order = tf.zeros_like(인덱스, tf.int32)
cnts = tf.zeros_like(uni, tf.int32)
# < 예시 >
# [0 1 0 2 1] --> [0,0,1,0,1]
ind_dp = tf.shape(인덱스)[0]
cnt_dp = tf.shape(cnts)[0]
범위(ind_dp)에 있는 i의 경우:
v = 인덱스[i]
c = cnts[v]
ind_idx = tf.one_hot(i, ind_dp, dtype=tf.int32)
cnt_idx = tf.one_hot(v, cnt_dp, dtype=tf.int32)
point_order = point_order + ind_idx * c
cnts = cnts + cnt_idx
point_order = tf.expand_dims(point_order, -1)
point_order = tf.minimum(point_order, point_count)
# 인덱스 생성
인덱스 = tf.concat([glob_grid_coords[...,::-1], point_order], -1)
# Bbox를 분산시킵니다
인코딩된_bbox = tf.concat([local_grid_coords, g_bboxes[:,2:]], 축=-1)
plane_shape = tf.shape(y)
인코딩된_bboxes = tf.scatter_nd(인덱스, 인코딩된_bbox, 평면_모양)
encoded_bbox를 반환합니다.
def _rotate_bbox(x, y, 각도):
img_side = tf.shape(x)[0]
img_side = tf.cast(img_side, tf.float32)
bboxes = y[y[...,4]==1]
box_count = tf.shape(bboxes)[0]
파이 = tf.math.acos(0.0)*2
라디안 = -도 * 파이 / 180.
cos = tf.math.cos([라디안])
죄 = tf.math.sin([라디안])
Rotate_matrix = tf.concat([cos, -sin, sin, cos], 축=-1)
Rotate_matrix = tf.reshape(rotate_matrix, (1,2,2))
cx = bboxes[:,0:1]
cy = b박스[:,1:2]
w = b박스[:,2:3]
h = b박스[:,3:4]
왼쪽 = cx - w/2
오른쪽 = cx + w/2
상단 = cy - h/2
하단 = cy + h/2
coord = tf.concat([왼쪽, 오른쪽, 위쪽, 아래쪽], 축=-1)
좌표 = tf.reshape(좌표, (-1,2,2))
coord = coord - tf.convert_to_tensor([[img_side/2, img_side/2], [img_side/2, img_side/2]])
rot_coord = 회전_매트릭스 @ 좌표
rot_coord = rot_coord + tf.convert_to_tensor([[img_side/2, img_side/2],[img_side/2, img_side/2]])
rot_coord = tf.clip_by_value(rot_coord, 0.0, img_side-1)
lt = rot_coord[...,0]
rb = rot_coord[...,1]
w = rb[...,0:1] - lt[...,0:1]
h = rb[...,1:2] - lt[...,1:2]
cx = lt[...,0:1] + w/2
cy = lt[...,1:2] + h/2
결과 = tf.concat([cx, cy, w, h, bboxes[...,4:]], 축=-1)
결과 반환