증상
Yolov5 + deepSORT object tracking 알고리즘 실행 시 다음과 같은 에러를 만났다. 어떤 matrix에 숫자로 타당하지 않은 원소가 있다는 에러이다.
return _lsap_module.calculate_assignment(cost_matrix)
ValueError: matrix contains invalid numeric entries
이 에러는 linear_assignment.py 파일안에 있는 scipy.optimize.linear_sum_assignment()에 의해 계산된 cost_matrix에 nan (Not a Number)이 포함되어 있어 발생하는 에러이다.
아래와 같이 프로그램을 다시 돌려 cost_matrix가 어떤 값을 가지는지 확인해보자.
역시 NaN이 들어있는 것을 알 수 있다. 이것은 주로 어떤 수를 0으로 나누었을 때 발생하는 data type이며, 예외 처리를 못하고 에러가 나게 된 것으로 보인다.
github 커뮤니티 논의 - Scipy 버그
이 에러에 대한 논의는 다음의 링크에서도 찾아볼 수 있다.
linear_sum_assignment with infinite weights #6900
위 링크속 논의에 의하면 linear_sum_assignment()는 scipy의 method인데, 이 코드에 버그가 있다는 것이다.
다음의 간단한 예를 통해 똑같은 에러를 일으켜 볼 수 있다.
inf의 원소를 가지는 costSet1과 NaN이 들어 있는 costSet2를 만든다.
import numpy as np
import scipy
costSet1 = np.array(
[[np.inf, 1, np.inf],
[np.inf, 3, np.inf],
[2, np.inf, 3]])
costSet2 = np.array(
[[np.nan, 1, np.nan],
[np.nan, 3, np.nan],
[2, np.nan, 3]])
print(f'costSet1: \n {costSet1}')
print("")
print(f'costSet2: \n {costSet2}')
- costSet1: cost matrix is infeasible
scipy.optimize.linear_sum_assignment(cost_matrix=costSet1)
- costSet2: matrix contains invalid numeric entries
scipy.optimize.linear_sum_assignment(cost_matrix=costSet2)
costSet2에서 볼 수 있듯이 NaN이 원래 문제와 같은 에러를 낸다.
해결 방법
이것이 진짜 버그인지 알 수 없지만 예외처리가 안되어 생긴 문제인 것은 분명하기 때문에, linear_assignment.py내의 함수를 수정하여 에러가 나지 않도록 처리를 하는 것이 좋겠다.
즉, NaN을 임의의 아주 큰 값 (INFTY_COST=1e5) 으로 대체하는 것이다.
다음의 코드는 linear_assignment.py의 한 부분이며 linear_sum_assignment_with_inf라는 함수를 만들어 cost_matrix에서 발생하는 예외를 처리해 주었다.
INFTY_COST = 1e+5
def linear_sum_assignment_with_inf(cost_matrix):
cost_matrix = np.asarray(cost_matrix)
nan = np.isnan(cost_matrix).any()
if nan:
cost_matrix[np.isnan(cost_matrix)]=INFTY_COST
return linear_assignment(cost_matrix)
def min_cost_matching(
distance_metric, max_distance, tracks, detections, track_indices=None,
detection_indices=None):
"""Solve linear assignment problem.
.
.
.
cost_matrix = distance_metric(
tracks, detections, track_indices, detection_indices)
cost_matrix[cost_matrix > max_distance] = max_distance + 1e-5
row_indices, col_indices = linear_sum_assignment_with_inf(cost_matrix)
.
.
.
이렇게 처리하면 일단 에러가 나서 프로그램이 중단하는 것은 막을 수 있다.
'Programming > Computer Vision' 카테고리의 다른 글
FFMPEG로 다양한 input-output 소스 스트리밍하기 (option 설명 포함) (0) | 2021.10.23 |
---|---|
[OpenCV] 이미지 이진화(Image binarization)를 이용한 image segmentation (Python) (0) | 2021.06.28 |
[OpenCV] K-Means를 이용한 Image Segmentation(이미지 분할) (0) | 2020.11.05 |
[OpenCV] Image Edge Enhancement: 라플라스 연산자 (Laplace Operator)-파이썬 코드 포함 (0) | 2020.11.04 |
[OpenCV] 이미지 경계선 강화: DoG - 파이썬 코드 포함 (0) | 2020.11.04 |
댓글