Community이미지github.com

naokuotong-1/photo-color-grader

사진의 색상을 보정하는 기술로, '조정 스타일'을 재사용 가능한 3D LUT으로 변환하고 일괄 적용합니다. 하늘/인물/식생 등 의미론적 영역 분할, 배치 자동 병합 및 취소, 피사체 자동 인식 및 스타일 선택, 참조 이미지 없이도 클래식 장면 통계를 통한 자체 검사, 로그(log) 미변환 소재 식별 등이 가능합니다. 픽셀 단위 색상 매핑만 수행하며 내용 재구성, 기하학적 변경 없이 고충실도 사진 전달에 적합합니다.

photo-color-grader란 무엇인가요?

이 AI 에이전트 스킬은 사진의 색상 그레이딩을 위한 전문 도구입니다. 주요 기능은 '조정 스타일'을 3D LUT 파일로 변환하고 일괄 적용하는 것으로, Claude Code, Cursor, Codex 등 다양한 플랫폼에서 사용할 수 있습니다. 핵심은 픽셀 단위 색상 매핑만 수행한다는 점으로, 내용 변경이나 기하학적 왜곡 없이 높은 충실도를 유지합니다. 하늘, 인물, 식생, 물, 지면, 건축물 등 6가지 의미론적 영역으로 이미지를 분할하여 각 영역에 독립적인 LUT를 적용할 수 있어, 예를 들어 '하늘만 어둡게 하고 지면과 얼굴은 그대로'와 같은 세밀한 조정이 가능합니다. 스타일은 기준 이미지 쌍을 학습(fit)하여 정밀하게 생성하거나(ΔE2000 0.55–0.9), 단일 참조 이미지에서 빠르게 추정(ref)하여 생성(ΔE2000 약 4)할 수 있습니다. 배치 제출 시 자동으로 기존 스타일과 유사도를 비교하여 병합하거나 새 스타일을 생성하며, 각 'fit'은 Git 커밋처럼 기록되어 언제든지 특정 배치를 취소(undo)할 수 있습니다. 또한 참조 이미지 없이도 장면 통계를 기반으로 이미지 품질(명도, 대비, 색상 편향 등)을 자체 점검하고, 로그(Log) 소재를 식별하는 기능을 제공합니다. JPEG 재압축 방지, ICC 프로필 유지, RAW 파일 처리 등 전문 사진가의 요구사항을 충족하며, 최종 결과물의 수학적 무결성(SSIM=1.0)과 시각적 일관성(과다 노출 보호, 모노토닉 위반 제거)을 보장합니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/naokuotong-1/photo-color-grader/tree/HEAD

Installed? Explore more 이미지 skills: steipete/songsee, affaan-m/frontend-design, mattpocock/improve-codebase-architecture · View all 6 →

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

사진 보정 색상 그레이딩

사용 시기

  • 사용자가 참조 이미지와 보정할 사진을 주며 '이 사진의 색조를 따라 해주세요'라고 요청할 때
  • 사용자가 이미 보정된 사진 모음을 가지고 있으며, 그 스타일을 고정하여 새로 찍은 사진에 적용하려 할 때
  • 사용자가 '하늘만 어둡게, 지면과 얼굴은 건드리지 마세요'와 같은 영역별 조정을 원할 때
  • 사용자가 특정 Look을 일괄 적용하면서 '내용을 변경하지 말고, 다시 그리지 마세요'라고 요구할 때
  • 사용자가 특정 스타일의 충실도를 확인하려 할 때(계조 끊김, 색상 편향, 하이라이트/섀도우 압축 여부)
  • 사용자가 사진 한 장을 주며 '이 사진 보정이 맞나요?', '어디가 문제인가요?'라고 물을 때, 참조 이미지 없음
  • 사용자가 제공한 소재가 log / 미변환(카메라 raw에서 추출한 S-Log3, V-Log, HLG 프레임)일 때
  • 사용자가 생성형 보정이 '사람 얼굴을 바꿨어요', '해상도가 떨어졌어요'라고 불평할 때 — 이러한 요구가 바로 이 스킬의 사용 사례입니다

적용 불가: 광원 방향 변경, 하늘 교체, 객체 추가, 의미론적 재구성 작업. 이 스킬은 색상 매핑만 출력하며 내용 수정은 불가능합니다.

