UserMat
UserMat

Reputation: 616

How to get the brightest area from webcam in Emgu CV C#?

I'm using Emgu CV library in C# and I can successfully display the webcam in a PictureBox. I want to set the brightness of the camera dynamically by:

Visible_capture.SetCaptureProperty(CapProp.Brightness, Convert.ToInt32(Value));

I need to get the brightest spot on the picture and change the camera brightness setting. I don't need the average brightness.

Example application that shows maximum brightness

Upvotes: 1

Views: 1028

Answers (2)

PeterJ
PeterJ

Reputation: 3795

Assuming you're using grayscale or looking for the maximum of any channel it looks like Mat.MinMax might be a good choice. You can using something like the following:

image.MinMax(out _, out double[] maxValues, out _, out _);

And because you're only interested in the maximum value not all their locations the result will be in maxValues[0]. I thought it would probably be faster to use image.GetRawData().Max() so wrote a rough benchmark in LINQPad to compare for a sample image:

void Main()
{
    const int testIterations = 1000;
    string imageUrl = "https://raw.githubusercontent.com/opencv/opencv/master/samples/data/orange.jpg";
    string imagePath = Path.Combine(Path.GetTempPath(), Path.GetFileName(imageUrl));
    using (WebClient client = new WebClient())
    {
        client.DownloadFile(imageUrl, imagePath);
    }
    using (Mat image = CvInvoke.Imread(imagePath, Emgu.CV.CvEnum.ImreadModes.Grayscale))
    {
        Stopwatch sw = new Stopwatch();
        sw.Start();
        for (int i = 0; i < testIterations; i++)
        {
            image.MinMax(out _, out double[] maxValues, out _, out _);
            if (i == testIterations - 1)
            {
                sw.Stop();
                Console.WriteLine($"Using Mat.MinMax: {maxValues[0]}, elapsed {sw.ElapsedMilliseconds} ms");
            }
        }
        sw.Reset();
        sw.Start();
        for (int i = 0; i < testIterations; i++)
        {

            var max = image.GetRawData().Max();
            if (i == testIterations - 1)
            {
                sw.Stop();
                Console.WriteLine($"Using Mat.GetRawData().Max(): {max}, elapsed {sw.ElapsedMilliseconds} ms");
            }
        }
        CvInvoke.Imshow("Test", image);
    }
}

But the result I got after a few runs were showing that the MinMax method was consistently quite a bit faster, presumably because of some overhead passing the data back from the unmanaged code, but you should probably compare for your own application:

Using Mat.MinMax: 253, elapsed 691 ms
Using Mat.GetRawData().Max(): 253, elapsed 3760 ms

Upvotes: 4

AbdelAziz AbdelLatef
AbdelAziz AbdelLatef

Reputation: 3744

Have you tried getting the brightness of all pixels, then selecting the highest value?

Upvotes: 1

Related Questions