20장. 교육 콘텐츠 설계와 종합 실습
실습 데이터를 코드로 만들기
과학 실험 수업에서 강사가 진짜 바닷물을 떠 오지 않고 물 1리터에 소금 35g 을 녹여 "연습용 바닷물"을 만든다고 해 봅시다. 소금이 정확히 몇 g 들었는지 알고, 더 짜게 하고 싶으면 소금만 더 넣으면 되고, 같은 조리법이면 어느 반에서든 똑같은 물이 나옵니다. 이 교안의 그림도 이렇게 코드로 만들었습니다.
그림의 세 상자가 코드로 그린 그림의 좋은 점입니다. 여기서 소금 35g 을 아는 것이 "정답을 안다", 소금을 더 넣는 것이 "손잡이가 있다", 같은 조리법이 씨앗 고정입니다. 비유가 맞지 않는 곳도 있습니다. 연습용 바닷물에는 플랑크톤이 없듯, 코드로 그린 그림에는 실제 사진의 복잡한 무늬와 빛이 없습니다. 그래서 마지막에는 실제 사진으로도 한 번 해 보게 안내합니다.
실제 사진과 코드로 그린 그림
| 견줄 것 | 실제 사진 | 코드로 그린 그림 |
|---|---|---|
| 저작권·초상권·개인정보 | 사진마다 확인해야 한다 | 직접 그렸으니 걱정이 없다 |
| 정답 | 사람이 칠하거나 상자를 그려야 한다 | 그리면서 함께 저장한다 |
| 난이도 | 고르기 어렵다 | 숫자 하나로 바꾼다 |
| 크기 | 수 MB 가 흔하다 | 수 KB 로 작다 |
| 실제와 닮은 정도 | 그대로 실제다 | 단순하다. 실제 사진 실습을 따로 둔다 |
이 교안에서 정답을 함께 만든 곳은 8장의 영수증 정답 마스크, 11장의 _edge 정답 경계, 12장의 answer.csv, 13장의 ch13_signs_answer.csv, 16장의 answer.csv, 17장의 mistakes.csv 입니다.
짧은 예시
동그라미를 무작위 자리에 그리면서 정답 마스크를 함께 칠하고, 같은 씨앗으로 다시 만들면 같은 그림이 나오는지 봅니다.
import cv2
import numpy as np
def draw_coins(seed, count=5):
"""흑백 연습 그림과 정답 마스크를 함께 돌려준다."""
rng = np.random.default_rng(seed) # 씨앗을 고정한 난수 만들개
img = np.full((120, 160), 60, dtype=np.uint8) # 어두운 회색 바탕
mask = np.zeros((120, 160), dtype=np.uint8) # 정답 마스크: 처음엔 모두 0
for _ in range(count):
x, y = int(rng.integers(15, 145)), int(rng.integers(15, 105))
cv2.circle(img, (x, y), 10, 190, -1) # 그림에 밝은 동그라미
cv2.circle(mask, (x, y), 10, 255, -1) # 같은 자리를 정답 마스크에도
return img, mask
a_img, a_mask = draw_coins(seed=7)
b_img, b_mask = draw_coins(seed=7)
c_img, c_mask = draw_coins(seed=8)
print("씨앗 7 두 번, 같은 그림인가:", np.array_equal(a_img, b_img)) # 결과: True
print("씨앗 7 과 8, 같은 그림인가:", np.array_equal(a_img, c_img)) # 결과: False
print("정답 마스크의 흰 칸 비율:", round(float((a_mask > 0).mean()), 3))주의할 점
- 정답은 그림을 그린 바로 그 좌표로 만듭니다. 그린 뒤에 그림을 보고 다시 찾으면 정답에 실수가 섞일 수 있습니다.
- 노이즈를 파일에 담으면 png 가 커집니다. 깨끗한 그림만 파일로 두고 노이즈는 실습 코드에서 씨앗을 고정해 더하는 쪽이 낫습니다(6장).
- 실제 사람, 상호, 상표를 그리지 않습니다. 가상 그림이라고 자료에 밝힙니다.