에듀테크 프로젝트 대시보드
이미지 컨볼루션
디지털 이미지는 픽셀 밝기의 격자다. 컨볼루션은 작은 숫자판(커널 또는 필터)을
이미지 위에서 한 칸씩 미끄러뜨리며, 겹친 픽셀들과 가중합을 계산해 새 픽셀 값을 만든다.
커널의 숫자만 바꾸면 블러, 샤픈, 엣지 검출, 엠보스가 전부 같은 연산 하나로 만들어진다.
포토샵 필터, 인스타그램 효과, 그리고 CNN(합성곱 신경망)의 첫 단계가 모두 이것이다.
프리셋을 눌러 커널을 채우거나, 아래 3×3 칸의 숫자를 직접 고쳐 보자.
오른쪽 결과가 즉시 다시 계산된다. 나눗값은 모든 곱의 합을 나눠 밝기를 유지한다(정규화).
가장자리 처리: 커널이 이미지 밖으로 삐져나가는 테두리 픽셀은 가장 가까운 픽셀 값을 복제해서(clamp) 채웠다. 다른 방식으로는 0으로 채우기, 거울처럼 반사하기, 순환(wrap)이 있다.
파란 3×3 창 안의 원본 픽셀들과, 현재 커널을 같은 위치끼리 곱해서 모두 더한 값이 가운데 픽셀의 새 값이 된다. 창을 옮겨 가며 값을 확인해 보자.
같은 3×3 틀에 어떤 숫자를 넣느냐에 따라 전혀 다른 효과가 나온다.
# 항등 (그대로) # 박스 블러 (÷9) # 샤픈 0 0 0 1 1 1 0 -1 0 0 1 0 1 1 1 -1 5 -1 0 0 0 1 1 1 0 -1 0 # 라플라시안 엣지 # 소벨 Gx (세로선) # 엠보스 (+128 오프셋) 0 1 0 -1 0 1 -2 -1 0 1 -4 1 -2 0 2 -1 1 1 0 1 0 -1 0 1 0 1 2
블러는 주변을 평균 내 고주파(디테일)를 없앤다. 샤픈은 원본에서 블러를 빼서 경계를 강조한다. 소벨은 좌우(또는 상하) 밝기 차이를 재는 미분 필터라서, 밝기가 급변하는 가장자리에서만 큰 값이 나온다.
function convolve(src, W, H, kernel, div, offset) { const out = new Float32Array(W * H); const kSize = 3, half = 1; for (let y = 0; y < H; y++) { for (let x = 0; x < W; x++) { let sum = 0; for (let ky = 0; ky < kSize; ky++) { for (let kx = 0; kx < kSize; kx++) { // 테두리는 가까운 픽셀로 clamp const sx = clamp(x + kx - half, 0, W - 1); const sy = clamp(y + ky - half, 0, H - 1); sum += src[sy * W + sx] * kernel[ky * 3 + kx]; } } out[y * W + x] = sum / div + offset; // 정규화 + 오프셋 } } return out; }