Page 38 of 60

Re: PureBasic Interface to OpenCV

Posted: Sun May 22, 2016 10:38 am
by JHPJHP
Hi wilbert,

Thank you, it's good to have the option. I'm also glad we moved to an open thread; your scripts are a great reference for anyone wanting to create their own examples.

I just converted another example I think you may like. After the example opens press the [ M Key ]...

Re: PureBasic Interface to OpenCV

Posted: Sun May 22, 2016 10:45 am
by wilbert
JHPJHP wrote:I just converted another example I think you may like.
Nice example JHPJHP :)

Re: PureBasic Interface to OpenCV

Posted: Sun May 22, 2016 11:13 pm
by JHPJHP
Hi wilbert,

Thank you, I'm glad you liked the example.

When you have a minute can you look at the OpenCV Function: cvBoundingRect.
- this was one of the Functions that gave me grief when building the Windows interface

As you can see it returns a Structure:
CvRect cvBoundingRect(CvArr* points, int update=0 )
In the Windows interface I declared it this way: cvBoundingRect(*rect, *points, update)

In OSX I tried using a pointer, Structure, pointer to a Structure, etc. and was only able to return the X / Y values, but not the Width / Height: *rect = cvBoundingRect(*points, update)

Thank you.

NB*: I've also converted another four examples.

Re: PureBasic Interface to OpenCV

Posted: Mon May 23, 2016 4:55 am
by wilbert
Hi JHPJHP,
JHPJHP wrote:When you have a minute can you look at the OpenCV Function: cvBoundingRect.
The rect is returned in the rax and rdx registers.

I think it will be something like declaring as cvBoundingRect(*points, update) and using it as this

Code: Select all

    ReturnRect.cvRect
    cvBoundingRect(*points, update)
    !mov [p.v_ReturnRect], rax
    !mov [p.v_ReturnRect + 8], rdx
    Debug ReturnRect\x
    Debug ReturnRect\y
    Debug ReturnRect\width
    Debug ReturnRect\height

Re: PureBasic Interface to OpenCV

Posted: Mon May 23, 2016 5:55 am
by JHPJHP
Hi wilbert,

Try the following (not tested):
- builds an array of points bounded in a rectangle

Code: Select all

