Skip to content

Inference

segmentation.InferenceHandler

학습한 Segmentation 모델을 사용하여 검사를 하기 위한 InferenceHandler class 입니다.

Usage

demo/inference.py 참고

build(config) classmethod

InferenceHandler class의 instance를 생성합니다.

Parameters:

Name Type Description Default
config dict

InferenceHandler를 build 하기 위한 config가 담겨 있는 dictionary 입니다.

{
    "checkpoint_path": str,  # 체크포인트 경로
    "inference_options": dict  | None, # 인퍼런스 옵션 config (default None). 구조는 `get_default_inference_option`의 Keys 참고.
    "password": str | None,  # 체크포인트 패스워드 (default None)
    "device": torch.device | str | int,  # GPU 번호 (int) or "cpu" (str) (default "cpu")
    "intersection_threshold": Optional[float], # Object label 또는 prediction의 correctness 판정 threshold
                                               # 값은 [0.0, 1.0] 사이의 실수로 1에 가까울수록 과검과 미검이 증가 (default 0.3)
}

required

Returns:

Name Type Description
InferenceHandler InferenceHandler

build가 완료된 segmentation.InferenceHandler class의 instance를 반환합니다.

get_default_inference_option(key)

Inference & postprocess 옵션의 기본 설정 값을 반환합니다.

Parameters:

Name Type Description Default
key str

옵션 key

required

Returns:

Name Type Description
Any Any

옵션 value

Keys

사용 가능한 key와 value 목록:

{
    "outputs.mask": bool,  # (default True, output 중 mask를 계산할 지 여부. True인 경우 계산)
    "outputs.scoremap": bool,  # (default True, output 중 scoremap을 계산할 지 여부. True인 경우 계산)
    "outputs.objects": bool,  # (default True, output 중 objects를 계산할 지 여부. True인 경우 계산)
    "outputs.time": bool,  # (default False, 인퍼런스 시 각 요소에 걸린 시간 측정 여부. True인 경우 측정)
    "params.object_boundary_threshold": list[int],  # mask를 계산할 때 적용되며, 각 클래스별로 픽셀의 스코어값이 threshold보다 작은 경우 스코어가 0으로 치환 됩니다.
                                                    # 각 값은 [0, 255] 범위의 정수. (default [100, ... , 100])
                                                    # background(0번 클래스)의 값은 변경할 수 없습니다.
    "params.calc_object_area_and_apply_threshold": bool,  # True인 경우 object마다 area(=픽셀수)를 계산하고 object_area_threshold를 적용합니다.
                                                          # outputs.objects가 True일때만 적용.
                                                          # (default True)
    "params.calc_object_score_and_apply_threshold": bool,  # True인 경우 object마다 평균 score를 계산하고 object_score_threshold를 적용합니다.
                                                           # outputs.objects가 True일때만 적용.
                                                           # (default True)
    "params.object_area_threshold": list[int],  # 각 클래스별로 예측된 object의 면적이 threshold보다 작은 경우 필터링 됩니다. 각 값은 0 이상의 정수. (default [0, ... , 0])
                                                # background(0번 클래스)의 값은 변경할 수 없습니다.
    "params.object_score_threshold": list[float],  # 각 클래스별로 예측된 object의 평균 score가 threshold 보다 작은 경우 필터링 됩니다. 각 값은 [0.0, 255.0] 범위의 실수. (default [0.0, ... , 0.0])
                                                   # background(0번 클래스)의 값은 변경할 수 없습니다.
    "params.batch_size": int,  # `infer_and_postprocess`에 한 번에 입력할 수 있는 최대 이미지 개수 입니다.
                               # 파라미터가 변경되는 경우 해당 값으로 warmup을 수행합니다.
                               # (default 1)
    "params.inspection_size_wh": list[int] | tuple[int, int] | None,  # inference를 할 때, 내부 연산이 진행되는 image size 입니다.
                                                       # input image가 inspection_size_wh 넘는 경우 aspect ratio를 유지하며 resize 됩니다.
                                                       # input image가 inspection_size_wh 보다 작은 경우 부족한 부분을 zero padding으로 채웁니다.
                                                       # 파라미터가 변경되는 경우 해당 값으로 warmup을 수행합니다.
                                                       # (default None)
    "params.oversized_image_handling": str,  # inference시 inspection_size_wh 보다 큰 이미지에 대한 핸들링 옵션 입니다.
                                             # 아래 옵션들 중 한 가지를 선택할 수 있습니다.
                                             #   "do_not_inspect" - 큰 이미지가 들어오면 에러 레이즈
                                             #   "resize_to_fit" - 큰 이미지가 들어오면 inspection_size_wh 로 리사이즈해서 검사
                                             #   "crop_into_tiles" - 큰 이미지가 들어오면 inspection_size_wh 크기의 타일로 잘라서 검사
                                             # (default "do_not_inspect")
}

