5분 AI.
GitHub 딥다이브 · 2026-08-24 · ★5.2k

Remove AI Watermarks (wiltodelta/remove-ai-watermarks) 딥다이브
— AI 이미지·영상의 "출처 표식" 3종을 각기 다른 방법으로 지우는 파이썬 도구

AI로 만든 이미지에는 보통 세 겹의 표식이 붙는다 — 눈에 보이는 로고, 눈에 안 보이는 픽셀 워터마크(SynthID 등), 그리고 파일 안에 적힌 메타데이터(C2PA·EXIF). 이 저장소는 그 셋을 완전히 다른 기술로 다룬다. 셋을 하나의 "제거" 버튼으로 뭉뚱그리지 않고, 각 표식의 물리적 성질에 맞는 파이프라인을 따로 만든 것이 이 프로젝트의 뼈대다.
(저장소: wiltodelta/remove-ai-watermarks · Apache-2.0 · v0.28.1 · Python 3.11–3.14 · 별 5,217 / 포크 494 · 2026-03-25 생성 · src/ 53개 파일 20,913줄 · PyPI remove-ai-watermarks · 호스팅판 raiw.cc)
먼저 읽을 것 · 이 도구의 경계
"내가 만든 것"에만 쓰라고 저자가 못 박아 둔 도구다

저장소는 docs/legal-and-safety.md에서 범위를 명시한다 — 본인이 생성·편집한 콘텐츠의 AI 표식만 대상이고, 스톡 사진 미리보기·마켓플레이스 워터마크·타일 오버레이·Nightshade/Glaze 같은 작가 보호 장치는 범위 밖이다. watermark_registry.py에 스톡·에이전시 마크를 추가하는 것 자체가 기여 규칙으로 금지돼 있다.

또한 표식을 지운다고 해서 "사람이 만들었다"가 증명되지는 않는다. 제공자 서버에 남은 생성 이력·계정 연결은 그대로이고, 통계적 AI 탐지기도 따로 돈다. 나라·플랫폼에 따라 AI 표기 의무나 출처정보 제거 금지 규정이 있으니, 기술 학습 자료로 읽되 실제 사용은 각자의 법적 책임이다. 이 문서도 그 전제로 쓰였다.

목차
  1. 프로젝트 한 줄 요약
  2. 왜 주목받는가
  3. 기술 스택 전체 지도
  4. 아키텍처 심화 분석
  5. 디렉토리 구조 해부
  6. 학습 포인트
  7. 하드웨어 · 시스템 요구사항
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 학습 로드맵
  10. 핵심 키워드 사전
  11. 참고 링크

1프로젝트 한 줄 요약

"한 문장으로 뭐 하는 물건인가"
한 줄 정의

AI 생성물에 붙은 출처 표식 3종(보이는 로고 · 안 보이는 픽셀 워터마크 · 파일 메타데이터)을 각각 다른 방식으로 제거하는 파이썬 라이브러리 + CLI.

이미지와 동영상을 모두 다루며, GPU 없이 되는 작업(메타데이터·보이는 로고·판별)과 CUDA가 반드시 필요한 작업(안 보이는 워터마크)이 설치 단계부터 갈라져 있다.

표식 종류어디에 있나제거 방식GPU
보이는 마크화면 구석 로고·글자
(Gemini 반짝이, 즉몽, 千问 등)
찾아서 지우고 메워 넣기
(localize → inpaint)
불필요
메타데이터파일 헤더의 텍스트
(C2PA·EXIF·XMP·IPTC·TC260)
포맷별 정밀 삭제
(픽셀 재압축 없음)
불필요
안 보이는 워터마크픽셀·주파수 영역 전체
(SynthID 등)
이미지 전체 재생성
(diffusion / VAE 통과)
CUDA 필수
쉽게 말하면

