
2026/08/05 0:16
Show HN: 肌の色調を多様化する単純なアルゴリズムと色彩空間
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
このプロジェクトは、デジタルアートおよびキャラクター作成向けに包摂的なツールを促進することを目的とした、簡略化された RGB ベースの色空間を導入します。これは、現在のシステム(絵文字:5 色、メイクアップパレット:約 50 色など)の限界に対処するものです。本モデルは、生物学的要因(メラニンや血流など)、個々のバイアス、健康状態(例:黄疸など)、および異なるディスプレイ環境によって複雑化している人間の肌トンの莫大な複雑性に対する科学的権威を主張するのではなく、実用的で「十分良好な」エンジニアリングの起点を優先します。手法は、手動での RGB データラベリング、主成分分析(PCA)によるデータセットの変換、Desmos 3D、SymPy、matplotlib、scikit-learn などのツールを用いた球面式のフィッティングを含みます。得られたシステムは、PCA 軸から導かれる 3 つの独立した値を利用し、UI を介して調整されます。ここで、可変的な球半径パラメータは色の変化を制御します;具体的には、この半径を小さくすると、すべての肌トーン(深肤色、白人、冷色調、温色調)において一様に変化が減少し、特定のグループを不均衡に排除することはありません。原点点はニュートラルな曖昧なトーンを表し、マッピングバイアスを特定するために有用です。今後の作業では、専門家ラベラーを用いてモデルを微調整し、黄疸や白斑症などの状態に対する簡略化された表現を取り入れる予定です。本アプローチは科学的でないことを認める一方で、エンジニアリング用途においては依然として非常に機能性を備えていることを認識しています。
本文
カスタムカラーピッカーと肌トーン生成アルゴリズム
概要
本プロジェクトでは、JavaScript と Python を用いて、インクルーシブなカラーツールを構築するためのカスタムカラーピッカーとプロシージャル生成アルゴリズムを実装しています。
- 目的: キャラクター作成ツールやデジタルアートなどで多様な肌トーンを表現しやすくする、新しい**「カラースペース」**の定義です。
- アプローチ: 既存の色セット(限定的なパレット)ではなく、現実の人間の皮膚色を可能な限り網羅し、排除しないように設計されています。
- 重要事項: 結果は有用な出発点ですが、絶対的な基準として扱うべきではありません。「十分良好(good enough)」という限界を認識してご活用ください。
問題と背景:肌トーン表現の課題
現状の問題点
人間は単一の色ではないにもかかわらず、多くのツールでは以下の不十分な扱いがされています。
- 絵文字: 5 シェード程度(または黄色っぽいカートゥン調)。
- コスメブランド: 最大でも約 50 シェード。
- キャラクター作成ツール: 「1,677,7216 のオプションから選んでください」といった形式的な対応。
これらは現実の多様性に及びません。「私たちが『何色』なのか?」 という問いに対し、多くの人が適切に表現できない状況があります。
技術的アプローチ
本作業では、以下の手法を用いて肌トーンに対応する広範な色の範囲を特定しました。
- RGB カラースペースでの現実的な簡略化モデルの構築。
- **「十分良好」**で運用可能な単純な方程式の発見(定義と実装)。
限界点と倫理的配慮
この作業には以下の本質的な限界と考慮事項があります。
- 肌トーンの複雑さ: 単一の色ではなく、血液の流れ、メラニン濃度、光の散乱など生物学的要因の影響を強く受けます。また、しみ、傷跡、白斑など個々のバリエーションも存在します。
- 健康状態: アルギリア(銀中毒症)、黄疸(ビリルビン値の上昇)などにより、健康な範囲から外れた肌トーンを示す場合もあります。
- 主観性: 作成者は人間であり、色彩認識やバイアスの影響を受けます。色覚障碍のいない状態でのみ検証しています。
- 表示環境: ディスプレイの種類や照明条件により RGB 値の見え方は一貫しません。
社会的文脈と歴史的背景
技術的な数式だけでなく、以下の社会的背景を理解することが重要です。
- 歴史的偏見: 明るい肌色への称賛と優先に対し、暗い肌色は边缘化されてきました(カラーリズム)。
- 推奨読物: 多様性の課題を扱った作品や記事として以下が挙げられます。
- Nyma Tang: 「The Darkest Shade」(コスメブランドの darkest shade 検証)
- Kat Blaque: Youthforia の黒人向けファンデーション(現実的範囲を超えた色)
- Vox: 「How beauty brands failed women of color」
- Austin Walker: 「Me, On The Screen」(『Animal Crossing』における自己表現の限界)
- Angélica Dass: 『The Humanae』(人種分類ではなく真なる肌の色の文書化)
手法(メソッドロジー)
本プロジェクトでは、完全な科学的手法ではありませんが、「十分良好」な結果を得るために以下のプロセスを実行しました。
1. データセットのラベル付け
- 手法: RGB で手動で色をラベル付けしました。
- UI: Web ページ上でクリックし、画像(顔)の色と一致するか「はい/いいえ」を判定するインタラクティブな UI を作成しました。
- 結果: データは
と(0, 0, 0)
の間でバナナのような曲線形状を描き、赤寄りで青から遠ざかる傾向がありました。(255, 255, 255)
2. 主成分分析(PCA)
- 目的: データセットの形状(歪んだバナナ形)を回転・伸縮させ、座標軸に沿って整理します。
- 効果: 変異の主要な方向が軸に重なるようになり、データを扱いやすくしました。
- 空間の定義: PCA 変換後の空間を**「XYZ スペース」**と呼びます(後述する TUV との対応も含む)。
3. 関数的手工適合
- プロセス: RGB から XYZ への変換を行い、球体($R^2 = t^2 + u^2 + v^2$)をデータ形状に合わせて手動で調整しました。
- $t, u, v$ を定義して形状に合わせる。
- 関係を逆転させて $x, y, z$ で表現する。
- ツール: Desmos 3D を使用し、視覚的に曲線を適合させました(回帰分析は行いません)。
4. アルゴリズム実装
得られた方程式を活用し、以下のコードを実装しています。
コード実装
select_point の出力を to_rgb(t, u, v) に渡すことで、TUV スペースから RGB 値に変換できます。
Python による実装
import math from numpy.random import uniform as unif # 'uniform' はランダムライブラリ(例:numpy.random または random)からインポート済みと仮定 def select_point(r_square: float = 2.) -> tuple[float, float, float]: """単位球から均等にサンプリング(決定論的アプローチ)""" # 半径を計算 radius = r_square ** (1. / 2) # 球面座標系の要素をランダムに生成 phi = unif(0, 2 * math.pi) # 方位角 costheta = unif(-1, 1) # コサインの theta n = unif(0, 1) # ランダムなスケーリング係数 theta = math.acos(costheta) # 極角 r = radius * (n ** (1.0 / 3)) # ボルツマン分布による体積内サンプリング # デカルト座標に変換(TUV スペース) t = r * math.sin(theta) * math.cos(phi) u = r * math.sin(theta) * math.sin(phi) v = r * math.cos(theta) return (t, u, v) def select_point(r_square: float = 2.) -> tuple[float, float, float]: """単位球から均等にサンプリング(拒絶サンプリング法を使用)""" radius = r_square ** (1. / 2) R = radius + 1 # ボックスからランダムに生成し、球体内部にあるか確認する手法 while R > radius: t = unif(-radius, radius) u = unif(-radius, radius) v = unif(-radius, radius) R = (t**2 + u**2 + v**2) ** (1.0 / 2) # 距離の計算 return (t, u, v) def to_rgb(t, u, v) -> tuple[int, int, int]: """TUV スペースから RGB へ変換する方程式""" # TUV から XYZ 座標への変換(簡略化されたモデル) x = (t - 0.15) / 0.45 y = (v - 1.2 * t ** 2 + 0.2 * t + 0.655) / 1.84 z = u / 3.6 # XYZ から RGB への変換行列の適用 r = 28.77438370854 * x + 36.78307445559 * y - 19.69766918644 * z + 187.1436241611 g = 35.38327306318 * x - 2.009931981182 * y + 47.93462563172 * z + 137.1073825503 b = 36.14733717939 * x - 43.54346996173 * y - 28.50821294135 * z + 108.2241610738 return int(round(r)), int(round(g)), int(round(b))
JavaScript による実装(ページソース内にあるバージョンの概要)
Python と同様のロジックが、ブラウザ環境で動作する JS として提供されています。
ピッカーユーザーインターフェース(UI)
通常のカラーピッカーのように独立した 3 つの値を調整する仕組みを持っています。これらは TUV スペースに対応します。
| コントロール | アスペクト / 意味合い | 変数名 |
|---|---|---|
| 垂直スライダー (上下) | Deep(深みのある) ⇔ Fair(明るい) | T |
| 水平スライダー A (左右) | Flushed(赤らんだ) ⇔ Ochre(黄褐色) | U |
| 水平スライダー B (左右) | Cool(寒色系) ⇔ Warm(暖色系) | V |
軸の意味と特性
- PCA の成果: これらの軸は、主成分分析によってデータの変異を最大化した結果であり、単一の色空間の直感とは異なります。
- HSL/HSV との違い: 類似していますが完全一致しません。特に
は彩度とは異なる性質を持ちます(青からオレンジへのスペクトル)。V
R² の調整と半径の意味
生成アルゴリズムで使用する球体の半径(
R)は、生成される肌トーンの「範囲」を制御するパラメータです。
- 定義: 球体 $R^2 = t^2 + u^2 + v^2$ の半径の二乗値です。
- 特性:
- 半径を変えると、深みのある色から明るい色まで均等に多様性が減少・増加します(特定のトーンを除外するわけではありません)。
で原点を確認し、空間のマッピングバイアスを検出できます。R² = 0
おすすめの R² 値表
| R² 値 | 特徴と用途 |
|---|---|
| 0.1 | ほとんど変化がない |
| 0.5 | 軽微な変化(限定的) |
| 1.0 | ランダム選択時に適切な多様性を確保する最小値 |
| 1.5 | リアリズムを保ちつつ良い多様性(推奨範囲) |
| 2.0 | カートゥンチックになり得る(ランダム選択では稀な外れ値が発生) |
| 2.5 | 予期しない値が出ることがあるが、ピッカー UI では有用 |
| 10 | 想像の舞台設定向け(極めて広範囲) |
- 調整のコツ: 非現実的な結果を生成した場合は、半径を少し減らすだけでバリエーションの減少を抑えつつ制御できます。
まとめと次のステップ
成果物
- カスタムカラーピッカーの UI とロジック。
- プロシージャルな肌トーン生成アルゴリズム(TUV → RGB 変換)。
- デジタルアートやゲーム開発で多様性を表現するための新しい基盤。
フィードバックと改善案
このプロジェクトは「十分良好」を目標としていますが、以下のような方向性での拡張が可能です。
- データセットの洗練: 複数の人による手動ラベル付けにより、現在の主観的なバイアスを補正する。
- 肌の変異と状態: 黄疸やアルギリアなど、病態的な色の変化をモデル化する簡易手法の開発。
- 形式化の向上: 象徴的リグレッションを用いて方程式を最適化し、計算効率を高める。
- 他空間への展開: 他のカラースペース(LAB, YUV など)での表現を検討する。
コミュニケーション
- ご意見やご質問は、プロジェクトのリポジトリの Issues ページ に投稿いただくか、メールにてご連絡ください。
- 再現性のあるコードを整理して公開し、皆様もこの作業に貢献できる場を目指しています。
使用ツール: matplotlib, scikit-learn, Desmos, SymPy