사용 예시:

handler.get_default_inference_option(key="outputs.mask")
handler.set_inference_option(key="outputs.mask", value=False)

get_inference_option(key)

현재 설정된 inference & postprocess 옵션 값을 읽습니다.

Parameters:

Name Type Description Default
key str

옵션 key

required

Returns:

Name Type Description
Any Any

옵션 value

Keys

get_default_inference_option과 동일합니다.

set_inference_option(key, value)

Inference & postprocess 옵션을 설정합니다.

Parameters:

Name Type Description Default
key str

설정하고자 하는 옵션 key 입니다.

required
value Any

설정하고자 하는 옵션 value 입니다.

required

Returns:

Name Type Description
None None

None

Keys

get_default_inference_option에서 warmup이 필요한 [params.inspection_size_wh, params.batch_size]를 제외하면 동일합니다.

infer_and_postprocess(images)

image의 list를 입력으로 받아 모델 인퍼런스와 후처리를 수행합니다. (for Runtime) 실시간 검사를 위해 연산 과정이 최적화되어 있으며, 중간 결과를 제거하고 postprocess 최종 결과만을 반환합니다.

Parameters:

Name Type Description Default
images list[ndarray] | list[str] | list[list[ndarray]] | list[list[str]]
- list[np.ndarray]: numpy image가 들어있는 list 입니다. 각 image는 다음 제약 조건을 갖습니다.
                    data type: uint8, uint16
                    channel: H x W / H x W x 1 - Gray
                             H x W x 3 - RGB
                             H x W x 4 - RGBA
- list[str]: image 경로가 들어있는 list 입니다.
- list[list[np.ndarray]]: multipage인 경우 사용.
- list[list[str]]: multipage인 경우 사용.
required

Returns:

Type Description
list[dict]

list[dict]: image의 postprocess 결과들이 들어있는 list 입니다.

[
    {  # 아래 키들 중 inference_options에 설정된 출력 값들만 포함.
        "mask": ndarray(uint8, shape=(H, W)),  # 각 픽셀이 예측된 클래스를 값으로 갖는 array 입니다.
        "scoremap": ndarray(uint8, shape=(C, H, W)),  # 각 클래스별로 픽셀의 score가 저장된 array
        "objects": [  # 클래스별로 contouring을 해서 얻은 object들의 리스트. (list[dict])
            {  # segmentation object 구조
                "class_index": int,
                "contours": [  # cv2 형식의 contours. 0번째 contour가 outer, 나머지는 모두 inner.
                    ndarray(int32, shape=(52, 1, 2)),
                    ndarray(int32, shape=(44, 1, 2)),
                    ndarray(int32, shape=(11, 1, 2)),
                    ...,  # times number of contours
                ],
                "area": int,  # object의 픽셀 수. calc_object_score_and_apply_threshold True일때만 존재하는 key입니다.
                "score": float,  # 모델이 예측한 object의 점수입니다. 점수가 높을수록 해당 클래스일 확률이 높다는 뜻입니다. calc_object_score_and_apply_threshold가 True일때만 존재하는 key입니다.
                "bounding_box": list[int],  # [left, top, width, height]
                "bounding_rot_box": list,  # [[center_x, center_y], [width, height], angle, [[x1, y1], [x2, y2], [x3, y3], [x4, y4]]], all items are float
                "fitted_ellipse": list,  # [[center_x, center_y], [width, height], angle], all items are float
            },
            ...,  # times number of objects
        ],
        "is_oversized": bool,  # 입력한 이미지가 oversized인지 여부 (True면 oversized)
        "time": {  # inference에 소요된 시간을 담고있는 dictionary 입니다. (단위: ms)
            "imread_time": float,  # 실제 image를 load하여 연구팀이 사용하는 image format (PIL)으로 변경하기까지 걸리는 시간 (각 이미지 별로 걸리는 시간)
            "inference_time": float,  # resize, roi, tensorize, network forward 등을 포함하는 시간 (각 이미지 별로 걸리는 시간)
            "post_processing_time": float,  # postprocess에 걸린 시간 (각 이미지 별로 걸리는 시간)
        },
    },
    ...,  # times number of images
]

analyze(images, labeled)

images들에 대한 모델 인퍼런스 후 analysis 결과 계산

Parameters:

Name Type Description Default
images dict[str, dict]

analysis에 사용할 데이터 리스트. Trainer 빌드에 사용하는 이미지 리스트와 동일한 구조.