사진에 남은 세 가지 흔적을 지우는 일과 같다. 스티커는 떼고 그 자리를 메우면 된다(보이는 마크). 사진 뒤에 적힌 연필 메모는 지우개로 지우면 된다 — 사진 자체는 손대지 않는다(메타데이터). 그런데 종이 섬유에 눌러 새긴 자국은 지울 방법이 없어서, 사진을 통째로 다시 인화하는 수밖에 없다(안 보이는 워터마크). 세 번째만 원본이 미묘하게 달라지는 이유가 이것이다.

2왜 주목받는가

"비슷한 도구가 널렸는데 왜 이게 5,200개 별을 받았나"

① 시점이 정확했다

2026-03 생성 후 5개월 만에 별 5.2k. 배경은 Nano Banana(Gemini 이미지) 대중화다. 생성물에 반짝이 로고가 자동으로 박히기 시작하면서 "내가 만든 건데 로고가 남는다"는 수요가 폭발했다. 저장소 키워드에 nano-banana·gemini-watermark가 들어 있는 게 그 증거다.

② 경쟁 도구 대비: "지웠다고 우기지 않는다"

흔한 워터마크 제거 도구이 저장소
"AI 워터마크 제거!" 한 버튼표식 3종을 명령어부터 분리 (visible / metadata / invisible)
신호가 없으면 "깨끗함"으로 표시신호 없음 = Unknown. "깨끗하다"고 절대 말하지 않는다
제거 성공률을 광고docs/known-limitations.md에 실패 조건을 나열. SynthID는 "공개 디코더가 없어 런타임 검증 불가"라고 명시
탐지 실패 시 그냥 지움탐지 못 하면 아무것도 쓰지 않는다(no output)

③ 실패한 설계를 코드에 측정치와 함께 남긴다

이 저장소를 읽을 가치가 있게 만드는 지점. 폐기된 접근이 왜 폐기됐는지가 주석에 숫자로 남아 있다.

폐기 기록 1 · 2026 초
reverse-alpha 복원 — 수식은 맞는데 실무에서 틀렸다

원래는 로고의 투명도 지도(alpha map)를 미리 캡처해 두고 원본 = (합성본 − a×로고) / (1−a)로 역산해 복원했다. 폐기 이유 둘: ⓐ 벤더가 로고를 다시 그리거나 위치를 옮기면 캡처가 통째로 무효, ⓑ 맞는 alpha map을 써도 색이 안 맞는다 — 나눗셈이 JPEG 색차 압축 오차를 1/(1−a)배로 증폭하기 때문. 사용자 제보 "색만 변하고 안 지워짐"의 정체가 이것이었다.

폐기 기록 2 · 2026-07-19
assume_ai 모드 — 사용자의 "이거 AI야"는 지시가 아니라 도박이었다

"이 이미지는 AI다"라고 사용자가 주장하면 모든 마크의 탐지 문턱을 낮춰 주던 옵션. 문제는 그 주장이 어느 벤더의 로고가 어디에 있는지는 하나도 말해 주지 않는다는 것. 문턱만 내려간 결과, 신뢰도 하한을 두기 전 측정에서 진짜 카메라 사진의 59.8%에 있지도 않은 반짝이를 그려 메웠다. 대안은 명확했다 — 로고가 보이는 사용자는 erase --region으로 위치를 찍거나 --mark X로 이름을 대면 된다. 추측 대신 지시를 실행하게 바꾼 것이다.

3기술 스택 전체 지도

"무엇으로 만들어졌나 — 그리고 왜 설치가 여러 갈래인가"

기본 설치는 놀랄 만큼 가볍다

계층구성비고
기본(필수)pillow · piexif · click · c2pa 공식 리더numpy·torch·OpenCV 없음. 메타데이터 검사/제거만으로 쓰는 사람이 다수라 기본을 일부러 가볍게 유지
픽셀 계층numpy + opencv-python-headless[pixels]. 보이는 마크 탐지·제거의 최소 단위
영상PyAV + 시스템 ffmpeg[video]. PyAV는 가변 프레임 타임스탬프 유지용
학습형 인페인팅onnxruntime (MI-GAN / big-LaMa)[migan]·[lama]. torch 없이 CPU에서 돈다
확산 재생성torch(CUDA) · diffusers · transformers 5.x · DiffSynth[diffusion]·[qwen-zimage]. 여기서만 GPU 필요
선택 디코더PyWavelets(DWT-DCT) · trustmark · pillow-heif · paddleocr각각 [detect]·[trustmark]·[heif]·[text-draft]
설계 포인트
extras 그래프 = "필요한 무게만 지불한다"

