PureBasic Interface to OpenCV

Developed or developing a new product in PureBasic? Tell the world about it.
JHPJHP
Addict
Addict
Posts: 2129
Joined: Sat Oct 09, 2010 3:47 am
Contact:

Re: PureBasic Interface to OpenCV

Post by JHPJHP »

skywalk wrote:Mine is a muddy river with beaver and muskrat and the usual water fowl.
Sounds like heaven; my favorite times in life have been in places like the one you have just described.

----------------------------------

Updated (Windows Main Packages):
- added 1 example
-- pbcv_webcam_MDI_cvtcolor.pb: PureBasic parent window hosting an OpenCV webcam child window

This example starts a new naming convention [ pbcv ]; a PureBasic example with an embedded OpenCV window.

Using a wide range of API's and Callbacks I managed to embed an OpenCV window into a PureBasic frame.
While the embedding was fairly easy, my main focus was to have a dynamic window that responded correctly when mixing with PureBasic Gadgets.

The embedded window (webcam) can be resized and moved, and includes an optional title bar.
The CONSTANTS at the beginning of the code can be used to control most options, but this is only an example meant for instructional purposes.

The advantage of this example is that it combines speed with function.
The examples that start with [ cv ] have speed, but access to PureBasic Gadgets is limited.
The examples that start with [ pb ] have access to PureBasic Gadgets, but the speed of OpenCV is reduced because images are converted between platforms.
Last edited by JHPJHP on Mon Apr 05, 2021 12:53 am, edited 4 times in total.
JHPJHP
Addict
Addict
Posts: 2129
Joined: Sat Oct 09, 2010 3:47 am
Contact:

Re: PureBasic Interface to OpenCV

Post by JHPJHP »

Updated (all packages):
- improvements to pbcv_webcam_MDI_cvtcolor.pb
- renamed some examples, conforming to a new naming convention
- set DPI Aware to all Windows examples that start with [ pb ]

Naming Convention
1. cv_ : OpenCV examples, OpenCV image / window
2. cv_le_ : OpenCV Legacy examples, OpenCV image / window
3. cv_pb_ : OpenCV examples, PureBasic to OpenCV image / window
4. pb_cv_ : PureBasic examples, OpenCV to PureBasic image / window
5. pbcv_ : PureBasic examples, OpenCV image / window embedded into PureBasic gadget / window

NB*: There is no one right solution, each of the example types above have there own benefits depending on your requirements.
Last edited by JHPJHP on Mon Apr 05, 2021 12:54 am, edited 4 times in total.
JHPJHP
Addict
Addict
Posts: 2129
Joined: Sat Oct 09, 2010 3:47 am
Contact:

Re: PureBasic Interface to OpenCV

Post by JHPJHP »

Updated (Windows Main Packages):
- added 1 example
-- pbcv_webcam_cvtcolor.pb: PureBasic ContainerGadget hosting an OpenCV webcam child window

pbcv_webcam_cvtcolor.pb
This example greatly expands the use of OpenCV with PureBasic, converting the ContainerGadget into an OpenCvGadget.

Updated Packages
- OpenCV_2.4.13.6_WIN_32_SRC_(main)
- OpenCV_2.4.13.6_WIN_64_SRC_(main)
- OpenCV_3.4.1_WIN_32_SRC_(world)
- OpenCV_3.4.1_WIN_64_SRC_(world)

Image
Last edited by JHPJHP on Fri Apr 02, 2021 4:23 am, edited 2 times in total.
JHPJHP
Addict
Addict
Posts: 2129
Joined: Sat Oct 09, 2010 3:47 am
Contact:

Re: PureBasic Interface to OpenCV

Post by JHPJHP »

Updated (Windows Main Packages):
- pbcv_webcam_cvtcolor.pb
- pbcv_webcam_MDI_cvtcolor.pb
- numerous small improvements to various parts of the code

pbcv_webcam_cvtcolor.pb
Code has been restructured; main OpenCV loop is now threaded.

