質問

私は、JPG画像に原稿をスキャンしています。スキャナは、黒と白と色など、すべてのページまたはすべてのページをスキャンする必要があります。私のページの多くは色なので、私は色など、すべてのページをスキャンする必要があります。スキャンが完了すると、私はネットで画像を調べて、私はグレースケールとストレージを節約するために、これらの画像を変換することができるように黒と白であるかの画像を検出してみたいと思います。

誰もがネットでグレースケール画像を検出する方法を知っていますか?

私に知らせてくださいます。

役に立ちましたか?

解決

単純なアルゴリズムは、色をテストする:画素のRGB値が等しいかどうかを確認するためにループ(幅と高さ)とテストのために、ネストされた画素によって画像ピクセルをウォーク。彼らはその後、されていない場合、画像は色情報を持っています。あなたはこの条件に遭遇することなく、すべての画素を、それをすべての方法を作る場合は、グレースケール画像を持っています。

を、より複雑なアルゴリズムを持つリビジョン:

この記事の最初の回転では、私は、各ピクセルのRGBの値である場合の画素がグレースケールであることを前提とし、単純なアルゴリズムを提案等しいです。だから、0,0,0または128,128,128または230230230のRGBSはグレーのように、すべてのテストが123,90,78はないだろうがだろう。シンプルます。

ここで、グレーからの分散をテストコードの抜粋です。二つの方法は、より複雑なプロセスの小さなサブセクションですが、元の質問を支援するための十分な生のコードを提供するべきである。

/// <summary>
/// This function accepts a bitmap and then performs a delta
/// comparison on all the pixels to find the highest delta
/// color in the image. This calculation only works for images
/// which have a field of similar color and some grayscale or
/// near-grayscale outlines. The result ought to be that the
/// calculated color is a sample of the "field". From this we
/// can infer which color in the image actualy represents a
/// contiguous field in which we're interested.
/// See the documentation of GetRgbDelta for more information.
/// </summary>
/// <param name="bmp">A bitmap for sampling</param>
/// <returns>The highest delta color</returns>
public static Color CalculateColorKey(Bitmap bmp)
{
    Color keyColor = Color.Empty;
    int highestRgbDelta = 0;

    for (int x = 0; x < bmp.Width; x++)
    {
        for (int y = 0; y < bmp.Height; y++)
        {
            if (GetRgbDelta(bmp.GetPixel(x, y)) <= highestRgbDelta) continue;

            highestRgbDelta = GetRgbDelta(bmp.GetPixel(x, y));
            keyColor = bmp.GetPixel(x, y);
        }
    }

    return keyColor;
}

/// <summary>
/// Utility method that encapsulates the RGB Delta calculation:
/// delta = abs(R-G) + abs(G-B) + abs(B-R) 
/// So, between the color RGB(50,100,50) and RGB(128,128,128)
/// The first would be the higher delta with a value of 100 as compared
/// to the secong color which, being grayscale, would have a delta of 0
/// </summary>
/// <param name="color">The color for which to calculate the delta</param>
/// <returns>An integer in the range 0 to 510 indicating the difference
/// in the RGB values that comprise the color</returns>
private static int GetRgbDelta(Color color)
{
    return
        Math.Abs(color.R - color.G) +
        Math.Abs(color.G - color.B) +
        Math.Abs(color.B - color.R);
}

他のヒント

あなたは、このためのライブラリを見つけることができない場合は、画像のための多数の画素(またはすべてを)つかむ試みることができると彼らのR、G、Bの値が一定の閾値以内であれば(参照されますが経験的に設定、または1つ別の設定)として持っているかもしれません。その場合、画像はグレースケールです。

私は間違いなく0よりも少し大きなテストのためのしきい値になるだろう、しかし...ので、私には、例えば、R = Gをテストしていないだろうが、(ABS(R-G)を与えない限り、あなたは正確にのグレースケール、...あなたの偽色の陽性を抑えることができます。

その方法

速いバージョン。 8.ワークウェルのしきい値とテストの私の

使用します。

bool grayScale;
Bitmap bmp = new Bitmap(strPath + "\\temp.png");
grayScale = TestGrayScale(bmp, 8);
if (grayScale)
   MessageBox.Show("Grayscale image");


/// <summary>Test a image is in grayscale</summary>
/// <param name="bmp">The bmp to test</param>
/// <param name="threshold">The threshold for maximun color difference</param>
/// <returns>True if is grayscale. False if is color image</returns>
public bool TestGrayScale(Bitmap bmp, int threshold)
{
    Color pixelColor = Color.Empty;
    int rgbDelta;

    for (int x = 0; x < bmp.Width; x++)
    {
        for (int y = 0; y < bmp.Height; y++)
        {
            pixelColor = bmp.GetPixel(x, y);
            rgbDelta = Math.Abs(pixelColor.R - pixelColor.G) + Math.Abs(pixelColor.G - pixelColor.B) + Math.Abs(pixelColor.B - pixelColor.R);
            if (rgbDelta > threshold) return false;
        }
    }
    return true;
}

あなたはより高速なものを持っていますか?

お使いのスキャナソフトウェアの場所場合は、

JPEGは、メタデータのサポートを持っているとして、あなたは最初に保存した画像上のいくつかの特別なデータを確認する必要があり、あなたがその情報に頼ることができるかどうか。

私はPythonのセクションに掲載のの回答はには役に立つかもしれません。あなたは、例えば見つける画像人間が同一のR、G、B値を持っていないことが多いグレースケールを検討するウェブ上。あなたは万画素をチェックする必要はありませんので、あなたは、分散のいくつかの計算とサンプリングプロセスのいくつかの種類が必要です。スキャナからの単一の赤色画素アーチファクトが非グレースケールにグレースケール画像を回すことができるようにポールが得られた溶液を、最大差に基づいています。私が投稿ソリューションは、13,000画像に99.1%の精度と再現率92.5%を得ています。

私は、このアプローチは、少なくともコードを必要とすべきだと思う、それはJPEGファイル上でテストされています。以下bImageはバイト配列です。

 MemoryStream ms = new MemoryStream(bImage);
 System.Drawing.Image returnImage = System.Drawing.Image.FromStream(ms);
 if (returnImage.Palette.Flags == 2)
 {
      System.Diagnostics.Debug.WriteLine("Image is greyscale");
 }
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top