핵심 모델

  1. '스타일' = 기본 .cube + 선택적 영역 .cube (각 영역별 하나) + 버전 기록 + 배치 아카이브 + 피사체 태그로 구성되며 color-styles/<name>/에 저장됩니다.
  2. 스타일 적용 = 픽셀 단위 LUT 조회 후, 의미론적 마스크를 사용하여 영역 LUT를 오버레이합니다. 출력물은 원본 이미지와 완전히 동일한 크기이며, 구조적 SSIM은 항상 1.0입니다.
  3. 스타일 생성 방식은 두 가지입니다:
    • fit: '원본 / 보정 후' 이미지 쌍을 학습하여 정밀 생성 (실측 ΔE2000 0.55–0.9), 3쌍 이상 필요
    • ref: 참조 이미지의 통계를 전이하여 빠르지만 대략적 생성 (실측 ΔE2000 ≈ 4), 단일 이미지로 가능, 콜드 스타트에 적합
  4. 매 fit은 '커밋'이며 자동으로 병합됩니다: 어떤 스타일에 속하는지 판단 → 해당 스타일에 병합 시 모든 과거 샘플로 재피팅 → 아카이브 → 피사체 태그 지정. 모델 학습 불필요, GPU 불필요

영역 분할이 해결하는 문제

전역 LUT는 '이 색상을 무엇으로 매핑할까'라는 질문에만 답할 수 있습니다. 동일한 색상이 다른 영역에서 다른 결과로 기대될 때 — 가장 전형적인 예는 회색빛 하늘은 어둡게, 같은 회색빛 도로는 그대로 유지 — 전역 매핑은 수학적으로 해가 없으며, 최소 제곱법은 중간값만 취해 양쪽 모두를 만족시키지 못합니다.

실측 (흐린 거리 풍경, 하늘만 −28% 어둡게):

하늘 ΔE2000비-하늘 ΔE2000
전역 LUT11.270.322
전역 + sky 영역1.500.324

비-하늘 오차가 완전히 동일하다는 것은 영역 분할이 추가 오염을 유발하지 않으며, 단지 '학습할 수 없었던 부분'만 보완했음을 의미합니다.

영역 차원: sky / people / veg / water / ground / arch, 기본값 sky,people,veg, 내장 SegFormer-B0 (4.4 MB)이 소프트 마스크를 제공합니다.

워크플로우

1. 의존성 확인

python -c "import numpy, PIL; print('ok')"
python -c "import onnxruntime; print('seg ok')"   # 영역 분할과 피사체 태그에 필요
python -c "import tifffile; print('tif ok')"      # 16bit TIFF 읽기/쓰기에 필요
python -c "import rawpy; print('raw ok')"         # RAW 직접 읽기에 필요, 선택 사항

누락 시 python -m pip install numpy pillow onnxruntime tifffile rawpy 실행. onnxruntime이 없어도 중단되지 않으며, 순수 전역 색상 보정으로 폴백됩니다.

2. 먼저 소재 확인 (권장, 헛수고 방지)

python <SKILL_DIR>/scripts/grade.py check --in ./photos/original --person

참조 이미지가 필요 없으며, 두 가지 질문에 답합니다:

  • 이것은 어떤 소재인가: transfer.verdict = display / ambiguous / log. log 소재를 직접 fit하면 log 커브 자체가 LUT에 학습되어 화면에서는 적절해 보이지만 잘못된 결과를 냅니다. --person은 분할을 한 번 실행하여 피부색 색상이 의미를 가지도록 합니다 (인물 없을 시 판단 안 함).
  • 최종 결과물에 문제가 있는가: 중간 명도, 블랙 레벨, 데드 화이트/블랙 비율, 색상 편향 단계, 색상 풍부도. 범위를 벗어나면 warnings에 포함됩니다.

apply와 fit 모두 내부적으로 이 두 항목을 자동 실행하므로, 일괄 전달 전에 한 번만 수행하면 됩니다.

3. 소재 배치 제출 (핵심 작업)

