Jump to content

EmguCV (OpenCV wrapper) UDF


Recommended Posts

I wanted to use OpenCV v4+ in AutoIt.

I found Opencv UDF on the forum, but there was no support for OpenCV v4+

This UDF provides support for OpenCV v4+

Prerequisites

Examples

Showing an image

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

Opt("MustDeclareVars", 1)

#include "emgucv-autoit-bindings\cve_extra.au3"

; Open the library
_OpenCV_DLLOpen("libemgucv-windesktop-4.5.3.4721\libs\x64\cvextern.dll")

Local $img = _cveImreadAndCheck("data\lena.jpg")
_cveImshowMat("Image", $img)
_cveWaitKey()

; always release resources to avoid memory leaks on long running processes
_cveMatRelease($img)
_cveDestroyAllWindows()

; Close the library
_Opencv_DLLClose()

Showing an image in autoit GUI

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

Opt("MustDeclareVars", 1)

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include "emgucv-autoit-bindings\cve_extra.au3"

#Region ### START Koda GUI section ### Form=
Local $FormGUI = GUICreate("show image in autoit gui", 400, 400, 200, 200)
Local $Pic = GUICtrlCreatePic("", 0, 0, 400, 400)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

; Open the library
_OpenCV_DLLOpen("libemgucv-windesktop-4.5.3.4721\libs\x64\cvextern.dll")

Local $img = _cveImreadAndCheck("data\lena.jpg")

_cveImshowControlPic($img, $FormGUI, $Pic)

Local $nMsg
While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

; always release resources to avoid memory leaks on long running processes
_cveMatRelease($img)
_cveDestroyAllWindows()

; Close the library
_Opencv_DLLClose()

Showing an image in autoit GUI autosized

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

Opt("MustDeclareVars", 1)

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include "emgucv-autoit-bindings\cve_extra.au3"

#Region ### START Koda GUI section ### Form=
Local $FormGUI = GUICreate("show image in autoit gui [WINDOW_AUTOSIZE]", 400, 400, 200, 200)
Local $Pic = GUICtrlCreatePic("", 0, 0, 400, 400)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

; Open the library
_OpenCV_DLLOpen("libemgucv-windesktop-4.5.3.4721\libs\x64\cvextern.dll")

Local $img = _cveImreadAndCheck("data\lena.jpg")

; get the image size and resize the GUI and the PIC control
Local $tSize = _cvSize()
_cveMatGetSize($img, $tSize)
WinMove($FormGUI, "", Default, Default, $tSize.width, $tSize.height)
GUICtrlSetPos($Pic, Default, Default, $tSize.width, $tSize.height)

_cveImshowControlPic($img, $FormGUI, $Pic)

Local $nMsg
While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

; always release resources to avoid memory leaks on long running processes
_cveMatRelease($img)
_cveDestroyAllWindows()

; Close the library
_Opencv_DLLClose()

Screen capture

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

Opt("MustDeclareVars", 1)

#include "emgucv-autoit-bindings\cve_extra.au3"

; Open the library
_OpenCV_DLLOpen("libemgucv-windesktop-4.5.3.4721\libs\x64\cvextern.dll")

Local $iLeft = 200
Local $iTop = 200
Local $iWidth = 400
Local $iHeight = 400

Local $tRect = DllStructCreate($tagRECT)
$tRect.Left = $iLeft
$tRect.Top = $iTop
$tRect.Right = $iLeft + $iWidth
$tRect.Bottom = $iTop + $iHeight

Local $tBits = _cveGetDesktopScreenBits($tRect)
Local $img = _cveMatCreateWithData($iHeight, $iWidth, $CV_8UC4, $tBits, $CV_MAT_AUTO_STEP)

_cveImshowMat("Screen capture", $img)
_cveWaitKey()

; always release resources to avoid memory leaks on long running processes
_cveMatRelease($img)
_cveDestroyAllWindows()

