Do you want to use OpenCV v4+ in AutoIt v3 ?
If yes, then this udf might be for you.
- Download and extract libemgucv-windesktop-4.5.3.4721.zip into a folder
- Download and extract emgucv-autoit-bindings-v1.0.0-rc.0.zip into a folder
#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()
# get the source files
git clone https://github.com/smbape/node-emgucv-autoit-generator
cd node-emgucv-autoit-generator
# download libemgucv-windesktop-4.5.3.4721
curl -L 'https://github.com/emgucv/emgucv/releases/download/4.5.3/libemgucv-windesktop-4.5.3.4721.zip' -o libemgucv-windesktop-4.5.3.4721.zip
unzip libemgucv-windesktop-4.5.3.4721.zip -d libemgucv-windesktop-4.5.3.4721
Now you can run any file in the samples\tutorial_code
folder.
This shows how to put performance critical tasks in c++ functions, export those functions in a dll and then use them in autoit.
Look at samples\tutorial_code\Histograms_Matching\calcHist_Demo.au3
for an example of usage.
- Install CMAKE >= 3.5
- Install visual studio >= 10
Run build.bat
script located in the autoit-addon
folder.
- Finding the functions/constants names.
- Transform the parameter types according to the UDF parameter. This step might involve looking at the opencv documentation.
- Adjust the return type and variable. This step might involve looking at the opencv documentation.
For a function named foo or Foo, there is usually a function named _cve
Foo
For a constant FOO, there is usually a Global Const ending with _FOO
and starting with $CV_
For cv::Point, cv::Range, cv::Rect, cv::Scalar and cv::Size types,
there are _cv
Point, _cv
Range, _cv
Rect, _cv
Scalar and _cv
Size functions to convert parameters.
For cv::ScalarAll, there is _cvScalarAll function.
Types which are *Array like cv::_InputArray, are harder to translate because there is no automatic convertion in AutoIt like in c++.
For this reason, for functions which take those type of parameters, there will be 2 additionnal functions.
_cve
FooTyped
where you specified the type of the Array parameter and
_cve
FooMat
where you specified the type of all the Array parameter are Mat
.
For vectors, there are functions starting with _VectorOf
that allows to managed them.
As examples, for std::vector<int>*
, there is
_VectorOfInt
_VectorOfIntCreateSize
_VectorOfIntGetSize
_VectorOfIntPush
_VectorOfIntPushMulti
_VectorOfIntPushVector
_VectorOfIntClear
_VectorOfIntRelease
_VectorOfIntCopyData
_VectorOfIntGetStartAddress
_VectorOfIntGetEndAddress
_VectorOfIntGetItem
_VectorOfIntGetItemPtr
_VectorOfIntSizeOfItemInBytes
As examples, for std::vector<std::vector<cv::Point>>*
, there is
_VectorOfVectorOfPoint
_VectorOfVectorOfPointCreateSize
_VectorOfVectorOfPointGetSize
_VectorOfVectorOfPointPush
_VectorOfVectorOfPointPushMulti
_VectorOfVectorOfPointPushVector
_VectorOfVectorOfPointClear
_VectorOfVectorOfPointRelease
_VectorOfVectorOfPointCopyData
_VectorOfVectorOfPointGetStartAddress
_VectorOfVectorOfPointGetEndAddress
_VectorOfVectorOfPointGetItem
_VectorOfVectorOfPointGetItemPtr
_VectorOfVectorOfPointSizeOfItemInBytes
Let's translate the following python code
blurred = cv2.GaussianBlur(image, (3, 3), 0)
T, thresh_img = cv2.threshold(blurred, 215, 255, cv2.THRESH_BINARY)
cnts, _ = cv2.findContours(thresh_img,
cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
blurred = cv2.GaussianBlur(image, (3, 3), 0)
The UDF function of GaussianBlur
is
Func _cveGaussianBlur($src, $dst, $ksize, $sigmaX, $sigmaY = 0, $borderType = $CV_BORDER_DEFAULT)
; CVAPI(void) cveGaussianBlur(cv::_InputArray* src, cv::_OutputArray* dst, CvSize* ksize, double sigmaX, double sigmaY, int borderType);
The GaussianBlur documentation gives the following information
void cv::GaussianBlur ( InputArray src,
OutputArray dst,
Size ksize,
double sigmaX,
double sigmaY = 0,
int borderType = BORDER_DEFAULT
)
Python:
cv.GaussianBlur( src, ksize, sigmaX[, dst[, sigmaY[, borderType]]] ) -> dst
src input image;
dst output image;
In python, the returned value dst
, is the OutputArray dst
parameter of the c++ function, hence the UDF function.
src
and dst
are images, that means of type Mat
Because there are Array
parameters, we have to use the Typed
version of the UDF.
It allows to specify the type the Array
parameters.
The python code will therefore become
$blurred = _cveMatCreate()
_cveGaussianBlurTyped("Mat", $image, "Mat", $blurred, _cvSize(3, 3), 0)
And because all the Array
types are Mat
, it is equivalent to
$blurred = _cveMatCreate()
_cveGaussianBlurMat($image, $blurred, _cvSize(3, 3), 0)
T, thresh_img = cv2.threshold(blurred, 215, 255, cv2.THRESH_BINARY)
Applying the same steps leads to
$thresh_img = _cveMatCreate()
$T = _cveThresholdMat($blurred, $thresh_img, 215, 255, $CV_THRESH_BINARY)
cnts, _ = cv2.findContours(thresh_img,
cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
Accoroding to findContours documentation
countours is a std::vector<std::vector<cv::Point>>
hierarchy Optional output vector (e.g. std::vector<cv::Vec4i>):
hierarchy is harder to translate. cv::Vec4i
is a Mat
rix. A vector of Mat
trix is also a Mat
rix.
The python code will become
$cnts = _VectorOfVectorOfPointCreate()
$_ = _cveMatCreate()
_cveFindContoursTyped("Mat", $thresh_img, "VectorOfVectorOfPoint", $cnts, "Mat", $_, $CV_RETR_EXTERNAL, $CV_CHAIN_APPROX_SIMPLE)
Python
blurred = cv2.GaussianBlur(image, (3, 3), 0)
T, thresh_img = cv2.threshold(blurred, 215, 255, cv2.THRESH_BINARY)
cnts, _ = cv2.findContours(thresh_img,
cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
AutoIt
$blurred = _cveMatCreate()
_cveGaussianBlurTyped("Mat", $image, "Mat", $blurred, _cvSize(3, 3), 0)
$thresh_img = _cveMatCreate()
$T = _cveThresholdMat($blurred, $thresh_img, 215, 255, $CV_THRESH_BINARY)
$cnts = _VectorOfVectorOfPointCreate()
$_ = _cveMatCreate()
_cveFindContoursTyped("Mat", $thresh_img, "VectorOfVectorOfPoint", $cnts, "Mat", $_, $CV_RETR_EXTERNAL, $CV_CHAIN_APPROX_SIMPLE)
- Install CMAKE >= 3.5
- Install visual studio >= 2017
- Install Git for Windows
- Install nodejs
In Git BASH, excute the following commands
# get the source files
git clone https://github.com/smbape/node-emgucv-autoit-generator
cd node-emgucv-autoit-generator
# Install nodejs dependencies
npm ci
# Install submodules
git submodule update --init --recursive
# Build emgucv cvextern.dll
git apply -v emgucv.patch --directory emgucv
find emgucv/ -type f -name '*.bat' -exec unix2dos '{}' \;
(cd $(realpath emgucv)/platforms/windows; CMAKE_BUILD_TYPE=Release ADDITIONAL_BUILD_TARGET=opencv_modules cmd.exe //c Build_Binary_x86.bat 64 nogpu vc no-openni "" "" build)
node generate.js
I wanted to use OpenCV v4+ in AutoIt v3.
I found the Opencv UDF on the forum.
However it was for OpenCV v2 and there was a question for OpenCV v4+ without any anwser.
Therefore, there was no other option than trying find an answer myself.
AutoIt v3 is a freeware BASIC-like scripting language designed for automating the Windows GUI and general scripting.
AutoIt v3 can use dynamic libraries (dll).
However, since v3, OpenCV does not expose all the needed functions for image processing.
It is now focused on c++ project integration.
That means, if you want to use OpenCV in AutoIt v3,
you will need to write your own dll and export as many functions as you need.
It can be tedious.
I supposed that other languages will have the same problem.
AutoIt v3 is focused on windows and .Net is, at least in the past, focused on windows.
There was a high chance that an OpenCV binding to .Net will involve dlls.
Therefore, I looked for OpenCV in .Net and I found emgucv.
emgucv is a cross platform .Net wrapper to the OpenCV image processing library.
The project has exported almost all the OpenCV functions in a dll, making their dll suitable to be used with AutoIt v3