TL;DR

  • 35mm 필름 스캔·보정·게시 파이프라인을 구축해 롤당 약 4시간 걸리던 작업에서 반복적인 처리를 줄이고, 사진을 찍고 결과를 감상하는 데 더 집중함.
  • Claude가 SANE으로 스캐너를 직접 제어하려다 스캔 방향을 거꾸로 설정해 기어 장치를 손상시킬 뻔했으며, 이후 스캔은 VueScan으로 직접 진행하고 후처리를 자동화함.
  • numpy 기반 변환으로 롤 전체의 색을 일관되게 조정하고, LaMa 인페인팅 모델과 이미지 분석으로 먼지를 찾아 보정함.
  • Ollama에서 로컬 실행하는 Qwen3-VL이 프레임별 태그를 약 5초 안에 작성하며, 카메라·렌즈·날짜·필름 정보와 함께 검색 가능한 라이브러리를 구성함.
  • Cloudflare R2에 선별한 사진을 게시하고 필름 롤 형태로 보여주는 갤러리를 구축했으며, 프로젝트는 11일·64개 커밋, 총 22롤·314장으로 구성됨.

스캐너 하드웨어를 직접 제어하려다 생긴 문제

  • 필름 사진 작업은 촬영 후 필름을 현상하고, 네거티브를 자르고 홀더에 끼운 뒤 각 프레임을 스캔하는 방식임. 이후 darktable에서 파일을 열어 수동으로 반전·보정하고 내보낸 이미지를 저장하거나 공유함.
  • 36장짜리 한 롤을 스캔하고 보정하는 데 평균 약 4시간이 들었으며, 필름을 다룰 때 먼지나 긁힘을 막으려면 세심한 주의가 필요함. 촬영보다 이미지 처리에 더 많은 시간을 쓰게 되면서 개인 작업실의 절차를 간소화할 방법을 찾음.
  • 처음에는 Claude가 오픈소스 스캐너 드라이버 스택인 SANE을 통해 스캐너를 제어하고 스캔·색 변환·보정을 끝까지 처리하도록 하려는 가설을 세움.
  • 첫 스캔에서 Claude가 스캔 베드의 X·Y 방향을 반대로 설정해 스캐너 내부 기어 장치를 거의 망가뜨림. 새 스캐너 구매에 200달러를 쓰지 않기 위해 스캐너를 분해해 수리해야 했음.
  • 스캔 결과가 흰색으로 나온 원인은 설정이 아니라 이동 방향 문제였음. 스캔 센서가 움직이지 않아 이미지 정보 없이 램프의 불균일한 조명만 감지했고, genesys 백엔드는 매 스캔이 끝날 때 캐리지가 앞으로 움직였다고 가정해 반대 방향으로 복귀시킴.
  • 900dpi에서 7,010스텝, 3,600dpi에서는 그보다 더 많은 스텝을 이동시키는 복귀 동작이 이미 뒤쪽 끝에 도달한 캐리지를 계속 밀어 클릭 소리를 냄. 일곱 번 스캔해 이 동작도 일곱 번 반복됐으며, 밀려난 막대와 기어를 제자리로 돌려놓는 수리가 필요했음.
  • 하드웨어를 직접 제어하는 시도는 중단하고, 스캐너 호환성이 좋은 기존 유료 소프트웨어 VueScan으로 스캔을 직접 진행하기로 함. 물리적으로 필름을 넣고 스캔하는 작업을 대신할 로봇 팔도 없으므로, 스캔 이후의 처리를 자동화하는 방향으로 전환함.

스튜디오

  • 실패를 계기로 VueScan 작업 흐름은 유지하면서 스캔 결과를 자동 처리하는 도구를 구축함. 개별 이미지 데이터를 대상으로 여러 테스트를 거친 뒤 도구들을 조합함.

네거티브 변환

  • 네거티브를 포지티브로 바꾸는 작업은 대부분 일반 코드로 처리함. 짧은 numpy 루틴이 필름의 농도 정보를 이용하고 롤 전체의 색을 측정한 뒤, 각 프레임의 네거티브 범위 안에서 보정함.
  • 이 방식으로 한 롤의 36개 프레임이 일관된 색을 유지하고, 석양 장면이 지나치게 색 보정되는 일을 방지함. 수동 작업에서 어려움을 겪던 문제이기도 함.
  • 에이전트는 롤 앞부분의 빈 프레임을 다른 프레임의 색 보정 가중치를 정하는 기준으로 활용하는 방안을 제안함.
  • 본격적인 구축 전에 오래된 롤로 변환 테스트를 진행했으며, 29개 중 28개 프레임에서 테스트를 통과함. darktable 없이도 구축을 이어갈 만큼 변환 결과가 적절했음.
  • 테스트 비교에서 자동 변환 결과는 더 밝고 중립적인 색을 냈고, 기존 내보내기 결과는 호텔 델 코로나도 하늘·해변 인물 사진·정원 사진에서 더 어둡고 청록색에 가까웠음. 색의 선택은 정확성뿐 아니라 취향의 문제로 남음.