; Close the library
_Opencv_DLLClose()

Find template

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

Opt("MustDeclareVars", 1)

#include "emgucv-autoit-bindings\cve_extra.au3"

; Open the library
_OpenCV_DLLOpen("libemgucv-windesktop-4.5.3.4721\libs\x64\cvextern.dll")

Local $img = _cveImreadAndCheck("data\mario.png", $CV_IMREAD_COLOR)
Local $tmpl = _cveImreadAndCheck("data\mario_coin.png", $CV_IMREAD_COLOR)

; The higher the value, the higher the match is exact
Local $threshold = 0.8

Local $aMatches = _cveFindTemplate($img, $tmpl, $threshold)

Local $tRedColor = _cvRGB(255, 0, 0)
Local $w = _cveMatGetWidth($tmpl)
Local $h = _cveMatGetHeight($tmpl)
Local $tMatchRect = _cvRect(0, 0, $w, $h)

For $i = 0 To UBound($aMatches) - 1
    $tMatchRect.x = $aMatches[$i][0]
    $tMatchRect.y = $aMatches[$i][1]

    ; Draw a red rectangle around the matched position
    _cveRectangleMat($img, $tMatchRect, $tRedColor, 1, $CV_LINE_8, 0)
Next

_cveImshowMat("Find template example", $img)
_cveWaitKey()

; always release resources to avoid memory leaks on long running processes
_cveMatRelease($img)
_cveDestroyAllWindows()

; Close the library
_Opencv_DLLClose()

Video capture file

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

Opt("MustDeclareVars", 1)

#include <Misc.au3>
#include "emgucv-autoit-bindings\cve_extra.au3"

; Open the library
_OpenCV_DLLOpen("libemgucv-windesktop-4.5.3.4721\libs\x64\cvextern.dll")

Local $cap = _cveVideoCaptureCreateFromFile("data\vtest.avi", $CV_CAP_ANY, 0)
If Not _cveVideoCaptureIsOpened($cap) Then
    ConsoleWriteError("!>Error: cannot open the video file." & @CRLF)
    Exit
EndIf

Local $frame = _cveMatCreate()

While 1
    If _IsPressed("1B") Or _IsPressed(Hex(Asc("Q"))) Then
        ExitLoop
    EndIf

    _cveVideoCaptureReadMat($cap, $frame)
    If _cveInputArrayIsEmptyMat($frame) Then
        ConsoleWriteError("!>Error: cannot read the video or end of the video." & @CRLF)
        ExitLoop
    EndIf

    _cveImshowMat("capture video file", $frame)

    Sleep(30)
WEnd

_cveWaitKey()

; always release resources to avoid memory leaks on long running processes
_cveMatRelease($frame)
_cveVideoCaptureRelease($cap)
_cveDestroyAllWindows()

; Close the library
_Opencv_DLLClose()

Video capture camera

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

Opt("MustDeclareVars", 1)

#include <Misc.au3>
#include "emgucv-autoit-bindings\cve_extra.au3"

; Open the library
_OpenCV_DLLOpen("libemgucv-windesktop-4.5.3.4721\libs\x64\cvextern.dll")

Local $iCamId = 0
Local $cap = _cveVideoCaptureCreateFromDevice($iCamId, $CV_CAP_ANY, 0)
If Not _cveVideoCaptureIsOpened($cap) Then
    ConsoleWriteError("!>Error: cannot open the camera." & @CRLF)
    Exit
EndIf

Local $frame = _cveMatCreate()
Local $frame_flipped = _cveMatCreate()

While 1
    If _IsPressed("1B") Or _IsPressed(Hex(Asc("Q"))) Then
        ExitLoop
    EndIf

    _cveVideoCaptureReadMat($cap, $frame)

    If _cveInputArrayIsEmptyMat($frame) Then
        ConsoleWriteError("!>Error: cannot read the camera." & @CRLF)
    Else
        ;; Flip the image horizontally to give the mirror impression
        _cveFlipMat($frame, $frame_flipped, 1)
        _cveImshowMat("capture camera", $frame_flipped)
    EndIf

    Sleep(30)
