<어따놀래>는 사용자가 도면의 사진을 업로드하면 벽을 검출하여 표시하는 기능을 제공합니다.
단 본 프로젝트의 지향점이 AI의 성능 강화보단 전반적인 웹 서비스 구현에 초점을 맞추었기 때문에, 벽 검출 기능에 일부 오차가 있을 수 있습니다.
물론 직접 인공지능 모형을 훈련하거나 하는 식으로 해결할 순 있겠지만, 도면만들기보단 시뮬레이터에 집중해야 할 필요가 있겠다고 생각했습니다. (특히 정글이 AI 부트캠프는 아닌만큼, 선택과 집중을...)
대신 축척 설정 및 벽 추가 / 삭제 등 에디터 기능 역시 구현되어 있으므로, 벽 검출에 오차가 있더라도 사용자가 바로 수정할 수 있습니다.
벽 검출에는 공개 컴퓨터 비전 라이브러리인 OpenCV.js의 Hough Transformation을 사용하였습니다.
Hough Transformation은 도형 및 사진에서 선을 검출해 주는 알고리즘입니다. 동작 과정을 차례로 설명해 보겠습니다.
window.cv.cvtColor(srcImg, gray, window.cv.COLOR_RGBA2GRAY);
window.cv.threshold(gray,
binary,
0,
255,
window.cv.THRESH_BINARY_INV + window.cv.THRESH_OTSU
);
const kernel = window.cv.Mat.ones(3, 3, window.cv.CV_8U);
window.cv.morphologyEx(binary, cleaned, window.cv.MORPH_OPEN, kernel);
window.cv.Canny(cleaned, edges, canny1, canny2, 3, false);
canny1(50)보다 낮으면 경계선이 아니라고 판단하고, canny2(150)보다 높으면 확실한 경계선으로 판단합니다. 50과 150 사이의 값은 주변에 확실한 경계선이 있을 때만 경계선으로 인정합니다.window.cv.HoughLinesP(
edges,
lines,
1, // rho: 거리 해상도
Math.PI / 180, // theta: 각도 해상도 (1도)
houghTh, // 임계값 (80)
minLen, // 최소 선분 길이 (30)
maxGap // 선분 간 최대 간격 (20)
);
rho는 선의 위치를 1픽셀 단위로, theta는 선의 기울기를 1도 단위로 세밀하게 측정하여 정확한 직선을 찾아냅니다. houghTh(80)는 몇 개의 점이 일직선 위에 있어야 선으로 인정할지 정하는 값입니다. 80개 이상의 점이 일직선상에 있으면 벽으로 판단합니다.filterLines(lines, minLength = 80, angleThreshold = 5)
mergeParallelLines(lines, maxDistance = 15, angleThreshold = 5)
angleThreshold: 5도 이내의 각도 차이만 평행선으로 인정합니다.maxDistance: 15px 이내 거리의 선만 병합 대상입니다.