{
    "{image_id}": {
        "path": str | list[str],  # 이미지 경로 (multipage인 경우 경로 리스트)
        "width": int,  # image width
        "height": int,  # image height
        "labels": [  # (labeled = False)인 경우 필요하지 않습니다. 아래 2가지 타입을 지원합니다.
            {  # "bounding_box" + "bitmap" 타입
                "class_index": int,  # class index (0: background)
                "bounding_box": list[int],  # [left, top, width, height]
                "bitmap": str,  # base64 encoded png image string (shape: (h_label, w_label))
            },
            {  # "contours" 타입
                "class_index": int,  # class index (0: background)
                "contours": [  # cv2 형식의 contours. 0번째 contour가 outer, 나머지는 모두 inner.
                    ndarray(int32, shape=(num_points_0, 1, 2)),
                    ndarray(int32, shape=(num_points_1, 1, 2)),
                    ndarray(int32, shape=(num_points_2, 1, 2)),
                    ...  # contour 개수 만큼 반복
                ],
            },
            ...,  # times number of labels in the image
        ],
        "save_dir": str,  # 해당 이미지의 analysis 결과 저장 directory
    },
    ...,  # times number of images
}

required
labeled bool

label 존재 여부. label 존재 여부에 따라 analysis 결과 dict 구성 요소가 달라집니다.

required

Returns:

Name Type Description
dict dict

images들에 대한 analysis 결과

{
    "{image_id}": {
        "labels": [  # "labels" 결과는 labeled=True인 경우에만 존재
            {
                "correct": bool,  # True면 TP, False면 FN
                "recall": float,  # 라벨 영역 중 예측된 영역과 일치하는 영역의 비율. 'Label IoA(Intersection over Area)'와 동일합니다.
            },
            ... # 입력으로 넣어준 labels와 동일한 개수
        ],
        "predictions": {  # 아래 키들 중 inference_options에 설정된 출력 값들만 포함.
            "mask": ndarray(uint8, shape=(H, W)),  # 각 픽셀이 예측된 클래스를 값으로 갖는 array.
            "scoremap": ndarray(uint8, shape=(C, H, W)),  # 각 클래스별로 픽셀의 score가 저장된 array.
            "objects": [  # (list[dict]) 클래스별로 contouring을 해서 얻은 object들의 리스트.
                {
                    "class_index": int,
                    "contours": [  # cv2 형식의 contours. 0번째 contour가 outer, 나머지는 모두 inner.
                        ndarray(int32, shape=(52, 1, 2)),
                        ndarray(int32, shape=(44, 1, 2)),
                        ndarray(int32, shape=(11, 1, 2)),
                        ...  # contour 개수 만큼 반복
                    ],
                    "area": int,  # object의 픽셀 수. calc_object_score_and_apply_threshold True일때만 존재하는 key입니다.
                    "score": float,  # 모델이 예측한 object의 점수입니다. 점수가 높을수록 해당 클래스일 확률이 높다는 뜻입니다. calc_object_score_and_apply_threshold가 True일때만 존재하는 key입니다.
                    "bounding_box": list[int],  # [left, top, width, height]
                    "bounding_rot_box": list,  # [[center_x, center_y], [width, height], angle, [[x1, y1], [x2, y2], [x3, y3], [x4, y4]]], all items are float
                    "fitted_ellipse": list,  # [[center_x, center_y], [width, height], angle], all items are float
                    # 아래 항목들은 labeled=True인 경우에만 존재
                    "correct": bool,  # True면 TP, False면 FP.
                    "precision": float,  # 예측한 영역 중 라벨과 일치하는 영역의 비율. 'Prediction IoA(Intersection over Area)'와 동일합니다.
                },
                ... # 이미지 내의 검출된 object 개수만큼 반복
            ],
            "is_oversized": bool,  # 입력한 이미지가 oversized인지 여부 (True면 oversized)
            "time": {  # inference에 소요된 시간을 담고있는 dictionary 입니다. (단위: ms)
                "imread_time": float,  # 실제 image를 load하여 연구팀이 사용하는 image format (PIL)으로 변경하기까지 걸리는 시간 (각 이미지 별로 걸리는 시간)
                "inference_time": float,  # resize, roi, tensorize, network forward 등을 포함하는 시간 (각 이미지 별로 걸리는 시간)
                "post_processing_time": float,  # postprocess에 걸린 시간 (각 이미지 별로 걸리는 시간)
            },
            "object/underkill": int,  # 이미지 내에서 라벨 object 중 검출하지 못한 라벨의 개수 (미검)
            "object/overkill": int,  # 이미지 내에서 예측 object 중 틀린 예측의 개수 (과검)
        },
    },
    ... # 입력으로 넣어준 이미지 개수만큼 반복
},

Note1

analyze() 함수를 사용하기 위해서는 inference_options 중 output.mask=True & outputs.objects=True 여야 합니다.

Note2

모델 빌드 및 인퍼런스 없이 저장되어있는 network output을 활용하여 analyze하고 싶은 경우에는 AnalysisHandler.analyze()를 사용하세요.

warmup()

현재 설정된 inference 옵션을 바탕으로 warmup을 수행합니다.