pbcv_webcam_MDI_cvtcolor.pb
Example includes a second webcam window.
Code has been restructured; main OpenCV loop is now threaded.
Last edited by JHPJHP on Mon Apr 05, 2021 12:55 am, edited 1 time in total.
JHPJHP
Addict
Addict
Posts: 2129
Joined: Sat Oct 09, 2010 3:47 am
Contact:

Re: PureBasic Interface to OpenCV

Post by JHPJHP »

Updated (Windows Main Packages):
- pbcv_webcam_MDI_cvtcolor.pb
- various code improvements

pbcv_webcam_MDI_cvtcolor.pb
Added PureBasic Structured Maps to allow for individual customized window styles.
Windows can be made to look like OpenCV Gadgets (pbcv_webcam_cvtcolor.pb), but still be movable and resizable.

Image
spacebuddy
Enthusiast
Enthusiast
Posts: 346
Joined: Thu Jul 02, 2009 5:42 am

Re: PureBasic Interface to OpenCV

Post by spacebuddy »

Hi All,

Is it possible to set the exposure for a webcam using opencv?

Anyone have sample code?

Thanks
JHPJHP
Addict
Addict
Posts: 2129
Joined: Sat Oct 09, 2010 3:47 am
Contact:

PureBasic Interface to OpenCV

Post by JHPJHP »

Hi spacebuddy,

Note, the following available settings are dependent on your webcam.
spacebuddy wrote:Is it possible to set the exposure for a webcam using opencv?

Anyone have sample code?
Yes, and a code sample is as simple as the follow...

Code: Select all

