8import smdataset.utils_data
as utils
13 세이프모션 행동 데이터를 관리하는 클래스
14 데이터 불러오기, 저장하기, 업데이트(데이터 변경), 프레임단위로 데이터 get, 추적 아이디 단위로 get 등의 기능 제공
16 anno_path (str) : 어노테이션 파일(json 파일) 경로
17 save_path (str) : 저장 경로, 설정하지 않으면 anno_path에 저장됨
21 image_base_path =
None
27 image_filenames =
None
33 anno_idx_in_image =
None
35 def __init__(self, anno_path=None, save_path=None):
37 if anno_path
is not None:
66 def load_annotation(self, anno_path, image_base=None, program_label_map_version=None, save_path=None):
69 데이터를 로드하고 프레임 단위로 데이터 구조를 변경해둠
71 anno_path (str) : json 파일의 경로
72 image_base (str) : 이미지 베이스 경로 설정 가능, 설정하지 않으면 기본 디폴트 값을 사용함
73 program_label_map_version (str) : 라벨링 프로그램의 레이블맵 버전, 설정하지 않는다면 json 파일에 값을 사용
74 save_path (str) : 저장 경로 설정, 설정하지 않는다면 anno_path로 설정됨
83 self.
dataset) = utils.load_annotation(anno_path)
85 if image_base !=
None:
89 if program_label_map_version
is not None:
92 self.
dataset[
'info'][
'label_map_version'] = program_label_map_version/10
106 프레임 단위로 데이터 구조를 변경하는 기능
108 dataset (dict) : 어노테이션 데이터
109 info : json 파일의 기본 정보가 들어있음
110 images : 이미지 아이디, 이름 및 기타 정보
111 annotations : 라벨링된 데이터, 박스마다 데이터가 들어있음
112 대표 정보 : 어노테이션 아이디, 박스정보(x, y, w, h), 키포인트, 액션 라벨 등
114 anno_in_image (dict): 프레임 단위로 어노테이션(박스) 정보를 저장한 변수
116 value (list[dict]): 해당 프레임의 어노테이션(박스) 정보 리스트
117 anno_ids (list): 어노테이션 아이디 리스트
118 image_ids (list): 이미지 아이디 리스트
119 image_filenames (list): 이미지 이름 리스트
125 for img
in dataset[
'images']:
126 image_ids.append(img[
'id'])
127 image_filenames.append(img[
'file_name'])
128 anno_in_image[img[
'id']] = []
131 for anno
in dataset[
'annotations']:
132 anno_in_image[anno[
'image_id']].append(copy.deepcopy(anno))
133 anno_ids.append(anno[
'id'])
135 return anno_in_image, anno_ids, image_ids, image_filenames
147 맨 첫프레임, 첫번째 어노테이션(박스) 정보로 셋팅함
148 첫프레임에 어노테이션 정보가 없다면 관련 변수는 None으로 셋팅됨
168 현재 프레임의 어노테이션(박스) 인덱스 기준으로 관련 데이터를 셋팅함
170 anno_idx_in_image (int) : 설정하기 위한 현재 프레임의 어노테이션(박스) 인덱스
179 어노테이션(박스) 인덱스 기준으로 현재 정보를 셋팅함
181 anno_idx (int) : 셋팅하려는 어노테이션(박스) 인덱스
182 return (bool): 이미지 변경 유무
196 이미지 인덱스를 기준으로 현재 정보를 셋팅함
197 추적아이디 사용을 설정하면 현재 선택된 추적아이디와 같은 어노테이션 정보로 셋팅함
199 image_idx (int) : 셋팅하려는 이미지 인덱스
200 use_track_id (bool) : 추적아이디 사용 여부
201 return (bool): 이미지 변경 유무
207 if use_track_id
and self.
anno_idx is not None:
210 anno_idx_in_image = 0
214 if track_id
is not None:
216 if anno[
"track_id"] == track_id:
217 anno_idx_in_image = idx
234 return (bool): 이미지 변경 유무
236 check_change_image =
True
242 return check_change_image
247 return (bool): 이미지 변경 유무
249 check_change_image =
True
255 return check_change_image
278 현재 프레임에서 현재 선택되어 있는 어노테이션(박스)이 처음인지 마지막인지 확인하는 기능
280 check_index (int) : 첫프레임 체크인지 마지막 프레임 체크인지 설정하는 파라미터
293 현재 프레임이 수정된 상태인 확인하는 기능
298 if anno[
"ismodify"] == 0:
305 현재 프레임에 동일한 track_id 존재 유무 확인 기능(현재 선택된 객체는 제외하고 체크함)
306 return (bool): 추적 아이디 존재 유무
314 if anno[
'track_id'] == track_id:
324 어노테이션(박스) 수량을 출력하는 기능
325 return (int) : 어노테이션(박스) 수량
332 return (int) : 이미지 수량
338 현재 프레임의 어노테이션(박스) 수량을 출력하는 기능
339 return (int) : 현재 프레임의 어노테이션(박스) 수량
347 현재 프레임의 모든 어노테이션(박스)정보를 출력하는 기능
349 bbox_list (list[list]) : 박스위치 정보 리스트, [x, y, w, h]
350 action_id_list (list[dict]) : 행동라벨 리스트
351 track_id_list (list[int]) : 추적 아이디 리스트
352 keypoints_list (list[np.array]) : 스켈레톤 좌표정보 리스트(x, y, score), shape (17, 3)
360 np_key = np.array(anno[
"keypoints"])
362 bbox_list.append(anno[
"bbox"])
363 track_id_list.append(anno[
"track_id"])
364 action_id_list.append(anno[
"action_id"])
365 keypoints_list.append(np_key.reshape(17, 3))
366 return bbox_list, action_id_list, track_id_list, keypoints_list
370 현재 선택된 어노테이션(박스) 정보를 출력하는 기능
371 return (dict) : 어노테이션 정보(박스, 키포인트, 행동라벨 등)
379 입력한 이미지 인덱스의 데이터에서 설정한 데이터에 부합하는 어노테이션 정보를 출력하는 기능
381 image_idx (int) : 검색하려는 이미지 인덱스, 설정하지 않는다면 현재 프레임이됨
382 key (str) : 확인하려는 데이터의 키, 설정하지 않으면 필저링 조건만 체크함
384 filter (str) : 필터링 유무, 가려짐, 잘림 정도로 필터, Fasle로 설정하면 검색하려는 프레임의 모든 어노테이션 데이터를 반환함
385 return (list[dict] or dict):
386 필터링 조건을 통과한 어노테이션 리스트
388 조건에 부합하는 데이터가 없을경우 None을 반환함
390 if image_idx
is None:
399 if anno[
'occlusion'] > 2
or anno[
'truncation'] > 2:
401 ret_anno.append(copy.deepcopy(anno))
407 if anno[key] == value:
408 return copy.deepcopy(anno)
413 설정되어 있는 프레임보다 이전 프레임에서 데이터를 검색하는 기능
416 key (str): 확인하려는 데이터의 키
420 조건에 부합하는 데이터가 없을경우 None을 반환함
425 for i
in range(self.
image_idx-1, -1, -1):
427 if ann[key] == value:
428 return copy.deepcopy(ann)
433 모든 추적 아이디에 대해서 추적 아이디가 처음 등장하는 프레임과 등장하는 프레임 수를 반환하는 기능
434 return (dict): 추적 아이디의 정보
436 value (list): 첫번째 인자는 추적아이디가 등장하는 첫 프레임 인덱스, 두번째 인자는 추적아이디가 등장하는 프레임 수
439 for anno
in self.
dataset[
'annotations']:
440 if anno[
'track_id']
in track_info:
441 track_info[anno[
'track_id']][1] = track_info[anno[
'track_id']][1] + 1
443 track_info[anno[
'track_id']] = [self.
image_ids.index(anno[
'image_id']), 1]
448 설정한 프레임 구간에서 모든 어노테이션의 추적 아이디 정보를 반환하는 기능
450 filter (bool) : 필터링 유무, 가려짐, 잘림 정도로 필터
451 start_frame (int) : 검색하려는 시작 프레임 인덱스
452 end_frame (int) : 검색하려는 끝 프레임 인덱스(해당 인덱스를 포함하지 않음), 설정하지 않으면 맨 마지막 프레임까지 범위로 설정됨
453 return (dict) : 추적 아이디를 기준으로 변환된 어노테이션 정보
455 value (list[dict]): 추적 아이디의 어노테이션 리스트
459 if end_frame ==
None:
462 for anno
in self.
dataset[
'annotations']:
463 if filter
and (anno[
'occlusion'] > 2
or anno[
'truncation'] > 2):
466 img_idx = self.
image_ids.index(anno[
'image_id'])
467 if img_idx < start_frame
or img_idx >= end_frame:
470 if anno[
'track_id']
in track_data:
471 track_data[anno[
'track_id']].append(anno)
473 track_data[anno[
'track_id']] = [anno]
482 현재 선택된 어노테이션 정보를 입력 데이터로 업데이트하는 기능
484 anno (dict) : 업데이트 하려는 정보, anno에 포함된 키값의 데이터만 업데이트함
498 tmp_anno_ids.append(ann[
'id'])
499 tmp_track_ids.append(ann[
'track_id'])
501 new_anno_id = int(self.
image_id*100 + max(tmp_anno_ids)%100+1)
506 anno = utils.make_dummy_annotation(new_anno_id, self.
image_id, max(tmp_track_ids)+1)
509 self.
anno_ids.insert(new_anno_idx, new_anno_id)
510 self.
dataset[
'annotations'].insert(new_anno_idx, copy.deepcopy(anno))
518 입력한 추적 아이디의 어노테이션을 추가하는 기능
519 이전 프레임에서 해당 추적 아이디 정보를 복사해서 추가함, 이전 프레임에 해당 추적 아이디가 없다면 더미 데이터를 추가함
522 check_track_id =
False
524 tmp_anno_ids.append(ann[
'id'])
525 if ann[
'track_id'] == track_id:
526 check_track_id =
True
531 new_anno_id = int(self.
image_id*100 + max(tmp_anno_ids)%100+1)
539 anno = utils.make_dummy_annotation(new_anno_id, self.
image_id, track_id)
541 anno[
'id'] = new_anno_id
546 self.
anno_ids.insert(new_anno_idx, new_anno_id)
547 self.
dataset[
'annotations'].insert(new_anno_idx, copy.deepcopy(anno))
555 현재 선택된 어노테이션을 삭제하는 기능
572 현재 선택된 어노테이션션 데이터를 업데이트하는 기능
582 조건에 맞는 어노테이션을 모두 업데이트하는 기능
587 new_anno : 업데이트하려는 어노테이션 데이터
588 frame_range : 업데이트하려는 프레임 범위, 범위를 설정하지 않는다면 전체 범위로 설정됨
593 new_anno[
'ismodify'] = 1
594 if frame_range
is not None:
595 start = frame_range[0]
596 end = frame_range[1]+1
598 for image_idx
in range(start, end):
600 for idx_in_image, anno
in enumerate(self.
anno_in_image[image_id]):
601 if anno[key] == value:
603 anno_idx = self.
anno_ids.index(anno_id)
604 self.
dataset[
'annotations'][anno_idx].update(new_anno)
609 입력한 어노테이션 아이디에 해당하는 정보를 업데이트하는 기능
611 anno_id (int): 업데이트하려는 어노테이션 아이디
614 anno (dict)) : 업데이트하려는 데이터, 여러 데이터를 업데이트 하고싶을 때 사용
615 anno를 설정하지 않을 경우 아이디에 해당하는 데이터의 key의 정보를 data로 업데이트함
618 new_anno = {key:data}
622 anno_idx = self.
anno_ids.index(anno_id)
623 image_id = self.
dataset[
'annotations'][anno_idx][
'image_id']
626 self.
dataset[
'annotations'][anno_idx].update(new_anno)
627 self.
anno_in_image[image_id][anno_idx_in_image].update(new_anno)
635 설정한 프레임에서 특정 어노테이션 아이디의 인덱스를 반환하는 기능
637 anno_id (int) : 검색하려는 어노테이션 아이디
638 image_id (int) : 검색하려는 이미지 아이디
639 return (int) : 어노테이션 인덱스
643 if anno[
'id'] == anno_id:
649 설정한 프레임에 존재하는 어노테이션들 중 특정 인덱스(이미지 기준 변환 데이터)에 해당하는 어노테이션의 인덱스(원본 어노테이션 기준)를 반환하는 기능
651 image_id (int): 검색하려는 이미지 아이디
652 anno_idx_at_image (int): 해당 프레임에서의 이미지 인덱스
653 return (int) : 어노테이션 인덱스
658 anno_id = self.
anno_in_image[image_id][anno_idx_at_image][
'id']
666 어노테이션 정보에 대응하는 이미지가 저장되어있는 폴더를 반환하는 기능
675 image_idx (int): 경로를 원하는 이미지의 인덱스, 설정하지 않는다면 현재 설정된 이미지의 경로를 반환함
678 if image_idx
is None:
680 print(
'image_idx is None')
693 image_id (int) : 이름을 원하는 이미지의 아이디, 설정하지 않는다면 현재 설정된 이미지의 이름을 반환함
702 image_idx = self.
image_ids.index(image_id)
708 return (np.array): RGB 이미지
715 if not os.path.exists(image_path):
719 image = cv2.imread(image_path)
720 return cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
727 어노테이션 파일 저장 경로를 반환하는 기능
740 filename_re = re.compile(
'S\d{3}')
744 scenario_num =
"S001"
__init__(self, anno_path=None, save_path=None)
update_annotation_data_by_anno_id(self, anno_id, key, data, anno=None)
get_number_of_anno_in_image(self)
move_image_left(self, use_track_id=False)
update_annotation_data(self, key, data)
set_annotation_by_image_index(self, image_idx, use_track_id=False)
get_anno_index_in_image(self, anno_id, image_id)
set_annotation_by_anno_index(self, anno_idx)
delete_annotation_data(self)
check_anno_pose_in_frame(self, check_index)
load_annotation(self, anno_path, image_base=None, program_label_map_version=None, save_path=None)
set_anno_idx_in_image(self, anno_idx_in_image)
get_image_name(self, image_id=None)
batch_update_annotation_data(self, key, value, new_anno, frame_range=None)
check_same_track_id(self, track_id)
insert_annotation_data_by_prev_anno(self, track_id)
get_anno_index(self, image_id, anno_idx_at_image)
move_image_right(self, use_track_id=False)
get_number_of_image(self)
get_scenario_number(self)
get_track_anno_data(self, filter=False, start_frame=0, end_frame=None)
set_annotation_data(self, anno)
check_modified_image(self)
get_anno_data_in_image(self, image_idx=None, key=None, value=None, filter=False)
cvt_data_format(self, dataset)
insert_annotation_data(self)
get_prev_anno_data(self, key, value)
get_image_path(self, image_idx=None)