AUTOCRAFT는 흑백 선화(line art)를 업로드하면, 서버에서 자동으로 색을 채워주는 웹 애플리케이션입니다.
사용자는 단순히 이미지를 올리고, 팔레트를 선택하고, 필요하다면 선 위에 가이드 색을 조금 찍어주는 것만으로 컬러 이미지를 얻을 수 있습니다.
이 프로젝트의 목표는:
- 웹에서 바로 사용할 수 있는 간단한 자동 채색 도구를 만드는 것
- 팔레트 기반 채색과 가이드 색 기반 채색 두 가지 모드를 모두 지원하는 것
- 이미지 처리 알고리즘(선 검출, flood-fill, 영역 분할 등)을 직접 구현해 보는 것
입니다.
- 좌측 사이드바에서 이미지를 선택하면, 왼쪽 패널에 즉시 미리보기가 표시됩니다.
- 업로드 후
채색하기버튼을 누르면 서버에서 이미지를 처리하고, 오른쪽 패널에 결과 이미지가 나타납니다.
- “선화 위에 찍은 가이드 색을 기준으로 채색하기” 체크박스를 끄면 동작합니다.
- 선화 내부를 flood-fill로 영역 단위로 나눈 뒤, 선택한 팔레트에서 순서대로 색을 가져와 각 영역을 자동으로 채웁니다.
- “선화 위에 찍은 가이드 색을 기준으로 채색하기” 체크박스를 켠 상태에서 사용합니다.
- 사용자가 선화 위에 미리 칠해 둔 **가이드 색(작은 점이나 면)**을 분석하여,
같은 영역 안의 가이드 픽셀 색을 평균내어 그 영역 전체를 채우는 방식입니다.
- 진짜 선(검은/짙은 회색 + 채도 낮은 영역)을 먼저 검출하여 색을 덮지 않고 그대로 유지합니다.
- 연필/펜 선이 약간 흐리거나 안티에일리어싱된 경우를 위해 선 주변을 확장(seg_wall) 해서 flood-fill 시 벽으로 취급합니다.
- 채색 후에는 선 주변의 하얀 틈을 한 번 더 스캔해서, 주변 색을 참고해 자연스럽게 메워 줍니다.
- 채색이 완료되면 우측 하단의
이미지 다운로드버튼을 눌러 결과 PNG를 저장할 수 있습니다.
- Python 3.x
- Flask
- 파일 업로드 처리
- 템플릿 렌더링 (
index.html) - 정적 파일(
static/uploads,static/results) 제공
- Pillow (PIL) – 이미지 로딩 및 저장
- NumPy – 픽셀 연산, 배열 기반 이미지 처리
collections.deque– flood-fill 구현 시 BFS 큐에 사용random– 팔레트에서 색을 섞어 보다 자연스러운 색 배치
- HTML5
- Vanilla CSS (index.html에 인라인 스타일로 구성)
- Vanilla JavaScript
- 업로드 즉시 클라이언트 측 미리보기
- 폼 제출 시 버튼 비활성화 & 로딩 텍스트 표시
AUTOCRAFT/
├── app.py # Flask 서버 엔트리 포인트
├── color_engine.py # 자동 채색 알고리즘 핵심 로직
├── templates/
│ └── index.html # 메인 페이지 템플릿
├── static/
│ ├── uploads/ # 업로드된 원본 이미지가 저장되는 폴더
│ └── results/ # 채색 결과 이미지가 저장되는 폴더
└── README.md # 프로젝트 설명 문서 (이 파일)
# (선택) 가상환경 생성
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activatepip install flask pillow numpy혹은 requirements.txt를 따로 만들어 사용해도 됩니다.
Flask
Pillow
numpypython app.py기본 설정에서는 디버그 모드로 실행되며, 브라우저에서 다음 주소로 접속합니다.
http://127.0.0.1:5000/
Anaconda Prompt에서 아래 명령어를 순서대로 실행하면 AUTOCRAFT 서버를 실행할 수 있습니다.
- 프로젝트 폴더로 이동
cd 경로\autocraft- (선택) 가상환경 생성 및 활성화
conda create -n autocraft python=3.10 -y
conda activate autocraft- 필요한 라이브러리 설치
pip install flask pillow numpy- 서버 실행
python app.py실행 후 아래 주소로 접속하여 AUTOCRAFT를 사용할 수 있습니다.
http://127.0.0.1:5000/
- 좌측 상단 프로젝트 로고와 이름 AUTOCRAFT를 확인할 수 있습니다.
- 왼쪽 사이드바:
선화 / 가이드 이미지파일 선택팔레트 선택드롭다운선화 위에 찍은 가이드 색을 기준으로 채색하기체크박스채색하기버튼 및 로딩 메시지
- 중앙/오른쪽 패널:
- 왼쪽: Original / Guide – 업로드된 원본/가이드 이미지를 보여주는 영역
- 오른쪽: Colored Result – 자동 채색 결과 표시 + 다운로드 버튼
- 선화 이미지를 업로드합니다.
- 팔레트를 선택합니다. (예:
기본 팔레트 (따뜻한 파스텔)) - 가이드 체크박스를 끈 상태에서
채색하기버튼을 누릅니다. - 우측 결과 패널에 선택한 팔레트 색들이 층층이 적용된 결과가 표시됩니다.
- 선화를 준비할 때, 색이 들어가야 하는 영역에 작게 가이드 색을 찍어 둡니다.
- 이미지를 업로드합니다.
- 팔레트를 선택합니다. (팔레트는 가이드가 없는 영역에 사용되거나, 가이드 모드가 꺼진 경우에만 영향을 줍니다.)
- 가이드 체크박스를 켠 상태에서
채색하기버튼을 누릅니다. - 서버에서는 동일 영역 안의 가이드 픽셀 색을 분석하여, 전체 영역을 해당 색으로 채웁니다.
여기서는 color_engine.py에 구현된 핵심 흐름을 단계별로 설명합니다.
- 업로드된 이미지를
Pillow로 열고,RGB로 변환합니다. NumPy배열로 변환하여 각 픽셀의 R, G, B 값을 얻습니다.- 각 픽셀에 대해 다음을 계산합니다.
brightness = max(R, G, B)– 대략적인 밝기saturation = max(R, G, B) - min(R, G, B)– 단순 채도 지표
- 이 값을 이용해 선(라인) 영역과 나머지 영역을 분리합니다.
- 선 조건
- 밝기가 낮고(
brightness < 110) - 채도가 낮은(
saturation < 40) 픽셀을 선으로 간주합니다.
- 밝기가 낮고(
- 이렇게 얻은
wall마스크를 한 번 더 확장하여seg_wall을 만듭니다.- 상하좌우 + 대각선 주변 픽셀까지 선처럼 취급하여, flood-fill 시 영역이 선 사이로 새어나가지 않도록 합니다.
- 이 과정은 안티에일리어싱(회색 경계선) 때문에 선이 완전히 끊어져 보이는 문제를 줄여 줍니다.
- 완전 흰색에 너무 가깝지 않고(
dist_from_white > 25) - 어느 정도 채도가 있는 (
saturation > 10) - 선(seg_wall)이 아닌 픽셀들을 가이드 후보로 취급합니다.
- 사용자가 “가이드 모드”를 켜지 않았거나, 이미지 안에 가이드가 하나도 없다면
자동으로use_guide = False로 전환하여 팔레트 기반 채색 모드로 동작합니다.
visited배열을 두고, 아직 방문하지 않았고 선이 아닌 픽셀에서 시작해 BFS(큐)를 돌립니다.- 상하좌우 4방향으로 같은 영역을 확장하면서:
- 영역에 속한 모든 픽셀 좌표를
region_pixels에 수집 - 영역 안에 포함된 가이드 픽셀들의 색을
guide_colors에 수집 - 영역이 이미지의 가장자리(테두리)에 닿았는지 여부를
touches_border로 기록
- 영역에 속한 모든 픽셀 좌표를
- 이렇게 해서 이미지 전체를 여러 개의 연속된 영역(region) 으로 나눕니다.
각 영역에 대해:
- 평균 밝기(
region_mean_brightness) - 평균 흰색 거리(
region_mean_dist) - 테두리 접촉 여부(
region_touches_border) - 가이드 포함 여부(
region_has_guide)
를 계산한 뒤, 다음 기준으로 배경을 판정합니다.
- 가이드 모드일 때:
- (가이드 없음) + (밝음) + (테두리 접촉) → 배경
- 또는 (가이드 없음) + (매우 밝음) + (흰색에 매우 가까움) → 배경
- 가이드 모드가 아닐 때:
- (테두리 접촉) + (밝음) → 배경
만약 어떤 영역도 배경으로 선택되지 않았다면,
가장자리와 닿아 있으면서 가장 큰 영역 또는 가장 큰 영역 하나를 강제로 배경으로 지정합니다.
-
결과 캔버스
result를 전체 흰색(255,255,255)으로 초기화합니다. -
선택된 팔레트를 가져와 랜덤 셔플하여 색의 배치가 매번 약간씩 달라지도록 합니다.
-
각 영역에 대해:
- 배경 영역 →
fill_color = (255,255,255)(흰색 유지) - 가이드 모드 + 가이드가 있는 영역
guide_colors의 평균 색을 구해fill_color로 사용
- 가이드 모드 + 가이드가 없는 영역
- 의도치 않은 채색을 막기 위해 흰색으로 남김
- 가이드 모드가 아닌 경우(팔레트 모드)
- 팔레트에서 다음 색을 하나 꺼내
fill_color로 사용
- 팔레트에서 다음 색을 하나 꺼내
- 배경 영역 →
-
실제 채색 시에는 선(wall) 픽셀은 건드리지 않고, 선 내부 영역만 색을 칠합니다.
- 채색이 끝난 후,
wall마스크를 이용해 선 위치의 픽셀을 다시 원본 이미지의 색으로 덮어써 선을 선명하게 유지합니다. - 그 다음
seg_wall & ~wall인 픽셀(선 주변 확장 영역) 중 아직 흰색인 곳을 검사하여, 주변 8방향 이웃에 색이 있으면 그 평균 색으로 채워 줍니다. - 이 과정 덕분에 선 근처의 하얀 틈(픽셀 단위 구멍) 이 자연스럽게 메워져 깔끔한 결과를 얻을 수 있습니다.
- 단순 라이브러리 호출이 아니라, 직접 flood-fill + 영역 분할 + 배경 판정 로직을 구현
- 안티에일리어싱/회색선 때문에 선이 끊어지는 문제를 해결하기 위해
선 마스크를 확장(segmentation wall) 하는 전처리 단계를 추가 - 가이드 모드와 팔레트 모드를 분리하여,
- 가이드 모드: 사용자의 의도를 최대한 반영 (가이드 없는 영역은 비워두기)
- 팔레트 모드: 컬러링북처럼 자동으로 전체를 예쁘게 채색
- 선과 배경을 보호하면서도, 선 주변의 흰색 틈을 후처리로 메워
시각적으로 매끄러운 결과를 얻도록 함 - Flask + HTML/CSS/JS 구조를 사용하여
- UI는 단일 페이지에서 직관적으로 조작 가능
- 서버에서는 이미지 처리에 집중하도록 프론트/백의 역할을 분리
- 브러시 기반 가이드 편집: 웹 상에서 직접 색을 찍거나 지울 수 있는 간단한 브러시 도구 추가
- 영역별 팔레트 잠금 기능: 같은 객체(예: 토끼 2마리)는 항상 비슷한 계열 색이 나오도록 제한
- 다단계 언두 / 리두: 여러 번 채색해 본 기록을 남겨 손쉽게 비교
- 더 고급 알고리즘 연동: 딥러닝 기반 colorization 모델과의 비교 실험
- 모바일 UI 최적화: 작은 화면에서도 편하게 사용할 수 있도록 레이아웃 재구성
AUTOCRAFT는 비교적 단순한 구조이지만,
- 선 검출
- flood-fill 기반 영역 분할
- 배경 판정
- 가이드/팔레트 모드 분기
- 선 주변 틈 메우기
와 같은 중요한 이미지 처리 아이디어를 모두 담고 있는 작은 실험 프로젝트입니다.
This project is licensed under the MIT License.