cvSetCaptureProperty(*capture, #CV_CAP_PROP_EXPOSURE, -4)
I believe the following sets manual exposure (0.25 sets auto exposure OFF and 0.75 sets auto exposure ON)...

Code: Select all

cvSetCaptureProperty(*capture, #CV_CAP_PROP_AUTO_EXPOSURE, 0.25)
If you're having trouble with the correct settings or prefer a dialog window...

Code: Select all

cvSetCaptureProperty(*capture, #CV_CAP_PROP_SETTINGS, #True)
Image Image
Last edited by JHPJHP on Tue Jun 22, 2021 8:00 pm, edited 6 times in total.
JHPJHP
Addict
Addict
Posts: 2129
Joined: Sat Oct 09, 2010 3:47 am
Contact:

PureBasic Interface to OpenCV

Post by JHPJHP »

Updated (Windows Main Packages):
- added two default examples
-- default\aaa_pbcv_webcam_default.pb
-- default\aaa_pbcv_webcam_MDI_default.pb

Default Examples
The new default examples can be used as templates for a PureBasic / OpenCV hybrid application.
Default examples must be copied from their current location to the main examples folder in order to execute.

The examples pbcv_webcam_cvtcolor.pb and pbcv_webcam_MDI_cvtcolor.pb are more advanced, but offer greater detail on how to merge OpenCV with PureBasic.

NB*: The new examples include a context menu option to open webcam settings; see previous post for additional information.
spacebuddy
Enthusiast
Enthusiast
Posts: 346
Joined: Thu Jul 02, 2009 5:42 am

Re: PureBasic Interface to OpenCV

Post by spacebuddy »

thank you, works great!!

I do have another question, my webcam has 5 times zoom, is there anyway to use that with opencv?

Thanks
JHPJHP
Addict
Addict
Posts: 2129
Joined: Sat Oct 09, 2010 3:47 am
Contact:

PureBasic Interface to OpenCV

Post by JHPJHP »

Hi spacebuddy,
spacebuddy wrote:I do have another question, my webcam has 5 times zoom, is there anyway to use that with opencv?
The answer is yes, providing your webcam supports it.
My previous response still applies... if you're having trouble with the correct settings...

Code: Select all

cvSetCaptureProperty(*capture, #CV_CAP_PROP_SETTINGS, #True)
If Zoom is available from the dialog window then maybe. If the slider works to adjust the webcam zoom then maybe.

The only way to tell if OpenCV has access to your webcam is to try it for yourself...

Code: Select all

cvSetCaptureProperty(*capture, #CV_CAP_PROP_ZOOM, [the dialog window should provide working values])
JHPJHP
Addict
Addict
Posts: 2129
Joined: Sat Oct 09, 2010 3:47 am
Contact:

Re: PureBasic Interface to OpenCV

Post by JHPJHP »

Updated (main Windows packages):
- some minor improvements to the OpenCV_Gadget examples
-- pbcv_webcam_cvtcolor.pb, pbcv_webcam_MDI_cvtcolor.pb

NB*: Update also includes improvement to the Default OpenCV_Gadget examples.
AAT
Enthusiast
Enthusiast
Posts: 256
Joined: Sun Jun 15, 2008 3:13 am
Location: Russia

Re: PureBasic Interface to OpenCV

Post by AAT »

Hi, JHPJHP!

Have you seen this topic? https://www.purebasic.fr/english/viewto ... 13&t=77156
I have a simple example for solving this task and I will send it to skinkairewalker at his request. I think this script could be added to the examples of the OpenCV package, you just need to get consent to use the video.
The algorithm for constructing a skeleton by points is not the best, but I had neither the time nor the goal to find a beautiful solution.

Best regads!
AAT
Enthusiast
Enthusiast
Posts: 256
Joined: Sun Jun 15, 2008 3:13 am
Location: Russia

Re: PureBasic Interface to OpenCV

Post by AAT »

Hi
This is a simple example of solving the task of constructing a cyclist's skeleton using the reflective balls on his equipment.
https://www.purebasic.fr/english/viewto ... 85#p569885

Captured and processed frame from the video (the face in this picture was blurred in another program before publishing):
Image
Original video (6.3 MB) can be dowloaded here:
https://disk.yandex.ru/i/W6bAdprTvul1tg
Processed video (19.5 MB) can be dowloaded here:
https://disk.yandex.ru/i/CCkH9mXQRnvY-A

Code: Select all

; AAT 
;
IncludeFile "includes/cv_functions.pbi"

;                                  
;  Select the video source here: 
;                                     
#WebCam = 0            ; > --------+           
#Video = 1             ; > --------+
;                                  |
#VideoSource = #Video  ; <---------+

#WriteSkeleton = #True                  ; #True, if you need to write the processed video to a file 
#WriteFileName = "C:\Skeleton\1.avi"    ; the folder for the file must exist before recording starts 

#MinArea = 30
#MaxArea = 300

#CV_WINDOW_NAME = "Cyclist's skeleton"
#CV_DESCRIPTION = "How to get cyclist's skeleton by using glowing spheres and the OpenCV package + #LF$ + #LF$ + SpaceKey - capture the frame and save it"

Structure xy
  x.l
  y.l
EndStructure

Global lpPrevWndFunc
Global  Dim sk.xy(7), Dim sk1.xy(7)

Procedure WindowCallback(hWnd, uMsg, wParam, lParam)
  Shared exitCV

  Select uMsg
    Case #WM_COMMAND
      Select wParam
        Case 10
          exitCV = #True
      EndSelect
    Case #WM_DESTROY
      exitCV = #True
  EndSelect
  ProcedureReturn CallWindowProc_(lpPrevWndFunc, hWnd, uMsg, wParam, lParam)
EndProcedure

Procedure CvMouseCallback(event, x.l, y.l, flags, *param.CvUserData)
  Select event
    Case #CV_EVENT_RBUTTONDOWN
      DisplayPopupMenu(0, *param\Value)
  EndSelect
EndProcedure

CompilerIf #VideoSource = #WebCam 
  Repeat
    nCreate + 1
    *capture = cvCreateCameraCapture(0)
  Until nCreate = 5 Or *capture
CompilerElseIf #VideoSource = #Video
  Pattern$ = "MP4 (*.mp4)|*.mp4|AVI (*.avi)|*.avi|All files (*.*)|*.*"
  PatternPosition = 0
  Filename.s = OpenFileRequester("Select video source", "videos/1.mp4", Pattern$, PatternPosition)
  If FileSize(Filename) > 0
    *capture.CvCapture = cvCreateFileCapture(Filename)
  Else
    MessageRequester(#CV_WINDOW_NAME, "Video not selected.", #MB_ICONERROR)
  EndIf
CompilerEndIf

If *capture
     
  *image.IplImage  
  *storage.CvMemStorage = cvCreateMemStorage(0)  
  *contours.CvSeq  
  *poly.CvContour
  moments.CvMoments
  
CompilerIf #WriteSkeleton = #True    
  FrameWidth = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_WIDTH)
  FrameHeight = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_HEIGHT) 
  
  sVideo.s = #WriteFileName
  fps.d = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FPS)
  *writer.CvVideoWriter = cvCreateVideoWriter(sVideo, CV_FOURCC("X", "V", "I", "D"), fps, FrameWidth, FrameHeight, #True)  
  
  If *writer        
CompilerEndIf    
    cvNamedWindow(#CV_WINDOW_NAME, #CV_WINDOW_AUTOSIZE)
    window_handle = cvGetWindowHandle(#CV_WINDOW_NAME)
    *window_name = cvGetWindowName(window_handle)
    lpPrevWndFunc = SetWindowLongPtr_(window_handle, #GWL_WNDPROC, @WindowCallback())
  
    If CreatePopupImageMenu(0, #PB_Menu_ModernLook)
      MenuItem(10, "Exit")
    EndIf  
    hWnd = GetParent_(window_handle)
    iconCV = LoadImage_(GetModuleHandle_(#Null), @"icons/opencv.ico", #IMAGE_ICON, 35, 32, #LR_LOADFROMFILE)
    SendMessage_(hWnd, #WM_SETICON, 0, iconCV)
    wStyle = GetWindowLongPtr_(hWnd, #GWL_STYLE)
    SetWindowLongPtr_(hWnd, #GWL_STYLE, wStyle & ~(#WS_MAXIMIZEBOX | #WS_MINIMIZEBOX | #WS_SIZEBOX))
    FrameWidth = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_WIDTH)
    FrameHeight = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_HEIGHT) 
    cvMoveWindow(#CV_WINDOW_NAME, 20, 20)
    ToolTip(window_handle, #CV_DESCRIPTION) 
    *param.CvUserData = AllocateMemory(SizeOf(CvUserData))
    *param\Value = window_handle
    cvSetMouseCallback(*window_name, @CvMouseCallback(), *param)
      
    Repeat
      *image = cvQueryFrame(*capture)
  
      If *image
                      
        ImageHeight = *image\height
        If *image\nChannels = 1
          *gray.IplImage = cvCloneImage(*image)
        Else
          *gray.IplImage = cvCreateImage(*image\width, *image\height, #IPL_DEPTH_8U, 1)
          cvCvtColor(*image, *gray, #CV_BGR2GRAY, 1)        
        EndIf
        cvThreshold(*gray, *gray, 210, 255, #CV_THRESH_BINARY)        
        
        cvClearMemStorage(*storage)
        nContours = cvFindContours(*gray, *storage, @*contours, SizeOf(CvContour), #CV_RETR_LIST, #CV_CHAIN_APPROX_SIMPLE, 0, 0)
    
        If nContours
          *contour.IplImage = cvCreateImage(*gray\width, *gray\height, #IPL_DEPTH_8U, 3)
          cvSet(*contour, 25, 36, 0, 0, #Null)
                     
          cntr = 0
          For rtnCount = 0 To nContours - 1
            area.d = cvContourArea(*contours, 0, #CV_WHOLE_SEQ_END_INDEX, 0)
            
  ; selecting glowing spheres by area
            If area >= #MinArea And area <= #MaxArea             
              *poly = cvApproxPoly(*contours, SizeOf(CvContour), *storage, #CV_POLY_APPROX_DP, 5, 1)
  ; mass center of sphere
              cvMoments(*contours, @moments, 0)
              cx.d = moments\m10 / area
              cy.d = moments\m01 / area
              x = Round(cx, #PB_Round_Nearest)
              y = Round(cy, #PB_Round_Nearest)
              
              If cntr <= 7
                sk(cntr)\x = x
                sk(cntr)\y = y
                cntr + 1
              EndIf
  ; drawing the red circle in the mass center of a glowing sphere 
              cvCircle(*image, x, y, 2, 0, 0, 255, 0, 2, #CV_AA, #Null)              
            EndIf
            *contours = *contours\h_next
          Next
          
  ; connecting the dots to draw a skeleton
          SortStructuredArray(sk(), #PB_Sort_Descending, OffsetOf(xy\x), TypeOf(xy\x))
          For k=0 To 3
            sk1(k)\x = sk(k)\x
            sk1(k)\y = sk(k)\y
          Next        
          If sk(4)\y > ImageHeight/3
            sk1(4)\x = sk(4)\x
            sk1(4)\y = sk(4)\y        
            sk1(7)\x = sk(5)\x
            sk1(7)\y = sk(5)\y         
          Else
            sk1(4)\x = sk(5)\x
            sk1(4)\y = sk(5)\y  
            sk1(7)\x = sk(4)\x
            sk1(7)\y = sk(4)\y          
          EndIf                  
          SortStructuredArray(sk(), #PB_Sort_Ascending, OffsetOf(xy\x), TypeOf(xy\x))    
          For k=0 To 1
            sk1(k+5)\x = sk(k)\x
            sk1(k+5)\y = sk(k)\y
          Next              
          For k=0 To 7
            If k > 0
              cvLine(*image, sk1(k-1)\x, sk1(k-1)\y, sk1(k)\x, sk1(k)\y, 0, 255, 255, 0, 2, #CV_AA, #Null)
            EndIf        
          Next 
        EndIf    
CompilerIf #WriteSkeleton = #True                  
        cvWriteFrame(*writer, *image)                      
CompilerEndIf          
        cvShowImage(#CV_WINDOW_NAME, *image)
        keyPressed = cvWaitKey(30)
        cvReleaseImage(@*contour)
        cvReleaseImage(@*gray)
        
        If keyPressed = 32                                         ; SpaceKey - capture the frame and save it
          If FileSize(GetCurrentDirectory()+"/Frames") <> -2 
            CreateDirectory(GetCurrentDirectory()+"/Frames") 
          EndIf        
          sFrame.s = GetCurrentDirectory()+"/Frames/"+ FormatDate("%yyyy.%mm.%dd %hh-%ii-%ss", Date()) + ".png"       
          cvSaveImage(sFrame, *image, #Null)
          HaveToSaveFrame = #False        
        EndIf
        
      Else
        Break
      EndIf
    Until keyPressed = 27 Or exitCV    
    
    FreeMemory(*param)         
    cvReleaseMemStorage(@*storage)
    cvReleaseImage(@*gray)
CompilerIf #WriteSkeleton = #True         
    cvReleaseVideoWriter(@*writer)     
  Else
    MessageRequester(#CV_WINDOW_NAME, "Unable start writer", #MB_ICONERROR)
  EndIf   
CompilerEndIf    
  cvDestroyAllWindows()
  cvReleaseCapture(@*capture)
Else
  MessageRequester(#CV_WINDOW_NAME, "Unable to open video - operation cancelled.", #MB_ICONERROR)
EndIf
You have to setup compiler options
Current directory: binaries\
https://disk.yandex.ru/i/K3THeV2a8Vr7MA
JHPJHP
Addict
Addict
Posts: 2129
Joined: Sat Oct 09, 2010 3:47 am
Contact:

Re: PureBasic Interface to OpenCV

Post by JHPJHP »

Hi AAT,

The video results look very good; your example will be a great addition...

I just started a 2 -3 month contract and will be mostly unavailable for the duration, but I didn't want you to think I was ignoring you.

I hope this post finds you well; take care my friend.
AAT
Enthusiast
Enthusiast
Posts: 256
Joined: Sun Jun 15, 2008 3:13 am
Location: Russia

Re: PureBasic Interface to OpenCV

Post by AAT »

Hi JHPJHP!
I'm glad you're ok, my friend!
Locked