python <SKILL_DIR>/scripts/grade.py fit \
  --src ./photos/original --tgt ./photos/retouched
  • --src / --tgt는 파일 이름 기준으로 쌍을 구성합니다. --pair 원본 보정후를 사용하여 단일 쌍을 반복 지정할 수도 있습니다.
  • 디렉토리에 다른 크기의 사진이 섞여 있어도 문제없지만, 각 쌍 내부에서는 크기가 동일해야 합니다.
  • --name을 지정하지 않으면 자동 모드: 기존 스타일과 거리를 비교하여 충분히 가까우면 병합, 그렇지 않으면 새로 생성합니다.
  • --name warm_film은 명시적 지정: 이름이 이미 존재하면 병합, 존재하지 않으면 새로 생성합니다.
  • --regions sky,people,veg는 영역 분할을 활성화합니다 (기본값). --regions ""를 쓰면 순수 전역으로 폴백됩니다.
  • --auto-threshold 1.5는 '같은 스타일'로 판단하는 ΔE 임계값입니다.

4. 적용

python <SKILL_DIR>/scripts/grade.py apply \
  --style warm_film --in ./photos/new --out ./out --strength 1.0

--style auto는 먼저 입력 사진의 피사체를 식별한 후, 태그가 가장 잘 일치하는 스타일을 선택합니다 (결과는 auto 필드에 선택 이유와 함께 표시됩니다).

look과 warnings를 확인한 후 전달하세요. look.median_luma가 [0.195, 0.302]에서 [0.55, 0.95]로 변경되었다면, 이는 이 사진이 스타일이 학습한 소재보다 훨씬 밝아서 하이라이트가 뚫렸다는 의미입니다. 이 경우 세 가지 방법만 있습니다 — --strength 0.7로 강도 줄이기, --match-key on으로 먼저 노출을 스타일이 학습한 수준에 맞추기 (동일한 조명 조건의 연사에만 적합), 또는 배경이 밝아지는 것을 받아들이기. 사용자 대신 선택하지 마십시오.

--match-key off|on|auto (기본값 off): 먼저 화면의 중간 명도를 스타일이 학습한 수준에 맞춘 후 LUT를 적용합니다. 역광 사진의 경우 피사체에 역효과를 줄 수 있습니다. '충실도 경계선' 14번 항목 참조.

출력 형식과 화질

기본적으로 매번 두 개의 파일을 생성합니다. 첫 번째 파일만 보내지 마십시오:

산출물기본값용도
<이름>__<스타일>_v<N>.jpgq98, 4:4:4, 원본 ICC/EXIF/DPI 유지전달, 공유, SNS 게시
<이름>__<스타일>_v<N>__master.png8bit 무손실, ±0.5 LSB 디더링 포함추가 수정, 확대, 인쇄용
  • --quality 98: JPEG 품질. q95→q98 실측 PSNR 48.7→50.6 dB, 용량 337→512 KB. q92로 낮추면 용량 절반, 3 dB 손실, 그라데이션 하늘에서 눈에 띕니다.
  • --master png|tif|none: tif는 16bit (tifffile 필요, 설치 불가 시 8bit PNG로 자동 다운그레이드되며 master_note에 기록, 기존 JPG는 손상되지 않음). 일괄 출력 시 공간 차지가 부담되면 --master none 사용.
  • 원본 파일이 이미 .png/.tif/.bmp인 경우 마스터를 생성하지 않습니다 — 주요 출력물이 이미 무손실입니다.
  • ICC, EXIF, DPI는 원본에서 그대로 전달됩니다. ICC를 잃어버리는 것이 '화질 저하'처럼 보이는 가장 큰 원인입니다: P3/AdobeRGB 이미지에 ICC 태그가 없으면 모든 뷰어가 sRGB로 해석하여 색상이 즉시 흐릿하고 답답해집니다.
  • 디더링은 무손실 형식에서만 활성화됩니다. JPEG의 양자화 오차는 이미 1 LSB보다 한 자릿수 크므로, JPEG에 디더링을 적용하는 것은 대역폭 낭비입니다.

사용자가 '압축됐어요'라고 말하면, 먼저 원본을 확인하고 매개변수를 조정하지 마십시오. apply는 source_note에 이를 표시합니다: 원본 JPEG가 0.10 바이트/픽셀 미만인 경우, 이는 채팅 앱을 통해 전송된 복사본(1080p에서 100 KB 정도)이며, 이 단계 전에 세부 사항이 이미 손실된 것입니다. 출력이 아무리 무손실이어도 복구할 수 없습니다. 또한 두 가지 일반적인 오해 — 채팅 창의 미리보기 이미지로 화질 판단 (플랫폼이 다시 압축함) 및 final_sheet.jpg와 같은 합성보드 미리보기로 판단 (절반 크기로 축소됨) — 에 주의하십시오.

5. 검증