13개 extras가 서로를 참조하는 의존성 그래프로 짜여 있다(visible → pixels, video → visible, qwen-zimage → diffusion → pixels). ML 모듈 import는 전부 is_available() 가드 뒤에 있어서, GPU 패키지가 없어도 identify·metadata는 그대로 돈다. 파이썬 CLI를 만들 때 그대로 베낄 만한 패턴이다.

버전 핀에 사고 기록이 붙어 있다

# pyproject.toml — diffusion extra 주석 요약
transformers>=5,<6      # diffusers 0.38이 transformers 5.x 전용 클래스를 import
tokenizers>=0.22,<0.23  # 0.23.0rc0의 CLIP 토크나이저가 SDXL 로딩을 깨뜨림
numpy>=2 (py3.13+)      # numpy 1.x는 CPython 3.13 휠이 없어 소스 빌드 시도됨

"왜 이 버전에 묶였나"가 각 줄 위에 적혀 있다. 의존성 핀을 나중에 푸는 사람이 같은 함정을 다시 밟지 않게 만드는 문서화 방식.

4아키텍처 심화 분석

"세 파이프라인이 어떻게 갈라지고, 각각 무엇을 지키는가"
remove-ai-watermarks <명령> 입력파일 │ ┌────────────────────┼────────────────────┐ ▼ ▼ ▼ ┌───────────────┐ ┌───────────────┐ ┌───────────────────┐ │ identify │ │ metadata │ │ visible │ │ (판별만) │ │ (헤더 수술) │ │ (찾기→메우기) │ └───────┬───────┘ └───────┬───────┘ └─────────┬─────────┘ │ │ │ C2PA 공식리더 ─┤ JPEG: 스캔 보존 watermark_registry caBX 폴백 ─┤ MP4: 박스크기 유지 (11개 마크) IPTC/EXIF ─┤ MKV/WebM: SimpleTag │ PNG 파라미터 ─┤ AVI: LIST/INFO/AIGC ┌─────┴─────┐ TrustMark ─┤ FLV: onMetaData ▼ ▼ DWT-DCT ─┘ localize resolve_trust │ (마스크) strict/confirmed ▼ └─────┬─────┘ ProvenanceReport ▼ 신호 없음 → Unknown region_eraser (절대 "clean" 아님) cv2 / MI-GAN / big-LaMa │ ▼ 결과 이미지 ┌──────────────────────── invisible (CUDA 전용) ────────────────────────┐ │ 원본 ─▶ Canny ControlNet + Qwen-Image-2512 Lightning ─▶ 전체 재생성 │ │ └─▶ SAM 마스크로 얼굴 검출 ─▶ Z-Image Turbo로 얼굴만 복구 │ │ ─▶ humanizer(그레인·수차·샤픈) │ └───────────────────────────────────────────────────────────────────────┘

설계 축 ① — "찾기"와 "메우기"를 완전히 분리했다

레지스트리(watermark_registry.py)의 마크 하나하나는 (어디에 있나 · 어떻게 알아보나 · 어떻게 지우나) 세 정보를 들고 있는데, 셋째는 모든 마크가 같은 것을 공유한다. 마크별 탐지기는 이진 마스크만 만들고, 그 마스크를 하나뿐인 채우기 엔진에 넘긴다.

쉽게 말하면

