PureBasic Interface to OpenCV

Developed or developing a new product in PureBasic? Tell the world about it.
User avatar
minimy
Enthusiast
Enthusiast
Posts: 552
Joined: Mon Jul 08, 2013 8:43 pm
Location: off world

Re: PureBasic Interface to OpenCV

Post by minimy »

Hi JHPJHP and all members! somebody can helpme with this?
I try to record a movie with 25 frames per second, i need write every frame at just moment or openCV do this automatic?
I use this code from cam_writeframe1 file, with a little modifications.
when play recorded movie is very fast, like buster keaton or charles chaplin in old film, quickly.. :mrgreen:
How can save a movie with real speed?
Thanks for help and greetings!

Code: Select all

IncludeFile "includes/cv_functions.pbi"

Global lpPrevWndFunc

#CV_WINDOW_NAME = "PureBasic Interface to OpenCV"
#CV_DESCRIPTION = "Video is saved to a folder." + Chr(10) + Chr(10) +
                  "Double-Click the window to open the folder where the video is saved."

ProcedureC WindowCallback(hWnd, Msg, wParam, lParam)
  Shared CaptureCV.b, exitCV.b

  Select Msg
    Case #WM_COMMAND
      Select wParam
        Case 1
          If CaptureCV
            SetMenuItemText(0, 1, "Capture")
            CaptureCV = #False
          Else
            SetMenuItemText(0, 1, "Pause")
            CaptureCV = #True
          EndIf
        Case 10
          exitCV = #True
      EndSelect
    Case #WM_DESTROY
      exitCV = #True
  EndSelect
  ProcedureReturn CallWindowProc_(lpPrevWndFunc, hWnd, Msg, wParam, lParam)
EndProcedure

ProcedureC CvMouseCallback(event, x, y, flags, *param.USER_INFO)
  Select event
    Case #CV_EVENT_RBUTTONDOWN
      DisplayPopupMenu(0, *param\uValue)
    Case #CV_EVENT_LBUTTONDBLCLK
      RunProgram("explorer", "..\Videos", "")
  EndSelect
EndProcedure

recfps=25 
defWidth=720
defHeight=576
deffps=25

Repeat
  nCreate + 1
  *capture = cvCreateCameraCapture(0)
Until nCreate = 5 Or *capture