python <SKILL_DIR>/scripts/grade.py verify \
  --style warm_film --src ./photos/original/a.jpg --tgt ./photos/retouched/a.jpg \
  --threshold 2.0

--threshold와 함께 사용하면, 임계값을 초과할 경우 종료 코드 2로 종료되어 파이프라인 게이트 역할을 합니다.

6. 다른 사람에게 내보내기

python <SKILL_DIR>/scripts/grade.py export --style warm_film --out ./for_lightroom --full

--full은 추가로 연결 설명서를 작성합니다 (기본 레이어가 전체 이미지를 덮고 → 영역 레이어가 소프트 마스크로 오버레이 → 1~2% 프레임 페더링). 영역 스타일은 단일 .cube 파일로만 제공할 수 없습니다: 단일 3D LUT는 픽셀 색상의 함수이며 '동일한 색상이 다른 영역에서 다르게 처리됨'을 표현할 수 없습니다.

7. 취소 및 추적

python <SKILL_DIR>/scripts/grade.py batches --style warm_film      # 이 스타일이 어떤 배치로 구성되었는지 확인
python <SKILL_DIR>/scripts/grade.py undo --style warm_film --batch b20261108_101500
python <SKILL_DIR>/scripts/grade.py styles                          # 전체 스타일 + 태그 + 한 줄 설명
python <SKILL_DIR>/scripts/grade.py styles --name warm_film         # 단일 스타일의 전체 manifest

undo는 버전을 삭제하는 것이 아닙니다: 해당 배치를 구성에서 제거하고, 나머지 배치로 재피팅하여 새 버전을 생성합니다. 이전 버전은 영구 보존됩니다.

출력 판독

모든 명령은 stdout에 JSON을 출력합니다.

필드의미판단
quality.dE2000_mean학습 쌍의 평균 색차 (영역 포함)< 2 사용 가능; 2–4 간신히; > 4는 쌍이 순수 색상 관계가 아님을 의미
decision이번 제출이 어떻게 처리되었는지create-new / merge-nearest / merge-into-named
auto.distance가장 가까운 스타일과의 거리임계값보다 훨씬 작은데 새로 생성되었거나, 임계값보다 훨씬 큰데 병합되었다면 판단 오류
auto.nearest가장 가까운 세 가지 스타일과 거리'왜 이렇게 판단했는지' 확인용
learned_from병합 시 사용된 과거 샘플 수new_samples만 있고 archived가 없으면 최초 병합
diagnostics.coverage_pctLUT 그리드 포인트가 데이터로 덮인 비율30–50% 정상 (자연 이미지는 색 공간의 일부만 차지)
diagnostics.lut_clipped_pct_observed데이터가 있는 영역에서 0/1로 압축된 비율> 2%는 하이라이트/섀도우 손실 가능성 경고
regions.active실제로 적용된 영역비어 있으면 이 배치에서 해당 영역이 나타나지 않았음을 의미
region_diagnostics.<r>.skipped영역이 건너뛰어진 이유too few pixels 정상; no residual learned는 해당 영역이 전역과 동일하게 동작함을 의미
description.summary한 줄 스타일 설명사용자에게 보여주기 위한 것으로, 직접 전달
description.region_extra각 영역이 전역에 비해 추가로 수행한 작업영역이 있을 때만 표시
tags자동 판단된 피사체portrait / landscape / street / indoor / night
diagnostics.prior_shrink사전 강도, 1.0은 완전 채택각 피팅 시 1.0 / 0.5 / 0.2 / 0.05 중에서 실측 최적값을 선택, prior_trials는 각각의 dE 제공
health.monotonic_violations단조성 위반 횟수기본적으로 강제 0으로 설정됨; --no-monotonic을 사용하여 끌 때만 나타남
fit_quality.geometry_preserved기하학적 구조 유지 여부반드시 true여야 함
key_match.applied이 이미지의 노출을 스타일에 맞추었는지 여부기본값 off; 켜면 stops, gamma, 조정된 중간값 제공
transfer.verdict소재가 디스플레이 기준, log, 또는 불확실한지log는 먼저 색 공간 변환 후 fit; ambiguous는 사용자에게 출처 확인 요청
warnings[].metric / .note무참조 자체 검사에서 발견된 문제note 원문을 사용자에게 전달; 빈 배열은 문제 없음
look[원본, 결과]의 중간 명도 / 데드 화이트 비율 / 채도'이 스타일이 이 이미지에 무엇을 했는지' 질문에 답변하는 데 사용
input_guardfit 시 원본이 디스플레이 기준 인코딩이 아님blocking: false, 단지 알림, 차단하지 않음
input_transferapply 시 입력에 display가 아닌 이미지가 섞임파일별로 verdict 제공, 상동