얼룩 제거를 "얼룩 찾는 사람"과 "천을 기워 넣는 사람"으로 나눈 것이다. 얼룩 종류가 11가지든 30가지든 기워 넣는 기술은 하나만 잘 만들면 되고, 반대로 더 좋은 기움 기술(MI-GAN·LaMa)이 나오면 11가지 얼룩에 동시에 적용된다. 앞서 폐기된 reverse-alpha는 이 분리가 없어서 마크마다 별도 복원 로직을 들고 있었고, 그래서 벤더가 로고를 바꿀 때마다 전부 깨졌다.

설계 축 ② — 신뢰 사다리(trust ladder): 문턱을 낮추되 근거가 있을 때만

단계의미언제 도달하나
strict고정밀 시각 검사만. 깨끗한 이미지는 절대 안 건드림기본. 근거가 없으면 여기 머무름
confirmed오탐 방지 게이트를 우회같은 벤더의 증거가 있을 때만 — ① 해당 벤더의 메타데이터가 남아 있거나 ② 같은 제품의 형제 마크가 확실히 검출됨

핵심은 confirmed로 올라가는 조건이 "이 벤더"를 지목하는 증거뿐이라는 점. 형제 마크로 근거를 삼을 때도, 자기 탐지가 부실한 마크는 다른 마크에 면허를 넘겨줄 수 없게 별도 목록으로 막아 뒀다. 오탐이 잦은 탐지기가 게이트 우회권을 배포하는 사고를 구조로 차단한 것.

설계 축 ③ — 영상: 한 프레임의 판단은 절대 신뢰하지 않는다

지키는 것어떻게
오탐 방지시간적 중재자(temporal arbiter) — 후보가 인접 프레임에서 같은 위치에 반복돼야 제거 허가. 깨끗한 영상 속 우연한 닮은꼴이 마스크가 되는 걸 막는다
깜빡임 방지광학 흐름(optical flow)으로 직전 채움을 이동 정렬해 블렌드. 단, 주변 원본이 동의할 때만 적용(--no-temporal-consistency로 끔)
타이밍 보존가변 프레임 간격을 평균 fps로 뭉개지 않고 PyAV NUT 브리지로 PTS를 그대로 통과. 시작 타임스탬프·오디오 오프셋도 유지
색 보존ffmpeg 기본값(raw BGR)에 맡기지 않고 원본의 크로마 서브샘플링·컬러 태그·트랙 타임스케일을 그대로 씀. HDR/PQ/HLG·10bit 입력은 인코딩 전에 거부(조용히 8bit로 뭉개는 대신)
부분 파일 방지인코딩 완료본만 원자적으로 게시. 마크를 못 찾으면 출력 자체를 안 만든다
오디오재인코딩 없이 stream copy, 자연 종료까지 허용
여기서 배울 것
"미디어 파이프라인은 픽셀만 맞으면 되는 게 아니다"

위 표 6줄 중 픽셀 품질에 관한 건 하나뿐이다. 나머지는 타임스탬프·색 태그·오디오 오프셋·원자성 — 결과물을 재생기에 넣었을 때 "뭔가 이상한데"를 만드는 것들이다. 영상 처리 코드를 짤 때 무엇을 체크리스트로 삼아야 하는지의 실물 예시.

설계 축 ④ — 메타데이터 제거는 "픽셀을 건드리지 않는다"

포맷AI 표식 위치제거 방식
JPEGEXIF·XMP·C2PA인코딩된 스캔 데이터를 그대로 두고 헤더만 수술 (재압축 = 화질 손실이므로)
MP4 / MOVmoov.udta.meta의 중국 TC260 AIGC 태그박스 크기·미디어 오프셋을 바꾸지 않고 값만 공백 처리. moov가 뒤에 있는 파일, Doubao iOS 익스포트의 변종 형태까지 대응
MKV / WebMSegment.Tags.Tag.SimpleTag스트림 복사로 리먹스
AVILIST/INFO/AIGC스트림 복사로 리먹스
FLVscript.onMetaData.AIGC스트림 복사로 리먹스

