Monday, April 26, 2010

Green Screen Compositing Project

Green Screen Video:
Done in Maya


Camera got a little wacky at the end, something we will fix for the final.

Compositing Code:

'Green Screen Compositing

Strict

Global AppTitle$="Green Screen Compositor"

Graphics(800,600)


Global PixMapBack:TPixmap
Global PixMapFront:TPixmap
Global PixMapResult:TPixmap
Global PixMapBKsmall:TPixmap
Global PixMapFsmall:TPixmap
Global PixMapResultSmall:TPixmap
Global i,j,pixel,PixTmp:Long
Global autotest:String
Global BaseBackName:String="bk"
Global BaseForegroundName:String="fg"
Global BKindexString:String="0001"
Global FGindexString:String="0001"
Global BKindex:Int=1, FGindex:Int=1
Global Backgroundfile:String = "bk0001.png"
Global Foregroundfile:String = "fg0001.png"

'--- Build file names if command line arguments are present
If AppArgs.length > 2
Backgroundfile = AppArgs[1] + "0001.png"
foregroundfile = AppArgs[2] + "0001.png"
EndIf

'---- Create full size background and foreground pixmaps
PixMapBack = LoadPixmapPNG(Backgroundfile)
PixMapFront = LoadPixmapPNG(Foregroundfile)

'---- Creae full size result pixmap
PixMapResult = CreatePixmap(720,480,PixmapFormat(PixMapBack))

'---- Create half size pixmaps for display purposes
PixMapBKsmall = CreatePixmap(360,240,PixmapFormat(PixMapBack))
PixMapFsmall = CreatePixmap(360,240,PixmapFormat(PixMapBack))
PixMapResultSmall = CreatePixmap(360,240,PixmapFormat(PixMapBack))

ProcessImage()

If AppArgs.length > 3 Then autotest = AppArgs[3] Else autotest = "manual"


'********************** Main Loop *********************************
If autotest = "auto" '--- If command line arg3="auto" then process all images and exit
UpdateDisplay()
Flip
AllFrames()
Else

While Not KeyDown(KEY_ESCAPE) And Not AppTerminate()
UpdateDisplay()
Flip

If KeyHit(KEY_COMMA) Then PreviousFrame()
If KeyHit(KEY_PERIOD) Then NextFrame()
If KeyHit(KEY_SPACE) Then AllFrames()
Wend
EndIf
End


'------------------ Process All frames after current frame ------------------------
Function AllFrames()
Local Done = 1

While Done <> Null And Not KeyHit(KEY_ESCAPE)
Done = NextFrame()
If Done <> Null
UpdateDisplay()

'--------- Display ESCAPE message
SetColor(210,210,210)
DrawRect(420,50,350,30)
SetColor(0,0,0)
DrawText("Press ESCAPE to stop",422,52)
SetColor(255,255,255)

Flip
EndIf
Wend

If Done = Null
PreviousFrame() '--- Back up to last good image file
Else
Flip
SetColor(210,210,210)
DrawRect(420,50,350,30)
SetColor(255,0,0)
DrawText("Release ESCAPE now",422,52)
SetColor(255,255,255)
Flip

While KeyDown(KEY_ESCAPE)
'--- Wait for escape key to be released
Wend
EndIf

End Function




'------------------ Move to next frame (Return null if file error) -------------
Function NextFrame:Int()
Local LoadResult

BKindex = BKindex + 1
BKindexString = String.fromint(BKindex)
BKindexString = AddZeros(BKindexString)
Backgroundfile = BaseBackName + BKindexString + ".png"

FGindex = FGindex + 1
FGindexString = String.fromint(FGindex)
FGindexString = AddZeros(FGindex)
Foregroundfile = BaseForegroundName + FGindexString + ".png"
LoadResult = LoadPix()
If LoadResult <> Null Then ProcessImage()
Return LoadResult
End Function



'------------------ Move to previous frame (Stop at frame 1) ------------------
Function PreviousFrame:Int()
Local LoadResult

BKindex = BKindex - 1
If BKindex < 1 Then BKindex = 1
BKindexString = String.fromint(BKindex)
BKindexString = AddZeros(BKindexString)
Backgroundfile = BaseBackName + BKindexString + ".png"

FGindex = FGindex - 1
If FGindex < 1 Then FGindex = 1
FGindexString = String.fromint(FGindex)
FGindexString = AddZeros(FGindex)
Foregroundfile = BaseForegroundName + FGindexString + ".png"

LoadResult = LoadPix()
If LoadResult <> Null Then ProcessImage()
Return LoadResult
End Function





