3

so what I'm doing is creating a simple green screen image maker in vb.net. My code is quite simple (albeit probably not the most efficient)

Dim overlay As Bitmap = New Bitmap(My.Resources.GreenScreen)
    Dim backImage As Bitmap = New Bitmap(My.Resources.Tunnel)

    Dim x As Integer
    Dim y As Integer

    For x = 0 To overlay.Width - 1
        For y = 0 To overlay.Height - 1
            Dim pixelColor As Color = overlay.GetPixel(x, y)
            If pixelColor = Color.FromArgb(255, 0, 254, 0) Then
                overlay.MakeTransparent(overlay.GetPixel(x, y))
            End If
        Next
    Next

    Dim g As Graphics = Graphics.FromImage(backImage)
    g.DrawImage(overlay, 0, 0)
    PictureBox1.Image = backImage

but for now it works, and I'm happy with it (sort of)

What I am facing is that I've downloaded a sample image of someone stood in front of a green screen. The above code removes the majority of the green, but not all. I need to feather the edge of the subject (I think that's what it's called anyway).

What I was thinking was that I need to catch all the different shades of green in the image, is there a way I can specify a max and min range for the RGB?

Wilko84
  • 81
  • 1
  • 6
  • 2
    Consider using OpenCV ([Nuget Emgu.CV](https://www.nuget.org/packages/EMGU.CV/)) and the operation you are seeking is Chroma Keying – djv Feb 11 '20 at 19:15
  • If not using OpenCV, your approach could be sped up by locking the bitmap. [This approach](https://stackoverflow.com/a/3654231/832052) uses a transparency mask which you could certainly use. – djv Feb 11 '20 at 19:32
  • The [Chroma-key effect](https://learn.microsoft.com/en-us/windows/win32/direct2d/chromakey-effect#sample-code) is a built-in feature of [Direct-2D](https://learn.microsoft.com/en-us/windows/win32/direct2d/reference), in case you're interested. You see these filters in action in a lot of open-source an commercial software. Simply replacing pixels' content of won't get you far. – Jimi Feb 12 '20 at 03:53

1 Answers1

1

This is a non-trivial problem to get consistent results across any input sample, however, if you approach gives satisfying results to you, maybe that's all you will need.

You should compute the distance to a particular color:

enter image description here

https://en.wikipedia.org/wiki/Color_difference

So basically, you pick green color, decide of an acceptable distance, then check how close a pixel color is and transform it or not.

Also, for performance, consider using Bitmap.LockBits, read all pixels at once instead of GetPixel which is very slow by nature.

EDIT

Consider using the approach @djv has commented, it will be slightly more complex to setup but the results will be much more consistent.

aybe
  • 15,516
  • 9
  • 57
  • 105