이걸 위해 저장소가 컨테이너 파서를 직접 갖고 있다_internal/isobmff.py(MP4), ebml.py(MKV), riff.py(AVI), flv.py. 바이너리 포맷 파싱 학습 자료로 이 네 파일이 통째로 쓸 만하다.

덤: 두 개의 이색 모듈

모듈하는 일왜 흥미로운가
pixel_evidence.py이미지 1장에서 6계열 통계 추출 — DCT 계수 + 벤포드 법칙 이탈, FFT 방사 대역 + CFA 주기성(카메라 디모자이킹 흔적), 노이즈 첨도, ELA, 그래디언트, 색 히스토그램제거가 아니라 포렌식 쪽. "이 사진 카메라로 찍힌 게 맞나"를 통계로 재는 교과서
humanizer.py결과물에 필름 그레인·색수차를 넣고 언샤프 마스크로 선명도 회복확산 재생성이 남기는 "지나치게 매끈한 표면" 자체가 AI 티라는 관찰에서 나온 후처리
프라이버시 주의 · 저자 본인이 코드에 적어 둔 경고
pixel_evidenceartifacts는 통계값이 아니다

DCT 히스토그램 같은 스칼라·고정길이 통계로는 원본을 복원할 수 없다. 그러나 같은 모듈이 함께 뱉는 artifacts(64비트 지각 해시 · 128px 썸네일 · 거친 ELA/노이즈/FFT-위상 맵)는 종류가 다르다 — 썸네일은 그림이고, 지각 해시는 원본을 식별한다. 이걸 수집·저장하는 쪽은 "통계 로그"가 아니라 원본을 특정할 수 있는 기록을 쌓고 있는 것이다.

5디렉토리 구조 해부

"어디부터 열어야 하나"
remove-ai-watermarks/ ├── src/remove_ai_watermarks/ # 53개 파일 · 20,913줄 │ ├── api.py ★ 여기부터 — 3줄짜리 고수준 API의 전부 │ ├── cli.py click 기반 명령 라우팅 │ ├── watermark_registry.py ★ 심장 — 마크 11개의 카탈로그 + 신뢰 사다리 │ ├── identify.py ★ 판별 — "Unknown ≠ clean" 철학이 사는 곳 │ ├── region_eraser.py 채우기 엔진 (cv2 / MI-GAN / LaMa 선택) │ ├── {gemini,doubao,jimeng,qwen,kling,yuanbao, │ │ baidu,liblib,samsung,runninghub,pill}_engine.py # 마크별 탐지기 11종 │ ├── metadata.py · forensic_metadata.py · metadata_record.py │ ├── video.py · video_visible.py · video_invisible.py │ │ · video_encoding.py · video_temporal.py · video_synthid.py │ ├── invisible_engine.py · invisible_watermark.py · dwt_dct.py │ ├── trustmark_detector.py · pixel_evidence.py · humanizer.py │ ├── optional_deps.py is_available() 가드 — 선택 의존성 격리 │ └── _internal/ │ ├── isobmff.py · ebml.py · riff.py · flv.py # 컨테이너 파서 4종 │ ├── c2pa.py 공식 리더가 거부하는 blob용 폴백 파서 │ ├── qwen_zimage_pipeline.py · sdxl_zimage_pipeline.py │ ├── watermark_remover.py · watermark_profiles.py · tiling.py │ └── text_restoration.py 검증된 텍스트만 복원(OCR을 정답으로 안 믿음) ├── docs/ 22개 md — ★ module-internals.md가 정본 │ ├── module-internals.md 모듈별 설계 결정·임계값·보정 이력·사고 기록 │ ├── legal-and-safety.md 범위·법적 경계 (읽고 시작할 것) │ ├── known-limitations.md · supported-signals.md · synthid.md │ └── watermarking-landscape.md 워터마킹 기술 지형 개관 ├── scripts/ 41개 연구용 하네스 (제품 코드 아님) │ ├── video_synthid_sweep.py 후보 생성 — 판정은 비워 둠 │ ├── video_fidelity_probe.py "이 출력이 치른 대가"를 PSNR로 측정 │ └── visible_eval.py · robustness_suite.py · vendor_mark_calibrate.py ... ├── data/ 고정 픽스처 · 보정 데이터 · 오라클 판정 CSV ├── tests/ pytest (병렬, xdist) └── maintain.sh ★ 프로젝트 게이트 한 줄