WEnd

_cveWaitKey()

; always release resources to avoid memory leaks on long running processes
_cveMatRelease($frame_flipped)
_cveMatRelease($frame)
_cveVideoCaptureRelease($cap)
_cveDestroyAllWindows()

; Close the library
_Opencv_DLLClose()

Sources

Sources are available here

emgucv-autoit-bindings-v1.0.0-rc.1.zip

Edited by smbape
Update udf version
Link to post
Share on other sites
  • Replies 88
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Popular Posts

I wanted to use OpenCV v4+ in AutoIt. I found Opencv UDF on the forum, but there was no support for OpenCV v4+ This UDF provides support for OpenCV v4+ Prerequisites Download and

$contours is a VectorOfVectorOfPoint. Therefore, if used as a Mat, like shown in _cveConvexHullTyped, it will crash. convexHull cannot but applied on a VectorOfVectorOfPoint. It can only be applied on

Hi @Lion66 I am not convinced. Your file has 2 sets of functions. Contour features Mophological operations Don't you think it is more natural to have them in 2 files? Your s

Posted Images

Congratulations on the birth of the theme!
Interesting and necessary direction.

I looked at your example matching_homography_Demo.au3 and found some problems:
1. If you try to select an algorithm, the script crashes with a message:

"Error: The image \box.png could not be loaded." , 

If not exist file $OPENCV_SAMPLES_DATA_PATH & "\box.png". Even if another file is selected!

2. I propose move

;-- Show detected matches
    ; _cveImshowMat("Good Matches & Object detection", $img_matches) ;
    _cveImshowControlPic($img_matches, $FormGUI, $PicMatches)

to the end of the cycle

;;-- Need at least 4 point correspondences to calculate Homography
    If _VectorOfDMatchGetSize($good_matches) >= 4 Then


And add an "ELSE" that clears the picture in the GUI and changes the message

"Good Matches && Object detection" to "no matches found."

 


3. Testing with standard "box_in_scene.png" files does not cause any problems.
But when I try to work with custom files, I can see the difference.
I checked about 10 different sets of images and came to the conclusion that the ORB algorithm has low ability to find points.
In the same script (python) when replacing ORB with KAZE and sometimes with BRISK, I get a positive result.
I'm attaching a couple of pictures and a code on the python that recognizes them.
Unfortunately, your script using the same KAZE algorithm cannot do this!
I can't compare the difference in scripts, but if you try to repeat all the steps used in the python, then it should work.

4. It may be worth adding the ability for the user to modify the MIN_MATCH_COUNT to cut off false matches.

Thanks and success in working on the project!

dog.jpg

dog-scene.jpg

KAZE-DetectAndFrame.py

Edited by Lion66
Link to post
Share on other sites

Hi @Lion66

Thanks for the feedback and the encouragement.

I though that KAZE did not have detectAndCompute implemented, but it is NORM_HAMMING and NORM_HAMMING2 that are not compatible with KAZE. I will update the example to take that into account.

I was testing with BRISK and I had no matches, while with KAZE I have similar results as your python script. See the attached file.

 

3 hours ago, Lion66 said:

1. If you try to select an algorithm, the script crashes with a message:

I don't have that error.
Can you check your value of $OPENCV_SAMPLES_DATA_PATH ?
The examples are designed to work inside the repository.
As  describe in these instructions, can you clone the whole repo, and try again ?

 

3 hours ago, Lion66 said:

2. I propose move

;-- Show detected matches
    ; _cveImshowMat("Good Matches & Object detection", $img_matches) ;
    _cveImshowControlPic($img_matches, $FormGUI, $PicMatches)

to the end of the cycle

;;-- Need at least 4 point correspondences to calculate Homography
    If _VectorOfDMatchGetSize($good_matches) >= 4 Then

 