IncludeFile "includes/cv_functions.pbi"

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)
point.CvPoint : rect.CvRect
color.CvScalar : color\val[0] = 255 : color\val[1] = 0 : color\val[2] = 0 : color\val[3] = 0
#CV_SEQ_ELTYPE_POINT = CV_MAKETYPE(#CV_32S, 2)
*storage.CvMemStorage = cvCreateMemStorage(0) : cvClearMemStorage(*storage)
*points.CvSeq = cvCreateSeq(#CV_SEQ_ELTYPE_POINT, SizeOf(CvSeq), SizeOf(CvPoint), *storage)

For rtnCount = 1 To 100
  point\x = Random(450, 50)
  point\y = Random(450, 50)
  cvSeqPush(*points, @point)
  PokeL(@*center, point\x) : PokeL(@*center + 4, point\y)
  cvCircle(*image, *center, 3, #CV_FILLED, #CV_AA, #Null, PeekQ(@color), PeekQ(@color + 8), PeekQ(@color + 16), 0)
Next
cvBoundingRect(@rect, *points, 0)
PokeL(@*pt1a, rect\x) : PokeL(@*pt1a + 4, rect\y)
PokeL(@*pt1b, rect\x + rect\width) : PokeL(@*pt1b + 4, rect\y + rect\height)
cvRectangle(*image, *pt1a, *pt1b, 2, #CV_AA, #Null, PeekQ(@color), PeekQ(@color + 8), PeekQ(@color + 16), 0)

Debug rect\x
Debug rect\y
Debug rect\width
Debug rect\height

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

Re: PureBasic Interface to OpenCV

Posted: Mon May 23, 2016 6:23 am
by wilbert
It looks kind of ugly but it works as I expected

Code: Select all

ImportC "binaries/libopencv_imgproc.2.4.12.dylib"
  cvBoundingRect2(*points, update) As "_cvBoundingRect"
EndImport

IncludeFile "includes/cv_functions.pbi"

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)
point.CvPoint : rect.CvRect
color.CvScalar : color\val[0] = 255 : color\val[1] = 0 : color\val[2] = 0 : color\val[3] = 0
#CV_SEQ_ELTYPE_POINT = CV_MAKETYPE(#CV_32S, 2)
*storage.CvMemStorage = cvCreateMemStorage(0) : cvClearMemStorage(*storage)
*points.CvSeq = cvCreateSeq(#CV_SEQ_ELTYPE_POINT, SizeOf(CvSeq), SizeOf(CvPoint), *storage)

For rtnCount = 1 To 100
  point\x = Random(450, 50)
  point\y = Random(450, 50)
  cvSeqPush(*points, @point)
  PokeL(@*center, point\x) : PokeL(@*center + 4, point\y)
  cvCircle(*image, *center, 3, #CV_FILLED, #CV_AA, #Null, PeekQ(@color), PeekQ(@color + 8), PeekQ(@color + 16), 0)
Next

cvBoundingRect2(*points, 0)
!mov [v_rect], rax
!mov [v_rect + 8], rdx

PokeL(@*pt1a, rect\x) : PokeL(@*pt1a + 4, rect\y)
PokeL(@*pt1b, rect\x + rect\width) : PokeL(@*pt1b + 4, rect\y + rect\height)
cvRectangle(*image, *pt1a, *pt1b, 2, #CV_AA, #Null, PeekQ(@color), PeekQ(@color + 8), PeekQ(@color + 16), 0)

Debug rect\x
Debug rect\y
Debug rect\width
Debug rect\height

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

Re: PureBasic Interface to OpenCV

Posted: Mon May 23, 2016 8:04 am
by JHPJHP
Hi wilbert,

It worked great, thank you. I don't know about ugly, but it did feel like cheating :)

I've once again updated the OSX interface with a couple more conversions, using your ASM script in the example cv_morph_faces.pb.

Enjoy.

Re: PureBasic Interface to OpenCV

Posted: Mon May 23, 2016 9:58 am
by wilbert
JHPJHP wrote:I don't know about ugly, but it did feel like cheating :)
It would be nice if Fred would add support for passing and receiving of structures but until then this ASM workaround is the only thing I could think about that worked.

That morphing example looks funny :)
Nice work !

Re: PureBasic Interface to OpenCV

Posted: Tue May 24, 2016 7:31 am
by JHPJHP
All the PureBasic Interface to OpenCV packages have been updated.
- improved the Open and Save image Procedures with additional formats

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

Hi wilbert,

I came up against an interesting problem/solution converting the following example cv_minarea_1.pb.
- finds the minimal area of a point set wrapping it in a circle and a rectangle
- press the Spacebar to populate a matrix with a new random set of points

The circle algorithm worked fine, but the rectangle algorithm failed at the following Function cvBoxPoints.

The first part of the rectangle algorithm (cvMinAreaRect2) populates a Structure (CvBox2D) with the x, y, width, height, and angle of a rotated rectangle.

The second part of the Function cvBoxPoints converts the data from the Structure CvBox2D to four X/Y points used to create the rotated rectangle.

I couldn't get the Function cvBoxPoints to return the correct data, but I did find the algorithm that OpenCV used to create the Function, and wrapped it in a Procedure named cvBoxPoints2.

Code: Select all

ProcedureC cvBoxPoints2(*box.CvBox2D, Array pt.CvPoint2D32f(1))
  angle.d = *box\angle * #PI / 180
  a.f = Sin(angle) * 0.5
  b.f = Cos(angle) * 0.5
  pt(0)\x = *box\center\x - a * *box\size\height - b * *box\size\width
  pt(0)\y = *box\center\y + b * *box\size\height - a * *box\size\width
  pt(1)\x = *box\center\x + a * *box\size\height - b * *box\size\width
  pt(1)\y = *box\center\y - b * *box\size\height - a * *box\size\width
  pt(2)\x = 2 * *box\center\x - pt(0)\x
  pt(2)\y = 2 * *box\center\y - pt(0)\y
  pt(3)\x = 2 * *box\center\x - pt(1)\x
  pt(3)\y = 2 * *box\center\y - pt(1)\y
EndProcedure
If you have some time to look at the example, I'd be interested to know a solution for returning the four points from the original Function.

Re: PureBasic Interface to OpenCV

Posted: Tue May 24, 2016 8:28 am
by wilbert
JHPJHP wrote:If you have some time to look at the example, I'd be interested to know a solution for returning the four points from the original Function.
This one was quite difficult to figure out :?
The box structure needs to be passed by memory.

Import:

Code: Select all

cvBoxPoints(*pt, d1,d2,d3,d4,d5, b1,b2,b3)
Usage:

Code: Select all

cvBoxPoints(@pt(), 0,0,0,0,0, PeekQ(@box), PeekQ(@box + 8), PeekL(@box + 16))

Re: PureBasic Interface to OpenCV

Posted: Tue May 24, 2016 7:06 pm
by JHPJHP
Hi wilbert,

I don't want to push my luck because I know I'll need your expertise again, but your skillset is impressive so I have to ask...

Can you explain how you managed to figure out that last Function. Not just where the information was located, but also the tools used to derive it, and knowing what to look for.

Thank you.

NB*: Converted another three examples.

Re: PureBasic Interface to OpenCV

Posted: Wed May 25, 2016 5:14 am
by wilbert
Hi JHPJHP,
JHPJHP wrote:Can you explain how you managed to figure out that last Function. Not just where the information was located, but also the tools used to derive it, and knowing what to look for.
First you look at the original C function declaration.
cvBoxPoints( CvBox2D box, CvPoint2D32f pt[4] )
The first argument "box" is a structure of 5 floats (20 bytes) which is passed here by value.
The second argument "pt" is an array.

After that you look at section 3.2.3 of the ABI I mentioned before
http://www.x86-64.org/documentation/abi.pdf

In this case, I think the following rule applies to "box"
If the size of the aggregate exceeds two eightbytes and the first eightbyte
isn’t SSE or any other eightbyte isn’t SSEUP, the whole argument
is passed in memory.
So now you have an idea of how the parameters should be passed; "box" by memory and "pt" as an array pointer.

As mentioned before, PureBasic doesn't support all of this.
PureBasic simply passes the first 6 integer arguments and the first 8 floating point arguments by register and remaining ones by memory.
So now you have to simulate things.

The first argument becomes the array pointer of "pt" (the first integer argument).
Now 5 dummy integer arguments are needed to get to the point where things can be passed by memory.
There are 20 bytes to be passed by memory. Divided by 8 that is two quads (done by PeekQ) and a long (done by PeekL).

Re: PureBasic Interface to OpenCV

Posted: Wed May 25, 2016 6:08 am
by JHPJHP
Hi wilbert,

Thank you, that was a great explanation. I also appreciate the Application Binary Interface document.

It's one thing to understand the concept, but quite another to put it into practice; I'm thankful for all the support you provided.

NB*: Converted another two examples.

Re: PureBasic Interface to OpenCV

Posted: Wed May 25, 2016 9:19 am
by wilbert
JHPJHP wrote:NB*: Converted another two examples.
Nice work.
Funny to see that thinning example :)

Re: PureBasic Interface to OpenCV

Posted: Wed May 25, 2016 7:12 pm
by JHPJHP
Hi wilbert,

I wrote some of these example over a year ago, but your post reminds me that people are still seeing them for the first time...

Is there enough information in the Constant #CV_DESCRIPTION (tooltip) for someone new to the interface to view the examples full effect?

For instance 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

Converted a couple more examples.

The newly converted example cv_poisson_blending_1.pb uses a powerful blending algorithm to merge two images seamlessly.
- press the Spacebar once to add the second image
- press the Spacebar a second time to blend the images
- press the Enter key at anytime to switch between 1 of 5 image combinations

NB*: Many of the examples need user interaction for multiple options to achieve the desired results.