충실도 경계선

  1. RAW는 근사 디코딩입니다. libraw는 카메라 화이트 밸런스 + 일반 색상 매트릭스를 사용하며, 카메라 DCP를 사용하지 않습니다. 동일한 스타일을 다른 바디에 적용하면 색상이 달라지며, Lightroom의 렌더링 결과도 아닙니다. 정확한 전달을 위해서는 사용자가 16bit TIFF를 내보내도록 하십시오.
  2. LUT 앵커 공간은 sRGB gamma 2.2입니다. .cube를 내보낼 때 상대방에게 이를 명시해야 합니다. 그렇지 않으면 상대방이 잘못된 공간에서 LUT를 적용하여 색상이 완전히 틀어집니다.
  3. 영역 스타일은 단일 .cube로 표현될 수 없습니다. vN.cube는 전역 기본 레이어일 뿐입니다. 영역 매핑은 vN_<region>.cube에 있으며 마스크와의 협력이 필요합니다. 내보내기 시 export --full을 사용하면 영역 레이어와 연결 설명서가 함께 제공됩니다.
  4. 과다 노출 픽셀은 원본 그대로 통과시킵니다. 렌더링 마지막에 가장 밝은 채널이 ≥0.97인 픽셀에 대해 원본 이미지로 소프트 전환됩니다: 과다 노출 영역에는 색상 정보가 없으며, 어떤 매핑도 발명에 불과합니다. 역광 태양 디스크는 영역 블록에 의해 회색-파란색 얼룩으로 압축될 수 있지만, 보호 기능을 추가하면 따뜻한 흰색 광원으로 복원됩니다. 대가는 가장 밝은 고채도 하이라이트가 더 이상 재매핑되지 않는다는 것입니다 (색상 차트 실측 학습 ΔE 1.15→1.21). 과다 노출 영역까지 함께 압축해야 하는 경우 --no-clip-guard를 사용하십시오.
  5. 소프트 마스크 경계에는 전이 영역이 있습니다, 이는 의도된 것입니다: 두 개의 다른 매핑이 직접 충돌하면 가시적인 윤곽이 생성됩니다. 대가는 하늘과 나무 꼭대기 경계에 수십 픽셀의 '반-매핑' 영역이 있을 수 있다는 것입니다.
  6. 마스크 해상도는 128×128에 불과합니다. 프레임의 약 1/128보다 미세한 구조 (마른 가지, 전선, 가는 난간)는 해당 영역에 포함됩니다. 이러한 구조는 일반적으로 실루엣에 가까워 어둡게 처리되면 눈에 띄지 않습니다. 픽셀 수준의 정확도가 필요하면 외부 마스크 도구를 사용하십시오.
  7. 신뢰도가 낮은 영역은 조정하지 않습니다. 역광으로 과다 노출되어 색상이 없는 하늘, 나뭇잎에 의해 조각난 하늘 등은 모델이 신뢰할 수 있는 마스크를 제공할 수 없으며, 해당 부분은 전역 LUT로 폴백됩니다. 적게 조정하는 것이 잘못 조정하는 것보다 낫습니다.
  8. 동물 클로즈업이 인물로 인식될 수 있습니다. ADE20K는 고양이 클로즈업을 person으로 판단할 수 있습니다 (실측으로 화면의 88% 차지). 이 스킬은 'person 영역 내 피부색 비율'을 기준으로 하여 5% 미만이면 0으로 초기화하는 안전장치가 있습니다. 극단적인 밝은 색상의 애완동물은 여전히 누출될 수 있습니다.
  9. ref 모드를 '정밀 복제'로 홍보하지 마십시오. Lab 분포만 정렬하며, 실측 ΔE는 약 4입니다. 정밀함이 필요하면 반드시 fit을 사용해야 합니다.
  10. 설명 레이어의 슬라이더 숫자는 추정치입니다. measured 열은 직접 재현 가능하지만, estimate_lightroom은 그렇지 않습니다 — LUT에서 슬라이더로 가는 유일한 해는 없습니다.
  11. 무참조 자체 검사는 '명백한 오류'만 발견할 수 있으며, '예쁜지 여부'는 판단할 수 없습니다. 이는 클래식 통계 목표(중간 명도 0.45, 블랙 레벨 0.02, 피부색 20°)를 사용하지만, 야간 촬영은 원래 낮은 중간 명도를 가져야 하고, 일몰은 원래 따뜻해야 하므로 각 항목에 허용 범위가 있습니다. 경고의 의미는 '한 번 확인하라'는 것이지 '틀렸다'는 것이 아닙니다. 두 가지 엄격한 제한: 피부색은 분할에서 사람이 감지된 경우에만 판단하며, 그렇지 않으면 따뜻한 거리 풍경이 화면의 30%를 피부로 오판할 수 있습니다. 화이트 밸런스는 화면에 충분한 중성 픽셀이 있는 경우에만 판단합니다.
  12. log 판별은 메타데이터가 아닌 히스토그램 모양을 봅니다. 이미지가 이 단계에 도달하면 일반적으로 PNG 또는 libraw의 렌더링 결과이며, EXIF는 이미 손실되었습니다. 따라서 블랙 레벨 상승 / 하이라이트 움츠림 / 좁은 동적 범위 / 낮은 채도를 통계로 집계하여 세 가지 이상이 일치하면 log, 두 가지는 ambiguous로 판단합니다. 압축된 퇴색 스타일의 최종 결과물이 ambiguous로 보고될 수 있으며, 이는 알려진 거짓 양성 방향입니다.
  13. 스타일은 노출 속성을 가지고 있으며, LUT는 학습된 명암 범위 내에서만 신뢰할 수 있습니다. 중간값을 0.19에서 0.28로 올리는 look을 중간값 0.55인 이미지에 적용하면 중간값이 0.95로 치솟습니다 — 이는 버그가 아니라 look 자체에 충분한 하이라이트 여유가 없기 때문입니다. 실측: 피팅은 원본 이미지의 0~0.42 범위만 관찰했습니다 (원본 p99 0.42 / 목표 p99 0.56). p99 0.72인 이미지에 적용하면 초과 부분은 선형 외삽에 의존하며, 이는 하이라이트를 뚫는 것과 같습니다.
  14. 사용자 대신 '노출을 맞추지' 마십시오. --match-key는 먼저 화면의 중간값을 스타일이 학습한 수준으로 당긴 후 LUT를 적용할 수 있지만, 역광 이미지의 경우 역효과가 납니다: 실제 촬영에서 역광 인물 사진 (얼굴 0.27, 배경 0.62)을 전체 화면 중간값에 맞추면 얼굴이 0.08로 압축되어 피사체가 완전히 검게 변합니다. 따라서 기본값은 off이며, '동일한 카메라 위치와 조명 조건의 연사에서 노출이 일치하지 않을 때'만 켜야 합니다. 판단 기준은 간단합니다: 이 사진에서 피사체 밝기와 배경 밝기의 관계가 참조 사진과 일치하는지 여부입니다.
  15. 한 프레임에서 피사체가 배경보다 어둡고 참조 프레임에서 피사체가 가장 밝은 경우, 어떤 전역 단조 매핑도 양쪽을 모두 만족시킬 수 없습니다. 둘 다 만족시키려면 로컬 조정만 가능합니다. 이 경우 피사체를 우선시하고 배경이 밝아지는 것을 받아들입니다. 반대로 배경을 우선시하면 얼굴이 압축됩니다.
  16. 소재의 기존 따뜻한 편향이 따뜻한 스타일과 중첩되어 주황-빨간색이 될 수 있습니다. 이미 0.46 스톱 따뜻한 어두운 인물 사진에 따뜻한 look을 적용하면 얼굴이 따뜻한 갈색에서 주황-빨간색으로 변하고, cast가 0.77까지 치솟으며 뺨에 얼룩덜룩한 느낌이 나타납니다. 이때 먼저 화이트 밸런스를 중화하지 마십시오 — 화면에서 유일한 '중성색'은 종종 동일한 조명으로 비춰진 벽이며, 이를 기준으로 보정하면 벽이 녹색으로, 피부색이 황록색으로 밀려납니다 (실측으로 0.5/0.75 두 단계 모두 더 나빠짐). 올바른 순서는: 먼저 --strength를 낮추고 (0.6 근처), 여전히 만족스럽지 않으면 컬러 그레이딩을 포기하고 순수 휘도 커브 또는 선형 노출 게인으로 전환합니다 — 명암만 변경하고 색상은 건드리지 않으며, 따뜻한 느낌은 그대로 유지합니다.
  17. JPEG는 저장할 때마다 정보가 손실되며 되돌릴 수 없습니다. 전달은 q98로 한 번에 완료합니다. 추가 수정이 필요하면 __master.png에서 수정하고, 이미 저장된 JPG에 반복해서 저장하지 마십시오. 동일한 LUT를 q95로 세 번 저장하면 PSNR이 48.7에서 48.6으로 떨어져 얼마 차이 나지 않지만, 매번 부드러운 그라데이션 (밝아진 하늘, 배경 흐림)에 블록 계단이 쌓입니다. 손실의 원인을 판단할 때: 원본이 먼저 압축되었는지 (<0.10 바이트/픽셀) 확인하고, 인코딩 매개변수에서 원인을 찾지 마십시오.