'-------------------- Load Pixmap files (Return null if file error) ---------------
Function LoadPix:Int()
PixMapBack = LoadPixmapPNG(Backgroundfile)
If PixMapBack <> Null Then PixMapFront = LoadPixmapPNG(Foregroundfile)
If PixMapBack = Null Or PixMapFront = Null
Return Null
Else
Return 1
EndIf

End Function



'------------------ Add zeros to beginning of string to fill in 4 digits ---------
Function AddZeros:String(strin:String)
Local i:Int

For i = 1 To 4
If strin.length < 4 Then strin = "0" + strin
Next

Return strin
End Function




'-------------------------- Draw Frame around picture -----------------------
Function DrawFrame(Posx:Int, Posy:Int, SizeX:Int, SizeY:Int)
'SetColor(60,60,60)
'DrawRect(Posx,Posy,SizeX+2,SizeY+2)
SetColor(127,127,127)
'DrawRect(Posx-1,Posy-1,SizeX+4,SizeY+4)
'SetColor(220,220,220)
DrawRect(Posx-2,Posy-2,SizeX+6,SizeY+6)
SetColor(255,255,255)
EndFunction




'----------------------- Process the Foreground and Background Images ------------------------------------
Function ProcessImage()
Local rd,gr,bl

'--- Make a half size background image to display
For i = 0 To 359
For j = 0 To 239
pixel = ReadPixel(PixMapBack,2*i,2*j)
WritePixel(PixMapBKsmall,i,j,pixel)
Next
Next

'--- Make a half size foreground image to display
For i = 0 To 359
For j = 0 To 239
pixel = ReadPixel(PixMapFront,2*i,2*j)
WritePixel(PixMapFsmall,i,j,pixel)
Next
Next

'--- Make composite picture
For i = 0 To 719
For j = 0 To 479
'--- Copy background image unchanged
pixel = ReadPixel(PixMapBack,i,j)
WritePixel(PixMapResult,i,j,pixel)

'--- Copy only non-green pixels from foreground image
pixel = ReadPixel(PixMapFront,i,j)
rd = (pixel & $0FF0000) Shr 16 'Get RED part of pixel
gr = (pixel & $0FF00) Shr 8 'Get GREEN part of pixel
bl = pixel & $0FF 'Get BLUE part of pixel
'--- IF pixel is not mostly GREEN, then copy it to result image
If ((gr - rd + gr - bl) < $080) Then WritePixel(PixMapResult,i,j,pixel)
Next
Next

'--- Make a half size result picture to display
For i = 0 To 359
For j = 0 To 239
pixel = ReadPixel(PixMapResult,2*i,2*j)
WritePixel(PixMapResultSmall,i,j,pixel)
Next
Next

SavePixmapJPeg(PixMapResult,"Result" + FGindexString + ".jpg")

EndFunction




'---------------- Update the display ---------------------
Function UpdateDisplay()
Cls() 'Clear the screen

'--- If right mouse button the display the color under the cursor
If MouseDown(2)
PixTmp = ReadPixel(PixMapFront,MouseX(),MouseY())
DrawText(Hex$(PixTmp),600,100)
EndIf

'--- Draw a small background picture
DrawFrame(4,44,360,240)
DrawPixmap(PixMapBKsmall,5,47)

'--- Draw a small foreground picture
DrawFrame(4,339,360,240)
DrawPixmap(PixMapFsmall,5,340)

'--- Draw a small result picture
DrawFrame(399,179,360,240)
DrawPixmap(PixMapResultSmall,400,180)


'--------- Display Keyboard instructions --------------
SetColor(210,210,210)
DrawRect(420,480,350,100)
SetColor(0,0,0)
DrawText(" Controls:",422,482)
DrawText("'>' for next frame",422,498)
DrawText("'<' For previous frame",422,514)
DrawText("'SPACE' to process all frames",422,530)
DrawText(BaseBackName + "--" + BaseForegroundName + " " + BKindex + " " + FGindex, 422,546)
SetColor(255,255,255)

End Function



echo off

if [%1]==[] goto usage
if [%2]==[] goto usage

::Execute the green screen compositing program
greenscreen1 %1 %2 auto
::Next execute ffmpeg to convert the result to an AVI movie file
ffmpeg -i Result%%4d.jpg result.mpg

goto done

:usage
echo "Missing file names !!!"
echo " "
echo " Usage:"
echo "composite BackgroundFileName ForegroundFileName"
echo " "
echo "BackgroundFileName is the base name of the first of the sequence of background images"
echo " example: if your first image file is bk0001.png then BackgroundFileName will be bk"
echo " "
echo "ForegroundFileName is the name of the first of the sequence of green screen images"
echo " example: if your first image file is fg0001.png then ForegroundFileName is fg"
echo " "
echo " Note: file names must have a four digit number at the end and must be png files"
echo " "

:done

No comments:

Post a Comment