5.20. 회귀와 유사도¶
Image 클래스의 두 가지 추가 측정은 이미지를 픽셀 값의 분포가 아닌 다른 무언가로 요약합니다. 임계값 처리된 픽셀의 선형 회귀는 애플리케이션에 대응할 수 있는 선을 제공합니다. 이는 라인 추종 로봇의 고전적인 입력입니다. 유사도 측정은 두 이미지가 얼마나 비슷한지를 기술하는 단일 숫자를 애플리케이션에 제공합니다. 이는 골든 이미지 회귀 테스트나 대규모 변화 검출기의 자연스러운 입력입니다.
5.20.1. 선형 회귀¶
이미지의 전경 픽셀이 프레임을 가로지르는 선을 이루는 경우 – 로봇이 따라가는 트랙의 테이프, 지평선, 도로나 복도의 가장자리 – 애플리케이션은 보통 개별 전경 픽셀 하나하나를 원하지 않습니다. 애플리케이션은 그 모두를 관통하는 최적합 선을 원하며, 선이 어떻게 기울어져 있고 프레임의 어디를 가로지르는지를 결정할 수 있도록 매개변수화되기를 원합니다.
get_regression() 가 그 적합을 수행합니다. 이 메서드는 binary() 와 find_blobs() 가 사용하는 것과 동일한 임계값 튜플 형태를 받아, 임계값에 일치하는 모든 픽셀을 식별하고, 그 픽셀들을 관통하는 최적합 선을 기술하는 단일 line 결과를 반환합니다:
line = img.get_regression([(0, 60)])
if line:
img.draw_line((line.x1(), line.y1(),
line.x2(), line.y2()),
color=(255, 0, 0))
이 적합은 Theil-Sen 선형 회귀로, 더 익숙한 최소 제곱 적합보다 이상치를 더 잘 견디는 강건한 방법입니다. 참 선에서 멀리 떨어진 소수의 픽셀이 최소 제곱에서처럼 결과를 왜곡하지 않는데, 이는 실제 임계값 출력의 노이즈가 많은 전경 현실에 부합합니다.
line 결과는 이미지 직사각형으로 클리핑된 끝점(x1, y1, x2, y2), 선의 길이와 크기(length, magnitude), 그리고 극좌표 형태의 선의 기하학적 기술(theta, rho) – 수평으로부터의 선의 각도와 원점으로부터의 수직 거리 – 을 담고 있습니다. 극좌표 형태는 보통 제어 루프가 원하는 것입니다. theta 는 로봇에게 선이 어느 쪽으로 기울어져 있는지 알려주고, rho 는 선이 이미지의 어디를 가로지르는지 알려주며, 이 둘에 대한 피드백 루프가 로봇을 선 중앙에 유지시킵니다.
몇 가지 키워드 인수가 강건성과 비용을 조정합니다. x_stride 와 y_stride 는 적합 중에 픽셀을 건너뜁니다. 더 큰 스트라이드는 더 적은 픽셀을 적합하는 대가로 회귀를 더 저렴하게 만듭니다. area_threshold 와 pixels_threshold 는 충분한 일치 픽셀이 뒷받침하지 않는 선을 거부합니다. target_size 는 적합하기 전에 입력을 더 작은 크기로 재스케일합니다. 회귀는 이미지의 80×60 대체본에서 선 방향 정확도의 큰 손실 없이 더 빠르게 실행됩니다.
허용 가능한 선을 적합할 수 없는 경우 – 임계값에 일치하는 픽셀이 없거나, 선처럼 보이지 않는 패턴에 일치한 경우 – 메서드는 None 을 반환합니다. 실제 라인 추종 코드는 선의 속성에 접근하기 전에 모든 get_regression() 호출을 None 검사로 보호합니다.
5.20.2. 이미지 유사도¶
다른 종류의 측정 방식입니다. “이미지에 무엇이 들어 있는가?”를 묻는 대신 “이 두 이미지는 얼마나 비슷한가?”를 묻습니다. 이때 사용할 연산은 get_similarity()로, 소스 이미지와 참조 이미지 사이의 구조적 유사도 지수(Structural Similarity Index, SSIM)를 계산합니다.
s = img.get_similarity(reference)
print(s.mean, s.stdev)
SSIM은 이미지 처리 전반에서 사용되는 표준 이미지 유사도 지표인데, 유사도에 대한 사람의 직관이 동작하는 방식대로 동작하기 때문입니다. 작은 이동이나 작은 밝기 변화는 점수를 약간 낮추는 반면, 큰 구조적 변화(객체 누락, 다른 장면)는 점수를 극적으로 낮춥니다. 점수는 -1 에서 +1 까지 범위를 가집니다. +1 은 두 이미지가 동일함을 의미하고, 0 은 둘이 무관함을 의미하며, -1 은 둘이 구조적으로 정반대임을 의미합니다. 반환된 similarity 객체는 이미지 전체에 걸친 평균 SSIM과, 타일별 점수의 표준 편차, 최솟값, 최댓값을 노출합니다.
큰 숫자보다 작은 숫자가 더 나은 종류의 비교의 경우 – “아무것도 변하지 않음”에 대해 0을 보고하고 변화가 누적됨에 따라 상승해야 하는 회귀 테스트 – dssim=True 플래그는 구조적 비유사도를 반환합니다. 즉 평균 SSIM을 1 에서 뺀 값으로, 반환값은 동일한 이미지에 대해 0.0 이고 둘이 달라짐에 따라 상승합니다.
5.20.3. SSIM의 활용 사례¶
두 가지 흔한 애플리케이션:
골든 이미지 회귀 테스트. 테스트 프레임워크가 양호함이 확인된 조건에서 기준 프레임을 캡처하여 골든 이미지로 저장합니다. 이후의 테스트 실행은 동일한 조건에서 캡처하여 SSIM으로 골든 이미지와 비교합니다. 어떤 임계값(허용 오차에 따라 0.95 또는 0.98) 이상의 점수는 통과이고, 그 아래는 실패입니다. 테스트 프레임워크는 무엇이 변했는지 알 필요가 없습니다. SSIM 점수가 곧 신호입니다.
대규모 변화 검출. 더 거친 버전의 프레임 차분을 원하는 애플리케이션 – 작은 밝기 변화는 무시하지만 큰 구조적 변화에는 반응하는 – 은 픽셀별 difference() 에 이은 임계값 처리 대신 기준 프레임에 대한 SSIM을 사용할 수 있습니다. SSIM은 픽셀별 차분보다 조명 변동에 덜 민감하며, 이는 목표가 “개별 픽셀이 변함”이 아니라 “장면이 실질적으로 달라 보임”을 검출하는 것일 때 더 나은 선택으로 만들어 줍니다.
두 애플리케이션 모두 동일한 호출 – img.get_similarity(reference) – 을 사용하고 반환된 점수의 임계값에서 트리거합니다. 차이는 단지 임계값이 높은지(거의 동일한 일치를 찾는 회귀 테스트) 낮은지(큰 구조적 변화를 찾는 변화 검출)일 뿐입니다.
5.20.4. 변환 후 비교 형태¶
유용한 미묘함이 있습니다. get_similarity() 는 draw_image() 와 동일한 x, y, x_scale, y_scale, roi, rgb_channel, alpha, color_palette, alpha_palette, hint, transform 매개변수를 받아들입니다. 기준 이미지는 SSIM 비교가 실행되기 전에 이러한 매개변수에 의해 위치 지정, 스케일링, 변환됩니다.
이는 애플리케이션이 미리 변환된 기준 이미지를 준비하지 않고도 “알려진 변위/회전/스케일 이후 이 장면이 기준 프레임과 얼마나 유사한가”를 물을 수 있음을 의미합니다. 이는 매개변수 공간을 탐색하고 기준 이미지의 어떤 변환이 현재 프레임과 가장 잘 일치하는지 보고하는 추적기를 만드는 저렴한 방법입니다.