읽는 순서 추천

순서파일얻는 것
1docs/legal-and-safety.md이 도구가 무엇을 하지 않기로 했는지
2src/.../api.py전체 그림 — 고수준 호출 4개가 뭘 감싸는지
3watermark_registry.py 모듈 독스트링이 문서의 4장이 통째로 여기서 나왔다. 설계 결정과 폐기 사유가 코드 맨 위에 있음
4identify.py"신호 없음"을 어떻게 정직하게 보고하는가
5video_visible.py 독스트링영상 파이프라인이 지키는 불변식 목록
6docs/module-internals.md임계값이 왜 그 숫자인지 (측정 이력 포함)

6학습 포인트

"워터마크에 관심이 없어도 가져갈 것"
배울 것어디서왜 일반적으로 유용한가
탐지와 조치의 분리watermark_registry.pyN개 입력 유형 × 1개 처리 엔진. 유형이 늘어도 처리 코드는 안 늘고, 처리를 개선하면 N개가 동시에 좋아진다
확신 등급으로 임계값 관리resolve_trust"민감도 슬라이더" 대신 증거가 있을 때만 완화. 오탐과 미탐 사이에서 정책을 설명 가능하게 만드는 패턴
선택 의존성 격리optional_deps.py + extras 그래프무거운 ML 패키지를 안 깐 사용자도 기본 기능은 그대로 쓰게. 파이썬 CLI/라이브러리 배포의 정석
바이너리 컨테이너 파싱_internal/{isobmff,ebml,riff,flv}.pyMP4·MKV·AVI·FLV 구조를 코드로 배우는 가장 빠른 길. 각각 200줄 안팎
미디어 파이프라인 불변식video_encoding.py, video_temporal.pyVFR PTS·색 태그·오디오 오프셋·원자적 게시 — 영상 도구가 조용히 망가지는 지점들의 목록
이미지 포렌식 기초pixel_evidence.pyDCT/벤포드·CFA 주기성·ELA·노이즈 첨도. AI 탐지·위변조 탐지 양쪽의 공통 토대
실패를 남기는 문서화모듈 독스트링 전반"이건 안 된다, 왜냐면 측정해 보니 59.8%" — 팀 문서를 이렇게 쓰면 같은 실수가 반복되지 않는다
가장 이식성 높은 한 가지
"없음"과 "깨끗함"을 구분하는 API 설계

identify는 신호를 못 찾으면 Unknown을 낸다. 로컬에서 못 읽는 워터마크(SynthID 픽셀)가 존재하기 때문이다. 탐지기를 만드는 사람이 가장 흔히 저지르는 실수가 "안 걸림 = 무해"로 보고하는 것이고, 보안 스캐너·헬스체크·품질 게이트 어디든 같은 함정이 있다. 반환 타입에 3번째 상태를 넣는 것만으로 하류 코드의 오독을 막는다.

7하드웨어 · 시스템 요구사항

"내 컴퓨터로 어디까지 되나"
하려는 것필요 사양설치
identify · metadata아무 데서나. numpy도 필요 없음remove-ai-watermarks
visible (cv2 채움)CPU만. 수백 MB RAM[visible]
visible (MI-GAN 채움)CPU. 약 700~950MB 피크 RAM · 호출당 ~0.19초. 모델 28MB 최초 1회 다운로드[migan]
visible (big-LaMa 채움)CPU. 약 4.7GB 피크 RAM. 모델 200MB 최초 1회 다운로드[lama]
영상 visibleCPU + 시스템 ffmpeg 필수. 전 프레임 디코드라 길이에 비례[video]
invisible (이미지)NVIDIA CUDA 필수. CPU·MPS·XPU 폴백 없음 — 생성 시점에 거부한다. VRAM 부족 시 --cpu-offload(느려짐)[qwen-zimage]
video invisibleGPU 권장. 512px 긴 변 · 12fps로 재생성되므로 해상도·프레임레이트·디테일이 바뀐다[video,diffusion]
기대치 조정
"안 보이는 워터마크 제거"는 무손실이 아니다

