Page 37 of 60

Re: PureBasic Interface to OpenCV

Posted: Tue Apr 19, 2016 3:58 am
by JHPJHP
Updated:
- updated 2 examples
-- cv_motion_blur.pb
-- cv_radial_blur.pb

cv_motion_blur.pb
- 4 different directions of blur
- hold down the spacebar to better view the direction of blur (gives the illusion that some pixel-areas are spinning)

cv_radial_blur.pb
- click an X/Y point on the image to reposition the blur
- press enter to reset X/Y point to center

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

A new download link has been added to the first post...

PureBasic Interface to OpenCV :: Demo (32bit / 64bit)

... with a couple bare-metal examples modified from the main 2.4.12 interface, containing only the required includes and binaries.
- pb_sepia.pb: convert a color image to sepia
- pb_webcam.pb: displays the webcam in an image gadget

The examples in the main interface were structured to demonstrate OpenCV functionality written in PureBasic, while these examples were structured towards creating a PureBasic application with the added functionality of OpenCV.

Unlike the main interface examples which use OpenCV Functions to create the window and display an image, these examples convert an OpenCV image to display in a PureBasic gadget.
- this method could be applied to any of the 200+ examples contained in the main interface
- many of the algorithms could be used in a PureBasic application without OpenCV

NB*: As with the main interface project the C-Runtime files have been included, but may not be needed depending on your computers configuration.

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

Updated the following interface examples similar to the method used in the Demo examples:
-- pb_cam_effects_1.pb, pb_cam_effects_2.pb, pb_cam_preferences.pb, pb_cam_resolution.pb
-- pb_gl_cam_cube.pb, pb_gl_cam_invert.pb, pb_gl_parametric_curve.pb, pb_gl_photo_cube.pb

Modified the Procedure OpenCV2PBImage in all projects.

Globally updated all examples replacing the Function MessageBox with MessageRequester.

Re: PureBasic Interface to OpenCV

Posted: Tue Apr 19, 2016 4:03 pm
by AAT
Hi. JHPJHP
"PureBasic Interface to OpenCV ::Demo" is great and usefool addition to the project!

Some words about the Procedure OpenCV2PBImage: i prefer more compact code

Code: Select all

   *mat.CvMat = cvEncodeImage(".bmp", *image, 0)      ;  with ".jpg" it works too
   Result = CatchImage(1, *mat\ptr)   
   SetGadgetState(0, ImageID(1)) 
The demo example "pb_webcam.pb" with this code modification:

Code: Select all

#CV_CAP_ANY                                           = 0
#CV_CAP_PROP_FRAME_WIDTH                              = 3 
#CV_CAP_PROP_FRAME_HEIGHT                             = 4 

Structure CvCapture Align #PB_Structure_AlignC : EndStructure

Structure IplImage Align #PB_Structure_AlignC
  nSize.l
  ID.l
  nChannels.l
  alphaChannel.l
  depth.l
  colorModel.a[4]
  channelSeq.a[4]
  dataOrder.l
  origin.l
  align.l
  width.l
  height.l
  *roi.IplROI
  *maskROI.IplImage
  *imageId
  *tileInfo.IplTileInfo
  imageSize.l
  *imageData.BYTE
  widthStep.l
  BorderMode.l[4]
  BorderConst.l[4]
  *imageDataOrigin.BYTE
EndStructure

Structure CvMat Align #PB_Structure_AlignC
  type.l
  Step.l
  *refcount.LONG
  hdr_refcount.l
  StructureUnion
    *ptr.BYTE
    *s.WORD
    *i.LONG
    *fl.FLOAT
    *db.DOUBLE
  EndStructureUnion
  rows.l
  cols.l
EndStructure

Structure CvScalar Align #PB_Structure_AlignC
  val.d[4]
EndStructure

ImportC "opencv_core2412.lib"
  cvFlip(*src, *dst, flip_mode)
  cvGet2D(*scalar, *arr, idx0, idx1)
  cvSet2D(*arr, idx0, idx1, blue.d, green.d, red.d, alpha.d)
  cvReleaseMat(*mat) 
