# Generating masks from green screen pictures when the green pixel isn't green enough?

Hello,

I’d like to handle pictures that have some kind of green screen in the background. The problem is the green pixels aren’t pure green, because that’s not a professional background and lights aren’t projectors either. I don’t have much influence on the equipment used.

The principle is already coded (looping thru every pixel, determining if it’s green or not and filling the mask with white or black). But the determination step causes problems.

Currently, I’m using this check:

Result=Green<35 or Red>Green or Blue>Green
(code found on the Internet, as my attempts have all been overcomplicated and not working )

With this, the result looks almost good, but near-white pixels and bright areas are also considered as transparent. It’s close, but not enough (and I tested only on one picture).

I’m attaching here an example picture. The green background appears rather yellowish (but the shadows are also a problem). I’m not even sure any code could work with that…

Any idea for a working check?

Try looking into “color distance” - how similar two colors are by calculating the distance between them in 3D space (one dimension for each channel of color in the RGB image). If you’re familiar with the Pythagorean Theorem, it will click right into place.

Essentially you’ll be calculating how far each pixel’s color is from the key green, and you’ll be able to give the user pretty good controls if the detection parameters needs fine tuning.

1 Like

Thank you.
And I was so close with my code.
The Result computation was actually right, but the bug was earlier.

In my previous design, Green, Blue and Red (in the formula) were the difference between each of the pixel’s channel and a colour chosen by the user (a colour to be chosen near the background one).
Now, I’m just comparing each pixel against plain green and it works!

1 Like

from my greenscreen pic tool but not optimized

``````Public Function RemoveGreen(picIn As Picture) As Picture

Var picOut As New Picture(picIn.Width,picIn.Height)
picOut.Graphics.DrawPicture(picIn,0,0)

Var surf As RGBSurface = picOut.RGBSurface

Var c As Color
For x As Integer = 0 To picIn.Width-1
For y As Integer = 0 To picIn.Height-1
c = surf.Pixel(x,y)

If Alpha(c.Red,c.Green,c.Blue) > 3  Then '<- threshold
surf.Pixel(x,y) = Color.Clear
Else
'surf.Pixel(x,y) = c
End If
Next
Next

Return picOut

End Function

Public Function Alpha(red as Integer, green as Integer, blue as Integer) As Integer
'Color Difference Key

Return green-Max(red,blue)

End Function``````

The edge areas are not yet ok
I still have to work manually

rem Line
If mend <> Nil Then
Var fx As Double = mypic.Width/Me.Width
Var fy As Double = mypic.Height/Me.height
Var x As Double = mend.xfx
Var y As Double = mend.y * fy
Var xx As Double = mstart.x
fx
Var yy As Double = mstart.y * fy
Var brx As Double = TextField4.Text.Val * fx
Var bry As Double = TextField4.Text.Val * fy
mypic.graphics.PenSize = brx
mypic.graphics.DrawingColor = Color.clear // rem Color.clear ??
mypic.graphics.drawline(xx-brx/2,yy-bry/2,xfx-brx/2,yfy-bry/2)