Are you talking about the file matching_homography_Demo.au3 ?
If yes, it is already at the end of the cycle.
Are you refering to another file?

 

3 hours ago, Lion66 said:

And add an "ELSE" that clears the picture in the GUI and changes the message

"Good Matches && Object detection" to "no matches found."

The message label can be changed to "no matches found." in case of no matches.
However I don't understand the need of clearing then GUI.
$img_matches is always a new image.
Can you describe a test case where clearing the GUI might help?

160732-opencv-udf.au3

Link to post
Share on other sites

About file 160732-opencv-udf.au3.

Great implementation! Finally, custom pictures are recognized.

1 hour ago, smbape said:

I was testing with BRISK and I had no matches

BRISK applicable to other images. I checked both algorithms. Both show the expected result.

A few questions:

1. Could you add an ORB algorithm here just in case 😉.

2. When there are dots, but they are scattered, and the object is not recognized (there is no red frame in the "found" window), is it possible to track this and issue a message?

3. Is there a way to move the mouse to the center of the red frame in the "found" window?

 

Less important, but still: about matching_homography_Demo.au3:

As a user, I assume that I will use the script with my images and without having a "\samples\data" folder.
Now this causes an emergency closure.

That is, the GUI must be opened without any file.
And select an algorithm without having a specified file should not cause an emergency closure.

Many thanks.

Link to post
Share on other sites
21 minutes ago, Lion66 said:

1. Could you add an ORB algorithm here just in case 😉.

You can do it by adding the following lines where needed (I prefer not to upload the whole file again)

_cveOrbCreate(500, 1.2, 8, 31, 0, 2, $CV_ORB_HARRIS_SCORE, 31, 20, $tFeature2DPtr, $tSharedPtr)
$destructor = "_cveOrbRelease"

 

23 minutes ago, Lion66 said:

2. When there are dots, but they are scattered, and the object is not recognized (there is no red frame in the "found" window), is it possible to track this and issue a message?

That is the case when UBound($dmatches) < 4 or _cveFindHomography did not find any homography.
I will add a ConsoleWriteError in the example

 

30 minutes ago, Lion66 said:

3. Is there a way to move the mouse to the center of the red frame in the "found" window?

The red frame not being a rectangle, the center is not well defined.
You can define the center as the crossing point of the 2 diagonals from the corners.
The four corners points are $dst_0, $dst_1, $dst_2, $dst_3.
The diagonals are [$dst_0, $dst_2] and [$dst_1, $dst_3].
If you remember you mathematical courses, you know how to get the crossing point of two segments.
If not, use your favorite search engine. I don't remember.
If you have hard time finding an answer, ask again in the post.

 

38 minutes ago, Lion66 said:

Now this causes an emergency closure.

I really don't reproduce it. I copied and pasted the coded in an isolated location and I had no crash.
The GUI showed up, but I had a bunch of errors in the console

Error while loading unkinwn.dll
Error - cveMatCreate: unable to use the DLL file
Error - cveStringCreateFromStr: unable to use the DLL file
Error - cveImread: unable to use the DLL file
Error - cveStringRelease: unable to use the DLL file
Error - cveInputArrayFromMat: unable to use the DLL file
Error - cveInputArrayIsEmpty: unable to use the DLL file
Error - cveInputArrayRelease: unable to use the DLL file
!>Error: The image \box.png could not be loaded.

 

Link to post
Share on other sites
Posted (edited)

@Lion66

I found a way to get the center of a polygons

; draw a circle at the center
Local $moments = _cveMomentsCreate()
_cveMoments($i_arr_dst_32, False, $moments)
Local $cx = _cveMomentsGetM10($moments) / _cveMomentsGetM00($moments)
Local $cy = _cveMomentsGetM01($moments) / _cveMomentsGetM00($moments)
_cveCircleMat($img2, _cvPoint($cx, $cy), 5, _cvScalar(255, 255, 255), $CV_FILLED)
_cveMomentsRelease($moments)

