如何在C#中识别黑色或暗色图像?

时间:2009-10-19 09:12:50

标签: c# .net image-processing

如何在C#中识别黑/暗图像。有没有API来检查图像可见度或暗度比?在我的应用程序中,在复制图像时,我想检查每个图像并想要丢弃黑色图像。

任何想法如何实现这一目标?

6 个答案:

答案 0 :(得分:7)

// For fast access to pixels        
public static unsafe byte[] BitmapToByteArray(Bitmap bitmap) { 
    BitmapData bmd = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly,
                                     PixelFormat.Format32bppArgb);
    byte[] bytes = new byte[bmd.Height * bmd.Stride];
    byte* pnt = (byte*) bmd.Scan0;
    Marshal.Copy((IntPtr) pnt, bytes, 0, bmd.Height * bmd.Stride);
    bitmap.UnlockBits(bmd);
    return bytes;
}

public bool IsDark(Bitmap bitmap, byte tolerance, double darkProcent) {
    byte[] bytes = BitmapToByteArray(bitmap);
    int count = 0, all = bitmap.Width * bitmap.Height;
    for (int i = 0; i < bytes.Length; i += 4) {
        byte r = bytes[i + 2], g = bytes[i + 1], b = bytes[i];
        byte brightness = (byte) Math.Round((0.299 * r + 0.5876 * g + 0.114 * b));
        if (brightness <= tolerance)
            count++;
    }
    return (1d * count / all) <= darkProcent;
}

public void Run(Bitmap bitmap) { // Example of use
    // some code
    bool dark = IsDark(bitmap, 40, 0.9); 
    // some code
}

答案 1 :(得分:5)

获得图像暗度/亮度的想法可以是:

Bitmap bitmap = // the bitmap
var colors = new List<Color>();
for (int x = 0; x < bitmap.Size.Width; x++)
{
    for (int y = 0; y < bitmap.Size.Height; y++)
    {
        colors.Add(bitmap.GetPixel(x, y));
    }
}

float imageBrightness = colors.Average(color => color.GetBrightness());

可能会将暗图像视为亮度小于0.1(或任何其他相关值)的图像

答案 2 :(得分:3)

您可以使用包含图像处理支持的AForge.NJET框架。 例如,请参阅ImageStatisticsHSL Class。选择正确的Saturation值,或使用Luminance直方图。

  

该类用于累积每个HSL颜色通道的图像统计值,如直方图,平均值,标准偏差等。

     

该类接受24和32 bpp彩色图像进行处理。

     

示例用法C#:

// gather statistics
ImageStatisticsHSL stat = new ImageStatisticsHSL( image );
// get saturation channel's histogram
ContinuousHistogram saturation = stat.Saturation;
// check mean value of saturation channel
if ( saturation.Mean > 0.5 )
{
    // do further processing
}

答案 3 :(得分:0)

我首先迭代图像中的所有像素,计算每个像素的HSV颜色,然后平均“V”分量(代表颜色的“亮度”)。

答案 4 :(得分:0)

感谢Elisha的想法,我这样做:

Bitmap bitmap = new Bitmap("123712.jpg");
float brightness = 0;
for (int x = 0; x < bitmap.Size.Width; x++)
{
     for (int y = 0; y < bitmap.Size.Height; y++)
     {
          brightness += bitmap.GetPixel(x, y).GetBrightness();
     }
}

float average = brightness / (bitmap.Size.Width * bitmap.Size.Height);

答案 5 :(得分:0)

我使用Accord.Net Imaging以获得更好的性能。 GetPixel相当慢。

注意所需的using语句:

using Accord.Imaging;

using Accord.Imaging.Converters;


    private bool IsDarkImage(Bitmap aBitmap, int darkThreshold)
    {
        double arrayAverage = 0;
        bool isDark = true;

        ImageToArray conv = new ImageToArray(min: 0, max: 255);
        conv.Convert(aBitmap, out double[] array);
        arrayAverage = (double) array.Sum() / (double) array.Length;
        if (arrayAverage < darkThreshold)
        {
            isDark = true;
        }
        else
        {
            isDark = false;
        }
        return isDark;
    }