web-dev-qa-db-ja.com

赤目軽減アルゴリズム

作業中のアプリケーションに赤目軽減を実装する必要があります。

グーグルは主に商用エンドユーザー製品へのリンクを提供します。

GPLアプリケーションで使用できる優れた赤目軽減アルゴリズムを知っていますか?

41

私はここでのパーティーにかなり遅れていますが、将来の検索者のために、私が書いた個人用アプリに次のアルゴリズムを使用しました。

まず、縮小する領域をユーザーが選択し、中心点と半径として赤目軽減方法に渡します。このメソッドは、半径内の各ピクセルをループし、次の計算を実行します。

//Value of red divided by average of blue and green:
Pixel pixel = image.getPixel(x,y);
float redIntensity = ((float)pixel.R / ((pixel.G + pixel.B) / 2));
if (redIntensity > 1.5f)  // 1.5 because it gives the best results
{
    // reduce red to the average of blue and green
    bm.SetPixel(i, j, Color.FromArgb((pixel.G + pixel.B) / 2, pixel.G, pixel.B));
}

色の濃さを保ち、目の光の反射が減らないので、この結果が本当に気に入っています。 (これは、目が「生きている」外観を保つことを意味します。)

43
Benry

目を見つけるのに最適なライブラリは openCV です。画像処理機能が豊富です。 Ilia V. Safonovの「自動赤目検出」というタイトルの紙 this も参照してください。

7
akiva

まず、目を見つける必要があります!標準的な方法は、エッジ検出器を実行してからハフ変換を実行して同じサイズの2つの円を見つけることですが、赤いピクセルのクラスターを簡単に見つけるためのより簡単なアルゴリズムがあるかもしれません。

次に、画像に十分な緑/青のデータがあると仮定して、それらを何に置き換えるかを決定する必要があります。単に赤のチャネルを無視することができます。

OpenCVは画像処理のための非常に優れた無料のライブラリであり、あなたが望むものにはやり過ぎかもしれませんが、多くの例と非常に活発なコミュニティがあります。オブジェクト追跡アルゴリズムを検索することもできます。シーン内の色付きオブジェクトの追跡は、非常によく似た一般的な問題です。

6
Martin Beckett

他の誰もより直接的な答えを思い付かない場合は、いつでも GIMPのソースコード をダウンロードして、彼らがどのようにそれを行うかを見ることができます。

4
Bill the Lizard

最も単純なアルゴリズムであり、それでも非常に効果的なアルゴリズムは、関心領域のRGBトリプルのRをゼロにすることです。

赤は消えますが、他の色は保持されます。

このアルゴリズムをさらに拡張すると、赤が支配的な色(R> GおよびR> B)であるトリプルのみのR値をゼロにする必要があります。

3
japollock

あなたはimagemagickを試すことができます-それを行う方法についてのこのページのいくつかのヒント

http://www.cit.gu.edu.au/~anthony/info/graphics/imagemagick.hints

ページで赤目を検索する

3
Lou Franco

オープンソースプロジェクト Paint.NET はC#で実装されています。

3
JC.

これがJava実装ソリューションです

public void corrigirRedEye(int posStartX, int maxX, int posStartY, int maxY, BufferedImage image) {
    for(int x = posStartX; x < maxX; x++) {
        for(int y = posStartY; y < maxY; y++) {

            int c = image.getRGB(x,y);
            int  red = (c & 0x00ff0000) >> 16;
            int  green = (c & 0x0000ff00) >> 8;
            int  blue = c & 0x000000ff;

            float redIntensity = ((float)red / ((green + blue) / 2));
            if (redIntensity > 2.2) {
                Color newColor = new Color(90, green, blue);
                image.setRGB(x, y, newColor.getRGB());
            }


        }
    }
}

Open cvのようなアプリケーションによって検出された2つの長方形から取得されたパラメーターであること(これは目の位置を含む長方形である必要があります)

int posStartY = (int) leftEye.getY();

    int maxX = (int) (leftEye.getX() + leftEye.getWidth());
    int maxY = (int) (leftEye.getY() + leftEye.getHeight());

    this.corrigirRedEye(posStartX, maxX, posStartY, maxY, image);

    // right eye

    posStartX = (int) rightEye.getX();
    posStartY = (int) rightEye.getY();

    maxX = (int) (rightEye.getX() + rightEye.getWidth());
    maxY = (int) (rightEye.getY() + rightEye.getHeight());

    this.corrigirRedEye(posStartX, maxX, posStartY, maxY, image);
2
aConstantino

これは、Benryによって提供された回答のより完全な実装です。

  using SD = System.Drawing;

  public static SD.Image ReduceRedEye(SD.Image img, SD.Rectangle eyesRect)
  {
     if (   (eyesRect.Height > 0)
         && (eyesRect.Width > 0)) {
        SD.Bitmap bmpImage = new SD.Bitmap(img);
        for (int x=eyesRect.X;x<(eyesRect.X+eyesRect.Width);x++) {
           for (int y=eyesRect.Y;y<(eyesRect.Y+eyesRect.Height);y++) {
              //Value of red divided by average of blue and green:
              SD.Color pixel = bmpImage.GetPixel(x,y);
              float redIntensity = ((float)pixel.R / ((pixel.G + pixel.B) / 2));
              if (redIntensity > 2.2f)
              {
                 // reduce red to the average of blue and green
                 bmpImage.SetPixel(x, y, SD.Color.FromArgb((pixel.G + pixel.B) / 2, pixel.G, pixel.B));
                 pixel = bmpImage.GetPixel(x,y); // for debug
              }
           }
        }
        return (SD.Image)(bmpImage);
     }
     return null;
  }
1
cdavidyoung

このブログを読んでください、赤目の検出と修正に関する素晴らしい説明があります。 OpenCVとPythonによる赤目補正

0
Shahrukh khan