Hi
How to identify black/dark image in C#. Is there any API to check the image visibility or darkness ratio? In my application, while copying images, I want to check each image and want to discard black images.
Any Idea how to achieve this?
Hi
How to identify black/dark image in C#. Is there any API to check the image visibility or darkness ratio? In my application, while copying images, I want to check each image and want to discard black images.
Any Idea how to achieve this?
An idea to get the image darkness/brightness can be:
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());
Maybe consider dark images as ones with brightness less than 0.1 (or any other value relevant)
I'd start by iterating over all pixels in your image, computing the HSV color of each pixel, and then averaging the 'V' component (which represents the 'brightness' of the color).
// 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
}
You can use the AForge.NJET framework which includes Image Processing support.
For example, see the ImageStatisticsHSL
Class. Choose a proper Saturation
value, or use the Luminance
histogram.
The class is used to accumulate statistical values about images, like histogram, mean, standard deviation, etc. for each HSL color channel.
The class accepts 24 and 32 bpp color images for processing.
Sample usage 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
}
Thanks Elisha for the idea, I am doing it in this way:
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);