invisible은 이미지를 통째로 다시 생성한다. 얼굴·글자·미세 디테일이 바뀔 수 있고(그래서 SAM 마스크 얼굴 복구 단계가 따로 있다), 영상은 해상도까지 내려간다. 게다가 구글이 공개 SynthID 디코더를 내놓지 않아 로컬에서 "지워졌는지" 검증할 방법이 없다 — 저장소가 noise_std=0.15를 기본으로 삼은 근거도 2026-07-29·07-31에 제공자 검증기로 직접 돌려 본 두 건의 오라클 기록(data/evaluations/video-synthid-oracle.csv)이 전부다. 그 판정은 그 파일들에 대한 결과지 모든 이미지에 대한 보장이 아니다.

8직접 해볼 수 있는 실습 과제

"GPU 없이도 5개 중 4개는 된다"
과제 1난이도 ★☆☆ · GPU 불필요

내 사진첩의 "출처 지도" 만들기

identify를 폴더 전체에 돌려 결과를 CSV로 모은 뒤, C2PA가 있는 파일 / EXIF 생성 파라미터가 있는 파일 / 아무 신호도 없는 파일 비율을 세어 본다.

핵심 관찰: 카톡·인스타를 한 번 거친 파일은 메타데이터가 통째로 날아간다. "AI로 만든 게 확실한데 신호가 0개"인 파일이 나오면, 그게 바로 Unknown ≠ clean이 필요한 이유다.

과제 2난이도 ★☆☆ · GPU 불필요

채움 백엔드 3종 눈으로 비교하기

같은 이미지에 --backend cv2 / migan / lama를 각각 돌려 결과를 나란히 놓는다. 배경이 단색일 때는 셋이 거의 같고, 벽돌·격자·글자 위에서는 확 갈린다. RAM 사용량(/usr/bin/time -v)도 함께 재서 "품질 대 메모리" 표를 직접 만들어 본다.

과제 3난이도 ★★☆ · GPU 불필요

MP4의 AIGC 태그를 손으로 찾아보기

_internal/isobmff.py를 읽고, 스크립트 30줄로 MP4 박스 트리를 출력해 moov → udta → meta → keys/ilst를 직접 걸어 들어간다. 그다음 video metadata --check와 결과를 대조.

얻는 것: MP4 구조를 평생 안 잊는다. 자막·챕터·회전 플래그 문제를 다룰 때 그대로 쓰인다.

과제 4난이도 ★★☆ · GPU 불필요

새 마크 하나를 레지스트리에 추가해 보기 (AI 생성 라벨만)

기존 *_engine.py 하나를 골라 구조를 흉내 내, 임의로 만든 로고를 스스로 합성한 테스트 이미지에서 탐지·제거하도록 등록한다. 기여 규칙상 스톡·마켓플레이스 워터마크는 추가 금지이므로 반드시 자작 라벨로 연습할 것.

진짜 배우는 지점은 탐지가 아니라 오탐 게이트 튜닝이다 — 깨끗한 사진 50장에 돌려서 한 장도 안 건드리는지 확인해 보면, 폐기된 assume_ai가 왜 59.8%를 망쳤는지 몸으로 안다.

과제 5난이도 ★★★ · CUDA 필요

"대가"를 측정하기 — 재생성 전후 화질 비교

scripts/video_fidelity_probe.py의 발상을 이미지에 옮겨, invisible 전후의 PSNR·SSIM·LPIPS를 잰다. 저장소 설계에서 중요한 건 엔진 자체가 보고하는 PSNR은 리사이즈·인코딩 이라 실제 전달된 그림보다 후하다는 점 — 프로브만이 최종 결과를 본다.

