0

I use Canon EOS SDK and want to realize live greenscreening with the camera stream.

I have a simple greenscreen algorithm with pixel operations optimizations.

 public Bitmap greenScreen(Bitmap input, int tolerance)
        {
            FastPixel fpinput = new FastPixel(input);
            fpinput.Lock();

            Bitmap output = new Bitmap(input.Width, input.Height);
            FastPixel fpoutput = new FastPixel(output);
            fpoutput.Lock();

            for (int y = 0; y < output.Height; y++)
            {
                for (int x = 0; x < output.Width; x++)
                {
                    Color camColor = fpinput.GetPixel(x, y);

                    // Every component (red, green, and blue) can have a value from 0 to 255, so determine the extremes
                    byte max = Math.Max(Math.Max(camColor.R, camColor.G), camColor.B);
                    byte min = Math.Min(Math.Min(camColor.R, camColor.G), camColor.B);

                    bool replace =
                        camColor.G != min // green is not the smallest value
                        && (camColor.G == max // green is the bsiggest value
                        || max - camColor.G < 8) // or at least almost the biggest value
                        && (max - min) > tolerance; // minimum difference between smallest/biggest value (avoid grays)

                    if (!replace)
                        fpoutput.SetPixel(x, y, camColor);

                }
            }

            fpinput.Unlock(true);
            fpoutput.Unlock(true);

            return fpoutput.Bitmap;
        }

for 800x600 pictures this takes around 300ms on my i5. Of course this is not fast enough for a smooth livestream.

What optimization options do I have? Is there an opportunity to use gpu functions? What would be an opportunity? I can't use DirectShow with the Canon Camera (no driver does exist)

daniel
  • 34,281
  • 39
  • 104
  • 158

1 Answers1

2
  1. GetPixel/SetPixel

    Do not know your environment (I do not code in C#) but these functions tend to be painfully slow in all environments. There are usually alternatives for bitmaps like:

  2. Image acquisition

    Again I do not know the SDK you are using nor target fps you need but there is a possibility that your SDK streaming is slow and not only your app. The DirectShow can provide you with around 30 fps for lower resolutions. I noticed however that for bigger resolutions it is slower then VFW but it could be related to USB and not to streaming and driver itself. As you do not have DirectShow driver you are out of luck. If you got VFW driver then you can use that but it can give you usually only up to 15 fps but the code is significantly simpler and less CPU demanding.

    Btw some drivers has capability to set fps for streaming (or the time interval) so search your SDK for such function or token maybe you just have low fps set on default.

    Also Try use different USB (if an USB connection is used) some USB can have bandwith already taken away by other devices (ideally test with single camera on whole Root HUB).

To detect which one is the problem count the fps while no pixels are transfered or viewed (just rem all the image related code and measure just the even occurrence). If acquisition is fast then driver is not the issue. Then measure with the transfer and if slows too much that code is also a problem.

Community
  • 1
  • 1
Spektre
  • 49,595
  • 11
  • 110
  • 380