The code with ORB added and the above code added

 

160732-opencv-udf.au3

Edited by smbape
Link to post
Share on other sites

Hi @smbape

Thank you for your answers and examples.

My mouse now tends to the center of the polygon. 😄

I added exit to the last script if number of object key point or scene key point  is zero. There's no point in continuing.

For the ORB algorithm, need to change too the match type to $CV_NORM_HAMMING. Otherwise, the frame is not drawn correctly.

And for others, match type $CV_NORM_L2 works better than $CV_NORM_L1.

If $algorithm = "ORB" Then
    $bf_matcher = _cveBFMatcherCreate($CV_NORM_HAMMING, False, $tMatcherPtr)
Else
    $bf_matcher = _cveBFMatcherCreate($CV_NORM_L2, False, $tMatcherPtr)
EndIf

I do not yet understand whether it is possible to track behavior when there were matches, but they are false and the frame is not drawn?

For example, with these pictures and the ORB algorithm, I get 61 matches, but there is no frame.

frame-obj.png

frames-scene.png

Link to post
Share on other sites
Posted (edited)
28 minutes ago, Lion66 said:

For example, with these pictures and the ORB algorithm, I get 61 matches, but there is no frame.

The number of matches does not indicate a correlation in images.
It indicates how many descriptors of the object are matched in the descriptors of the scene.
However, it doesn't say if there is an homography that can be applied to transform those matched descriptors of object into the matched descriptors of the scene.
In other word, if object can be transformed and then found in scene.

It will be hard to find a combination that works for every set of images.
The script I provided does not allow to easily test different combinations.
Using matching_homography_Demo.au3 , and with the provided object and scene, the following combinations find the object in the scene:

  • Brisk + ($CV_NORM_L2, $CV_NORM_L1, $CV_NORM_HAMMING, $CV_NORM_HAMMING2, $CV_NORM_L2SQR)
  • KAZE + ($CV_NORM_L2, $CV_NORM_L1, $CV_NORM_L2SQR)
  • AKAZE + ($CV_NORM_L2, $CV_NORM_L1, $CV_NORM_HAMMING, $CV_NORM_HAMMING2, $CV_NORM_L2SQR)
Edited by smbape
Link to post
Share on other sites
8 hours ago, smbape said:

if object can be transformed and then found in scene.

Visually we see this when the object is not detected, and there is no solution for the script to understand this?

Link to post
Share on other sites
5 hours ago, Lion66 said:

Visually we see this when the object is not detected, and there is no solution for the script to understand this?

I don't understand the question.
What do we see when the object is not detected?

Link to post
Share on other sites

Maybe the answer is obvious, but not for me.

What variable do I need to check in the code to get a message in case I don't see the red frame visually?

(not a successful homography???).

Link to post
Share on other sites
Posted (edited)

Ok, I understand the question.

There are 2 cases when you will not see the red frame:

  • After _cveDescriptorMatcherMatch1Mat, If UBound($dmatches) < 4 Then there is not enough matches, which will lead to no red frame
  • After _cveFindHomography, If _cveMatIsEmpty($M) Then there no homography, which will lead to no red frame

If what I said is not clear, post your code and I will modify it.

Edited by smbape
Link to post
Share on other sites

Take your code 160732-opencv-udf.au3.

Take two previously incompatible pictures: frame-obj.png (attached above ) and box_in_scene.png.

We successfully pass the test "If UBound($dmatches) >= 4 Then". Ok.

But I was expecting an event "else" in loop "If Not _cveMatIsEmpty($M) Then" (I added debug message in Else).

However, the "Else" block is not activated, but there is no red frame.

Link to post
Share on other sites
Posted (edited)

There is a red frame.
However, the points are so close that it displays a red line.
Look at the window "found" to see it.

Here are the coordinates of the points

