13장. Shape 분석과 ROI 처리
모양 분류 규칙 만들기
약국에서 약을 고르는 약사를 떠올려 봅시다. "알약이 둥근가? 둥글면 흰색인가? 흰색이면 가운데 줄이 있나?" 하고 질문을 차례로 던져 범위를 좁힙니다. 모양 이름도 이렇게 붙입니다. 앞에서 잰 숫자들을 표로 모아 두고, 가장 확실하게 갈리는 질문부터 if 로 차례로 묻습니다.
그림의 다섯 단계가 이 장의 실습 3에서 쓰는 규칙의 순서입니다. 먼저 볼록 비율로 움푹한 모양(별, 초승달)을 따로 빼고, 남은 볼록한 모양을 꼭짓점 수로 나눕니다. 꼭짓점 4개는 종횡비로 막대를 가르고, 채움 비율로 바로 선 네모와 기운 네모를 가릅니다. 여기서 약사의 질문 하나가 if 하나이고, 범위를 좁혀 가는 순서가 규칙의 순서입니다.
이 장의 규칙 표
| 순서 | 묻는 것 | 조건 | 이름 |
|---|---|---|---|
| 1 | 움푹한가 | 볼록 비율 < 0.9, 꼭짓점 10개 | 별 |
| 1 | 움푹한가 | 볼록 비율 < 0.9, 그 밖 | 초승달 |
| 2 | 꼭짓점 수 | 3 | 세모 |
| 3 | 길쭉한가 | 꼭짓점 4, 긴 변 ÷ 짧은 변 ≥ 2 | 막대 |
| 4 | 꽉 찼나 | 꼭짓점 4, 채움 비율 ≥ 0.9 | 네모 |
| 4 | 꽉 찼나 | 꼭짓점 4, 그 밖 | 기운 네모 |
| 5 | 꼭짓점 수 | 8 | 팔각형 |
| 5 | 꼭짓점 수 | 9 이상 | 원 |
| 6 | 어디에도 안 맞음 | 그 밖 | 모름 |
경계값 0.9, 2 는 도형 판의 숫자를 보고 정한 연습용 값입니다. 다른 그림에서는 그 그림의 숫자를 표로 찍어 본 뒤 다시 정합니다.
규칙은 만든 그림에서는 잘 맞아도 조건이 바뀌면 틀립니다. 그림의 세 상자가 흔히 틀리는 경우입니다. 기울어지면 똑바로 선 상자로 잰 숫자가 바뀌고, 작아지면 칸의 계단 때문에 꼭짓점과 원형도가 흔들리고, epsilon 이 맞지 않으면 원이 팔각형이 됩니다.
짧은 예시
def name_shape(vertices, aspect_long, extent, solidity):
"""특징 숫자 네 개로 모양 이름을 붙인다. 위에서부터 차례로 묻고 처음 맞는 곳에서 멈춘다."""
if solidity < 0.9: # 1. 움푹한 모양
return "별" if vertices == 10 else "초승달"
if vertices == 3: # 2. 꼭짓점 셋
return "세모"
if vertices == 4:
if aspect_long >= 2: # 3. 길쭉한 네모
return "막대"
return "네모" if extent >= 0.9 else "기운 네모" # 4. 상자를 꽉 채웠나
if vertices == 8: # 5. 꼭짓점 여덟
return "팔각형"
if vertices > 8:
return "원"
return "모름" # 6. 어디에도 안 맞음
print(name_shape(4, 3.1, 0.938, 1.0)) # 결과: 막대
print(name_shape(4, 1.0, 0.596, 0.966)) # 결과: 기운 네모
print(name_shape(10, 1.03, 0.342, 0.507)) # 결과: 별주의할 점
- 규칙의 순서가 결과를 바꿉니다. 별은 근사 다각형의 꼭짓점이 10개라, 움푹한지를 먼저 묻지 않으면 "원"(9 이상)으로 잘못 붙습니다.
- 경계값에 딱 붙은 물체(볼록 비율 0.89, 0.91 등)는 작은 노이즈에도 이름이 바뀝니다. 실습 3의 마지막 단계에서 도형 판을 작게 줄였을 때 어떤 이름이 바뀌는지 직접 봅니다.
- 모양이 많고 복잡해지면 규칙을 사람이 다 정하기 어렵습니다. 그때는 17장부터 다룰 딥러닝 모델이 정답 사진에서 규칙을 배우게 합니다.