Speaking of real life examples, I have created a small application that enables multiple video capture with some additional OCV features. This is how it works.
Naturally, it requires lots of additional work but this is kind of a "proof of concept". It was, however, rebuilt with threads (TBB) support so here are DLL's ->
It also uses ESCAPI to detect camera names so you will need that DLL as well! As far as I know, that is not supported in OpenCV, perhaps someone has additional insight regarding that one?
Code: Select all
XIncludeFile "includes/cv_functions.pbi"
EnableExplicit
Structure SimpleCapParams
*mTargetBuf
mWidth.l
mHeight.l
EndStructure
PrototypeC countCaptureDevicesProc()
PrototypeC initCaptureProc(deviceno, *aParams.SimpleCapParams)
PrototypeC deinitCaptureProc(deviceno)
PrototypeC doCaptureProc(deviceno)
PrototypeC isCaptureDoneProc(deviceno)
PrototypeC getCaptureDeviceNameProc(deviceno, *namebuffer, bufferlength)
PrototypeC ESCAPIDLLVersionProc()
PrototypeC initCOMProc()
Global countCaptureDevices.countCaptureDevicesProc
Global initCapture.initCaptureProc
Global deinitCapture.deinitCaptureProc
Global doCapture.doCaptureProc
Global isCaptureDone.isCaptureDoneProc
Global getCaptureDeviceName.getCaptureDeviceNameProc
Global ESCAPIDLLVersion.ESCAPIDLLVersionProc
Global initCOM.initCOMProc
Procedure setupESCAPI()
Protected.i capdll
capdll = OpenLibrary(#PB_Any, "escapi.dll")
If capdll = 0
ProcedureReturn 0
EndIf
countCaptureDevices = GetFunction(capdll, "countCaptureDevices")
initCapture = GetFunction(capdll, "initCapture")
deinitCapture = GetFunction(capdll, "deinitCapture")
doCapture = GetFunction(capdll, "doCapture")
isCaptureDone = GetFunction(capdll, "isCaptureDone")
initCOM.initCOMProc = GetFunction(capdll, "initCOM")
getCaptureDeviceName = GetFunction(capdll, "getCaptureDeviceName")
ESCAPIDLLVersion = GetFunction(capdll, "ESCAPIDLLVersion")
If countCaptureDevices = 0 Or initCapture = 0 Or deinitCapture = 0 Or doCapture = 0 Or isCaptureDone = 0 Or initCOM = 0 Or getCaptureDeviceName = 0 Or ESCAPIDLLVersion = 0
ProcedureReturn 0
EndIf
If ESCAPIDLLVersion() < $200
ProcedureReturn 0
EndIf
initCOM();
ProcedureReturn countCaptureDevices()
EndProcedure
If setupESCAPI(): Else : End 0 : EndIf
#ApplicationName = "Your Application Name"
Enumeration #PB_Event_FirstCustomValue
#Event_ThreadMessage
#EventType_DetectCameras
#EventType_ManageGadgets
#EventType_DrawToCanvas
EndEnumeration
Enumeration
#Window_Main
#Window_NewProject
#Button_NewProjectOK
#Button_NewProjectCancel
#ComboBox_NewProjectCanvasSize
#SpinGadget_NewProjectHorizontal
#SpinGadget_NewProjectVertical
#Canvas_NewProject
#Tree_NewProject_Cameras
#Tree_NewProject_Texts
#PopUpMenu_Cameras
#PopUpMenu_Texts
#PopUpMenu_Texts_TL
#PopUpMenu_Texts_TR
#PopUpMenu_Texts_BL
#PopUpMenu_Texts_BR
#StatusBar_Main
#ImageGadget_Main
#MainMenu
#MainMenu_NewProject
#MainMenu_SaveProject
#MainMenu_LoadProject
#MainMenu_CloseProject
#MainMenu_Settings
#MainMenu_DetectCameras
#MainMenu_RecordPause
#MainMenu_Exit
EndEnumeration
Structure CaptureDevices
ID.i
Name.s
*capture
EndStructure
Structure VideoFrame
*VideoFrame.IplImage
CaptureDevice.CaptureDevices
Font.CvFont
Text.s
X.i
Y.i
Width.i
Height.i
Position.s
TextPosition.s
EndStructure
Structure VideoCanvas
Name.s
Width.i
Height.i
W.i
H.i
ResolutionW.i
ResolutionH.i
EndStructure
Structure VideoText
Position.s
Text.s
TextPosition.s
EndStructure
Declare CaptureFrames(*p)
Declare QuitSoftware()
Declare TreeViewExpandSubLevel(GadgetID.i, SubLevelToExpand.i)
Global NewList VideoFrames.VideoFrame(), NewList VideoDevices.CaptureDevices(), NewList VideoTexts.VideoText(), DeviceCount
Global Dim Canvases.VideoCanvas(5), Dim *Images.IplImage(1)
Global.i MainImage, DetectCamerasThr, CaptureThr, CaptureFlag = #False, WriterFlag = #False
Global *dst.IplImage
Global Dim *Images.IplImage(1)
Global *Resolution.VideoCanvas
Global *writer, WriterFileName.s = ""
Define.i Event, img
Threaded.i i, j, k
;Callback
Procedure WinProc(hWnd, msg, wParam, lParam)
Protected.i result
result = #PB_ProcessPureBasicEvents
If msg = #WM_SYSCOMMAND
If wparam = #SC_CLOSE
result = 0
QuitSoftware()
EndIf
EndIf
ProcedureReturn result
EndProcedure
;Methods
Procedure MethodWindowNewProjectOK()
Protected.i W, H, RatioW, RatioH, FrameWidth, FrameHeight
Protected.d ResizeRatio
W = GetGadgetState(#SpinGadget_NewProjectHorizontal)
H = GetGadgetState(#SpinGadget_NewProjectVertical)
RatioW = GadgetWidth(#Canvas_NewProject) / W
RatioH = GadgetHeight(#Canvas_NewProject) / H
; Get First Camera settings FIXME
ResetList(VideoDevices()) : NextElement(VideoDevices())
FrameWidth = cvGetCaptureProperty(VideoDevices()\capture, #CV_CAP_PROP_FRAME_WIDTH)
FrameHeight = cvGetCaptureProperty(VideoDevices()\capture, #CV_CAP_PROP_FRAME_HEIGHT)
For i = 0 To CountGadgetItems(#Tree_NewProject_Cameras)
If i % 2
AddElement(VideoFrames())
CopyStructure(GetGadgetItemData(#Tree_NewProject_Cameras, i), @VideoFrames()\CaptureDevice, CaptureDevices)
EndIf
Next
*Resolution.VideoCanvas = GetGadgetItemData(#ComboBox_NewProjectCanvasSize, GetGadgetState(#ComboBox_NewProjectCanvasSize))
*Resolution\W = W
*Resolution\H = H
*Resolution\ResolutionW = *Resolution\Width / W
*Resolution\ResolutionH = *Resolution\Height / H
*dst.IplImage = cvCreateImage(*Resolution\Width, *Resolution\Height, #IPL_DEPTH_8U, 3)
ReDim *Images(W*H)
ResetList(VideoFrames())
i = 1
MainImage = CreateImage(#PB_Any, *Resolution\Width, *Resolution\Height)
ForEach VideoFrames()
*Images(i - 1) = cvCreateImage(*Resolution\ResolutionW, *Resolution\ResolutionH, #IPL_DEPTH_8U, 3)
VideoFrames()\Position = GetGadgetItemText(#Tree_NewProject_Texts, 2 * i - 2)
VideoFrames()\TextPosition = GetGadgetItemText(#Tree_NewProject_Texts, 2 * (i - 1) + 1)
cvInitFont(VideoFrames()\Font, #CV_FONT_HERSHEY_SIMPLEX, 1, 1, #Null, 1, #CV_AA)
i+1
Next
If *Resolution\Width > WindowWidth(#Window_Main)
ResizeRatio = *Resolution\Width / *Resolution\Height
ResizeGadget(#ImageGadget_Main, 0, 0, Int(WindowHeight(#Window_Main) - 2 * StatusBarHeight(#StatusBar_Main)) * ResizeRatio, WindowHeight(#Window_Main) - 2 * StatusBarHeight(#StatusBar_Main))
Else
ResizeGadget(#ImageGadget_Main, 0, 0, *Resolution\Width, *Resolution\Height)
EndIf
ResetList(VideoTexts())
ForEach VideoTexts()
ResetList(VideoFrames())
ForEach VideoFrames()
If VideoFrames()\Position = VideoTexts()\Position
VideoFrames()\Text = VideoTexts()\Text
VideoFrames()\TextPosition = VideoTexts()\TextPosition
Break
EndIf
Next
Next
ClearList(VideoTexts())
CloseWindow(#Window_NewProject)
DisableWindow(#Window_Main, #False)
CaptureThr = CreateThread(@CaptureFrames(), 0)
CaptureFlag = #True
ProcedureReturn
EndProcedure
Procedure MethodWindowNewProjectCancel()
CloseWindow(#Window_NewProject)
DisableWindow(#Window_Main, #False)
ProcedureReturn
EndProcedure
Procedure MethodDrawLayoutCanvas()
Protected.i W, H, RatioW, RatioH
W = GetGadgetState(#SpinGadget_NewProjectHorizontal)
H = GetGadgetState(#SpinGadget_NewProjectVertical)
RatioW = GadgetWidth(#Canvas_NewProject) / W
RatioH = GadgetHeight(#Canvas_NewProject) / H
StartDrawing(CanvasOutput(#Canvas_NewProject))
Box(0, 0, GadgetWidth(#Canvas_NewProject), GadgetHeight(#Canvas_NewProject))
For i = 0 To W
Line(0 + (i * RatioW), 0, 1, GadgetHeight(#Canvas_NewProject), RGB(255, 0, 0))
Next
For i = 0 To H
Line(0, 0 + (i * RatioH), GadgetWidth(#Canvas_NewProject), 1, RGB(255, 0, 0))
Next
StopDrawing()
ClearGadgetItems(#Tree_NewProject_Cameras)
ClearGadgetItems(#Tree_NewProject_Texts)
ClearList(VideoTexts())
k = 0
For i = 1 To W
For j = 1 To H
AddGadgetItem(#Tree_NewProject_Cameras, k, Str(i) + "x" + Str(j))
SetGadgetItemData(#Tree_NewProject_Cameras, k, k)
AddGadgetItem(#Tree_NewProject_Texts, k, Str(i) + "x" + Str(j))
SetGadgetItemData(#Tree_NewProject_Texts, k, k)
AddElement(VideoTexts())
VideoTexts()\Position = Str(i) + "x" + Str(j)
k + 1
Next
Next
ProcedureReturn
EndProcedure
; Procedures
Procedure TreeViewExpandSubLevel(GadgetID.i, SubLevelToExpand.i)
For i = 0 To CountGadgetItems(GadgetID) - 1
If GetGadgetItemAttribute(GadgetID, i, #PB_Tree_SubLevel) <= SubLevelToExpand
SetGadgetItemState(GadgetID, i, #PB_Tree_Expanded)
EndIf
Next i
EndProcedure
Procedure DetectCameras(*p)
Protected.s TmpStr = Space(255)
Protected.b nCreate
Protected *capture
PostEvent(#Event_ThreadMessage, #Window_Main, #PB_Ignore, #EventType_DetectCameras, 0)
PostEvent(#Event_ThreadMessage, #Window_Main, #PB_Ignore, #EventType_ManageGadgets, 1)
ClearList(VideoDevices())
DeviceCount = setupESCAPI()
For i = 0 To DeviceCount - 1
nCreate = 0
AddElement(VideoDevices())
Repeat
nCreate + 1
*capture = cvCreateCameraCapture(i)
If *capture
getCaptureDeviceName(0, @TmpStr, 255)
If PeekS(@TmpStr, -1, #PB_UTF8) <> ""
VideoDevices()\ID = i
VideoDevices()\Name + "#" + Str(i+1) + " " + PeekS(@TmpStr,-1,#PB_UTF8)
VideoDevices()\capture = *capture
EndIf
EndIf
Until nCreate = 5 Or *capture
Next
PostEvent(#Event_ThreadMessage, #Window_Main, #PB_Ignore, #EventType_DetectCameras, DeviceCount)
PostEvent(#Event_ThreadMessage, #Window_Main, #PB_Ignore, #EventType_ManageGadgets, 0)
ProcedureReturn
EndProcedure
Procedure CreateGadgets()
If CreateMenu(#MainMenu, WindowID(#Window_Main))
MenuTitle("File")
MenuItem(#MainMenu_NewProject, "New project")
MenuItem(#MainMenu_LoadProject, "Load project")
MenuBar()
MenuItem(#MainMenu_SaveProject, "Save project") : DisableMenuItem(#MainMenu, #MainMenu_SaveProject, #True)
MenuItem(#MainMenu_CloseProject, "Close project") : DisableMenuItem(#MainMenu, #MainMenu_CloseProject, #True)
MenuBar()
MenuItem(#MainMenu_Exit, "Exit")
MenuTitle("Project")
MenuItem(#MainMenu_RecordPause, "Record") : DisableMenuItem(#MainMenu, #MainMenu_RecordPause, #True)
MenuBar()
MenuItem(#MainMenu_Settings, "Settings") : DisableMenuItem(#MainMenu, #MainMenu_Settings, #True)
MenuBar()
MenuItem(#MainMenu_DetectCameras, "Detect cameras")
EndIf
If CreateStatusBar(#StatusBar_Main, WindowID(#Window_Main))
AddStatusBarField(WindowWidth(#Window_Main))
EndIf
ImageGadget(#ImageGadget_Main, 0, 0, WindowWidth(#Window_Main), WindowHeight(#Window_Main) - 2 * StatusBarHeight(#StatusBar_Main),#Null)
ProcedureReturn
EndProcedure
Procedure CreateNewProject()
DisableWindow(#Window_Main, #True)
If OpenWindow(#Window_NewProject, 0, 0, 640, 640, "Create new project", #PB_Window_WindowCentered | #PB_Window_Tool, WindowID(#Window_Main))
TextGadget(#PB_Any, 10, 13, 100, 20, "Video canvas size")
ComboBoxGadget(#ComboBox_NewProjectCanvasSize, 120, 10, 120, 20)
For i = 0 To ArraySize(Canvases())
AddGadgetItem(#ComboBox_NewProjectCanvasSize, i, Canvases(i)\Name)
SetGadgetItemData(#ComboBox_NewProjectCanvasSize, i, @Canvases(i))
Next
SetGadgetState(#ComboBox_NewProjectCanvasSize, 0)
TextGadget(#PB_Any, 260, 13, 100, 20, "Horizontal tiles")
SpinGadget(#SpinGadget_NewProjectHorizontal, 360, 10, 40, 20, 1, 16, #PB_Spin_Numeric) : SetGadgetState(#SpinGadget_NewProjectHorizontal, 1)
TextGadget(#PB_Any, 420, 13, 100, 20, "Vertical tiles")
SpinGadget(#SpinGadget_NewProjectVertical, 520, 10, 40, 20, 1, 16, #PB_Spin_Numeric) : SetGadgetState(#SpinGadget_NewProjectVertical, 1)
TextGadget(#PB_Any, 10, 40, 100, 20, "Pick cameras")
TreeGadget(#Tree_NewProject_Cameras, 10, 70, 200, 170) : GadgetToolTip(#Tree_NewProject_Cameras, "Right click to assign camera to frame.")
TextGadget(#PB_Any, 220, 40, 100, 20, "Assign text")
TreeGadget(#Tree_NewProject_Texts, 220, 70, 200, 170)
CanvasGadget(#Canvas_NewProject, 10, 260, 620, 340)
MethodDrawLayoutCanvas()
ButtonGadget(#Button_NewProjectOK, 210, 610, 100, 20, "OK")
ButtonGadget(#Button_NewProjectCancel, 330, 610, 100, 20, "Cancel")
EndIf
ProcedureReturn
EndProcedure
Procedure CaptureFrames(*p)
Protected.i FrameWidth, FrameHeight
Protected.d RowNumber, ColumnNumber
While CaptureFlag = #True
ResetList(VideoFrames())
RowNumber = ListSize(VideoFrames()) / *Resolution\W
ColumnNumber = ListSize(VideoFrames()) / *Resolution\H
i = 0
ForEach VideoFrames()
FrameWidth = *Images(i)\width
FrameHeight = *Images(i)\height
VideoFrames()\X = Mod(i,ColumnNumber) * FrameWidth
VideoFrames()\Y = Round(i/ColumnNumber, #PB_Round_Down) * FrameHeight
VideoFrames()\Width = FrameWidth
VideoFrames()\Height = FrameHeight
VideoFrames()\VideoFrame = cvQueryFrame(VideoFrames()\CaptureDevice\capture)
cvResize(VideoFrames()\VideoFrame, *Images(i), #CV_INTER_AREA)
If VideoFrames()\TextPosition = "Top left"
If VideoFrames()\Text = "TimeDate()"
cvPutText(*Images(i), FormatDate("%yyyy-%mm-%dd %hh:%ii:%ss", Date()), 10, 30, VideoFrames()\Font, 0, 0, 255, 0)
Else
cvPutText(*Images(i), VideoFrames()\Text, 10, 30, VideoFrames()\Font, 0, 0, 255, 0)
EndIf
ElseIf VideoFrames()\TextPosition = "Top right"
If VideoFrames()\Text = "TimeDate()"
cvPutText(*Images(i), FormatDate("%yyyy-%mm-%dd %hh:%ii:%ss", Date()), FrameWidth - 200, 30, VideoFrames()\Font, 0, 0, 255, 0)
Else
cvPutText(*Images(i), VideoFrames()\Text, FrameWidth - 200, 30, VideoFrames()\Font, 0, 0, 255, 0)
EndIf
ElseIf VideoFrames()\TextPosition = "Bottom left"
If VideoFrames()\Text = "TimeDate()"
cvPutText(*Images(i), FormatDate("%yyyy-%mm-%dd %hh:%ii:%ss", Date()), 10, FrameHeight - 20, VideoFrames()\Font, 0, 0, 255, 0)
Else
cvPutText(*Images(i), VideoFrames()\Text, 10, FrameHeight - 20, VideoFrames()\Font, 0, 0, 255, 0)
EndIf
ElseIf VideoFrames()\TextPosition = "Bottom right"
If VideoFrames()\Text = "TimeDate()"
cvPutText(*Images(i), FormatDate("%yyyy-%mm-%dd %hh:%ii:%ss", Date()), FrameWidth - 200, FrameHeight - 20, VideoFrames()\Font, 0, 0, 255, 0)
Else
cvPutText(*Images(i), VideoFrames()\Text, FrameWidth - 200, FrameHeight - 20, VideoFrames()\Font, 0, 0, 255, 0)
EndIf
EndIf
cvFlip(*Images(i), #Null, 0)
cvSetImageROI(*dst, Mod(i,ColumnNumber) * FrameWidth, Round(i/ColumnNumber, #PB_Round_Down) * FrameHeight, FrameWidth, FrameHeight)
cvAndS(*Images(i), 0, 0, 0, 0, *dst, #Null)
cvAdd(*dst, *Images(i), *dst, #Null)
cvResetImageROI(*dst)
i + 1
Next
cvFlip(VideoFrames()\VideoFrame, #Null, 0)
StartDrawing(ImageOutput(MainImage))
DrawImage(ImageID(MainImage),0,0)
CopyMemory(*dst\imageData, DrawingBuffer(), *dst\width * *dst\height * 3)
StopDrawing()
ResizeImage(MainImage, GadgetWidth(#ImageGadget_Main), GadgetHeight(#ImageGadget_Main))
If WriterFlag
cvFlip(*dst, #Null, 0)
cvWriteFrame(*writer, *dst)
EndIf
PostEvent(#Event_ThreadMessage, #Window_Main, #PB_Ignore, #EventType_DrawToCanvas, #PB_Ignore)
Delay(40)
Wend
ProcedureReturn
EndProcedure
Procedure QuitSoftware()
If IsThread(DetectCamerasThr)
KillThread(DetectCamerasThr)
EndIf
WriterFlag = #False
If IsThread(CaptureThr)
WaitThread(CaptureThr, 40)
cvReleaseVideoWriter(@*writer)
CaptureFlag = #False
WaitThread(CaptureThr, 40)
EndIf
ResetList(VideoDevices())
ForEach VideoDevices()
cvReleaseCapture(@VideoDevices()\capture)
Next
FreeList(VideoDevices())
If IsThread(CaptureThr)
KillThread(CaptureThr)
EndIf
End 0
ProcedureReturn
EndProcedure
Procedure CameraPopUpMenuEvent()
Protected.i CurrentTreePosition
Protected.s MenuItemText
CurrentTreePosition = GetGadgetState(#Tree_NewProject_Cameras)
MenuItemText = GetMenuItemText(#PopUpMenu_Cameras, EventMenu())
AddGadgetItem(#Tree_NewProject_Cameras, CurrentTreePosition + 1, MenuItemText, #Null, 1)
ResetList(VideoDevices())
ForEach VideoDevices()
If VideoDevices()\Name = MenuItemText
Break
EndIf
Next
SetGadgetItemData(#Tree_NewProject_Cameras, CurrentTreePosition + 1, @VideoDevices())
SetGadgetItemState(#Tree_NewProject_Cameras, CurrentTreePosition + 1, #PB_Tree_Expanded)
TreeViewExpandSubLevel(#Tree_NewProject_Cameras, 1)
ProcedureReturn
EndProcedure
Procedure TextsPopUpMenuEvent()
Protected.i CurrentTreePosition
Protected.s MenuItemText, Position
CurrentTreePosition = GetGadgetState(#Tree_NewProject_Texts)
MenuItemText = GetMenuItemText(#PopUpMenu_Texts, EventMenu())
Position = GetGadgetItemText(#Tree_NewProject_Texts, CurrentTreePosition)
AddGadgetItem(#Tree_NewProject_Texts, CurrentTreePosition + 1, MenuItemText, #Null, 1)
TreeViewExpandSubLevel(#Tree_NewProject_Texts, 1)
ResetList(VideoTexts())
ForEach VideoTexts()
If VideoTexts()\Position = Position
VideoTexts()\TextPosition = MenuItemText
VideoTexts()\Text = InputRequester("Please enter text", "Please enter text for camera on position " + Position, "Camera x")
Break
EndIf
Next
ProcedureReturn
EndProcedure
Procedure CreateCanvases()
Canvases(0)\Name = "DV PAL - 720x576"
Canvases(0)\Width = 720
Canvases(0)\Height = 576
Canvases(1)\Name = "DV NTSC - 720x480"
Canvases(1)\Width = 720
Canvases(1)\Height = 480
Canvases(2)\Name = "D4 - 1440x1024"
Canvases(2)\Width = 1440
Canvases(2)\Height = 1024
Canvases(3)\Name = "D16 - 2880x2048"
Canvases(3)\Width = 2880
Canvases(3)\Height = 2048
Canvases(4)\Name = "720p - 1280x720"
Canvases(4)\Width = 1280
Canvases(4)\Height = 720
Canvases(5)\Name = "1080p - 1920x1080"
Canvases(5)\Width = 1920
Canvases(5)\Height = 1080
ProcedureReturn
EndProcedure
; OnThread Messages
Procedure OnThreadMessage()
Select EventType()
Case #EventType_DetectCameras
If EventData()
StatusBarText(#StatusBar_Main, 0, "Detected " + Str(EventData()) + " camera(s).")
If CreatePopupMenu(#PopUpMenu_Cameras)
i = 1000
ResetList(VideoDevices())
ForEach VideoDevices()
MenuItem(i, VideoDevices()\Name)
BindMenuEvent(#PopUpMenu_Cameras, i, @CameraPopUpMenuEvent())
i + 1
Next
EndIf
If CreatePopupMenu(#PopUpMenu_Texts)
MenuItem(#PopUpMenu_Texts_TL, "Top left")
MenuItem(#PopUpMenu_Texts_TR, "Top right")
MenuItem(#PopUpMenu_Texts_BL, "Bottom left")
MenuItem(#PopUpMenu_Texts_Br, "Bottom right")
For i = #PopUpMenu_Texts_TL To #PopUpMenu_Texts_BR
BindMenuEvent(#PopUpMenu_Texts, i, @TextsPopUpMenuEvent())
Next
EndIf
Else
StatusBarText(#StatusBar_Main, 0, "Detecting cameras, stand by...")
EndIf
Case #EventType_ManageGadgets
If EventData() = 0
For i = #MainMenu_NewProject To #MainMenu_RecordPause
DisableMenuItem(#MainMenu, i, #False)
Next
ElseIf EventData() = 1
For i = #MainMenu_NewProject To #MainMenu_RecordPause
DisableMenuItem(#MainMenu, i, #True)
Next
EndIf
Case #EventType_DrawToCanvas
SetGadgetState(#ImageGadget_Main, ImageID(MainImage))
EndSelect
ProcedureReturn
EndProcedure
If OpenWindow(#Window_Main, 0, 0, 1024, 768, #ApplicationName, #PB_Window_Maximize | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget | #PB_Window_SizeGadget)
SetWindowCallback(@WinProc(), #Window_Main)
CreateGadgets()
CreateCanvases()
BindEvent(#Event_ThreadMessage, @OnThreadMessage())
DetectCamerasThr = CreateThread(@DetectCameras(), 0)
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Gadget
Select EventGadget()
Case #Tree_NewProject_Cameras
Select EventType()
Case #PB_EventType_RightClick
DisplayPopupMenu(#PopUpMenu_Cameras, WindowID(#Window_NewProject))
EndSelect
Case #Tree_NewProject_Texts
Select EventType()
Case #PB_EventType_RightClick
DisplayPopupMenu(#PopUpMenu_Texts, WindowID(#Window_NewProject))
EndSelect
Case #SpinGadget_NewProjectHorizontal
Select EventType()
Case #PB_EventType_Change
MethodDrawLayoutCanvas()
EndSelect
Case #SpinGadget_NewProjectVertical
Select EventType()
Case #PB_EventType_Change
MethodDrawLayoutCanvas()
EndSelect
Case #Button_NewProjectOK
MethodWindowNewProjectOK()
Case #Button_NewProjectCancel
MethodWindowNewProjectCancel()
EndSelect
Case #PB_Event_Menu
Select EventMenu()
Case #MainMenu_NewProject : CreateNewProject()
Case #MainMenu_DetectCameras
If IsThread(DetectCamerasThr) = 0
DetectCamerasThr = CreateThread(@DetectCameras(), 0)
EndIf
Case #MainMenu_RecordPause
WriterFileName = SaveFileRequester("Save video", "Video.avi", "AVI (*.avi)|*.avi", 0)
If WriterFileName
*writer = cvCreateVideoWriter(WriterFileName, CV_FOURCC("D", "I", "V", "X"), 7, *Resolution\Width, *Resolution\Height, #True)
If Not *writer : cvCreateVideoWriter(WriterFileName, CV_FOURCC("M", "S", "V", "C"), 7, *Resolution\Width, *Resolution\Height, #True) : EndIf
WriterFlag = #True
EndIf
Case #MainMenu_Exit : QuitSoftware()
EndSelect
EndSelect
Until Event = #PB_Event_CloseWindow
EndIf