$dst_0 [ 144.033889770508, 192.807693481445 ]
$dst_1 [ 147.521987915039, 180.503540039063 ]
$dst_2 [ 142.773986816406, 197.195739746094 ]
$dst_3 [ 155.550369262695, 152.486877441406 ]

 

Edited by smbape
Link to post
Share on other sites

That's good. Let's clean up points with close coordinates, say 10 pixels away.

In the hope that this will not harm in other cases.

I think it might be right for that "groupRectangles".

Will you try? 😉

(edit) Or is it easier to compare mathematically?

 

Edited by Lion66
Link to post
Share on other sites
Posted (edited)

The distance between 2 points (x1, y1), (x2, y2) is given by sqrt((x1 - x2)² + (y1 - y2)²)
Use it to compare the distance between the 4 corners.
If two corners are too close, do what you want

Local $mindist = 10
Local $points[4]= [$dst_0, $dst_1, $dst_2, $dst_3]
For $i = 0 To 3
    For $j = $i + 1 To 3
        If Sqrt((($points[$i].x - $points[$j].x) ^ 2) + (($points[$i].y - $points[$j].y) ^ 2)) < $mindist Then
            ConsoleWrite("Points are too close" & @CRLF)
            ExitLoop 2
        EndIf
    Next
Next

 

Edited by smbape
Link to post
Share on other sites

Hi

Beautiful solution and helped improve the code.

Although I prefer to cut only those cases where all 4 points are located close.

Often, displaying a frame as a line also gives a good result. I use it like this:

Local $mindist = 10
Local $points[4] = [$dst_0, $dst_1, $dst_2, $dst_3]
Local $Expression1 = Sqrt((($points[0].x - $points[1].x) ^ 2) + (($points[0].y - $points[1].y) ^ 2))
Local $Expression2 = Sqrt((($points[1].x - $points[2].x) ^ 2) + (($points[1].y - $points[2].y) ^ 2))
Local $Expression3 = Sqrt((($points[2].x - $points[3].x) ^ 2) + (($points[2].y - $points[3].y) ^ 2))
Local $Expression4 = Sqrt((($points[0].x - $points[3].x) ^ 2) + (($points[0].y - $points[3].y) ^ 2))

If (Execute("$Expression1") < $mindist) And (Execute("$Expression2") < $mindist) And (Execute("$Expression3") < $mindist)   And (Execute("$Expression4") < $mindist) Then

    MsgBox(0, "", "Points are too close")
    ;Return
EndIf

The problem remains only when the frame profile is concave.

I see that you are well versed in mathematics 😀.

I will ask, without much hope, if you know way to identify that the profile, drawn in the example, is closed and concave at the same time?

Thank you.

Edited by Lion66
Link to post
Share on other sites
Posted (edited)

Hi @Lion66

1 hour ago, Lion66 said:

The problem remains only when the frame profile is concave.

Sorry, that is beyond my knowledge, and I am not sure that you need to go in that direction.
It has to be confirmed, but I theorized that, if an homography where found, then a closed path will remain closed after applying the homography.

 

1 hour ago, Lion66 said:

I will ask, without much hope, if you know way to identify that the profile, drawn in the example, is closed and concave at the same time?

Are they cases where my provided code gives wrong results?
Can you give an example of coordinates representing a case?

Regarding your code, there things that bother me.

First, the equivalent without the loop is a check of 6 distances with an "Or" expression not an "And".
The 6 distances to check are:

  • $dst_0 <-> $dst_1
  • $dst_0 <-> $dst_2
  • $dst_0 <-> $dst_3
  • $dst_1 <-> $dst_2
  • $dst_1 <-> $dst_3
  • $dst_2 <-> $dst_3

You are only checking 4 distances which will most likely miss cases.