성능 기준

시나리오10.8 MP 이미지 소요 시간
순수 전역 렌더링3.6 초
영역 렌더링 (2개 영역 활성)6.7 초
분할 추론 (512px) + 업샘플링0.7 초
한 번의 fit (10쌍 이미지, 영역 및 태깅 포함)약 12 초

병목 현상은 알고리즘 분기가 아닌 픽셀 단위 LUT 수집 (픽셀당 8회 랜덤 읽기)에 있습니다. 일괄 처리 시 다중 프로세스를 사용하여 이미지별로 병렬화하는 것이 가장 효율적입니다.

일반적인 작업

사용자 말투수행 방법
'이 사진 색조로 내 사진 모음을 맞춰줘'ref로 스타일 생성 → apply 일괄 적용
'이 사진들은 보정된 거야. 앞으로는 이 스타일로 해줘'fit --src 원본 --tgt 보정후 → apply
'또 보정한 모음이 있어. 이것도 이 스타일로 해줘'fit 시 --name으로 같은 스타일 지정, 자동 병합 및 재피팅
'하늘만 어둡게 하고, 지면과 얼굴은 건드리지 마'기본적으로 영역 분할 활성화; regions.active에 sky 포함 확인
'이 스타일이 너무 진해'apply --strength 0.6, 재피팅 불필요
'이 버전은 저번 버전보다 못해'apply --version <이전 버전 번호>
'지난 배치가 잘못됐어, 취소해줘'batches로 batch_id 찾기 → undo
'이 사진들에 어떤 스타일을 써야 할까'apply --style auto, auto.ranking 확인
'이 스타일이 정확히 무엇을 조정한 거야'styles --name X, description.summary 읽기
'다빈치 리졸브용으로 내보내줘'export --full; sRGB gamma 2.2 앵커링, 영역 레이어에는 소프트 마스크 필요함을 상기
'역광/일출 사진인데, 태양이 회색으로 변하지 않게 해줘'기본적으로 적용됨 (과다 노출 보호); 여전히 회색이면 태양이 실제로 과다 노출되었는지 확인
'이 사진 보정이 맞는지, 문제가 뭔지 알려줘'check --in X --person, warnings를 항목별로 전달하고, 스스로 판단을 추가하지 마세요
'이게 log 소재인가요?'check --in X, transfer.verdict와 transfer.signals 확인
'이 스타일을 적용하면 하이라이트가 타버릴까요?'apply의 look이 전/후 비교를 제공하고, warnings가 직접 지적함
'이 사진이 참조보다 훨씬 밝아서 적용하니 하얗게 됐어요'먼저 look.median_luma 차이 확인; --strength 줄이기, 또는 동일 조명 연사는 --match-key on 사용
'피사체가 배경보다 어두운데, 적용하니 피사체가 검게 됐어요'--match-key를 켜지 마세요; 이는 참조 사진과 이 사진의 광비(light ratio)가 다르기 때문이며, 로컬 조정만 가능
'이 사진 자체가 따뜻한데, 적용하니 얼굴이 주황색이 됐어요'--strength를 0.6으로 먼저 낮춰보세요; 화이트 밸런스를 중화하지 마세요 (벽이 녹색으로 밀려남), 경계선 16번 참조

참고

  • references/style-schema.md: 스타일 디렉토리, style.json 필드, 버전 및 배치 의미론
  • references/color-pipeline.md: 색상 관리, 알고리즘 세부 사항, 알려진 한계 및 매개변수 조정 제안

관련 스킬