EndImport

ImportC "opencv_highgui2412.lib"
  cvCreateCameraCapture(index)
  cvGetCaptureProperty.d(*capture, property_id)
  cvQueryFrame(*capture)
  cvReleaseCapture(*capture)
  cvEncodeImage(ext.p-ascii, *image, *params)  
EndImport

Repeat
  nCreate + 1
  *capture.CvCapture = cvCreateCameraCapture(#CV_CAP_ANY)
Until nCreate = 5 Or *capture

If *capture
  FrameWidth = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_WIDTH)
  FrameHeight = cvGetCaptureProperty(*capture, #CV_CAP_PROP_FRAME_HEIGHT)
  *image.IplImage : pbImage = CreateImage(#PB_Any, FrameWidth, FrameHeight)

  If OpenWindow(0, 0, 0, FrameWidth, FrameHeight, "PureBasic Interface to OpenCV", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    ImageGadget(0, 0, 0, FrameWidth, FrameHeight, ImageID(pbImage))

    Repeat
      *image = cvQueryFrame(*capture)

      If *image
        cvFlip(*image, #Null, 1)
;         OpenCV2PBImage(*image, pbImage, FrameWidth, FrameHeight)
;         SetGadgetState(0, ImageID(pbImage))                
        *mat.CvMat = cvEncodeImage(".bmp", *image, 0)      ;  with ".jpg" it works too
        Result = CatchImage(1, *mat\ptr)   
        SetGadgetState(0, ImageID(1)) 
        cvReleaseMat(@*mat)                     
      EndIf
    Until WindowEvent() = #PB_Event_CloseWindow
  EndIf
  FreeImage(pbImage)
  cvReleaseCapture(@*capture)
Else
  MessageRequester("PureBasic Interface to OpenCV", "Unable to connect to a webcam - operation cancelled.", #MB_ICONERROR)
EndIf
Good luck!

Re: PureBasic Interface to OpenCV

Posted: Wed Apr 20, 2016 4:28 am
by JHPJHP
Hi AAT,

Thank you for pointing out a more compact solution to the Procedure OpenCV2PBImage. It motivated me to streamline the examples even further by using CvMat in place of IplImage, which in turn introduced the following function not previously used in any examples:
OpenCV Manual wrote:CvMat* cvLoadImageM(const char* filename, int iscolor=CV_LOAD_IMAGE_COLOR )
The Procedure OpenCV2PBImage is still being used by the interface examples, as it provides an alternate solution without the loss of functionality or speed.
JHPJHP wrote:Updated the following interface examples similar to the method used in the Demo examples:
-- pb_cam_effects_1.pb, pb_cam_effects_2.pb, pb_cam_preferences.pb, pb_cam_resolution.pb
-- pb_gl_cam_cube.pb, pb_gl_cam_invert.pb, pb_gl_parametric_curve.pb, pb_gl_photo_cube.pb
---------------------------------------------------------------------------------

Updated ( PureBasic Interface to OpenCV :: Demo (32bit / 64bit) )
-- see previous post by AAT for changes
-- added 64bit version

Re: PureBasic Interface to OpenCV

Posted: Sat Apr 23, 2016 9:42 pm
by JHPJHP
Updated:
- renamed 1 example
-- cv_template.pb to cv_matchtemplate.pb
- added 6 examples
-- cv_cam_matchtemplate.pb: object recognition using the template matching algorithm
--- see instructions below
-- cv_draw_spiral.pb: draw a circular or square spiral
--- based on script found here
-- cv_gabor_filter_1.pb: a linear filter used for edge detection
-- cv_gabor_filter_2.pb: a linear filter used for edge detection
--- based on script found here
-- le_mov_bgcodebookmodel.pb: using an average difference learning method, foreground moving objects of a certain size are tracked
--- based on script found here
-- le_mov_gaussianbgmodel.pb: using a Gaussian background model, foreground moving objects of a certain size are tracked
--- based on script found here
- modified 1 example
-- cv_vignette.pb: added the option to set the X/Y axis

cv_cam_matchtemplate.pb:
- use the mouse to draw a square/rectangle on the screen
- center/fit an object (i.e. face, eyes, etc.) in the rectangle
- press the spacebar to capture the object and start tracking
- press the spacebar again to reset the selected area
- press enter to remove the selected area

Re: PureBasic Interface to OpenCV

Posted: Mon Apr 25, 2016 2:19 am
by JHPJHP
Updated:
- added 2 examples
-- cv_siemens_star.pb: a pattern used to test the resolution of optical instruments, printers and displays
--- based on script found here
-- cv_water_ripples.pb: creates the illusion of water ripples on a background image
--- based on script found here
- modified 2 examples
-- cv_mov_writeframe_FFMPEG.pb: added a viewable video-stream
-- cv_stereobm.pb: added a viewable disparity map and control panel
- added 1 sound file
-- /sounds/droplet.wav

NB*: Update also includes minor improvements and bug fixes to various examples.

Re: PureBasic Interface to OpenCV

Posted: Fri May 13, 2016 7:40 pm
by JHPJHP
PureBasic Interface to OpenCV :: OSX Demo (x64)

With a discussion that started from the thread Image Waves, wilbert, Keya, and myself looked into extending compatibility to OSX:
- Keya posted a link to a tool (install_name_tool) that modifies a dynamic libraries internal locations pointers
- wilbert built dynamic libraries from the latest OpenCV sources which partially worked, but failed when moved to another computer
- wilbert posted information regarding a tool (otool) that lists a dynamic libraries internal location pointers and dependencies
- wilbert posted a working set of libraries that were modified using the tools: otool, install_name_tool
- wilbert reported that the example would run from the IDE, but failed when compiled
- wilbert posted a link to a possible solution fixing the compiled example: Linking and Install Names

Working with the above information:
- installed XCode and CMake
-- created shared and dynamic libraries from the OpenCV sources
- using otool
-- listed all the dynamic libraries internal locations pointers and dependencies
- using install_name_tool
-- patched the necessary libraries to get the examples working from the IDE
-- patched the necessary libraries to get the compiled examples working

Re: PureBasic Interface to OpenCV

Posted: Tue May 17, 2016 7:53 pm
by JHPJHP
Updated:
- added an OpenCV OSX x64 demo version of PureBasic Interface to OpenCV
-- pb_sepia.pb: converts an RGB image to sepia
-- pb_webcam.pb: processes images from the webcam to an ImageGadget as either RGB or grayscale
- updated the Windows demo package
- updated the main downloads with a few minor improvements

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

I'd like to thank wilbert who was a big support getting the OpenCV libraries to work with PureBasic.

I would also like to thank Keya who helped test the various versions leading to this release.

I used the OSX ListIconGadget script by Shardik in the DyLib Patcher tool.
- thank you Shardik for making your script available, and wilbert for [PB Cocoa] Methods, Tips & Tricks

Re: PureBasic Interface to OpenCV

Posted: Wed May 18, 2016 8:34 am
by Keya
brilliant work JHP and wilbert!!! another door of possibilities opens :)
btw Im guessing it will be a bit easier to get working on linux than OSX!

Re: PureBasic Interface to OpenCV

Posted: Thu May 19, 2016 7:41 am
by JHPJHP
Hi Keya,

Thank you for your kind words, and the support you provided.

I'll most likely add a Linux version at some time, but I'm going to wait and see how the OSX version is first received.

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

Updated PureBasic Interface to OpenCV :: OSX Demo (64bit)
- new set of libraries patch for better compatibility
- some minor improvements to the examples

Adding to his already great support, wilbert provided a better solution for patching the libraries.

Re: PureBasic Interface to OpenCV

Posted: Fri May 20, 2016 9:39 pm
by JHPJHP
Updated:
- added an OpenCV OSX x64 version of PureBasic Interface to OpenCV

Not to be confused with the previous demo version, this new download is the start to a complete copy of the main Interface.
- currently 1 example has been converted to work in OSX; a template for all others

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

I've thanked wilbert for all his support, which continued to this latest release. But I would also like to emphasize to the PureBasic community, that without his help an OSX version of the Interface would have remained just an idea.

Re: PureBasic Interface to OpenCV

Posted: Sat May 21, 2016 5:06 pm
by JHPJHP
As anyone following this thread is aware, wilbert has been working with me to bring PureBasic Interface to OpenCV to OSX. This has mostly been done by PM, but because of the numerous contributions and updates, it would benefit the community better if the conservations were documented.

The follow is the latest code snippet written by wilbert. More of his OSX Procedures can be found at, and will be added to, the bottom part of /includes/pb_procedures.pbi.
wilbert wrote:I don't know if you noticed but when you post keyboard events when dragging the slider, they do get added every time the slider moves. This means when you release the mouse button, the return key event is processed multiple times which is most likely undesirable. A possible way to solve this would be to add an optional argument to the keybd_event procedure which removes all existing key events before posting a new one so there is always only one in the queue.

Code: Select all

ImportC ""
  CFRelease(CFTypeRef)
  CGEventCreateKeyboardEvent(CGEventSourceRef, CGVirtualKeyCode.u, KeyDown)
EndImport

Procedure keybd_event(VirtualKey.u, Clear = #False)
  KeyEvent = CGEventCreateKeyboardEvent(0, VirtualKey, #True)
  If KeyEvent
    NSApp = CocoaMessage(0, 0, "NSApplication sharedApplication")
    If Clear
      CocoaMessage(0, NSApp, "nextEventMatchingMask:", $600, "untilDate:", #nil,
                   "inMode:$", @"kCFRunLoopDefaultMode", "dequeue:", #YES)
    EndIf
    CocoaMessage(0, NSApp, "postEvent:",
                 CocoaMessage(0, 0, "NSEvent eventWithCGEvent:", KeyEvent),
                 "atStart:", #NO)
    CFRelease(KeyEvent)
    KeyEvent = CGEventCreateKeyboardEvent(0, VirtualKey, #False)
    CocoaMessage(0, NSApp, "postEvent:",
                 CocoaMessage(0, 0, "NSEvent eventWithCGEvent:", KeyEvent),
                 "atStart:", #NO)
    CFRelease(KeyEvent)
  EndIf
EndProcedure

Re: PureBasic Interface to OpenCV

Posted: Sat May 21, 2016 8:23 pm
by JHPJHP
Currently there is a problem with OpenCV Functions in OSX that include a color/scalar parameter.
- color cannot be set, it always returns black (value 0)

Save the following script to the folder /OpenCV_OSX_x64/
- add the following Compiler Option
-- Compiler -- Compiler Options -- Compile/Run -- Current directory: binaries\

Code: Select all

IncludeFile "includes/cv_functions.pbi"

ImportC "binaries/libopencv_core.2.4.12.dylib"
  cvRectangleJHP(*img, *pt1, *pt2, color.d, thickness, line_type, shift) As "_cvRectangle"
EndImport

SetWindowCloseEvent()
#CV_WINDOW_NAME = "PureBasic Interface to OpenCV"
cvNamedWindow(#CV_WINDOW_NAME, #CV_WINDOW_AUTOSIZE)
window_handle = cvGetWindowHandle(#CV_WINDOW_NAME)
AddWindowCloseButton(window_handle)
PokeL(@*size, 500) : PokeL(@*size + 4, 500)
*image.IplImage = cvCreateImage(*size, #IPL_DEPTH_8U, 3)

; The following Functions could have been used to set the background WHITE if color/scalar was working:
; color.CvScalar : color\val[0] = 255 : color\val[1] = 255 : color\val[2] = 255 : color\val[3] = 0
; cvSet(*image, @color, #Null)

For y = 0 To *image\height - 1
  For x = 0 To *image\width - 1
    PokeA(@*image\imageData\b + y * *image\widthStep + x * 3 + 0, 255)
    PokeA(@*image\imageData\b + y * *image\widthStep + x * 3 + 1, 255)
    PokeA(@*image\imageData\b + y * *image\widthStep + x * 3 + 2, 255)
  Next
Next
PokeL(@*pt1, 150) : PokeL(@*pt1 + 4, 150)
PokeL(@*pt2, 150 + 200) : PokeL(@*pt2 + 4, 150 + 200)
color.CvScalar : color\val[0] = 255 : color\val[1] = 0 : color\val[2] = 0 : color\val[3] = 0
cvRectangleJHP(*image, *pt1, *pt2, @color, 5, #CV_AA, #Null)

Repeat
  If *image
    cvShowImage(#CV_WINDOW_NAME, *image)
    keyPressed = cvWaitKey(0)
  EndIf
Until keyPressed = 27
cvReleaseImage(@*image)
cvDestroyAllWindows()

Re: PureBasic Interface to OpenCV

Posted: Sun May 22, 2016 5:33 am
by wilbert
JHPJHP wrote:Currently there is a problem with OpenCV Functions in OSX that include a color/scalar parameter.
- color cannot be set, it always returns black (value 0)
The real problem is that OpenCV expects structures to be passed by value instead of by reference; something PureBasic doesn't support.
For x86, it was relatively easy to work around this problem since every function argument is pushed on the stack for x86.
For x64, it's complicated. The reason why a different approach needs to be used for OSX compared to Windows is that Windows uses a different calling convention.

Both OSX and Linux use the System V ABI
http://www.x86-64.org/documentation/abi.pdf
See chapter 3.2.3 for Parameter Passing.

For the cvRectangle function, the arguments need to be passed like this
*img => register rdi
pt1 => register rsi
pt2 => register rdx
color => by memory (stack)
thickness => register rcx
line_type => register r8
shift => register r9

A possible way to simulate this for this particular function is like this
Import cvRectangle like this

Code: Select all

cvRectangle(*img, pt1, pt2, thickness, line_type, shift, c0, c1, c2, c3)
and use it like this

Code: Select all

IncludeFile "includes/cv_functions.pbi"

#CV_WINDOW_NAME = "PureBasic Interface to OpenCV"
cvNamedWindow(#CV_WINDOW_NAME, #CV_WINDOW_AUTOSIZE)
window_handle = cvGetWindowHandle(#CV_WINDOW_NAME)
SetWindowCloseEvent()
AddWindowCloseButton(window_handle)
PokeL(@*size, 500) : PokeL(@*size + 4, 500)
*image.IplImage = cvCreateImage(*size, #IPL_DEPTH_8U, 3)

Define pt1.CvPoint, pt2.CvPoint
pt1\x = 150 : pt1\y = 150
pt2\x = 200 : pt2\y = 200
color.CvScalar : color\val[0] = 0 : color\val[1] = 128 : color\val[2] = 255 : color\val[3] = 0
cvRectangle(*image, PeekQ(@pt1), PeekQ(@pt2), 1, #CV_AA, #Null, PeekQ(@color), PeekQ(@color+8), PeekQ(@color+16), PeekQ(@color+24))

Repeat
  If *image
    cvShowImage(#CV_WINDOW_NAME, *image)
    keyPressed = cvWaitKey(0)
  EndIf
Until keyPressed = 27
cvReleaseImage(@*image)
cvDestroyAllWindows()
Example of cvCircle

Code: Select all

IncludeFile "includes/cv_functions.pbi"

ImportC "binaries/libopencv_core.2.4.12.dylib"
  cvSet2(*arr, *mask, d1, d2, d3, d4, c0, c1, c2, c3) As "_cvSet"
EndImport

ImportC "binaries/libopencv_core.2.4.12.dylib"
  cvCircle2(*img, center, radius, thickness, line_type, shift, c0, c1, c2, c3) As "_cvCircle"
EndImport

Structure fnArg
  StructureUnion
    l.l[0]
    i.i[0]
    f.f[0]
    d.d[0]
  EndStructureUnion
EndStructure

#CV_WINDOW_NAME = "PureBasic Interface to OpenCV"
cvNamedWindow(#CV_WINDOW_NAME, #CV_WINDOW_AUTOSIZE)
window_handle = cvGetWindowHandle(#CV_WINDOW_NAME)
SetWindowCloseEvent()
AddWindowCloseButton(window_handle)
PokeL(@*size, 500) : PokeL(@*size + 4, 500)
*image.IplImage = cvCreateImage(*size, #IPL_DEPTH_8U, 3)

*pt.fnArg = AllocateStructure(CvPoint)
*color.fnArg = AllocateStructure(CvScalar)

*color\d[0] = 255 : *color\d[1] = 255 : *color\d[2] = 255 : *color\d[3] = 0
cvSet2(*image, #Null, 0,0,0,0, *color\i[0], *color\i[1], *color\i[2], *color\i[3])

*pt\l[0] = 150 : *pt\l[1] = 150
*color\d[0] = 0 : *color\d[1] = 128 : *color\d[2] = 255 : *color\d[3] = 0
cvCircle2(*image, *pt\i[0], 50, 1, #CV_AA, #Null, *color\i[0], *color\i[1], *color\i[2], *color\i[3])

FreeStructure(*pt)
FreeStructure(*color)

Repeat
  If *image
    cvShowImage(#CV_WINDOW_NAME, *image)
    keyPressed = cvWaitKey(0)
  EndIf
Until keyPressed = 27
cvReleaseImage(@*image)
cvDestroyAllWindows()
Another way to work around the structure by value problem is to use libffi.
https://sourceware.org/libffi/

But unfortunately things keep complicated if PureBasic doesn't start to support passing structures by value. :(

Re: PureBasic Interface to OpenCV

Posted: Sun May 22, 2016 9:07 am
by JHPJHP
Hi wilbert,

That's really great work, and I appreciate the explanation as much as the solution.

I've updated the OSX interface with a couple new examples. As I mentioned in a previous post, once the "color" issue was resolved for a single drawing Function, the rest would follow suit. This held true for all but one of the drawing Functions, but it didn't take much to figure out the solution based on your previous work. I've modified the code slightly using pointers in place of structures when not a scalar parameter. This falls inline with the 64bit Windows interface, which will make it easier to convert examples to OSX.

Re: PureBasic Interface to OpenCV

Posted: Sun May 22, 2016 10:23 am
by wilbert
Here's another way to work around the issue but it requires 8 floating point dummy arguments to get to the point where PB puts the remaining floating point values on the stack.

Code: Select all

IncludeFile "includes/cv_functions.pbi"

ImportC "binaries/libopencv_core.2.4.12.dylib"
  cvSet2(*arr, *mask, d1.d,d2.d,d3.d,d4.d,d5.d,d6.d,d7.d,d8.d, c0.d, c1.d, c2.d, c3.d) As "_cvSet"
EndImport

ImportC "binaries/libopencv_core.2.4.12.dylib"
  cvCircle2(*img, center, radius, thickness, line_type, shift, d1.d,d2.d,d3.d,d4.d,d5.d,d6.d,d7.d,d8.d, c0.d, c1.d, c2.d, c3.d) As "_cvCircle"
EndImport

#CV_WINDOW_NAME = "PureBasic Interface to OpenCV"
cvNamedWindow(#CV_WINDOW_NAME, #CV_WINDOW_AUTOSIZE)
window_handle = cvGetWindowHandle(#CV_WINDOW_NAME)
SetWindowCloseEvent()
AddWindowCloseButton(window_handle)
PokeL(@*size, 500) : PokeL(@*size + 4, 500)
*image.IplImage = cvCreateImage(*size, #IPL_DEPTH_8U, 3)

cvSet2(*image, #Null, 0,0,0,0,0,0,0,0, 240, 240, 240, 0)
PokeL(@*pt1, 150) : PokeL(@*pt1 + 4, 150)
cvCircle2(*image, *pt1, 50, 1, #CV_AA, #Null, 0,0,0,0,0,0,0,0, 128, 32, 128, 0)

Repeat
  If *image
    cvShowImage(#CV_WINDOW_NAME, *image)
    keyPressed = cvWaitKey(0)
  EndIf
Until keyPressed = 27
cvReleaseImage(@*image)
cvDestroyAllWindows()
Just choose the way you think works best :)