OpenCV Julia Bindings
============================
This module contains some limited functionality that allows OpenCV functions be used from Julia. Upon installation the binding files are automatically registered with Julia's package manager like any normal package.

This module requires Julia 1.4 and the CxxWrap.jl 0.10 when built from source. To use the compiled binary distributions Julia 1.6 is recommended.

Using Prebuilt Binaries
---
The easiest way to use OpenCV from Julia bindings is to use the version registered with Julia's package manager. This is also the only tested way to use Julia bindings on Windows. To do that simply start the Julia REPL. Hit `]` and then type `add OpenCV`.

```bash
$ julia
...
julia> ]
pkg> add OpenCV
```

---
The following steps walk over a source build of the Julia bindings.

CxxWrap Installation
----
Installation of CxxWrap is like any other Julia Package. Just start the REPL. Hit `]` and then type `add CxxWrap`.

```
$ julia
...
julia> ]
pkg> add CxxWrap
```

For now, Julia module is only compatible with Ubuntu and MacOS. Also, you must use a source build of [libcxxwrap-julia](https://github.com/JuliaInterop/libcxxwrap-julia). Follow the link for instructions on how to do that.

Build
-----
The Julia module is fully integrated into the OpenCV build system. While compiling add this to your command line `-DWITH_JULIA=ON`. If cmake finds a Julia executable available on the host system while configuring OpenCV, it will attempt to generate Julia wrappers for all OpenCV modules. If cmake is having trouble finding your Julia installation, you can explicitly point it to the Julia executable by defining the `Julia_EXECUTABLE` variable. For example:

    cmake -DWITH_JULIA=ON -DJulia_EXECUTABLE=/home/user/julia-1.4.1/bin ..

If you prefer using the gui version of cmake (cmake-gui), you can use the *Add Entry* option in the GUI to manually add the *path* variable `Julia_EXECUTABLE`.

Note, you need a valid Python installation to build the Julia Bindings.

Install
-------
By default the Julia package is installed in `CMAKE_BINARY_DIR`, you can change this by setting the `JULIA_PKG_INSTALL_PATH` cmake variable. The package is automatically registered with the Julia package manager.

---

Run
---

In order to use the bindings, simply type
```bash
$ julia
...
julia> using OpenCV
```

Note that this works only if you called `make install`. To run the wrapper package without making the installation target you must first set the environment variable `JULIA_LOAD_PATH` to the directory containing the OpenCV package. For example if in the build directory
```bash
$ export JULIA_LOAD_PATH=$PWD/OpenCV
$ julia
...
julia> using OpenCV
```

The Julia package does not export any symbols so all functions/structs/constants must be prefixed with OpenCV
```Julia
using OpenCV
const cv = OpenCV
img = cv.imread('cameraman.tif');

cv.imshow("window name", img)

cv.waitKey(Int32(0))
```

Finally, because Julia does not support OOP paradigm some changes had to be made. To access functions like `obj.function(ARGS)` you should instead use `function(obj, ARGS)`. The below example of reading frames from a VideoCapture should make it more clear.

```Julia
cap = OpenCV.VideoCapture(Int32(0))
ret, img = OpenCV.read(cap)
```

Instead of calling `cap.read()`, we called `OpenCV.read(cap)`

Another change is that all integer and float constants might need to prefixed with appropriate type constructor. This is needed because OpenCV functions accept 32-bit integers/floats but integer and float constants in Julia are sized based on the whether Julia is running in 64bit or 32bit mode.

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


Usage
---
This section has some more information about how to use the Julia bindings.

The function signatures are identical to Python bindings except the previously mentioned OOP exception. All functions that will accept a Mat/numpy array in C++/Python signatures will instead accept `OpenCV.InputArray` type in the Julia functions. `OpenCV.InputArray` is a union type between `CxxMat` and `AbstractArray{T, 3}`. As such, you can pass any arrays generated by any Julia function directly into OpenCV. If the AbstractArray is strided and has appropriate strides, the bindings will try to directly pass the memory region to OpenCV functions. However, if that's not possible then the array will first be copied to a `DenseArray` and then passed to OpenCV. The previously mentioned `CxxMat` is a black-box pointer type and should never be needed by users.

The output arrays of all OpenCV functions are of the type `OpenCV.Mat{T}`. Currently, all array input and output is restricted to 3D only (2D Mat and an additional dimension for color channels). The `OpenCV.Mat` type inherits from `AbstractArray{T, 3}` and can be directly passed to any Julia function that accepts AbstractArray types. It internally maintains a pointer to the original C++ `Mat` type to make sure that the memory is never deallocated. However, if you copy the `OpenCV.Mat` type object then the pointer is not copied and array moves to a Julia owned memory space.

All other types map directly to the corresponding types on C++. Unlike Python, `Point`, `Size`, `Rect` etc are represented not as tuples but as appropriate objects like `OpenCV.Point{Float32}` and so on. However, `Scalar` types are a tuple of numbers where the tuple has a size of 1-4.


Current Functionality
---

The bindings implement most of the functionality present in the core,imgproc,highgui,videoio,dnn,calib3d and imgcodecs. The samples also implement some additional manually wrapped functionality. The complete list of automatically wrapped functionality is [here](gen/funclist.csv).