If *capture
  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(1, "Pause")
    MenuBar()
    MenuItem(10, "Exit")
  EndIf
  hWnd = GetParent_(window_handle)
  opencv = LoadImage_(GetModuleHandle_(0), @"icons/opencv.ico", #IMAGE_ICON, 35, 32, #LR_LOADFROMFILE)
  SendMessage_(hWnd, #WM_SETICON, 0, opencv)
  wStyle = GetWindowLongPtr_(hWnd, #GWL_STYLE)
  SetWindowLongPtr_(hWnd, #GWL_STYLE, wStyle & ~(#WS_MAXIMIZEBOX | #WS_MINIMIZEBOX | #WS_SIZEBOX))
  cvMoveWindow(#CV_WINDOW_NAME, 20, 20)
  ToolTip(window_handle, #CV_DESCRIPTION)

  If FileSize("../Videos") <> -2 : CreateDirectory("../Videos") : EndIf
  sVideo.s = "../Videos/" + FormatDate("%mm-%dd-%yyyy %hh-%ii-%ss", Date()) + ".avi"
  
  ;set resolution and fps
  cvSetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_WIDTH, defWidth)
  cvSetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_HEIGHT, defHeight)
  cvSetCaptureProperty(*capture, #CV_CAP_PROP_FPS, deffps)
  
  ;Verify resolution and fps
  FrameWidth = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_WIDTH)
  FrameHeight = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_HEIGHT)
  Framefps = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FPS)
  Debug FrameWidth
  Debug FrameHeight
  Debug Framefps
  
  *writer = cvCreateVideoWriter(sVideo, CV_FOURCC("D", "I", "V", "X"), recfps, FrameWidth, FrameHeight, #True)
  If Not *writer : cvCreateVideoWriter(sVideo, CV_FOURCC("M", "S", "V", "C"), recfps, FrameWidth, FrameHeight, #True) : MessageRequester("","MSVC Codec en uso"): EndIf

  If *writer
    CaptureCV.b = #True
    *image.IplImage
    *param.USER_INFO = AllocateMemory(SizeOf(USER_INFO))
    *param\uValue = window_handle
    cvSetMouseCallback(*window_name, @CvMouseCallback(), *param)

    Repeat
      *image = cvQueryFrame(*capture)

      If *image
        cvFlip(*image, #Null, 1)

        If CaptureCV : cvWriteFrame(*writer, *image) : EndIf

        cvShowImage(#CV_WINDOW_NAME, *image)
        keyPressed = cvWaitKey(100)
      EndIf
    Until keyPressed = 27 Or exitCV
    FreeMemory(*param)
    cvReleaseVideoWriter(@*writer)
  EndIf
  cvDestroyWindow(#CV_WINDOW_NAME)
  cvReleaseCapture(@*capture)
Else
  MessageBox_(0, "No hay cámara.", #CV_WINDOW_NAME, #MB_ICONERROR)
EndIf
If translation=Error: reply="Sorry, Im Spanish": Endif
User avatar
JHPJHP
Addict
Addict
Posts: 2251
Joined: Sat Oct 09, 2010 3:47 am

Re: PureBasic Interface to OpenCV

Post by JHPJHP »

Hi minimy,

Using the "Quick Solution" I set my webcam's FPS to 15, returning good results. But you may want to make your scripts more dynamic by incorporating threads and calculating the FPS, as mentioned in the "Complete Solution"...

Complete Solution: https://aaka.sh/patel/2013/06/28/live-v ... th-opencv/

Quick Solution:
1. Test your webcam's (recording) max FPS: http://www.onlinemictest.com/webcam-test
2. Set the cvCreateVideoWriter FPS setting (recfps) to your max FPS
3. Change the cvWaitKey value to the following: keyPressed = cvWaitKey(1)

NB*: cvSetCaptureProperty(*capture, #CV_CAP_PROP_FPS, deffps) is not needed.

Additional references:

http://stackoverflow.com/questions/4347 ... mera-video
You're telling the writer that it should play at 30 frames per second. So if you're actually capturing, say, 15 frames per second, those frames are going to be played back faster than real time.
...
http://stackoverflow.com/questions/5035 ... rite-speed
...
So try to avoid waiting a lot at the end of the loop. For example, by decreasing the amount of time the cvWaitKey calls take up.
...
Last edited by JHPJHP on Sat Oct 17, 2015 11:57 am, edited 1 time in total.

If you're not investing in yourself, you're falling behind.

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
AAT
Enthusiast
Enthusiast
Posts: 259
Joined: Sun Jun 15, 2008 3:13 am
Location: Russia

Re: PureBasic Interface to OpenCV

Post by AAT »

Hi, JHPJHP and minimy.

About FPS of Live Capture: http://answers.opencv.org/question/1643 ... e-capture/

Code: Select all

IncludeFile "includes/cv_functions.pbi"
 
#CV_WINDOW_NAME = "Webcam FPS test"

frame_width.l = 640
frame_height.l = 480
frames2count.l = 32  

framecntr.l = 0 : t_start.q = 0 : fps.q = 0 : sfps.q = 0 : mfps.q = 0 : t.q = 0

Repeat
  nCreate + 1
  *capture = cvCreateCameraCapture(0)
Until nCreate = 5 Or *capture
cvSetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_WIDTH, frame_width)
cvSetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_HEIGHT, frame_height)          
If *capture
  *image.IplImage
  font.CvFont
  cvInitFont(@font, #CV_FONT_HERSHEY_SIMPLEX, 1, 1, #Null, 2, #CV_AA)
  cvNamedWindow(#CV_WINDOW_NAME, #CV_WINDOW_AUTOSIZE)    
  Repeat   
    t_start = cvGetTickCount()
    *image = cvQueryFrame(*capture)
    t = (cvGetTickCount() - t_start) / cvgetTickFrequency()
    fps = 1000000/t
    framecntr + 1
    If framecntr <= frames2count
      sfps + fps
    Else
      mfps = sfps/frames2count
      framecntr = 0
      sfps = 0
    EndIf  
    If *image
      cvPutText(*image, "FPS: "+Str(mfps), 20, 40, @font, 255, 0, 0, 0)        
      cvShowImage(#CV_WINDOW_NAME, *image)
      keyPressed = cvWaitKey(1)
    EndIf
  Until keyPressed = 27
  cvDestroyAllWindows()
  cvReleaseCapture(@*capture)
Else
  MessageBox_(0, "Unable to connect to a webcam - operation cancelled.", #CV_WINDOW_NAME, #MB_ICONERROR)
EndIf
I tested this code with my UVC webcam:
10 FPS for 1280x720
24 FPS for 800x600, 640x480, 320x240

Good luck!
Last edited by AAT on Tue Aug 25, 2015 5:41 am, edited 1 time in total.
User avatar
minimy
Enthusiast
Enthusiast
Posts: 552
Joined: Mon Jul 08, 2013 8:43 pm
Location: off world

Re: PureBasic Interface to OpenCV

Post by minimy »

Hi AAT and JHPJHP, Good solutions!
I think my webcam is cheap cam and not work with good speed.
Go to try this code and new camera.. :mrgreen:
Thanks friends!
If translation=Error: reply="Sorry, Im Spanish": Endif
AAT
Enthusiast
Enthusiast
Posts: 259
Joined: Sun Jun 15, 2008 3:13 am
Location: Russia

Re: PureBasic Interface to OpenCV

Post by AAT »

Hi

The idea of using threads, mentioned by JHPJHP (http://www.purebasic.fr/english/viewtop ... 04#p469504), works fine for me.

Code: Select all

IncludeFile "includes/cv_functions.pbi"

#CV_WINDOW_NAME = "Live webcam writer"

Global *image.IplImage, *capture, keyPressed.l

Procedure CamCapture(Dummy)
  cvNamedWindow(#CV_WINDOW_NAME, #CV_WINDOW_AUTOSIZE)
  Repeat
    *image = cvQueryFrame(*capture)
     cvShowImage(#CV_WINDOW_NAME, *image)
     keyPressed = cvWaitKey(1)
  ForEver
EndProcedure

Repeat
  nCreate + 1
  *capture = cvCreateCameraCapture(0)
Until nCreate = 5 Or *capture

If *capture     
  fps = 24
  max_write_time = 20 ; seconds
  max_framecntr = max_write_time * fps  
  
  FrameWidth = 640
  FrameHeight = 480
  cvSetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_WIDTH, FrameWidth)
  cvSetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_HEIGHT, FrameHeight)  
  
  If FileSize("../Videos") <> -2 : CreateDirectory("../Videos") : EndIf
  sVideo.s = "../Videos/" + FormatDate("%mm-%dd-%yyyy %hh-%ii-%ss", Date()) + ".avi" 
  *writer = cvCreateVideoWriter(sVideo, CV_FOURCC("D", "I", "V", "X"), fps, FrameWidth, FrameHeight, #True)  
  If Not *writer : cvCreateVideoWriter(sVideo, CV_FOURCC("M", "S", "V", "C"), fps, FrameWidth, FrameHeight, #True) : EndIf
  
  If *writer        
    t_start.q = 0
    t_end.q = 0
    deltaT.q = (1000000/fps) * cvGetTickFrequency()
    Repeat
      *image = cvQueryFrame(*capture)
    Until *image 
    ThreadNumb = CreateThread(@CamCapture(),0)    
    framecntr = 0    
    t_start = cvGetTickCount()
    t_end = t_start + deltaT   
    Repeat
      Repeat 
        t_start = cvGetTickCount()
      Until t_start >= t_end     
      cvWriteFrame(*writer, *image)
      t_start = cvGetTickCount()
      t_end + deltaT   
      framecntr + 1
    Until framecntr >= max_framecntr Or keyPressed = 27
    KillThread(ThreadNumb)  
    cvReleaseVideoWriter(@*writer)
  EndIf
  cvDestroyWindow(#CV_WINDOW_NAME)
  cvReleaseCapture(@*capture)
Else
  MessageBox_(0, "Unable to connect to a webcam - operation cancelled.", #CV_WINDOW_NAME, #MB_ICONERROR)
EndIf
Good luck!
nicolaus
Enthusiast
Enthusiast
Posts: 456
Joined: Tue Aug 05, 2003 11:30 pm
Contact:

Re: PureBasic Interface to OpenCV

Post by nicolaus »

Hi JHPJHP,

I can't download the zip files because DropBox give me all time a error 500.
Can you sahre it a differnt way plz?

Thanks,
Nico
User avatar
JHPJHP
Addict
Addict
Posts: 2251
Joined: Sat Oct 09, 2010 3:47 am

Re: PureBasic Interface to OpenCV

Post by JHPJHP »

Hi nicolaus,

I just tested the links from my laptop, and had a co-worker test the links from his computer with no issues.

Can you try a different browser or another computer; tested using Internet Explorer and Chrome.

NB*: If anyone else is having trouble downloading the files from the links provided in the first post please report it.
Last edited by JHPJHP on Sat Oct 17, 2015 11:56 am, edited 1 time in total.

If you're not investing in yourself, you're falling behind.

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
nicolaus
Enthusiast
Enthusiast
Posts: 456
Joined: Tue Aug 05, 2003 11:30 pm
Contact:

Re: PureBasic Interface to OpenCV

Post by nicolaus »

Hi,

after e second test the download works very well.

regards,
Nico
acreis
Enthusiast
Enthusiast
Posts: 204
Joined: Fri Jun 01, 2012 12:20 am

Re: PureBasic Interface to OpenCV

Post by acreis »

Hi JHPJHP,

I've tried run cv_inpaint.pb (OpenCV_32 / PB 5.31) and got this error in a message box:

Microsoft Visual C++ Runtime Library
Program: ....Purebasic_Compilation1.exe
This aplication has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

It seems the error occur at line 142:

Code: Select all

cvResize(*image, *resize, #CV_INTER_AREA)
I've checked *image and *resize, they are not null, I can Debug their widths before the stament.

I've tried the code in a range of Windows7 64bits laptops and it's Ok.

But in a particular desktop with Windows XP 32bits I got that error.

By the way, cv_distortion_1.pb runs Ok, unless I load a large image. When the image is resized (line 152 of cv_distortion_1.pb), then, the same error occurs.

Any idea?

Acreis
User avatar
JHPJHP
Addict
Addict
Posts: 2251
Joined: Sat Oct 09, 2010 3:47 am

Re: PureBasic Interface to OpenCV

Post by JHPJHP »

Hi acreis,

Thank you for reporting this problem.

Can you provide a link to a compressed copy of the images that are failing in both examples. I have an XP computer available and I want to recreate the issue, matching your environment as close as possible.

Thank you again.

If you're not investing in yourself, you're falling behind.

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
AAT
Enthusiast
Enthusiast
Posts: 259
Joined: Sun Jun 15, 2008 3:13 am
Location: Russia

Re: PureBasic Interface to OpenCV

Post by AAT »

Hi, JHPJHP!
Hi, acreis,

I have no problem with cv_inpaint.pb and cv_distortion_1.pb. Images size i tested was 4928x3264 pix 24 bit.
Windows XP 32 bit on desktop.

What version of the JHPJHP's OpenCV pack you are using?

Good luck!
acreis
Enthusiast
Enthusiast
Posts: 204
Joined: Fri Jun 01, 2012 12:20 am

Re: PureBasic Interface to OpenCV

Post by acreis »

Hi JHPJHP
Hi AAT

I'm using the opencv32 2.4.11, download of first post.

I found this problem occurs with any image that must be resized.

For example, the bigger images in the folder "\binaries\images" included in dowload.

I think the problem is not how big the image is, but the use of function cvResize().

By the way, the function cvCvtColor() in example "le_stitching_1.pb" causes the same error.

I hope it can help.

Thank you very much.

Acreis
User avatar
JHPJHP
Addict
Addict
Posts: 2251
Joined: Sat Oct 09, 2010 3:47 am

Re: PureBasic Interface to OpenCV

Post by JHPJHP »

Hi acreis, AAT,

Thank you both for looking into this.

I've found the problem, and like you thought it is related to memory allocation, but you'd never guess what caused it...
- applies to all the examples mentioned

includes/pb_procedures.pbi:
- GetImage: OpenFileRequester

Not the function itself, but the Windows API that it's wrapped in. There are numerous references that point to the function EmptyWorkingSet as a solution, but not with the tests I run so far.

To test this replace ProcedureReturn OpenFileRequester("Choose an image file", Folder, Pattern, Position) with ProcedureReturn [ "path\name" ].
Last edited by JHPJHP on Sat Oct 17, 2015 11:54 am, edited 1 time in total.

If you're not investing in yourself, you're falling behind.

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
acreis
Enthusiast
Enthusiast
Posts: 204
Joined: Fri Jun 01, 2012 12:20 am

Re: PureBasic Interface to OpenCV

Post by acreis »

Hi guys,

The proposed solution does not works.

The same problem occurs in example "le_stitching_1.pb", line 258, cvResize(), where no requester was used.

I think we are in a hard way.

Thanks

Acreis
User avatar
JHPJHP
Addict
Addict
Posts: 2251
Joined: Sat Oct 09, 2010 3:47 am

Re: PureBasic Interface to OpenCV

Post by JHPJHP »

Hi acreis,

Are you saying that the proposed solution didn't work with the following examples?
- cv_cvtcolor.pb, cv_inpaint.pb, and cv_distortion_1.pb
- I'll look into the example le_stitching_1.pb.

I was receiving the same error with Windows XP and very large images, but resolved it with the previously mentioned solution.

Like AAT mentioned, he's not getting the error at all. This leads me to believe that it's a Windows XP memory management issue based on configuration / available memory.
- the function cvResize requires a lot of memory, and depending on what is available at the time it's called...

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

Unlike the other examples I can't get le_stitching_1.pb to produce an error.

In order to recreate the error in other examples, I opened an image size of 17200 x 17200, and only when the function OpenFileRequester was involved, and only on Windows XP.
- http://www.purebasic.fr/english/viewtop ... WorkingSet
- http://www.asmcommunity.net/forums/topi ... post-42771
Last edited by JHPJHP on Sat Oct 17, 2015 11:54 am, edited 1 time in total.

If you're not investing in yourself, you're falling behind.

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
Locked