1

Monotouch でこれが可能かどうかわからないので、専門家に聞いてみようと思いました。塗装された壁の写真を撮り、そこから全体的な色を認識できるようにしたいとしましょう。C#/Monotouch でそれを行うにはどうすればよいでしょうか。

画像をキャプチャして画像処理を行う必要があることはわかっていますが、そのダイナミクスについてもっと興味があります。光の状態を気にする必要はありますか?フラッシュが私のイメージを「洗い流す」と思いますよね?

また、正確な色を知る必要はありません。一般的なカラー ファミリーを知る必要があるだけです。壁がロイヤルブルーであることを知る必要はありません。「青」を返すために必要なだけです。ハンターグリーンを知る必要はありません。「グリーン」を返すために必要なだけです。私は画像処理でそれをやったことがありません。

4

2 に答える 2

2

以下のコードは、.NET のSystem.Drawing.BitmapクラスとSystem.Drawing.Colorクラスに依存していますが、これらはどちらも MonoTouch でサポートされていると思います (少なくともMono Documentationを読んだ限りでは)。

したがって、bmpという名前のSystem.Drawing.Bitmapオブジェクトに画像があるとします。次のようなコードを使用して、その画像の平均色相を取得できます。

float hue = 0;
int w = bmp.Width;
int h = bmp.Height;               
for (int y = 0; y < bmp.Height; y++) {
  for (int x = 0; x < bmp.Width; x++) {
    Color c = bmp.GetPixel(x, y);
    hue += c.GetHue();
  }
}
hue /= (bmp.Width*bmp.Height);

これは画像全体を繰り返し処理しているため、大きな画像の場合は非常に遅くなる可能性があります。パフォーマンスが問題になる場合は、評価されるピクセルを画像の小さなサブセクションに制限するか ( juhan_hで提案されているように)、小さな画像を使用して開始することをお勧めします。

次に、0 から 360 度の範囲にある平均色相を指定すると、次のようにその数値を色名にマッピングできます。

String[] hueNames = new String[] {
  "red","orange","yellow","green","cyan","blue","purple","pink"
};
float[] hueValues = new float[] {
  18, 54, 72, 150, 204, 264, 294, 336
};                            

String hueName = hueNames[0];
for (int i = 0; i < hueNames.Length; i++) {
  if (hue < hueValues[i]) {
    hueName = hueNames[i];
    break;
  }
}         

hueValuesテーブルとhueNamesテーブルの値を推定したところなので、これらのテーブルを要件に合わせて調整することをお勧めします。値は、色が次の名前に変わるように見えるポイントです (たとえば、赤とオレンジの間の境界線は約 18 度で発生します)。

色相値によって表される色の範囲を把握するには、下のカラー ホイールを見てください。上から始めて、赤/オレンジ (約 0° - 北) から黄色/緑 (約 90° - 東)、シアン (約 180° - 南)、青/紫 (約 270° - 西) になります。 .

カラーホイール

ただし、彩度と明るさのレベルを無視しているため、この計算の結果は、色あせた色や暗い場所では理想的とは言えません。ただし、壁の全体的な色だけに関心がある場合は、それで十分だと思います。

于 2013-07-25T18:48:54.650 に答える
1

最近、iOS でのホワイト バランスのシフト (元の質問: iOS ホワイト ポイント/ホワイト バランス調整の例/提案) に対処しましたが、これには同様の問題が含まれていました。C# のコード サンプルを提供することはできませんが、次の手順を実行します。

  1. 画像をキャプチャする
  2. 画像のどのポイント/部分に関心があるかを決定します (小さいほど良い)
  3. 画像のその点の「色」を計算します
  4. 「色」を人間が読める形式に変換します(それが必要だと思いますか?)

ステップ 2 を完了するには、ユーザーにポイントを選択させるか、ポイントを画像の中心に配置します。これは通常、カメラが実際に向けられる場所であるためです。

手順 3 を実行する方法は、手順 2 で選択した領域の大きさによって異なります。領域が 1x1 ピクセルの場合、RGB でレンダリングし、そのレンダリングされたピクセルからコンポーネント (赤、緑、青) の値を取得します。領域が大きい場合は、その領域に含まれる各ピクセルの RGB 値を取得して平均化する必要があります。一般的な色だけが必要な場合は、これがほとんどです。しかし、照明条件を補正する必要がある場合、問題は非常に複雑になります。照明を補正する (つまり、ホワイト バランス) には、いくつかの変換を行い、写真が撮影された条件を推測する必要があります。詳細には触れませんが (私はその詳細について学士論文を書きました)、ホワイトバランスに関するウィキペディアの記事を参照してください。良い出発点です。また、ホワイトバランスの問題の解決策は常に主観的であり、写真が撮影された光の推測に依存することに注意する価値があります (少なくとも私が知る限り)。

ステップ 4 を完了するには、RGB 値を人間が判読できる色にマップするテーブルを検索する必要があります。この種のテーブルは必要ありませんでしたが、インターネット上のどこかに存在していることは確かです。

于 2013-07-24T07:51:28.740 に答える