You are also doing a "And" not an "Or".
That means the 4 following distances have to be close: $dst_0 <-> $dst_1, $dst_1 <-> $dst_2, $dst_2 <-> $dst_3, $dst_0 <-> $dst_1
However, as long as 2 points are close, you will not have a rectangle.
You will have a triangle (only 2 points are close), a line (2 groups of 2 points are close or 3 points are close), or a point (all the 4 points are close)

Second, why are you using Execute("$Expression1") < $mindist instead of $Expression1 < $mindist ?
Execute could have been usefull in the loop by doing

Execute("Sqrt((($dst_" & $i & ".x - $dst_" & $j & ".x) ^ 2) + (($dst_" & $i & ".y - $dst_" & $j & ".y) ^ 2))")

 

Third, since you are splitting the loop in individual check, there is no need for an array. Use $dst_0 instead of $points[0]

 

Edited by smbape
Link to post
Share on other sites

You're right. This is superfluous: Execute and $points[4].

Initially, I planned to leave cases of triangle and line. Therefore, I used AND and therefore it is enough to check 4 distances.

But now I have changed my mind, because such cases of detection are not quite accurate.

I'll see again, how your method works. But still there is a case with a strange form of frame.

They're always concave. I would like to filter the result by this.

Pic3: (similar you can see by file 160732-opencv-udf.au3, algorithm BRISK).

$dst_0 [ 97.4931182861328, 130.25163269043 ]
$dst_1 [ -130.481994628906, 344.5224609375 ]
$dst_2 [ 234.231307983398, 278.392486572266 ]
$dst_3 [ 124.302398681641, 250.157531738281 ]
Distance:
312.865210508152, 370.66017672785, 113.497038616658, 122.866440258512

But in the last file "matching_homography_Demo.au3" from GIThub, this does not happen. I'm completely confused 🙄

Pic3.jpg

Link to post
Share on other sites
Posted (edited)

Maybe you noticed that there is one point outside the view box.

$dst_1 [ -130.481994628906, 344.5224609375 ]

 

1 hour ago, Lion66 said:

But in the last file "matching_homography_Demo.au3" from GIThub, this does not happen. I'm completely confused

This is what I was refering to in a previous post.
All the matches are used to find the homagraphy,  which will most likely lead to an innacurrate homography.

In 160732-opencv-udf.au3, if you ReDim dmatches after populating and sorting it, you will have a more accurate homography

ReDim $dmatches[20]

matching_homography_Demo.au3 does not have this problem for 2 reasons:

  • _cveDescriptorMatcherKnnMatch1Mat is used instead of _cveDescriptorMatcherMatch1Mat thus, removing the need of sorting matches
  • Only good matches are kept. This is done with the condition "$tDMatch0.distance < $ratio_thresh * $tDMatch1.distance"

Regarding the detection of concave polygones, I theorize 2 ways to do it:

  • Calculate the angle at each corner and if there is an angle greater than 180°, then it is convex.
    This will definitly work, however it involves reminding how to calculate an angle between 2 vectors.
  • Use cv::convexHull to find the convex hull of the polygone.
    If the convex hull is also the polygone, then the polygone is convex, otherwise it is concave.
    It is in theory easier to implement.