먼지 제거와 편집

  • 일반 코드만으로 처리하기 어려운 영역에는 모델을 사용함. 네거티브를 이미지 분석해 먼지로 보이는 부분을 표시하지만, 해변 사진에서는 물 위의 햇빛 반사 약 2,000개를 먼지로 잘못 감지하는 문제가 있었음.
  • 주변 맥락을 반영하고 주변 영역이 매끄러운 경우에만 작동하도록 조정함. 감지한 점은 인페인팅 모델 LaMa로 채우고, 가까운 필름 영역의 세부 정보를 다시 반영해 패치가 번져 보이지 않게 함. 방식은 Photoshop의 복구 도구와 유사함.
  • 모든 영역을 자동으로 채우지는 않음. 입자가 있는 점을 검토 대상으로 남기는 임계값을 설정하고, 개별 또는 일괄 방식으로 승인하거나 거부할 수 있음.
  • 사진별 입자 상태에 맞춰 밝기와 색을 조정할 수 있도록 노출·대비·색온도 등의 제어 기능을 제공함.
  • 검토 화면에서는 초록색 원이 자동으로 먼지를 보정한 부분이고, 호박색 원은 검토 대상으로 남긴 부분임.

메타데이터

  • 아날로그 필름 사진의 정보를 여러 도구에 나눠 기록하면 색인 작업에 시간이 들 수 있음. 기술을 활용해 사진을 식별하고 나중에 쉽게 검색할 수 있도록 확장함.
  • 스캔이 들어오면 Ollama에서 로컬 실행하는 Qwen3-VL이 완성된 프레임을 살펴보고 약 5초 안에 태그 초안을 작성함.
  • 태그에 카메라·렌즈·날짜·필름 종류 정보를 더해 검색 가능한 사진 라이브러리를 구성함. 태그 초안은 프레임을 선택할 때 한 번 수정함.
  • 반복적인 처리에서 벗어나 촬영한 결과를 살펴보고 다음 촬영의 영감을 찾는 데 집중할 수 있게 됨.

갤러리

  • 몇 롤을 파이프라인으로 처리한 뒤 사진을 어디에 둘지 고민함. 기존에는 컴퓨터에 연결된 채 계속 회전하도록 설정한 4TB HDD에 사진을 저장함.
  • 개인 사이트의 일부 콘텐츠에 방문자가 가끔 접속하는 Cloudflare 계정을 활용해 무료 요금제를 사용하고, 이미지를 자체 R2 버킷에 올리는 게시 기능을 스튜디오에 추가함.

게시 흐름

  • 한 롤을 게시할 때 선택한 프레임을 화면에 표시된 순서대로 R2에 올리고, 태그도 함께 저장함. 그 밖의 정보는 게시하지 않음.

롤별 사진 전시

  • 썸네일 격자만으로는 게시 경험이 충분하지 않다고 판단해 필름 롤 자체를 본뜬 전시 방식을 구현함. 현상소 직원이 필름을 풀어 C41 현상기에 감는 모습을 본 기억에서 아이디어를 얻음.
  • 현실을 가장 정확하게 재현하는 방식은 아니라고 밝히면서도, 구현하고 발전시키는 과정이 즐거운 아이디어였음.
  • 3js로 만든 펠트 테이블 위에 실제 라벨 아트와 임의의 흠집이 있는 필름 통을 배치함. 필름 통을 집어 필름을 당기면 프레임이 드러나고, 이후 필름은 펠트 테이블 위로 다시 떨어짐.

나의 인터넷 공간

  • 프로젝트는 11일 동안 진행됐고 64개 커밋으로 구성됨. 갤러리에는 22롤·314장의 사진이 있으며, 가장 오래된 사진은 2020년 촬영분임.
  • 앞으로 필름과 현상에 더 많은 비용을 쓰면서 갤러리에 사진을 계속 추가할 예정임. 다시 방문해 인터넷을 잠시 벗어나 둘러볼 수 있는 개인 공간으로 운영함.
  • 스캐너와 처리 절차 자체를 다루는 일만큼 이런 사이트를 만드는 일에도 매력이 있음. 수동 작업을 즐기며 위임하고 싶지 않은 사람도 있을 수 있음.
  • 이 작업의 경우 수동 처리 과정은 컴퓨터에서 벗어나 세상을 탐험하는 시간에 집중하게 해줌. 세상을 다른 관점으로 담아내는 일이기도 함.