Safemotion Lib
Loading...
Searching...
No Matches
AnnotationDataManager.py
Go to the documentation of this file.
1import copy
2import os
3import re
4
5import cv2
6import numpy as np
7
8import smdataset.utils_data as utils
9
10
12 """
13 세이프모션 행동 데이터를 관리하는 클래스
14 데이터 불러오기, 저장하기, 업데이트(데이터 변경), 프레임단위로 데이터 get, 추적 아이디 단위로 get 등의 기능 제공
15 args:
16 anno_path (str) : 어노테이션 파일(json 파일) 경로
17 save_path (str) : 저장 경로, 설정하지 않으면 anno_path에 저장됨
18 """
19 json_version = 10 #json 파일 버전
20 anno_path = None
21 image_base_path = None
22 base_path = None
23 dataset = None
24 anno_in_image = None
25 anno_ids = None
26 image_ids = None
27 image_filenames = None
28
29 image_idx = None
30 image_id = None
31 anno_idx = None
32 anno_id = None
33 anno_idx_in_image = None
34
35 def __init__(self, anno_path=None, save_path=None):
36 self.init()
37 if anno_path is not None:
38 self.load_annotation(anno_path, save_path=save_path)
39
40 def init(self):
41 """
42 초기화 함수, 멤버변수 값을 초기화 함
43 """
44
45 #파일 정보
46 self.json_versionjson_version = 10 #json 파일 버전, json 파일에 들어있는 데이터 및 파일 포맷관련
47 self.label_map_version = 20 #레이블 맵 버전, 클래스 구조 관련
48 self.anno_path = None #로드하는 데이터 경로
49 self.save_path = None #저장하는 경로
50 self.image_base_path = None #이미지 폴더
51
52 #데이터 정보
53 self.dataset = None #json 파일 내용
54 self.anno_in_image = None #dataset의 annotations 값들을 프레임 단위로 구조를 변환한 데이터
55 self.anno_ids = None #어노테이션 아이디 리스트, 박스마다 어노테이션 아이디가 부여되어 있음
56 self.image_ids = None #이미지 아이디 리스트, 해당 변수기반으로 프레임 인덱스를 알아낼 수 있음
57 self.image_filenames = None #이미지 파일 이름 리스트
58
59 #현재 프레임 및 선택한 박스 정보
60 self.image_idx = None #현재 이미지 프레임 인덱스
61 self.anno_idx = None #현재 선택된 어노테이션(박스) 인덱스
62 self.anno_idx_in_image = None #현재 프레임의 어노테이션 인덱스, 현재 프레임에 있는 어노테이션중에 몇번째 데이터인지 알수 있는 변수
63 self.image_id = None #현재 프레임의 이미지 아이디
64 self.anno_id = None #현재 선택된 어노테이션(박스)의 아이디
65
66 def load_annotation(self, anno_path, image_base=None, program_label_map_version=None, save_path=None):
67 """
68 어노테이션 파일 로드
69 데이터를 로드하고 프레임 단위로 데이터 구조를 변경해둠
70 args:
71 anno_path (str) : json 파일의 경로
72 image_base (str) : 이미지 베이스 경로 설정 가능, 설정하지 않으면 기본 디폴트 값을 사용함
73 program_label_map_version (str) : 라벨링 프로그램의 레이블맵 버전, 설정하지 않는다면 json 파일에 값을 사용
74 save_path (str) : 저장 경로 설정, 설정하지 않는다면 anno_path로 설정됨
75 """
76 self.init()
77 self.anno_path = anno_path
78
81 self.base_path,
82 self.image_base_path,
83 self.dataset) = utils.load_annotation(anno_path)
84
85 if image_base != None:
86 image_folder = utils.make_image_folder(self.json_versionjson_version, anno_path)
87 self.image_base_path = os.path.join(image_base, image_folder)
88
89 if program_label_map_version is not None:
90 if self.label_map_version != program_label_map_version:
91 self.label_map_version = program_label_map_version
92 self.dataset['info']['label_map_version'] = program_label_map_version/10
93
94 (self.anno_in_image,
95 self.anno_ids,
96 self.image_ids,
97 self.image_filenames) = self.cvt_data_format(self.dataset)
98
99 if save_path is None:
100 self.save_path = self.anno_path
101 else:
102 self.save_path = save_path
103
104 def cvt_data_format(self, dataset):
105 """
106 프레임 단위로 데이터 구조를 변경하는 기능
107 args:
108 dataset (dict) : 어노테이션 데이터
109 info : json 파일의 기본 정보가 들어있음
110 images : 이미지 아이디, 이름 및 기타 정보
111 annotations : 라벨링된 데이터, 박스마다 데이터가 들어있음
112 대표 정보 : 어노테이션 아이디, 박스정보(x, y, w, h), 키포인트, 액션 라벨 등
113 return:
114 anno_in_image (dict): 프레임 단위로 어노테이션(박스) 정보를 저장한 변수
115 key (int): 이미지 아이디
116 value (list[dict]): 해당 프레임의 어노테이션(박스) 정보 리스트
117 anno_ids (list): 어노테이션 아이디 리스트
118 image_ids (list): 이미지 아이디 리스트
119 image_filenames (list): 이미지 이름 리스트
120 """
121 image_ids = []
122 image_filenames = []
123 anno_in_image = {}
124
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']] = []
129
130 anno_ids = []
131 for anno in dataset['annotations']:
132 anno_in_image[anno['image_id']].append(copy.deepcopy(anno))
133 anno_ids.append(anno['id'])
134
135 return anno_in_image, anno_ids, image_ids, image_filenames
136
138 """
139 데이터 저장 기능
140 """
141 utils.save_json(self.save_path, self.dataset)
142
143 #===========cur annotation data setting========#
145 """
146 현재 프레임 정보 초기화 기능
147 맨 첫프레임, 첫번째 어노테이션(박스) 정보로 셋팅함
148 첫프레임에 어노테이션 정보가 없다면 관련 변수는 None으로 셋팅됨
149 """
150 self.image_idx = None
151 self.image_id = None
152 self.anno_id = None
153 self.anno_idx = None
154 self.anno_idx_in_image = None
155 if len(self.image_ids) == 0:
156 return
157
158 self.image_idx = 0
159 self.image_id = self.image_ids[0]
160
161 if len(self.anno_in_image[self.image_id]) > 0:
162 self.anno_idx = 0
163 self.anno_idx_in_image = 0
164 self.anno_id = self.dataset['annotations'][0]['id']
165
166 def set_anno_idx_in_image(self, anno_idx_in_image):
167 """
168 현재 프레임의 어노테이션(박스) 인덱스 기준으로 관련 데이터를 셋팅함
169 args:
170 anno_idx_in_image (int) : 설정하기 위한 현재 프레임의 어노테이션(박스) 인덱스
171 """
172 if self.get_number_of_anno_in_image() > anno_idx_in_image:
173 self.anno_idx_in_image = anno_idx_in_image
174 self.anno_id = self.anno_in_image[self.image_id][anno_idx_in_image]['id']
175 self.anno_idx = self.anno_ids.index(self.anno_id)
176
177 def set_annotation_by_anno_index(self, anno_idx):
178 """
179 어노테이션(박스) 인덱스 기준으로 현재 정보를 셋팅함
180 args:
181 anno_idx (int) : 셋팅하려는 어노테이션(박스) 인덱스
182 return (bool): 이미지 변경 유무
183 """
184 pre_image_idx = self.image_idx
185 self.image_id = self.dataset['annotations'][anno_idx]['image_id']
186 self.image_idx = self.image_ids.index(self.image_id)
187
188 self.anno_idx = anno_idx
189 self.anno_id = self.anno_ids[anno_idx]
191
192 return pre_image_idx != self.image_idx
193
194 def set_annotation_by_image_index(self, image_idx, use_track_id=False):
195 """
196 이미지 인덱스를 기준으로 현재 정보를 셋팅함
197 추적아이디 사용을 설정하면 현재 선택된 추적아이디와 같은 어노테이션 정보로 셋팅함
198 args:
199 image_idx (int) : 셋팅하려는 이미지 인덱스
200 use_track_id (bool) : 추적아이디 사용 여부
201 return (bool): 이미지 변경 유무
202 """
203 pre_image_idx = self.image_idx
204 self.image_id = self.image_ids[image_idx]
205
206 track_id = None
207 if use_track_id and self.anno_idx is not None:
208 track_id = self.dataset['annotations'][self.anno_idx]['track_id']
209
210 anno_idx_in_image = 0
211 if self.image_idx > image_idx:
212 anno_idx_in_image = max(0, len(self.anno_in_image[self.image_id])-1)
213
214 if track_id is not None:
215 for idx, anno in enumerate(self.anno_in_image[self.image_id]):
216 if anno["track_id"] == track_id:
217 anno_idx_in_image = idx
218 break
219
220 self.image_idx = image_idx
221 self.anno_idx = self.get_anno_index(self.image_id, anno_idx_in_image)
222 if self.anno_idx is None:
223 self.anno_id = None
224 self.anno_idx_in_image = None
225 else:
226 self.anno_id = self.anno_ids[self.anno_idx]
227 self.anno_idx_in_image = anno_idx_in_image
228
229 return pre_image_idx != self.image_idx
230
232 """
233 다음 어노테이션(박스)로 이동함
234 return (bool): 이미지 변경 유무
235 """
236 check_change_image = True
237 if self.check_anno_pose_in_frame(-1):
238 self.set_annotation_by_image_index(self.image_idx+1, use_track_id=False)
239 else:
240 check_change_image = self.set_annotation_by_anno_index(self.anno_idx+1)
241
242 return check_change_image
243
244 def move_anno_left(self):
245 """
246 이전 어노테이션(박스)로 이동함
247 return (bool): 이미지 변경 유무
248 """
249 check_change_image = True
250 if self.check_anno_pose_in_frame(0):
251 self.set_annotation_by_image_index(self.image_idx-1, use_track_id=False)
252 else:
253 check_change_image = self.set_annotation_by_anno_index(self.anno_idx-1)
254
255 return check_change_image
256
257 def move_image_right(self, use_track_id=False):
258 """
259 다음 이미지로 이동함
260 """
261 if self.get_number_of_image() <= (self.image_idx+1):
262 return
263 self.set_annotation_by_image_index(self.image_idx+1, use_track_id=use_track_id)
264
265 def move_image_left(self, use_track_id=False):
266 """
267 이전 이미지로 이동함
268 """
269 if self.image_idx == 0:
270 return
271 self.set_annotation_by_image_index(self.image_idx-1, use_track_id=use_track_id)
272 #===============================================#
273
274
275 #=====================check=====================#
276 def check_anno_pose_in_frame(self, check_index):
277 """
278 현재 프레임에서 현재 선택되어 있는 어노테이션(박스)이 처음인지 마지막인지 확인하는 기능
279 args:
280 check_index (int) : 첫프레임 체크인지 마지막 프레임 체크인지 설정하는 파라미터
281 0 : 첫프레임인지 확인
282 -1 : 마지막 프레임인지 확인
283 return (bool): 확인 정보
284 """
285 check = True
286 if len(self.anno_in_image[self.image_id]) > 0:
287 check = self.anno_id == self.anno_in_image[self.image_id][check_index]["id"]
288
289 return check
290
292 """
293 현재 프레임이 수정된 상태인 확인하는 기능
294 return (bool): 수정 유무
295 """
296 ismod_image = True
297 for anno in self.anno_in_image[self.image_id]:
298 if anno["ismodify"] == 0:
299 ismod_image = False
300 break
301 return ismod_image
302
303 def check_same_track_id(self, track_id):
304 """
305 현재 프레임에 동일한 track_id 존재 유무 확인 기능(현재 선택된 객체는 제외하고 체크함)
306 return (bool): 추적 아이디 존재 유무
307 """
308 if self.anno_id is None:
309 return False
310
311 for idx, anno in enumerate(self.anno_in_image[self.image_id]):
312 if idx == self.anno_idx_in_image:
313 continue
314 if anno['track_id'] == track_id:
315 return True
316 return False
317
318 #===============================================#
319
320
321 #===============get annotation data=============#
323 """
324 어노테이션(박스) 수량을 출력하는 기능
325 return (int) : 어노테이션(박스) 수량
326 """
327 return len(self.anno_ids)
328
330 """
331 이미지 수량을 출력하는 기능
332 return (int) : 이미지 수량
333 """
334 return len(self.image_ids)
335
337 """
338 현재 프레임의 어노테이션(박스) 수량을 출력하는 기능
339 return (int) : 현재 프레임의 어노테이션(박스) 수량
340 """
341 if self.image_id is None:
342 return 0
343 return len(self.anno_in_image[self.image_id])
344
346 """
347 현재 프레임의 모든 어노테이션(박스)정보를 출력하는 기능
348 return:
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)
353 """
354 bbox_list = []
355 action_id_list = []
356 track_id_list = []
357 keypoints_list = []
358 if self.image_id is not None:
359 for anno in self.anno_in_image[self.image_id]:
360 np_key = np.array(anno["keypoints"])
361
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
367
368 def get_anno_data(self):
369 """
370 현재 선택된 어노테이션(박스) 정보를 출력하는 기능
371 return (dict) : 어노테이션 정보(박스, 키포인트, 행동라벨 등)
372 """
373 if self.anno_idx is None:
374 return None
375 return copy.deepcopy(self.dataset['annotations'][self.anno_idx])
376
377 def get_anno_data_in_image(self, image_idx=None, key = None, value = None, filter=False):
378 """
379 입력한 이미지 인덱스의 데이터에서 설정한 데이터에 부합하는 어노테이션 정보를 출력하는 기능
380 args:
381 image_idx (int) : 검색하려는 이미지 인덱스, 설정하지 않는다면 현재 프레임이됨
382 key (str) : 확인하려는 데이터의 키, 설정하지 않으면 필저링 조건만 체크함
383 value : 확인하려는 데이터의 값
384 filter (str) : 필터링 유무, 가려짐, 잘림 정도로 필터, Fasle로 설정하면 검색하려는 프레임의 모든 어노테이션 데이터를 반환함
385 return (list[dict] or dict):
386 필터링 조건을 통과한 어노테이션 리스트
387 또는 조건에 부합하는 어노테이션
388 조건에 부합하는 데이터가 없을경우 None을 반환함
389 """
390 if image_idx is None:
391 image_id = self.image_id
392 else:
393 image_id = self.image_ids[image_idx]
394
395 if key is None:
396 if filter:
397 ret_anno = []
398 for anno in self.anno_in_image[image_id]:
399 if anno['occlusion'] > 2 or anno['truncation'] > 2:
400 continue
401 ret_anno.append(copy.deepcopy(anno))
402 return ret_anno
403 else:
404 return copy.deepcopy(self.anno_in_image[image_id])
405
406 for anno in self.anno_in_image[image_id]:
407 if anno[key] == value:
408 return copy.deepcopy(anno)
409 return None
410
411 def get_prev_anno_data(self, key, value):
412 """
413 설정되어 있는 프레임보다 이전 프레임에서 데이터를 검색하는 기능
414 가장 가까운 프레임의 데이터를 반환함
415 args:
416 key (str): 확인하려는 데이터의 키
417 value : 확인하려는 데이터의 값
418 return (dict)):
419 조건에 부합하는 데이터
420 조건에 부합하는 데이터가 없을경우 None을 반환함
421 """
422 if value is None:
423 return None
424
425 for i in range(self.image_idx-1, -1, -1):
426 for ann in self.anno_in_image[self.image_ids[i]]:
427 if ann[key] == value:
428 return copy.deepcopy(ann)
429 return None
430
431 def get_track_info(self):
432 """
433 모든 추적 아이디에 대해서 추적 아이디가 처음 등장하는 프레임과 등장하는 프레임 수를 반환하는 기능
434 return (dict): 추적 아이디의 정보
435 key (int): 추적 아이디
436 value (list): 첫번째 인자는 추적아이디가 등장하는 첫 프레임 인덱스, 두번째 인자는 추적아이디가 등장하는 프레임 수
437 """
438 track_info = {}
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
442 else:
443 track_info[anno['track_id']] = [self.image_ids.index(anno['image_id']), 1]
444 return track_info
445
446 def get_track_anno_data(self, filter=False, start_frame=0, end_frame=None):
447 """
448 설정한 프레임 구간에서 모든 어노테이션의 추적 아이디 정보를 반환하는 기능
449 args:
450 filter (bool) : 필터링 유무, 가려짐, 잘림 정도로 필터
451 start_frame (int) : 검색하려는 시작 프레임 인덱스
452 end_frame (int) : 검색하려는 끝 프레임 인덱스(해당 인덱스를 포함하지 않음), 설정하지 않으면 맨 마지막 프레임까지 범위로 설정됨
453 return (dict) : 추적 아이디를 기준으로 변환된 어노테이션 정보
454 key (int): 추적 아이디
455 value (list[dict]): 추적 아이디의 어노테이션 리스트
456 """
457 track_data = {}
458
459 if end_frame == None:
460 end_frame = len(self.image_ids)
461
462 for anno in self.dataset['annotations']:
463 if filter and (anno['occlusion'] > 2 or anno['truncation'] > 2):
464 continue
465
466 img_idx = self.image_ids.index(anno['image_id'])
467 if img_idx < start_frame or img_idx >= end_frame:
468 continue
469
470 if anno['track_id'] in track_data:
471 track_data[anno['track_id']].append(anno)
472 else:
473 track_data[anno['track_id']] = [anno]
474
475 return track_data
476 #===============================================#
477
478
479 #=============annotation data change============#
480 def set_annotation_data(self, anno):
481 """
482 현재 선택된 어노테이션 정보를 입력 데이터로 업데이트하는 기능
483 args:
484 anno (dict) : 업데이트 하려는 정보, anno에 포함된 키값의 데이터만 업데이트함
485 """
486 if self.anno_idx is not None:
487 anno['ismodify'] = 1
488 self.dataset['annotations'][self.anno_idx].update(anno)
489 self.anno_in_image[self.image_id][self.anno_idx_in_image].update(anno)
490
492 """
493 더미 어노테이션을 추가하는 기능
494 """
495 tmp_anno_ids = [0]
496 tmp_track_ids = [0]
497 for ann in self.anno_in_image[self.image_id]:
498 tmp_anno_ids.append(ann['id'])
499 tmp_track_ids.append(ann['track_id'])
500
501 new_anno_id = int(self.image_id*100 + max(tmp_anno_ids)%100+1)
502 new_anno_idx = 0
503 for i in range(self.image_idx+1):
504 new_anno_idx = new_anno_idx + len(self.anno_in_image[self.image_ids[i]])
505
506 anno = utils.make_dummy_annotation(new_anno_id, self.image_id, max(tmp_track_ids)+1)
507 anno['ismodify'] = 1
508 self.anno_in_image[self.image_id].append(copy.deepcopy(anno))
509 self.anno_ids.insert(new_anno_idx, new_anno_id)
510 self.dataset['annotations'].insert(new_anno_idx, copy.deepcopy(anno))
511
512 self.anno_id = new_anno_id
513 self.anno_idx = new_anno_idx
514 self.anno_idx_in_image = len(self.anno_in_image[self.image_id])-1
515
517 """
518 입력한 추적 아이디의 어노테이션을 추가하는 기능
519 이전 프레임에서 해당 추적 아이디 정보를 복사해서 추가함, 이전 프레임에 해당 추적 아이디가 없다면 더미 데이터를 추가함
520 """
521 tmp_anno_ids = [0]
522 check_track_id = False
523 for ann in self.anno_in_image[self.image_id]:
524 tmp_anno_ids.append(ann['id'])
525 if ann['track_id'] == track_id:
526 check_track_id = True
527
528 if check_track_id:
529 return
530
531 new_anno_id = int(self.image_id*100 + max(tmp_anno_ids)%100+1)
532 new_anno_idx = 0
533 for i in range(self.image_idx+1):
534 new_anno_idx = new_anno_idx + len(self.anno_in_image[self.image_ids[i]])
535
536 anno = self.get_prev_anno_data('track_id', track_id)
537
538 if anno is None:
539 anno = utils.make_dummy_annotation(new_anno_id, self.image_id, track_id)
540 else:
541 anno['id'] = new_anno_id
542 anno['image_id'] = self.image_id
543
544 anno['ismodify'] = 1
545 self.anno_in_image[self.image_id].append(copy.deepcopy(anno))
546 self.anno_ids.insert(new_anno_idx, new_anno_id)
547 self.dataset['annotations'].insert(new_anno_idx, copy.deepcopy(anno))
548
549 self.anno_id = new_anno_id
550 self.anno_idx = new_anno_idx
551 self.anno_idx_in_image = len(self.anno_in_image[self.image_id])-1
552
554 """
555 현재 선택된 어노테이션을 삭제하는 기능
556 """
557 del self.dataset['annotations'][self.anno_idx]
558 del self.anno_in_image[self.image_id][self.anno_idx_in_image]
559 del self.anno_ids[self.anno_idx]
560
561 if self.get_number_of_anno_in_image() > 0:
562 self.anno_idx_in_image = 0
563 self.anno_id = self.anno_in_image[self.image_id][self.anno_idx_in_image]['id']
564 self.anno_idx = self.anno_ids.index(self.anno_id)
565 else:
566 self.anno_id = None
567 self.anno_idx = None
568 self.anno_idx_in_image = None
569
570 def update_annotation_data(self, key, data):
571 """
572 현재 선택된 어노테이션션 데이터를 업데이트하는 기능
573 args:
574 key : 업데이트하려는 데이터의 키
575 data : 업데이트하려는 데이터
576 """
577 anno = {key:data}
578 self.set_annotation_data(anno)
579
580 def batch_update_annotation_data(self, key, value, new_anno, frame_range=None):
581 """
582 조건에 맞는 어노테이션을 모두 업데이트하는 기능
583 프레임 범위를 설정할 수 있음
584 args:
585 key : 조건의 키
586 value : 조건
587 new_anno : 업데이트하려는 어노테이션 데이터
588 frame_range : 업데이트하려는 프레임 범위, 범위를 설정하지 않는다면 전체 범위로 설정됨
589 """
590 start = 0
591 end = self.get_number_of_image()
592
593 new_anno['ismodify'] = 1
594 if frame_range is not None:
595 start = frame_range[0]
596 end = frame_range[1]+1
597
598 for image_idx in range(start, end):
599 image_id = self.image_ids[image_idx]
600 for idx_in_image, anno in enumerate(self.anno_in_image[image_id]):
601 if anno[key] == value:
602 anno_id = anno['id']
603 anno_idx = self.anno_ids.index(anno_id)
604 self.dataset['annotations'][anno_idx].update(new_anno)
605 self.anno_in_image[image_id][idx_in_image].update(new_anno)
606
607 def update_annotation_data_by_anno_id(self, anno_id, key, data, anno=None):
608 """
609 입력한 어노테이션 아이디에 해당하는 정보를 업데이트하는 기능
610 args:
611 anno_id (int): 업데이트하려는 어노테이션 아이디
612 key : 데이터의 키
613 data : 업데이트하려는 데이터
614 anno (dict)) : 업데이트하려는 데이터, 여러 데이터를 업데이트 하고싶을 때 사용
615 anno를 설정하지 않을 경우 아이디에 해당하는 데이터의 key의 정보를 data로 업데이트함
616 """
617 if anno is None:
618 new_anno = {key:data}
619 else:
620 new_anno = anno
621
622 anno_idx = self.anno_ids.index(anno_id)
623 image_id = self.dataset['annotations'][anno_idx]['image_id']
624 anno_idx_in_image = self.get_anno_index_in_image(anno_id, image_id)
625
626 self.dataset['annotations'][anno_idx].update(new_anno)
627 self.anno_in_image[image_id][anno_idx_in_image].update(new_anno)
628
629 #===============================================#
630
631
632 #==================get anno index===============#
633 def get_anno_index_in_image(self, anno_id, image_id):
634 """
635 설정한 프레임에서 특정 어노테이션 아이디의 인덱스를 반환하는 기능
636 args:
637 anno_id (int) : 검색하려는 어노테이션 아이디
638 image_id (int) : 검색하려는 이미지 아이디
639 return (int) : 어노테이션 인덱스
640 """
641 ret_idx = None
642 for idx, anno in enumerate(self.anno_in_image[image_id]):
643 if anno['id'] == anno_id:
644 ret_idx = idx
645 return ret_idx
646
647 def get_anno_index(self, image_id, anno_idx_at_image):
648 """
649 설정한 프레임에 존재하는 어노테이션들 중 특정 인덱스(이미지 기준 변환 데이터)에 해당하는 어노테이션의 인덱스(원본 어노테이션 기준)를 반환하는 기능
650 args:
651 image_id (int): 검색하려는 이미지 아이디
652 anno_idx_at_image (int): 해당 프레임에서의 이미지 인덱스
653 return (int) : 어노테이션 인덱스
654 """
655 if len(self.anno_in_image[image_id]) <= anno_idx_at_image:
656 return None
657
658 anno_id = self.anno_in_image[image_id][anno_idx_at_image]['id']
659 return self.anno_ids.index(anno_id)
660 #===============================================#
661
662
663 #===================read image==================#
665 """
666 어노테이션 정보에 대응하는 이미지가 저장되어있는 폴더를 반환하는 기능
667 return (str): 이미지 폴더
668 """
669 return self.image_base_path
670
671 def get_image_path(self, image_idx=None):
672 """
673 특정 이미지 경로를 반환하는 기능
674 args:
675 image_idx (int): 경로를 원하는 이미지의 인덱스, 설정하지 않는다면 현재 설정된 이미지의 경로를 반환함
676 return (str): 이미지 경로
677 """
678 if image_idx is None:
679 if self.image_idx is None:
680 print('image_idx is None')
681 return None
682
683 image_idx = self.image_idx
684
685 image_name = self.image_filenames[image_idx]
686
687 return utils.join( [self.image_base_path, image_name] )
688
689 def get_image_name(self, image_id=None):
690 """
691 특정 이미지의 이름을 반환하는 기능
692 args:
693 image_id (int) : 이름을 원하는 이미지의 아이디, 설정하지 않는다면 현재 설정된 이미지의 이름을 반환함
694 return (str): 이미지 이름
695 """
696 if image_id is None:
697 image_id = self.image_id
698
699 if image_id is None:
700 return None
701
702 image_idx = self.image_ids.index(image_id)
703 return self.image_filenames[image_idx]
704
705 def read_image(self):
706 """
707 현재 설정된 이미지를 로드하는 기능
708 return (np.array): RGB 이미지
709 """
710 if self.image_idx is None:
711 return None
712
713 image_path = self.get_image_path(image_idx=self.image_idx)
714
715 if not os.path.exists(image_path):
716 print(image_path)
717 return None
718
719 image = cv2.imread(image_path)
720 return cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
721 #===============================================#
722
723
724 #===================read image==================#
725 def get_save_path(self):
726 """
727 어노테이션 파일 저장 경로를 반환하는 기능
728 """
729 return self.save_path
730
731 #===============================================#
732
733
734 #===============get scenario num================#
736 if self.image_idx is None:
737 return None
738
739 if self.json_versionjson_version == 10:
740 filename_re = re.compile('S\d{3}')
741 scenario_num = filename_re.search(self.image_filenames[self.image_idx]).group()
742 elif self.json_versionjson_version == 11:
743 #수정필요
744 scenario_num = "S001"
745
746 return scenario_num
747 #===============================================#
__init__(self, anno_path=None, save_path=None)
update_annotation_data_by_anno_id(self, anno_id, key, data, anno=None)
set_annotation_by_image_index(self, image_idx, use_track_id=False)
load_annotation(self, anno_path, image_base=None, program_label_map_version=None, save_path=None)
batch_update_annotation_data(self, key, value, new_anno, frame_range=None)
get_anno_index(self, image_id, anno_idx_at_image)
get_track_anno_data(self, filter=False, start_frame=0, end_frame=None)
get_anno_data_in_image(self, image_idx=None, key=None, value=None, filter=False)