cvReleaseImage should be commented, not cvReleaseCapture.chris319 wrote:Thanks for that. I have edited my previous post and removed it.It's true you do have to release images that you create, but in this particular case, when you handle the image with video, you don't have to do it. Just remove it and your program won't crash while exiting.
PureBasic Interface to OpenCV
Re: PureBasic Interface to OpenCV
Re: PureBasic Interface to OpenCV
Corrected.cvReleaseImage should be commented, not cvReleaseCapture.
Last edited by chris319 on Tue May 26, 2015 5:10 pm, edited 1 time in total.
Re: PureBasic Interface to OpenCV
Hi sphinx,
You're welcome, thanks for commenting.
-------------------------------------------------------------
Hi chris319,
Great addition to the example posted by AAT - nice work.
-------------------------------------------------------------
The 64bit version of "PureBasic Interface to OpenCV" is now available for download. The 32bit version has been updated with numerous bug fixes.
Cheers!
You're welcome, thanks for commenting.
-------------------------------------------------------------
Hi chris319,
Great addition to the example posted by AAT - nice work.
-------------------------------------------------------------
The 64bit version of "PureBasic Interface to OpenCV" is now available for download. The 32bit version has been updated with numerous bug fixes.
Cheers!
Last edited by JHPJHP on Mon Jun 01, 2015 9:02 pm, edited 1 time in total.
If you're not investing in yourself, you're falling behind.
My PureBasic Stuff ➤ FREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
Re: PureBasic Interface to OpenCV
Hi JHPJHP,JHPJHP wrote:The 64bit version of "PureBasic Interface to OpenCV" is now available for download. The 32bit version has been updated with numerous bug fixes.
NB*: The example cv_cam_chessboard_2.pb errors on the function cvCalibrateCamera2 in the 64bit interface; I think the problem may be internal to the DLL.
Cheers!
brilliant as usual!
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.
http://youtu.be/qufwKpjRux8?hd=1
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 -> http://dev.banelli.biz/tmp/OCL-TBB-binaries.7z (IOW - it should be compiled with Create threadsafe executable checked)
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
Last edited by bbanelli on Tue May 26, 2015 1:53 pm, edited 1 time in total.
Re: PureBasic Interface to OpenCV
Hi JHPJHP!
Thank you for your work and for sharing!
--------------------------------------
In numerous examples of the JHPJHP pack you can see next sequence of operands:
It make possible to show openCV window in the PB window at position x=1, y=1.
I needed to change position of the openCV window and i found this solution:
I have little skills in WinAPI, therefore it took some time...
The second solution - without WinAPI
Good luck!
Thank you for your work and for sharing!
--------------------------------------
In numerous examples of the JHPJHP pack you can see next sequence of operands:
Code: Select all
...
cvNamedWindow(#CV_WINDOW_NAME, #CV_WINDOW_AUTOSIZE)
window_handle = cvGetWindowHandle(#CV_WINDOW_NAME)
hWnd = GetParent_(window_handle)
ShowWindow_(hWnd, #SW_HIDE)
OpenWindow(0, 0, 0, FrameWidth, FrameHeight + 60, #CV_WINDOW_NAME, #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
SetParent_(window_handle, WindowID(0))
...
I needed to change position of the openCV window and i found this solution:
Code: Select all
IncludeFile "includes/cv_functions.pbi"
#CV_WINDOW_NAME = "OpenCV Window"
Repeat
nCreate + 1
*capture = cvCreateCameraCapture(0)
Until nCreate = 5 Or *capture
If Not *capture
MessageRequester("Error!", "WebCam not found!")
Else
FrameWidth = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_WIDTH)
FrameHeight = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_HEIGHT)
WinWidth = 800
WinHeight = 600
If WinWidth < FrameWidth + 20
WinWidth = FrameWidth + 20
EndIf
If WinHeight < FrameHeight + 20
WinHeight = FrameHeight + 20
EndIf
cvNamedWindow(#CV_WINDOW_NAME, #CV_WINDOW_NORMAL)
cvResizeWindow(#CV_WINDOW_NAME, FrameWidth, FrameHeight)
window_handle = cvGetWindowHandle(#CV_WINDOW_NAME)
hWnd = GetParent_(window_handle)
ShowWindow_(hWnd, #SW_HIDE)
OpenWindow(0, 0, 0, WinWidth, WinHeight, "Main Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
OpenWindow(1, 0, 0, FrameWidth, FrameHeight, "Child Window", #PB_Window_BorderLess)
SetParent_(WindowID(1), WindowID(0))
SetParent_(window_handle, WindowID(1))
MoveWindow_(WindowID(1), WinWidth-FrameWidth-10, WinHeight-FrameHeight-10, FrameWidth, FrameHeight, 1)
Repeat
event = WaitWindowEvent(1)
*image.IplImage = cvQueryFrame(*capture)
If *image
cvLine(*image, 0, FrameHeight/2, FrameWidth-1, FrameHeight/2, 50, 50, 255, 0, 1, #CV_AA, 0)
cvLine(*image, FrameWidth/2, 0, FrameWidth/2, FrameHeight-1, 50, 50, 255, 0, 1, #CV_AA, 0)
cvCircle(*image, FrameWidth/2, FrameHeight/2, 50, 50, 50, 255, 0, 1, #CV_AA, 0)
cvShowImage(#CV_WINDOW_NAME, *image)
EndIf
cvWaitKey(1)
Until event = #PB_Event_CloseWindow
cvDestroyWindow(#CV_WINDOW_NAME)
cvReleaseCapture(@*capture)The second solution - without WinAPI
Code: Select all
IncludeFile "includes/cv_functions.pbi"
Enumeration 100
#CamFrameID
#ImgGadgetID
#CatchedImgID
EndEnumeration
Repeat
nCreate + 1
*capture = cvCreateCameraCapture(0)
Until nCreate = 5 Or *capture
If Not *capture
MessageRequester("Error!", "WebCam not found!")
Else
imgWidth = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_WIDTH)
imgHeight = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_HEIGHT)
WinWidth = 800
WinHeight = 600
If WinWidth < imgWidth + 20
WinWidth = imgWidth + 20
EndIf
If WinHeight < imgHeight + 20
WinHeight = imgHeight + 20
EndIf
imgPosX = WinWidth - imgWidth - 10
imgPosY = WinHeight - imgHeight - 10
CreateImage(#CamFrameID, imgWidth, imgHeight)
OpenWindow(0, 0, 0, WinWidth, WinHeight, "Main Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ImageGadget(#ImgGadgetID, imgPosX, imgPosY, imgWidth, imgHeight, ImageID(#CamFrameID))
Repeat
event = WaitWindowEvent(1)
*image.IplImage = cvQueryFrame(*capture)
If *image
cvLine(*image, 0, imgHeight/2, imgWidth-1, imgHeight/2, 50, 50, 255, 0, 1, #CV_AA, 0)
cvLine(*image, imgWidth/2, 0, imgWidth/2, imgHeight-1, 50, 50, 255, 0, 1, #CV_AA, 0)
cvCircle(*image, imgWidth/2, imgHeight/2, 50, 50, 50, 255, 0, 1, #CV_AA, 0)
*mat.CvMat = cvEncodeImage(".bmp", *image, 0)
CatchImage(#CatchedImgID, *mat\ptr)
SetGadgetState(#ImgGadgetID, ImageID(#CatchedImgID))
FreeImage(#CatchedImgID)
cvReleaseMat(@*mat)
EndIf
Until event = #PB_Event_CloseWindow
cvReleaseCapture(@*capture)
EndIf Re: PureBasic Interface to OpenCV
There are two ways to implement the 'scope in my example: one is to use an image gadget; the other is to draw the image directly onto the window. If the window goes behind another, the image is being refreshed every 1/30 or 1/60 second, so there is no need for manual refresh. Which would be preferable/more efficient?
This might be asking a lot, but it would be nice if opencv clipped video values of 0 and 255 as they are forbidden values in Rec.709, like so:
This might be asking a lot, but it would be nice if opencv clipped video values of 0 and 255 as they are forbidden values in Rec.709, like so:
Code: Select all
If value > 254: value = 254:elseif value < 1: value = 1:endifRe: PureBasic Interface to OpenCV
In high-end video, Rec.709 specifies that digital code 16 shall be reference black, with codes 1 to 15 acting as "footroom". Digital code 235 shall be reference white, with codes 236 to 254 acting as "headroom". Codes 0 and 255 are used as sync and are not allowed.
http://en.wikipedia.org/wiki/Rec._709#D ... esentation
http://en.wikipedia.org/wiki/Rec._709#D ... esentation
Re: PureBasic Interface to OpenCV
Hi bbanelli,
Thank you for your comments, interest and support.
I just tried your application, and it has a lot of potential. You're correct OpenCV doesn't support camera names, but maybe an index would work:
- nCapture will need to be stored (list, array, etc.)
------------------------------------------------------------------------
Hi AAT,
You're very much welcome.
Thank you for the code examples and invaluable support.
------------------------------------------------------------------------
Hi chris319,
The following may be what you're looking for: cvCvtColor
- additional information
See the example: cv_cvtcolor.pb
- hit the spacebar until the heading reads "XYZ"
------------------------------------------------------------------------
I've compiled an "OpenCV 3.0 RC1" PureBasic (x86 / x64) interface package, but encountered some issues.
- I'm holding off posting an additional link until the final version of OpenCV 3.0 is released, and only if the problems are fixed or I find a way around them
NB*: Currently I have no plans on replacing 2.4.11 with 3.0 due to the changes in setup and support.
While working with "OpenCV 3.0 RC1" I noticed a new function was added (from version 2.4.10 - current):
I've updated the existing downloads, but instead of downloading both packages again, you can just add the above declaration to: cv_functions.pbi.
- new function should be placed before: cvSetTrackbarPos
Cheers.
Thank you for your comments, interest and support.
I just tried your application, and it has a lot of potential. You're correct OpenCV doesn't support camera names, but maybe an index would work:
- nCapture will need to be stored (list, array, etc.)
Code: Select all
Repeat
*capture = cvCreateCameraCapture(nCapture)
If Not *capture : Break : Else : nCapture + 1 : EndIf
cvReleaseCapture(@*capture)
ForEver
cvReleaseCapture(@*capture)
*capture = cvCreateCameraCapture(nCapture - 1)Hi AAT,
You're very much welcome.
Thank you for the code examples and invaluable support.
------------------------------------------------------------------------
Hi chris319,
The following may be what you're looking for: cvCvtColor
- additional information
See the example: cv_cvtcolor.pb
- hit the spacebar until the heading reads "XYZ"
------------------------------------------------------------------------
I've compiled an "OpenCV 3.0 RC1" PureBasic (x86 / x64) interface package, but encountered some issues.
- I'm holding off posting an additional link until the final version of OpenCV 3.0 is released, and only if the problems are fixed or I find a way around them
NB*: Currently I have no plans on replacing 2.4.11 with 3.0 due to the changes in setup and support.
While working with "OpenCV 3.0 RC1" I noticed a new function was added (from version 2.4.10 - current):
Code: Select all
cvSetTrackbarMax(trackbar_name.p-ascii, window_name.p-ascii, maxval)- new function should be placed before: cvSetTrackbarPos
Cheers.
If you're not investing in yourself, you're falling behind.
My PureBasic Stuff ➤ FREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
Re: PureBasic Interface to OpenCV
I tried it. It compiled OK but crashed with an "invalid memory access" error and again with a "pointer is null" error. "Create threadsafe executable" was checked.Speaking of real life examples, I have created a small application that enables multiple video capture with some additional OCV features.
Re: PureBasic Interface to OpenCV
Thanks for the tip (and all the hard work you've done so far for us!), I'll look into this.JHPJHP wrote:Hi bbanelli,
Thank you for your comments, interest and support.
I just tried your application, and it has a lot of potential. You're correct OpenCV doesn't support camera names, but maybe an index would work:
- nCapture will need to be stored (list, array, etc.)Code: Select all
Repeat *capture = cvCreateCameraCapture(nCapture) If Not *capture : Break : Else : nCapture + 1 : EndIf cvReleaseCapture(@*capture) ForEver cvReleaseCapture(@*capture) *capture = cvCreateCameraCapture(nCapture - 1)
It seems that 3.0 is mostly incompatible with your previous work, right? Will it generally be possible at all to work with 3.0 in PB, as far as I can see, they seem to be forcing C++ pretty hard in it...I've compiled an "OpenCV 3.0 RC1" PureBasic (x86 / x64) interface package, but encountered some issues.
- I'm holding off posting an additional link until the final version of OpenCV 3.0 is released, and only if the problems are fixed or I find a way around them
NB*: Currently I have no plans on replacing 2.4.11 with 3.0 due to the changes in setup and support.
Hi chris319,chris319 wrote:I tried it. It compiled OK but crashed with an "invalid memory access" error and again with a "pointer is null" error. "Create threadsafe executable" was checked.Speaking of real life examples, I have created a small application that enables multiple video capture with some additional OCV features.
are you sure your include files are also compiled with "Create threadsafe executable"? Since I've deployed a bit advanced version to several very different computers and it works without a problem. And naturally, you have to use my DLL's since they are recompiled with Intel's TBB to support multithreading. I am rather sure that ESCAPI is not thread safe, but since it is used only once in initialization, perhaps that's not even important (please someone correct me if I'm wrong in general).
Re: PureBasic Interface to OpenCV
Hi bbanelli,
You're welcome.
- the legacy functions have been excluded, but may return in the official release as well as the division of modules
- the functions needed to run the example cv_cam_motionhistory.pb have been removed (moved to legacy)
- in the 64bit version of the interface the function cvGetSize returns an error [ RESOLVED ]
- the "webcam" examples either don't connect or return a black screen
-------------------------------------------------------
Hi bbanelli, chris319,
You're welcome.
On the contrary OpenCV 3.0 is mostly compatible with the PureBasic interface, but there are some issues.bbanelli wrote:It seems that 3.0 is mostly incompatible with your previous work, right?
- the legacy functions have been excluded, but may return in the official release as well as the division of modules
- the functions needed to run the example cv_cam_motionhistory.pb have been removed (moved to legacy)
- in the 64bit version of the interface the function cvGetSize returns an error [ RESOLVED ]
- the "webcam" examples either don't connect or return a black screen
-------------------------------------------------------
Hi bbanelli, chris319,
I experienced the same crash by creating a project without first adding a camera, or adding too many cameras.chris319 wrote:I tried it. It compiled OK but crashed with an "invalid memory access" error and again with a "pointer is null" error.
Last edited by JHPJHP on Tue Jun 02, 2015 11:22 pm, edited 5 times in total.
If you're not investing in yourself, you're falling behind.
My PureBasic Stuff ➤ FREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
Re: PureBasic Interface to OpenCV
bbanelli: I got it to work by selecting File->New Project, then right clicking on "1x1" and selecting my camera after the tooltip appeared. My camera's output appeared on the screen and I was able to create an .avi file. The .avi file caused VLC to crash when I tried to play it back.
The user interface could be a bit more intuitive.
The user interface could be a bit more intuitive.
Re: PureBasic Interface to OpenCV
The thread about a webm recorder has been moved by the moderators to "Coding Questions".
I have a simple audio recorder which encodes to opus, but must clean it up and make sure the buffer contains a fixed number of samples.
I have a simple audio recorder which encodes to opus, but must clean it up and make sure the buffer contains a fixed number of samples.
Re: PureBasic Interface to OpenCV
I don't know if this helps, but it's an interesting find:
http://www.wischik.com/lu/programmer/av ... l#examples
http://www.wischik.com/lu/programmer/av ... l#examples
Re: PureBasic Interface to OpenCV
Updated (x86 / x64):
- Structures, Procedures, and Functions
- improved all the examples that use the Functions: cvCreateHist, cvCalcHist / cvCalcArrHist
-- previously the examples only accepted a single range, but now accept an array of ranges
- fixed the 64bit version of: cv_cam_chessboard_2.pb
OpenCV 3.0 RC1
- the binaries have been released as a World module (single DLL and LIB file)
- the World module became official in version 2.4.7, but the binaries needed building from source
I've created an interface to the latest OpenCV 3.0 RC1 x86 / x64 binaries, but encountered the following issues:
-----------------------------------------------------------------------------------------------------
Applied a global find / replace to all the examples:
- replaced cvDestroyWindow with cvDestroyAllWindows
NB*: I've updated all the Dropbox links in my various "Tricks 'n' Tips" posts to direct download by replacing the following section of the URL: "www.dropbox.com" with "dl.dropboxusercontent.com"
- Structures, Procedures, and Functions
- improved all the examples that use the Functions: cvCreateHist, cvCalcHist / cvCalcArrHist
-- previously the examples only accepted a single range, but now accept an array of ranges
- fixed the 64bit version of: cv_cam_chessboard_2.pb
OpenCV 3.0 RC1
- the binaries have been released as a World module (single DLL and LIB file)
- the World module became official in version 2.4.7, but the binaries needed building from source
I've created an interface to the latest OpenCV 3.0 RC1 x86 / x64 binaries, but encountered the following issues:
NB*: I've sent an email to "OpenCV Admin" concerning the webcam problem mentioned above, but I'm not sure they put a priority on their C interface.JHPJHP wrote:- the legacy functions have been excluded, but may return in the official release as well as the division of modules
- the functions needed to run the example cv_cam_motionhistory.pb have been removed (moved to legacy)
- in the 64bit version of the interface the function cvGetSize returns an error [ RESOLVED ]
- the "webcam" examples either don't connect or return a black screen
-----------------------------------------------------------------------------------------------------
Applied a global find / replace to all the examples:
- replaced cvDestroyWindow with cvDestroyAllWindows
NB*: I've updated all the Dropbox links in my various "Tricks 'n' Tips" posts to direct download by replacing the following section of the URL: "www.dropbox.com" with "dl.dropboxusercontent.com"
If you're not investing in yourself, you're falling behind.
My PureBasic Stuff ➤ FREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.