일반 교훈: 파이프라인 내부 지표와 최종 산출물 지표를 섞어 보고하면 자기 기만이 된다.

9관련 기술 심화 학습 로드맵

"4주 코스"
주차주제구체적으로
1주차이미지 메타데이터와 출처 표준EXIF·XMP·IPTC 구조 → C2PA / Content Credentials 매니페스트 읽기 → identify.py_internal/c2pa.py 대조. "공식 리더 + 자체 폴백 파서" 이중 구성의 이유를 확인
2주차인페인팅 계보cv2 Telea/Navier-Stokes(고전) → MI-GAN(경량 GAN) → big-LaMa(푸리에 합성곱). 셋의 원리 차이가 실습 과제 2의 결과 차이로 그대로 보인다. ONNX Runtime으로 torch 없이 추론하는 법도 함께
3주차워터마킹 이론docs/watermarking-landscape.mdDWT-DCT(주파수 영역 매립, dwt_dct.py가 구현체) → TrustMark(Adobe, 학습 기반) → SynthID(비공개). "왜 어떤 건 로컬 디코딩이 되고 어떤 건 안 되나"의 답
4주차확산 모델 + 영상 파이프라인latent diffusion / VAE 인코딩–디코딩이 왜 워터마크를 흐리는지 → ControlNet(Canny로 구도 고정) → SAM 세그멘테이션 → PyAV·ffmpeg로 VFR·색공간 다루기
순서에 대한 조언

4주차부터 시작하고 싶겠지만(가장 화려하니까), 1~2주차가 실제로 매일 쓰이는 기술이다. 메타데이터 파싱과 인페인팅은 워터마크와 무관한 프로젝트에서도 계속 나오는 반면, 확산 재생성은 GPU가 있어야 하고 결과도 확률적이다.

10핵심 키워드 사전

"README에서 막히는 단어들"
용어코드 위치
C2PA_internal/c2pa.py콘텐츠 출처를 서명해 파일에 넣는 업계 표준(Content Credentials). 누가·무엇으로 만들었는지가 검증 가능한 형태로 들어감
SynthIDvideo_synthid.py구글의 픽셀 워터마크. 공개 디코더가 없어 로컬 검증 불가 — 이 저장소의 여러 제약이 여기서 나온다
TC260 AIGCisobmff.py중국 표준의 AI 생성 라벨. 이미지뿐 아니라 MP4·MKV·AVI·FLV 메타데이터에도 들어감
localize → fillwatermark_registry.py이 저장소의 핵심 패턴. 마크를 찾아 마스크만 만들고, 채우기는 공용 엔진 하나에 맡김
inpaintingregion_eraser.py지워진 영역을 주변 맥락으로 자연스럽게 메우는 기술
MI-GAN / big-LaMa[migan]·[lama]학습형 인페인팅 모델 둘. 28MB/1GB RAM 대 200MB/4.7GB RAM — 가벼움 대 품질
trust ladderresolve_truststrictconfirmed 2단계. 같은 벤더 증거가 있을 때만 오탐 게이트를 우회
temporal arbitervideo_temporal.py인접 프레임에 같은 위치로 반복돼야 제거를 허가하는 영상 판정자
VFR / PTSvideo_encoding.py가변 프레임레이트와 각 프레임의 표시 시각. 평균 fps로 뭉개면 재생 타이밍이 어긋난다
ControlNet (Canny)qwen_zimage_pipeline.py확산 재생성 시 원본의 윤곽선을 조건으로 줘서 구도가 딴 그림이 되지 않게 잡아 주는 장치
ELApixel_evidence.pyError Level Analysis. 품질 90으로 재저장해 오차를 보는 위변조 탐지 기초 기법
oracle-certifiedREADME · data/evaluations/"제공자의 검증기로 실제로 돌려 봤다"는 뜻. 표본이 특정 파일들이라 일반 보장이 아니다

11참고 링크

"저장소 · 표준 · 배경 기술"