Edited by smbape
Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By JoGa
      Greetings,
      here is a Autoit3 v3.3.14.5, 64 Bit installation on windows 10 with current updates.
      In a simple script I'm Dllcall'ing a 64 bit dll.
      # T1.au3 Local $name = "T1DLL.dll" if (FileExists($name)) Then ConsoleWrite("DLL '" &$name &"' exists" &@CRLF) EndIf Local $DLL = DllOpen($name) if (@ERROR OR $DLL = -1) then ConsoleWrite("DllOpen ERROR=" &@ERROR &" DLL=" &$DLL &@CRLF) Else ConsoleWrite("DllOpen Success" &@CRLF) endif DllCall($DLL, "none:cdecl", "SomeFunction", "str", "DLL Call from T1.au3") if (@ERROR) then ConsoleWrite("DllCall ERROR=" &@ERROR &" DLL=" &$DLL &@CRLF) Else ConsoleWrite("DllCall Success" &@CRLF) endif The C code contains one 64 bit OpenCV call:    cv::destroyAllWindows();.

      Excuting T1.au3 with SciTE gives:

      If the c code is compiled *without* the OpenCV call T1.au3 runs successful:
       
      I checked T1DLL.dll, it's definitely a 64 bit dll.
      What could cause the problem?
      Any hint would be very much appreciated.
      Thanks
      Wolf
       
       
       
       
    • By BBs19
      I needed a function to automate programs at work that can't be fully automated via Autoits built in functions.
      For example a virtual machine running on your physical machine, meaning you would need to run an extra script within the virtual machine (if it is even running Windows) in order to automate everything.
      I came across OpenCV which allows matching/finding a picture in another picture. This would also allow searching for a button/text on the screen in order to press the exact position. Fortunately @mylise already translated all the required OpenCV functions to Autoit, I just had to remove all unnecessary functions to make the script as small as possible.
      The problem:
      Using this method, you will never be able to fully automate everything dynamically, as it will only work on the machine with same resolution/dpi settings, same theme etc.. This is only a last resort for programs that can't be automated using the built in Autoit functions.
      Features:
      Find a given picture on the entire screen (all monitors) or a certain area on the screen and execute mouse clicks on this position. Adjust the threshold so that the picture doesn't have to match 100%. Debugging options like logging and marking the screen where the picture was found etc. Includes a Snapshot-Tool that creates snapshots of a certain area(buttons, text etc.) on the screen and generates the code that is required for the matching. It can also be used to get the coordinates to a marked area on the screen in order to check only on a certain area for the match picture. Example:
      Note: The example will probably not work on your computer, depending on the display resolution and dpi settings, as the picture has to match the exact same size on the screen. Please use the included Snapshot-Tool to generate new match pictures and code very easily.
      #AutoIt3Wrapper_UseX64=n ; In order for the x86 DLLs to work #include "OpenCV-Match_UDF.au3" _OpenCV_Startup();loads opencv DLLs _OpenCV_EnableLogging(True,True,True) ;Logs matches, errors in a log file and autoit console output. ;Please note that these examples might not work as the match pictures have to be found with the exact same size on your screen. ;Example 1 ShellExecute("http://www.tv.com/");Open Website tv.com $Match1 = _MatchPicture(@ScriptDir&"\Match\1.png", 0.70,False,10,500);Try to find the match picture on the screen. Number of tries: 10, Sleep between each try: 500ms. If Not @error Then _MarkMatch($Match1) ;Debugging: Draws a rect on the screen/coordinates of the match to show the user where the match was found Sleep(100) _ClickMouse($Match1, "left",1) ;Calculates the center of the match and clicks the left mouse once on click position EndIf Sleep(1000) ;Example 2, matching on a specific area of the screen ShellExecute("notepad.exe");open nodepad WinWait("[CLASS:Notepad]","",5) WinMove("[CLASS:Notepad]","",0,0,500,500) Local $sCoords[4] = [0, 0, 500,500] $Match2 = _MatchPicture(@ScriptDir&"\Match\2.png", 0.80,$sCoords,3,500) If Not @error Then _MarkMatch($Match2) Sleep(100) _ClickMouse($Match2, "left", 1) EndIf _OpenCV_Shutdown();Closes DLLs So basically, all you need to do is provide a path to the match picture and the function will return you the coordinates (x1,y1,x2,y2) of where the picture has been found on the screen. With these, you can either calculate an exact position for the mouse click or use the "_ClickMouse" function which will execute a mouse click on the center of the coordinates where the picture was found. 
      Credits:
      @mylise for the OpenCV UDF
       
      Download:
      Includes the required .DLL files of OpenCV. You can also manually download them on the website of OpenCV (Version 3.x doesn't include these anymore, you need to download 2.x).
      OpenCV_Match.zip
×
×
  • Create New...