[
  {
    "path": ".gitattributes",
    "content": "# Auto detect text files and perform LF normalization\n* text=auto\n\n# Custom for Visual Studio\n*.cs     diff=csharp\n*.sln    merge=union\n*.csproj merge=union\n*.vbproj merge=union\n*.fsproj merge=union\n*.dbproj merge=union\n\n# Standard to msysgit\n*.doc\t diff=astextplain\n*.DOC\t diff=astextplain\n*.docx diff=astextplain\n*.DOCX diff=astextplain\n*.dot  diff=astextplain\n*.DOT  diff=astextplain\n*.pdf  diff=astextplain\n*.PDF\t diff=astextplain\n*.rtf\t diff=astextplain\n*.RTF\t diff=astextplain\n"
  },
  {
    "path": ".gitignore",
    "content": "# Windows image file caches\nThumbs.db\nehthumbs.db\n\n# Folder config file\nDesktop.ini\n\n# Recycle Bin used on file shares\n$RECYCLE.BIN/\n\n# Windows Installer files\n*.cab\n*.msi\n*.msm\n*.msp\n\n# =========================\n# Operating System Files\n# =========================\n\n# OSX\n# =========================\n\n.DS_Store\n.AppleDouble\n.LSOverride\n\n# Icon must end with two \\r\nIcon\n\n# Thumbnails\n._*\n\n# Files that might appear on external disk\n.Spotlight-V100\n.Trashes\n\n# Directories potentially created on remote AFP share\n.AppleDB\n.AppleDesktop\nNetwork Trash Folder\nTemporary Items\n.apdisk\n\n# =======\n# Other\n# =======\nbuild/\n"
  },
  {
    "path": ".readthedocs.yaml",
    "content": "# Read the Docs configuration file for Sphinx projects\n# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details\n\n# Required\nversion: 2\n\n# Set the OS, Python version and other tools you might need\nbuild:\n  os: ubuntu-22.04\n  tools:\n    python: \"3.11\"\n    # You can also specify other tool versions:\n    # nodejs: \"19\"\n    # rust: \"1.64\"\n    # golang: \"1.19\"\n\n# Build documentation in the \"docs/\" directory with Sphinx\nsphinx:\n   configuration: docs/source/conf.py\n\n# Optionally build your docs in additional formats such as PDF and ePub\n# formats:\n#    - pdf\n#    - epub\n\n# Optional but recommended, declare the Python requirements required\n# to build your documentation\n# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html\n# python:\n#    install:\n#    - requirements: docs/requirements.txt\n"
  },
  {
    "path": "README.md",
    "content": "OpenCV Java Tutorials\n============================\n\n[![No Maintenance Intended](http://unmaintained.tech/badge.svg)](http://unmaintained.tech/)\n\nLook at the tutorials on using OpenCV with Java (and JavaFX) at: http://opencv-java-tutorials.readthedocs.org/en/latest/index.html\n\nIf you are interested in mantaining these repos, please, contact me: https://github.com/orgs/opencv-java/people\n"
  },
  {
    "path": "docs/Makefile",
    "content": "# Makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS    =\nSPHINXBUILD   = sphinx-build\nPAPER         =\nBUILDDIR      = build\n\n# User-friendly check for sphinx-build\nifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)\n$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)\nendif\n\n# Internal variables.\nPAPEROPT_a4     = -D latex_paper_size=a4\nPAPEROPT_letter = -D latex_paper_size=letter\nALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source\n# the i18n builder cannot share the environment and doctrees with the others\nI18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source\n\n.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext\n\nhelp:\n\t@echo \"Please use \\`make <target>' where <target> is one of\"\n\t@echo \"  html       to make standalone HTML files\"\n\t@echo \"  dirhtml    to make HTML files named index.html in directories\"\n\t@echo \"  singlehtml to make a single large HTML file\"\n\t@echo \"  pickle     to make pickle files\"\n\t@echo \"  json       to make JSON files\"\n\t@echo \"  htmlhelp   to make HTML files and a HTML help project\"\n\t@echo \"  qthelp     to make HTML files and a qthelp project\"\n\t@echo \"  applehelp  to make an Apple Help Book\"\n\t@echo \"  devhelp    to make HTML files and a Devhelp project\"\n\t@echo \"  epub       to make an epub\"\n\t@echo \"  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter\"\n\t@echo \"  latexpdf   to make LaTeX files and run them through pdflatex\"\n\t@echo \"  latexpdfja to make LaTeX files and run them through platex/dvipdfmx\"\n\t@echo \"  text       to make text files\"\n\t@echo \"  man        to make manual pages\"\n\t@echo \"  texinfo    to make Texinfo files\"\n\t@echo \"  info       to make Texinfo files and run them through makeinfo\"\n\t@echo \"  gettext    to make PO message catalogs\"\n\t@echo \"  changes    to make an overview of all changed/added/deprecated items\"\n\t@echo \"  xml        to make Docutils-native XML files\"\n\t@echo \"  pseudoxml  to make pseudoxml-XML files for display purposes\"\n\t@echo \"  linkcheck  to check all external links for integrity\"\n\t@echo \"  doctest    to run all doctests embedded in the documentation (if enabled)\"\n\t@echo \"  coverage   to run coverage check of the documentation (if enabled)\"\n\nclean:\n\trm -rf $(BUILDDIR)/*\n\nhtml:\n\t$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html\n\t@echo\n\t@echo \"Build finished. The HTML pages are in $(BUILDDIR)/html.\"\n\ndirhtml:\n\t$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml\n\t@echo\n\t@echo \"Build finished. The HTML pages are in $(BUILDDIR)/dirhtml.\"\n\nsinglehtml:\n\t$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml\n\t@echo\n\t@echo \"Build finished. The HTML page is in $(BUILDDIR)/singlehtml.\"\n\npickle:\n\t$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle\n\t@echo\n\t@echo \"Build finished; now you can process the pickle files.\"\n\njson:\n\t$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json\n\t@echo\n\t@echo \"Build finished; now you can process the JSON files.\"\n\nhtmlhelp:\n\t$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp\n\t@echo\n\t@echo \"Build finished; now you can run HTML Help Workshop with the\" \\\n\t      \".hhp project file in $(BUILDDIR)/htmlhelp.\"\n\nqthelp:\n\t$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp\n\t@echo\n\t@echo \"Build finished; now you can run \"qcollectiongenerator\" with the\" \\\n\t      \".qhcp project file in $(BUILDDIR)/qthelp, like this:\"\n\t@echo \"# qcollectiongenerator $(BUILDDIR)/qthelp/OpenCVJavaTutorials.qhcp\"\n\t@echo \"To view the help file:\"\n\t@echo \"# assistant -collectionFile $(BUILDDIR)/qthelp/OpenCVJavaTutorials.qhc\"\n\napplehelp:\n\t$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp\n\t@echo\n\t@echo \"Build finished. The help book is in $(BUILDDIR)/applehelp.\"\n\t@echo \"N.B. You won't be able to view it unless you put it in\" \\\n\t      \"~/Library/Documentation/Help or install it in your application\" \\\n\t      \"bundle.\"\n\ndevhelp:\n\t$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp\n\t@echo\n\t@echo \"Build finished.\"\n\t@echo \"To view the help file:\"\n\t@echo \"# mkdir -p $$HOME/.local/share/devhelp/OpenCVJavaTutorials\"\n\t@echo \"# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/OpenCVJavaTutorials\"\n\t@echo \"# devhelp\"\n\nepub:\n\t$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub\n\t@echo\n\t@echo \"Build finished. The epub file is in $(BUILDDIR)/epub.\"\n\nlatex:\n\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex\n\t@echo\n\t@echo \"Build finished; the LaTeX files are in $(BUILDDIR)/latex.\"\n\t@echo \"Run \\`make' in that directory to run these through (pdf)latex\" \\\n\t      \"(use \\`make latexpdf' here to do that automatically).\"\n\nlatexpdf:\n\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex\n\t@echo \"Running LaTeX files through pdflatex...\"\n\t$(MAKE) -C $(BUILDDIR)/latex all-pdf\n\t@echo \"pdflatex finished; the PDF files are in $(BUILDDIR)/latex.\"\n\nlatexpdfja:\n\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex\n\t@echo \"Running LaTeX files through platex and dvipdfmx...\"\n\t$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja\n\t@echo \"pdflatex finished; the PDF files are in $(BUILDDIR)/latex.\"\n\ntext:\n\t$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text\n\t@echo\n\t@echo \"Build finished. The text files are in $(BUILDDIR)/text.\"\n\nman:\n\t$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man\n\t@echo\n\t@echo \"Build finished. The manual pages are in $(BUILDDIR)/man.\"\n\ntexinfo:\n\t$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo\n\t@echo\n\t@echo \"Build finished. The Texinfo files are in $(BUILDDIR)/texinfo.\"\n\t@echo \"Run \\`make' in that directory to run these through makeinfo\" \\\n\t      \"(use \\`make info' here to do that automatically).\"\n\ninfo:\n\t$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo\n\t@echo \"Running Texinfo files through makeinfo...\"\n\tmake -C $(BUILDDIR)/texinfo info\n\t@echo \"makeinfo finished; the Info files are in $(BUILDDIR)/texinfo.\"\n\ngettext:\n\t$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale\n\t@echo\n\t@echo \"Build finished. The message catalogs are in $(BUILDDIR)/locale.\"\n\nchanges:\n\t$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes\n\t@echo\n\t@echo \"The overview file is in $(BUILDDIR)/changes.\"\n\nlinkcheck:\n\t$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck\n\t@echo\n\t@echo \"Link check complete; look for any errors in the above output \" \\\n\t      \"or in $(BUILDDIR)/linkcheck/output.txt.\"\n\ndoctest:\n\t$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest\n\t@echo \"Testing of doctests in the sources finished, look at the \" \\\n\t      \"results in $(BUILDDIR)/doctest/output.txt.\"\n\ncoverage:\n\t$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage\n\t@echo \"Testing of coverage in the sources finished, look at the \" \\\n\t      \"results in $(BUILDDIR)/coverage/python.txt.\"\n\nxml:\n\t$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml\n\t@echo\n\t@echo \"Build finished. The XML files are in $(BUILDDIR)/xml.\"\n\npseudoxml:\n\t$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml\n\t@echo\n\t@echo \"Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml.\"\n"
  },
  {
    "path": "docs/make.bat",
    "content": "@ECHO OFF\n\nREM Command file for Sphinx documentation\n\nif \"%SPHINXBUILD%\" == \"\" (\n\tset SPHINXBUILD=sphinx-build\n)\nset BUILDDIR=build\nset ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source\nset I18NSPHINXOPTS=%SPHINXOPTS% source\nif NOT \"%PAPER%\" == \"\" (\n\tset ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%\n\tset I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%\n)\n\nif \"%1\" == \"\" goto help\n\nif \"%1\" == \"help\" (\n\t:help\n\techo.Please use `make ^<target^>` where ^<target^> is one of\n\techo.  html       to make standalone HTML files\n\techo.  dirhtml    to make HTML files named index.html in directories\n\techo.  singlehtml to make a single large HTML file\n\techo.  pickle     to make pickle files\n\techo.  json       to make JSON files\n\techo.  htmlhelp   to make HTML files and a HTML help project\n\techo.  qthelp     to make HTML files and a qthelp project\n\techo.  devhelp    to make HTML files and a Devhelp project\n\techo.  epub       to make an epub\n\techo.  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter\n\techo.  text       to make text files\n\techo.  man        to make manual pages\n\techo.  texinfo    to make Texinfo files\n\techo.  gettext    to make PO message catalogs\n\techo.  changes    to make an overview over all changed/added/deprecated items\n\techo.  xml        to make Docutils-native XML files\n\techo.  pseudoxml  to make pseudoxml-XML files for display purposes\n\techo.  linkcheck  to check all external links for integrity\n\techo.  doctest    to run all doctests embedded in the documentation if enabled\n\techo.  coverage   to run coverage check of the documentation if enabled\n\tgoto end\n)\n\nif \"%1\" == \"clean\" (\n\tfor /d %%i in (%BUILDDIR%\\*) do rmdir /q /s %%i\n\tdel /q /s %BUILDDIR%\\*\n\tgoto end\n)\n\n\nREM Check if sphinx-build is available and fallback to Python version if any\n%SPHINXBUILD% 2> nul\nif errorlevel 9009 goto sphinx_python\ngoto sphinx_ok\n\n:sphinx_python\n\nset SPHINXBUILD=python -m sphinx.__init__\n%SPHINXBUILD% 2> nul\nif errorlevel 9009 (\n\techo.\n\techo.The 'sphinx-build' command was not found. Make sure you have Sphinx\n\techo.installed, then set the SPHINXBUILD environment variable to point\n\techo.to the full path of the 'sphinx-build' executable. Alternatively you\n\techo.may add the Sphinx directory to PATH.\n\techo.\n\techo.If you don't have Sphinx installed, grab it from\n\techo.http://sphinx-doc.org/\n\texit /b 1\n)\n\n:sphinx_ok\n\n\nif \"%1\" == \"html\" (\n\t%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The HTML pages are in %BUILDDIR%/html.\n\tgoto end\n)\n\nif \"%1\" == \"dirhtml\" (\n\t%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.\n\tgoto end\n)\n\nif \"%1\" == \"singlehtml\" (\n\t%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.\n\tgoto end\n)\n\nif \"%1\" == \"pickle\" (\n\t%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished; now you can process the pickle files.\n\tgoto end\n)\n\nif \"%1\" == \"json\" (\n\t%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished; now you can process the JSON files.\n\tgoto end\n)\n\nif \"%1\" == \"htmlhelp\" (\n\t%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished; now you can run HTML Help Workshop with the ^\n.hhp project file in %BUILDDIR%/htmlhelp.\n\tgoto end\n)\n\nif \"%1\" == \"qthelp\" (\n\t%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished; now you can run \"qcollectiongenerator\" with the ^\n.qhcp project file in %BUILDDIR%/qthelp, like this:\n\techo.^> qcollectiongenerator %BUILDDIR%\\qthelp\\OpenCVJavaTutorials.qhcp\n\techo.To view the help file:\n\techo.^> assistant -collectionFile %BUILDDIR%\\qthelp\\OpenCVJavaTutorials.ghc\n\tgoto end\n)\n\nif \"%1\" == \"devhelp\" (\n\t%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished.\n\tgoto end\n)\n\nif \"%1\" == \"epub\" (\n\t%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The epub file is in %BUILDDIR%/epub.\n\tgoto end\n)\n\nif \"%1\" == \"latex\" (\n\t%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished; the LaTeX files are in %BUILDDIR%/latex.\n\tgoto end\n)\n\nif \"%1\" == \"latexpdf\" (\n\t%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex\n\tcd %BUILDDIR%/latex\n\tmake all-pdf\n\tcd %~dp0\n\techo.\n\techo.Build finished; the PDF files are in %BUILDDIR%/latex.\n\tgoto end\n)\n\nif \"%1\" == \"latexpdfja\" (\n\t%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex\n\tcd %BUILDDIR%/latex\n\tmake all-pdf-ja\n\tcd %~dp0\n\techo.\n\techo.Build finished; the PDF files are in %BUILDDIR%/latex.\n\tgoto end\n)\n\nif \"%1\" == \"text\" (\n\t%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The text files are in %BUILDDIR%/text.\n\tgoto end\n)\n\nif \"%1\" == \"man\" (\n\t%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The manual pages are in %BUILDDIR%/man.\n\tgoto end\n)\n\nif \"%1\" == \"texinfo\" (\n\t%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.\n\tgoto end\n)\n\nif \"%1\" == \"gettext\" (\n\t%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The message catalogs are in %BUILDDIR%/locale.\n\tgoto end\n)\n\nif \"%1\" == \"changes\" (\n\t%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.The overview file is in %BUILDDIR%/changes.\n\tgoto end\n)\n\nif \"%1\" == \"linkcheck\" (\n\t%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Link check complete; look for any errors in the above output ^\nor in %BUILDDIR%/linkcheck/output.txt.\n\tgoto end\n)\n\nif \"%1\" == \"doctest\" (\n\t%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Testing of doctests in the sources finished, look at the ^\nresults in %BUILDDIR%/doctest/output.txt.\n\tgoto end\n)\n\nif \"%1\" == \"coverage\" (\n\t%SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Testing of coverage in the sources finished, look at the ^\nresults in %BUILDDIR%/coverage/python.txt.\n\tgoto end\n)\n\nif \"%1\" == \"xml\" (\n\t%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The XML files are in %BUILDDIR%/xml.\n\tgoto end\n)\n\nif \"%1\" == \"pseudoxml\" (\n\t%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml\n\tif errorlevel 1 exit /b 1\n\techo.\n\techo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.\n\tgoto end\n)\n\n:end\n"
  },
  {
    "path": "docs/source/01-installing-opencv-for-java.rst",
    "content": "==========================\nInstalling OpenCV for Java\n==========================\n\nIntroduction to OpenCV for Java\n--------------------------------\nAs of OpenCV 2.4.4, OpenCV supports desktop Java development. This tutorial will help you install OpenCV on your desktop operating system.\n\nInstall the latest Java version\n--------------------------------\nDownload the latest Java JDK from the `Oracle <http://www.oracle.com/technetwork/java/javase/downloads/index.html>`_ website. Now you should be able to install the latest Java JDK by opening the file just downloaded.\n\nInstall the latest Eclipse version\n-----------------------------------\nDownload the latest Eclipse version at the `Eclipse Download page <https://www.eclipse.org/downloads/eclipse-packages/>`_ choosing the ``Eclipse IDE for Java Developers`` version (suggested).\n\nExtract the downloaded compressed file and put the resulting folder wherever you want to. You don't need to install anything. Alternatively, you can try the Eclipse installer.\n\nInstall OpenCV 3.x under Windows\n------------------------------------\nFirst of all you should download the OpenCV library (version 3.x) from `here <http://opencv.org/releases.html>`_.\n\nThen, extract the downloaded OpenCV file in a location of your choice. Once you get the folder ``opencv`` put in wherever you prefer.\n\nNow the only two things that you will need are: the ``opencv-3xx.jar`` file located at ``\\opencv\\build\\java`` and the ``opencv_java3xx.dll`` library located at ``\\opencv\\build\\java\\x64`` (for 64-bit systems) or ``\\opencv\\build\\java\\x86`` (for 32-bit systems). The `3xx` suffix of each file is a shortcut for the current OpenCV version, e.g., it will be `300` for OpenCV 3.0 and `330` for OpenCV 3.3. \n\nInstall OpenCV 3.x under macOS\n---------------------------------\nThe quickest way to obtain OpenCV under macOS is to use `Homebrew <http://brew.sh>`_. After installing Homebrew, you have to check whether the `XCode Command Line Tools` are already installed on your system.\n\nTo do so, open the `Terminal` and execute:\n``xcode-select --install``\nIf macOS asks for installing such tools, proceed with the download and installation. Otherwise, continue with the OpenCV installation.\n\nAs a prerequisite, check that Apache Ant is installed. Otherwise, install it with Homebrew:\n``brew install ant``.\nAnt should be available at ``/usr/local/bin/ant``.\n\nTo install OpenCV (with Java support) through Homebrew, you need to edit the *opencv* formula in Homebrew, to add support for Java:\n``brew edit opencv``\nIn the text editor that will open, change the line:\n``-DBUILD_opencv_java=OFF``\nin\n``-DBUILD_opencv_java=ON``\nthen, after saving the file, you can effectively install OpenCV:\n``brew install --build-from-source opencv``\n\nAfter the installation of OpenCV, the needed jar file and the dylib library will be located at ``/usr/local/Cellar/opencv/3.x.x/share/OpenCV/java/``, e.g., ``/usr/local/Cellar/opencv/3.3.1/share/OpenCV/java/``.\n\nPlease, notice that this method doesn't work if you update OpenCV from a previous version: you need to uninstall OpenCV and install it again.\n\nInstall OpenCV 3.x under Linux\n---------------------------------\nPlease, note: the following instructions are also useful if you want to compile OpenCV under Windows or macOS. Linux package management systems (`apt-get`, `yum`, etc.) *may* provide the needed version of the OpenCV library.\n\nAs first step, download and install `CMake <http://www.cmake.org/download/>`_ and `Apache Ant <http://ant.apache.org/>`_, if you don't have any of these. Download the OpenCV library from `its website <http://opencv.org/releases.html>`_.\nExtract the downloaded OpenCV file in a location of your choice and open CMake ( cmake-gui ).\nPut the location of the extracted OpenCV library in the ``Where is the source code field`` (e.g., /opencv/) and insert the destination directory of your build in the ``Where to build the binaries`` field (e.g., /opencv/build).\nAt last, check the ``Grouped`` and ``Advanced`` checkboxes.\n\n.. image:: _static/01-00.png\n\nNow press ``Configure`` and use the default compilers for ``Unix Makefiles``. Please, be sure to have installed a C/C++ compiler.\nIn the ``Ungrouped Entries`` group, insert the path to the Apache Ant (Add entry with the ``ANT_EXECUTABLE`` name) executable (e.g., ``/apache-ant-1.9.6/bin/ant``).\nIn the ``BUILD`` group, unselect:\n\n* ``BUILD_PERF_TESTS``\n* ``BUILD_SHARED_LIBRARY`` to make the Java bindings dynamic library all-sufficient\n* ``BUILD_TESTS``\n* ``BUILD_opencv_python``\n\nIn the ``CMAKE`` group, set to ``Debug`` (or ``Release``) the ``CMAKE_BUILD_TYPE``\n\nIn the ``JAVA`` group:\n\n* insert the Java AWT include path (e.g., ``/usr/lib/jvm/java-1.8.0/include/``)\n* insert the Java AWT library path (e.g., ``/usr/lib/jvm/java-1.8.0/include/jawt.h``)\n* insert the Java include path (e.g., ``/usr/lib/jvm/java-1.8.0/include/``)\n* insert the alternative Java include path (e.g., ``/usr/lib/jvm/java-1.8.0/include/linux``)\n* insert the JVM  library path (e.g., ``/usr/lib/jvm/java-1.8.0/include/jni.h``)\n\nPress ``Configure`` twice, and the CMake window should appear with a white background. If not, fix the red lines and press ``Configure`` again. Now, press ``Generate`` and close CMake.\n\n.. image:: _static/01 - 01.png\n\nNow open the terminal, go to the ``build`` folder of OpenCV and compile everything with the command: ``make -j``. Notice that the `-j` flag tells `make` to run in parallel with the maximum number of allowed job threads, which makes the build theoretically faster.\nWait for the process to be completed...\nIf everything went well you should have ``opencv-3xx.jar`` in the ``/opencv/build/bin`` directory and ``libopencv_java3xx.so`` in the ``/opencv/build/lib`` directory. The `3xx` suffix of each file is a shortcut for the current OpenCV version, e.g., it will be `300` for OpenCV 3.0 and `330` for OpenCV 3.3. This is everything you need.\n\nSet up OpenCV for Java in Eclipse\n----------------------------------\nOpen Eclipse and select a workspace of your choice. Create a User Library, ready to be used on all your next projects: go to  ``Window > Preferences...``.\n\n.. image:: _static/01 - 02.png\n\nFrom the menu navigate under ``Java > Build Path > User Libraries`` and choose ``New...``.\nEnter a name for the library (e.g., opencv) and select the newly created user library.\nChoose ``Add External JARs...``, browse to select ``opencv-3xx.jar`` from your computer.\nAfter adding the jar, extend it, select ``Native library location`` and press ``Edit...``.\n\n.. image:: _static/01 - 03.png\n\nSelect ``External Folder...`` and browse to select the folder containing the OpenCV libraries (e.g., ``C:\\opencv\\build\\java\\x64`` under Windows).\n\nIn case of MacOS, if you installed OpenCV *without* Homebrew, you need to create a soft link with .dylib extension for the .so file. E.g., from the terminal, type:\n``ln -s libopencv_java300.so libopencv_java300.dylib``\n\nSet up OpenCV for Java in other IDEs\n---------------------------------------------------\nIf you are using IntelliJ, you can specify the location of the library with the VM options argument in Run/Debug Configuration ``-Djava.library.path=/opencv/build/lib``.\n\n.. image:: _static/01 - 04.png\n.. image:: _static/01 - 05.png\n"
  },
  {
    "path": "docs/source/02-first-java-application-with-opencv.rst",
    "content": "=======================================\nYour First Java Application with OpenCV\n=======================================\n\n.. note:: We assume that by now you have already read the previous tutorials. If not, please check previous tutorials at `<http://opencv-java-tutorials.readthedocs.org/en/latest/index.html>`_. You can also find the source code and resources at `<https://github.com/opencv-java/>`_\n\nA Java application with OpenCV\n------------------------------\nThis tutorial will guide you through the creation of a simple Java console application using the  OpenCV library in Eclipse.\n\nWhat we will do in this tutorial\n--------------------------------\nIn this guide, we will:\n * Create a new Java Project\n * Add a User Library to the project\n * Write some OpenCV code\n * Build and Run the application\n\nCreate a New Project\n--------------------\nOpen Eclipse and create a new Java project; open the ``File`` menu, go to ``New`` and click on ``Java Project``.\n\n.. image:: _static/02-00.png\n\nIn the ``New Java Project`` dialog write the name of your project and click on ``Finish``.\n\nAdd a User Library\n------------------\nIf you followed the previous tutorial (``Installing OpenCV for Java``), you should already have the OpenCV library set in your workspace's user libraries; if not please check out the previous tutorial.\nNow you should be ready to add the library to your project.\nInside Eclipse's ``Package Explorer`` just right-click on your project's folder and go to ``Build Path --> Add Libraries...``.\n\n.. image:: _static/02-01.png\n\nSelect ``User Libraries`` and click on ``Next``, check the checkbox of the OpenCV library and click ``Finish``.\n\n.. image:: _static/02-02.png\n\nCreate a simple application\n---------------------------\nNow add a new Class to your project by  right-clicking on your project's folder and go to ``New --> Class``.\nWrite a name of your choice for both the package and the class then click on ``Finish``.\nNow we are ready to write the code of our first application.\nLet's start by defining the ``main`` method:\n\n.. code-block:: java\n\n    public class HelloCV {\n\t    public static void main(String[] args){\n\t\t    System.loadLibrary(Core.NATIVE_LIBRARY_NAME);\n\t\t    Mat mat = Mat.eye(3, 3, CvType.CV_8UC1);\n\t\t    System.out.println(\"mat = \" + mat.dump());\n\t    }\n    }\n\nFirst of all we need to load the OpenCV Native Library previously set on our project.\n\n.. code-block:: java\n\n    System.loadLibrary(Core.NATIVE_LIBRARY_NAME);\n\nThen we can define a new Mat.\n\n.. note:: The class **Mat** represents an n-dimensional dense numerical single-channel or multi-channel array. It can be used to store real or complex-valued vectors and matrices, grayscale or color images, voxel volumes, vector fields, point clouds, tensors, histograms. For more details check out the OpenCV `page <http://docs.opencv.org/3.0.0/dc/d84/group__core__basic.html>`_.\n\n.. code-block:: java\n\n    Mat mat = Mat.eye(3, 3, CvType.CV_8UC1);\n\nThe ``Mat.eye`` represents an identity matrix, we set the dimensions of it (3x3) and the type of its elements.\n\nAs you can notice, if you leave the code just like this, you will get some error; this is due to the fact that eclipse can't resolve some variables. You can locate your mouse cursor on the words that seems to be an error(red underlined line) and wait for a dialog box to pop up and click on the voice ``Import...``. If you do that for all the variables we have added to the code the following rows:\n\n.. code-block:: java\n\n    import org.opencv.core.Core;\n    import org.opencv.core.CvType;\n    import org.opencv.core.Mat;\n\nWe can now try to build and run our application by clicking on the Run button.\nYou should have the following output:\n\n.. image:: _static/02-03.png\n\nThe whole source code is available on `GitHub <https://github.com/opencv-java/getting-started/blob/master/HelloCV/>`_.\n"
  },
  {
    "path": "docs/source/03-first-javafx-application-with-opencv.rst",
    "content": "=========================================\nYour First JavaFX Application with OpenCV\n=========================================\n\n.. note:: We assume that by now you have already read the previous tutorials. If not, please check previous tutorials at `<http://opencv-java-tutorials.readthedocs.org/en/latest/index.html>`_. You can also find the source code and resources at `<https://github.com/opencv-java/>`_\n\nA JavaFX application with OpenCV\n--------------------------------\nThis tutorial will guide you through the creation of a simple JavaFX GUI application using the  OpenCV library in Eclipse.\n\nWhat we will do in this tutorial\n--------------------------------\nIn this guide, we will:\n * Install the ``e(fx)clipse`` plugin and (optionally) *Scene Builder*.\n * Work with *Scene Builder*.\n * Write and Run our application.\n\nYour First Application in JavaFX\n--------------------------------\nThe application you will write by following this tutorial is going to capture a video stream from a webcam and, then, it will display it on the user interface (GUI). We will create the GUI with Scene Builder: it will have a button, which will allow us to start and stop the stream, and a simple image view container where we will put each stream frame.\n\nInstalling e(fx)clipse plugin and Scene Builder\n-----------------------------------------------\nIn Eclipse, install the ``e(fx)clipse`` plugin, by following the guide at `<http://www.eclipse.org/efxclipse/install.html#fortheambitious>`_.\nIf you choose not to install such a plugin, you have to create a traditional **Java project**, only.\nDownload and install *JavaFX Scene Builder* 2.0 from `<http://www.oracle.com/technetwork/java/javafxscenebuilder-1x-archive-2199384.html>`_.\n\nNow you can create a new JavaFX project. ``Go to File > New > Project...`` and select ``JavaFX project...``.\n\n.. image:: _static/03-00.png\n\nChoose a name for your project and click ``Next``.\n\n.. image:: _static/03-01.png\n\nNow add your OpenCV user library to your project and click ``Next``.\n\n.. image:: _static/03-02.png\n\nChoose a name for your package, for the *FXML file* and for the *Controller Class*.\nThe *FXML file* will contain the description of your GUI in FXML language, while the *Controller Class* will handle all the method and event which have to be called and managed when the user interacts with the GUI's components.\n\n.. image:: _static/03-03.png\n\nWorking with Scene Builder\n--------------------------\nIf you have installed *Scene Builder* you can now right click on your *FXML file* in Eclipse and select ``Open with SceneBuilder``.\n*Scene Builder* can help construct you gui by interacting with a graphic interface; this allows you to see a real time preview of your window and modify your components and their position just by editing the graphic preview. Let's take a look at what I'm talking about.\nAt fist the *FXML file* will have just an *AnchorPane*.\nAn AnchorPane allows the edges of child nodes to be anchored to an offset from the anchorpane's edges. If the anchorpane has a border and/or padding set, the offsets will be measured from the inside edge of those insets.\nThe anchorpane lays out each managed child regardless of the child's visible property value; unmanaged children are ignored for all layout calculations.\nYou can go ahead and delete the anchorpane and add a *BorderPane* instead.\nA BorderPane lays out children in top, left, right, bottom, and center positions.\n\n.. image:: _static/03-04.png\n\nYou can add a BorderPane by dragging from the ``Container`` menu a borderpane and then drop it in the ``Hierarchy`` menu.\nNow we can add the button that will allow us to start and stop the stream. Take a button component from the ``Controls`` menu and drop it on the **BOTTOM** field of our BP.\nAs we can see, on the right we will get three menus (Properties, Layout, Code) which are used to customize our selected component.\nFor example we can change text of our button in \"Start Camera\" in the ``Text`` field under the ``Properties`` menu and the id of the button (e.g. \"start_btn\") in the ``fx:id`` field under the ``Code`` menu.\n\n.. image:: _static/03-05.png\n\n.. image:: _static/03-06.png\n\nWe are going to need the id of the button later, in order to edit the button properties from our *Controller*'s methods.\nAs you can see our button is too close to the edge of the windows, so we should add some bottom margin to it; to do so we can add this information in the ``Layout`` menu.\nIn order to make the button work, we have to set the name of the method (e.g. \"startCamera\") that will execute the action we want to preform in the field ``OnAction`` under the ``Code`` menu.\n\n.. image:: _static/03-07.png\n\nNow, we shall add an *ImageView* component from the ``Controls`` menu into the **CENTER** field of our BP. Let's also edit the id of the image view (e.g. \"currentFrame\"), and add some margin to it.\n\n.. image:: _static/03-08.png\n\nFinally we have to tell which Controller class will mange the GUI, we can do so by adding our controller class name in the ``Controller class`` field under the ``Controller`` menu located in the bottom left corner of the window.\n\nWe just created our first GUI by using Scene Builder, if you save the file and return to Eclipse you will notice that some FXML code has been generated automatically.\n\nKey Concepts in JavaFX\n----------------------\nThe **Stage** is where the application will be displayed (e.g., a Windows' window).\nA **Scene** is one container of Nodes that compose one \"page\" of your application.\nA **Node** is an element in the Scene, with a visual appearance and an interactive behavior. Nodes may be hierarchically nested .\nIn  the *Main class* we have to pass to the *start* function our *primary stage*:\n\n.. code-block:: java\n\n    public void start(Stage primaryStage)\n\nand load the fxml file that will populate our stage, the *root element* of the scene and the controller class:\n\n.. code-block:: java\n\n    FXMLLoader loader = new FXMLLoader(getClass().getResource(\"FXHelloCV.fxml\"));\n    BorderPane root = (BorderPane) loader.load();\n    FXController controller = loader.getController();\n\nManaging GUI Interactions With the Controller Class\n---------------------------------------------------\nFor our application we need to do basically two thing: control the button push and the refreshment of the image view.\nTo do so we have to create a reference between the gui components and a variable used in our controller class:\n\n.. code-block:: java\n\n    @FXML\n    private Button button;\n    @FXML\n    private ImageView currentFrame;\n\nThe ``@FXML`` tag means that we are linking our variable to an element of the fxml file and the value used to declare the variable has to equal to the id set for that specific element.\n\nThe ``@FXML`` tag is used with the same meaning for the Actions set under the Code menu in a specific element.\n\nfor:\n\n.. code-block:: xml\n\n    <Button fx:id=\"button\" mnemonicParsing=\"false\" onAction=\"#startCamera\" text=\"Start Camera\" BorderPane.alignment=\"CENTER\">\n\nwe set:\n\n.. code-block:: java\n\n    @FXML\n    protected void startCamera(ActionEvent event) { ...\n\nVideo Capturing\n---------------\nEssentially, all the functionalities required for video manipulation is integrated in the VideoCapture class.\n\n.. code-block:: java\n\n    private VideoCapture capture = new VideoCapture();\n\nThis on itself builds on the FFmpeg open source library. A video is composed of a succession of images, we refer to these in the literature as frames. In case of a video file there is a frame rate specifying just how long is between two frames. While for the video cameras usually there is a limit of just how many frames they can digitalize per second.\nIn our case we set as frame rate 30 frames per sec. To do so we initialize a timer (i.e., a ```ScheduledExecutorService```) that will open a background task every *33 milliseconds*.\n\n.. code-block:: java\n\n    Runnable frameGrabber = new Runnable() { ... }\n    this.timer = Executors.newSingleThreadScheduledExecutor();\n\t\tthis.timer.scheduleAtFixedRate(frameGrabber, 0, 33, TimeUnit.MILLISECONDS);\n\nTo check if the binding of the class to a video source was successful or not use the ``isOpened`` function:\n\n.. code-block:: java\n\n    if (this.capture.isOpened()) { ... }\n\nClosing the video is automatic when the objects destructor is called. However, if you want to close it before this you need to call its release function.\n\n.. code-block:: java\n\n    this.capture.release();\n\nThe frames of the video are just simple images. Therefore, we just need to extract them from the VideoCapture object and put them inside a Mat one.\n\n.. code-block:: java\n\n    Mat frame = new Mat();\n\nThe video streams are sequential. You may get the frames one after another by the read or the overloaded >> operator.\n\n.. code-block:: java\n\n    this.capture.read(frame);\n\nNow we are going to convert our image from *BGR* to *Grayscale* format. OpenCV has a really nice function to do this kind of transformations:\n\n.. code-block:: java\n\n    Imgproc.cvtColor(frame, frame, Imgproc.COLOR_BGR2GRAY);\n\nAs you can see, cvtColor takes as arguments:\n - a source image (frame)\n - a destination image (frame), in which we will save the converted image.\n - an additional parameter that indicates what kind of transformation will be performed. In this case we use ``COLOR_BGR2GRAY`` (because of ``imread`` has BGR default channel order in case of color images).\n\nNow in order to put the captured frame into the ImageView we need to convert the Mat in a Image.\nWe first create a buffer to store the Mat.\n\n.. code-block:: java\n\n    MatOfByte buffer = new MatOfByte();\n\nThen we can put the frame into the buffer by using the ``imencode`` function:\n\n.. code-block:: java\n\n    Imgcodecs.imencode(\".png\", frame, buffer);\n\nThis encodes an image into a memory buffer. The function compresses the image and stores it in the memory buffer that is resized to fit the result.\n\n.. note:: ``imencode`` returns single-row matrix of type ``CV_8UC1`` that contains encoded image as array of bytes.\n\nIt takes three parameters:\n - (\".png\") File extension that defines the output format.\n - (frame) Image to be written.\n - (buffer) Output buffer resized to fit the compressed image.\n\nOnce we filled the buffer we have to stream it into an Image by using ``ByteArrayInputStream``:\n\n.. code-block:: java\n\n    new Image(new ByteArrayInputStream(buffer.toArray()));\n\nNow we can put the new image in the ImageView.\nWith *Java 1.8* we cannot perform an update of a GUI element in a thread that differs from the main thread; so we need to get the new frame in a second thread and refresh our ImageView in the main thread:\n\n.. code-block:: java\n\n    Image imageToShow = grabFrame();\n    Platform.runLater(new Runnable() {\n\t    @Override public void run() { currentFrame.setImage(imageToShow); }\n    });\n\n.. image:: _static/03-09.png\n\nThe source code of the entire tutorial is available on `GitHub <https://github.com/opencv-java/getting-started/blob/master/FXHelloCV/>`_.\n"
  },
  {
    "path": "docs/source/04-opencv-basics.rst",
    "content": "=============\nOpenCV Basics\n=============\n\n.. note:: We assume that by now you have already read the previous tutorials. If not, please check previous tutorials at `<http://opencv-java-tutorials.readthedocs.org/en/latest/index.html>`_. You can also find the source code and resources at `<https://github.com/opencv-java/>`_\n\nWhat we will do in this tutorial\n--------------------------------\nIn this guide, we will:\n * Create a basic *checkbox* interaction to alter the color of the video stream.\n * Add a basic *checkbox* interaction to \"alpha over\" a logo to the video stream.\n * Display the video stream *histogram* (both one and three channels).\n\nGetting started\n---------------\nFor this tutorial we can create a new JavaFX project and build a scene as the one realized in the previous one. So we've got a window with a border pane in which:\n\n- in the **BOTTOM** we have a button inside a *HBox*:\n\n.. code-block:: xml\n\n    <HBox alignment=\"CENTER\" >\n       <padding>\n          <Insets top=\"25\" right=\"25\" bottom=\"25\" left=\"25\"/>\n       </padding>\n       <Button fx:id=\"button\" alignment=\"center\" text=\"Start camera\" onAction=\"#startCamera\" />\n    </HBox>\n\n- in the **CENTER** we have a ImageView:\n\n.. code-block:: xml\n\n    <ImageView fx:id=\"currentFrame\" />\n\nColor channel checkbox\n----------------------\nLet's open our fxml file with Scene Builder and add to the **RIGHT** field of our BorderPane a vertical box ``VBox``. A VBox lays out its children in a single vertical column. If the VBox has a border and/or padding set, then the contents will be layed out within those insets. Also it will resize children (if resizable) to their preferred heights and uses its ``fillWidth`` property to determine whether to resize their widths to fill its own width or keep their widths to their preferred (fillWidth defaults to true).\nA ``HBox`` works just like a VBox but it lays out its children horizontally instead of vertically.\n\nNow we can put inside the VBox a new checkbox, change its text to \"Show in gray scale\", and set an id (e.g., \"grayscale\").\n\n.. code-block:: xml\n\n    <CheckBox fx:id=\"grayscale\" text=\"Show in gray scale\" />\n\nLet's also add a title to this section by putting a text before our new checkbox, but still inside the VBox. Then, set its text to \"Controls\" (we can find the text element under the ``Shapes`` menu).\n\n.. code-block:: xml\n\n    <Text text=\"Controls\" />\n\nIn the Scene Builder we now have:\n\n.. image:: _static/04-00.png\n\nThe graphic interface is complete for the first task, now we need to work on the controller; in the previous tutorial we could control the number of channels displayed on screen with the line:\n\n.. code-block:: java\n\n    Imgproc.cvtColor(frame, frame, Imgproc.COLOR_BGR2GRAY);\n\nIn order to control this conversion with the check box, we have to link the check box with a FXML variable:\n\n.. code-block:: java\n\n    @FXML\n    private CheckBox grayscale;\n\nNow we can implement the control by adding a simple \"if\" condition which will perform the conversion only if our check box is checked:\n\n.. code-block:: java\n\n    if (grayscale.isSelected())\n    {\n       Imgproc.cvtColor(frame, frame, Imgproc.COLOR_BGR2GRAY);\n    }\n\nLoad an Image and Add it to the Stream\n--------------------------------------\nThe next step is to add another check box which, if checked, will trigger the display of an image over the camera stream.\nLet's start by adding the image to the project; create a new folder in the root directory of your project and put the image in there.\nIn my project I have a ``resources`` folder with a ``Poli.png`` image.\nGo back to Eclipse and refresh your project (you should have the new folder in it).\nLet's open the FXML file with Scene Builder and add a new checkbox below the one that controls the stream colors; we have to set the text, the name of the method in the ``OnAction`` field and an id.\nIn the code we will have for example:\n\n.. code-block:: xml\n\n    <CheckBox fx:id=\"logoCheckBox\" text=\"Show logo\" onAction=\"#loadLogo\" />\n\nIn the controller file we have to define a new variable associated with the checkbox, the method set on the ``OnAction`` field and adapt the code so that it will display the logo when the checkbox is checked and the stream is on.\nVariable:\n\n.. code-block:: java\n\n    @FXML\n    private CheckBox logoCheckBox;\n\n\n``loadLogo`` method:\nIn this method we are going to load the image whenever the logoCheckBox id selected (checked).\nIn order to load the image we have to use a basic OpenCV function: imread.\nIt returns a Mat and takes the path of the image and a flag (> 0 RGB image, =0 grayscale, <0 with the alpha channel).\n\n.. code-block:: java\n\n    @FXML\n    protected void loadLogo()\n    {\n     if (logoCheckBox.isSelected())\n        this.logo = Imgcodecs.imread(\"resources/Poli.png\");\n    }\n\nAdapt the code.\n\nWe are going to add some variants to the code in order to display our logo in a specific region of the stream. This means that for each frame capture, before the image could be converted into 1 or 3 channels, we have to set a **ROI** (region of interest) in which we want to place the logo.\nUsually a ROI of an image is a portion of it, we can define the ROI as a Rect object.\nRect is a template class for 2D rectangles, described by the following parameters:\n\n * Coordinates of the top-left corner. This is a default interpretation of Rect.x and Rect.y in OpenCV. Though, in your algorithms you may count x and y from the bottom-left corner.\n * Rectangle width and height.\n\n.. code-block:: java\n\n    Rect roi = new Rect(frame.cols()-logo.cols(), frame.rows()-logo.rows(), logo.cols(), logo.rows());\n\nThen we have to take control of our Mat's ROI, by doing so we are able to \"add\" our logo in the disired area of the frame defined by the ROI.\n\n.. code-block:: java\n\n    Mat imageROI = frame.submat(roi);\n\nWe had to make this operation because we can only \"add\" Mats with the same sizes; but how can we \"add\" two Mat together? We have to keep in mind that our logo could have 4 channels (RGB + alpha). So we could use two functions: ``addWeighted`` or ``copyTo``.\nThe ``addWeighted`` function calculates the weighted sum of two arrays as follows:\n\n\t\t*dst(I)= saturate(src1(I)* alpha + src2(I)* beta + gamma)*\n\nwhere I is a multi-dimensional index of array elements. In case of multi-channel arrays, each channel is processed independently. The function can be replaced with a matrix expression:\n\n\t\t*dst = src1*alpha + src2*beta + gamma*\n\n.. note:: Saturation is not applied when the output array has the depth ``CV_32S``. You may even get result of an incorrect sign in the case of overflow.\n\nParameters:\n - **src1** first input array.\n - **alpha** weight of the first array elements.\n - **src2** second input array of the same size and channel number as src1.\n - **beta** weight of the second array elements.\n - **gamma** scalar added to each sum.\n - **dst** output array that has the same size and number of channels as the input arrays.\n\nSo we'll have:\n\n.. code-block:: java\n\n    Core.addWeighted(imageROI, 1.0, logo, 0.7, 0.0, imageROI);\n\nThe second method (``copyTo``) simply copies a Mat into the other. We'll have:\n\n.. code-block:: java\n\n    Mat mask = logo.clone();\n    logo.copyTo(imageROI, mask);\n\nEverything we have done so far to add the logo to the image has to perform only IF our checkbox is check and the image loading process has ended successfully. So we have to add an if condition:\n\n.. code-block:: java\n\n    if (logoCheckBox.isSelected() && this.logo != null)\n    {\n\tRect roi = new Rect(frame.cols() - logo.cols(), frame.rows() - logo.rows(), logo.cols(),logo.rows());\n\tMat imageROI = frame.submat(roi);\n\t// add the logo: method #1\n\n\tCore.addWeighted(imageROI, 1.0, logo, 0.7, 0.0, imageROI);\n\t// add the logo: method #2\n\t// Mat mask = logo.clone();\n\t// logo.copyTo(imageROI, mask);\n    }\n\nCalculate a Histogram\n---------------------\nA histogram is a collected counts of data organized into a set of predefined bins.\nIn our case the data represents the intensity of the pixel so it will have a range like (0, 256).\n\nSince we know that the range of information value, we can segment our range in subparts (called bins); let's identify some parts of the histogram:\n 1. **dims**: The number of parameters you want to collect data of.\n 2. **bins**: It is the number of subdivisions in each dim. In our example, bins = 256\n 3. **range**: The limits for the values to be measured. In this case: range = [0,255]\n\nOur last goal is to display the histogram of the video stream for either RGB or in grayscale.\nFor this task we are going to define a method in our controller class that takes a Mat (our current frame) and a boolean that will flag if the frame is in RGB or in grayscale, for example:\n\n.. code-block: java\n\n    private void showHistogram(Mat frame, boolean gray){ ... }\n\nFirst thing we need to do is to divide the frame into other *n* frames, where *n* represents the number of channels of which our frame is composed. To do so we need to use the ``Core.split`` function; it needs a source Mat and a List<Mat> where to put the different channels. Obviously if the frame is in grayscale the list will have just one element.\n\n.. code-block: java\n\n    List<Mat> images = new ArrayList<Mat>();\n    Core.split(frame, images);\n\n\nBefore we could calculate the histogram of each channel we have to prepare all the inputs that the ``calcHist`` function needs.\nThe functions calcHist calculates the histogram of one or more arrays. The elements of a tuple used to increment a histogram bin are taken from the corresponding input arrays at the same location.\nParameters:\n\n - **images** Source arrays. They all should have the same depth, CV_8U or CV_32F, and the same size. Each of them can have an arbitrary number of channels.\n - **channels** List of the dims channels used to compute the histogram. The first array channels are numerated from 0 to images[0].channels()-1, the second array channels are counted from images[0].channels() to images[0].channels() + images[1].channels()-1, and so on.\n - **mask** Optional mask. If the matrix is not empty, it must be an 8-bit array of the same size as images[i]. The non-zero mask elements mark the array elements counted in the histogram.\n - **hist** Output histogram, which is a dense or sparse dims -dimensional array.\n - **histSize** Array of histogram sizes in each dimension.\n - **ranges** Array of the dims arrays of the histogram bin boundaries in each dimension. When the histogram is uniform (uniform =true), then for each dimension i it is enough to specify the lower (inclusive) boundary L_0 of the 0-th histogram bin and the upper (exclusive) boundary U_(histSize[i]-1) for the last histogram bin histSize[i]-1. That is, in case of a uniform histogram each of ranges[i] is an array of 2 elements. When the histogram is not uniform (uniform=false), then each of ranges[i] contains histSize[i]+1 elements: L_0, U_0=L_1, U_1=L_2,..., U_(histSize[i]-2)=L_(histSize[i]-1), U_(histSize[i]-1). The array elements, that are not between L_0 and U_(histSize[i]-1), are not counted in the histogram.\n - **accumulate** Accumulation flag. If it is set, the histogram is not cleared in the beginning when it is allocated. This feature enables you to compute a single histogram from several sets of arrays, or to update the histogram in time.\n\nThe image will be our frame, we don't need a mask and the last flag will be false; thus we need to define the channels, the hist, the ``histSize`` and the ``ranges``:\n\n.. code-block: java\n\n    MatOfInt channels = new MatOfInt(0);\n    Mat hist_b = new Mat();\n    Mat hist_g = new Mat();\n    Mat hist_r = new Mat();\n    MatOfInt histSize = new MatOfInt(256);\n    MatOfFloat histRange = new MatOfFloat(0, 256);\n\nIn the RGB case we will need all of the hist defined, in the grayscale case instead we will use just the ``hist_b`` one.\nWe are now ready to do the histogram calculation:\n\n.. code-block: java\n\n    Imgproc.calcHist(images.subList(0, 1), channels, new Mat(), hist_b, histSize, histRange, false);\n    if (!gray){\n\tImgproc.calcHist(images.subList(1, 2), channels, new Mat(), hist_g, histSize, \thistRange, false);\n\tImgproc.calcHist(images.subList(2, 3), channels, new Mat(), hist_r, histSize, \thistRange, false);\n    }\n\nwhere ``gray`` is the flag we passed to the ``showHistogram`` method.\n\nDraw the Histogram\n------------------\nNext step is to draw the calculated histogram in our GUI.\nOpen the fxml file with Scene Builder and add an ImageView above the \"Controls\" text in the right of the BP and set its id:\n\n.. code-block:: xml\n\n    <ImageView fx:id=\"histogram\" />\n\nNow back to the Controller class. Let's add a global variable to control the just added image view:\n\n.. code-block:: java\n\n    @FXML\n    private ImageView histogram;\n\nand continue to write the ``showHistogram`` method.\nFirst thing first, let's create an image to display the histogram:\n\n.. code-block:: java\n\n    int hist_w = 150;\n    int hist_h = 150;\n    int bin_w = (int) Math.round(hist_w / histSize.get(0, 0)[0]);\n    Mat histImage = new Mat(hist_h, hist_w, CvType.CV_8UC3, new Scalar(0, 0, 0));\n\nbefore drawing, we first normalize the histogram so its values fall in the range indicated by the parameters entered:\n\n.. code-block:: java\n\n    Core.normalize(hist_b, hist_b, 0, histImage.rows(), Core.NORM_MINMAX, -1, new Mat());\n    if (!gray){\n       Core.normalize(hist_g, hist_g, 0, histImage.rows(), Core.NORM_MINMAX, -1, new Mat());\n       Core.normalize(hist_r, hist_r, 0, histImage.rows(), Core.NORM_MINMAX, -1, new Mat());\n    }\n\nNow we can draw the histogram in our Mat:\n\n.. code-block:: java\n\n    for (int i = 1; i < histSize.get(0, 0)[0]; i++){\n       Imgproc.line(histImage, new Point(bin_w * (i - 1), hist_h - Math.round(hist_b.get(i - 1, 0)[0])), new Point(bin_w * (i), hist_h - Math.round(hist_b.get(i, 0)[0])), new Scalar(255, 0, 0), 2, 8, 0);\n       if (!gray){\n          Imgproc.line(histImage, new Point(bin_w * (i - 1), hist_h - Math.round(hist_g.get(i - 1, 0)[0])),new Point(bin_w * (i), hist_h - Math.round(hist_g.get(i, 0)[0])), new Scalar(0, 255, 0), 2, 8, 0);\n          Imgproc.line(histImage, new Point(bin_w * (i - 1), hist_h - Math.round(hist_r.get(i - 1, 0)[0])),Math.round(hist_r.get(i, 0)[0])), new Scalar(0, 0, 255), 2, 8, 0);\n       }\n    }\n\nLet's convert the obtained Mat to an Image with our method ``mat2Image`` and update the ImageView with the returned Image:\n\n.. code-block:: java\n\n    histo = mat2Image(histImage);\n    histogram.setImage(histo);\n\n.. image:: _static/04-01.png\n\n.. image:: _static/04-02.png\n\nThe source code of the entire tutorial is available on `GitHub <https://github.com/opencv-java/video-basics>`_.\n"
  },
  {
    "path": "docs/source/05-fourier-transform.rst",
    "content": "=================\nFourier Transform\n=================\n\n.. note:: We assume that by now you have already read the previous tutorials. If not, please check previous tutorials at `<http://opencv-java-tutorials.readthedocs.org/en/latest/index.html>`_. You can also find the source code and resources at `<https://github.com/opencv-java/>`_\n\nGoal\n----\nIn this tutorial we are going to create a JavaFX application where we can load a picture from our file system and apply to it the *DFT* and the *inverse DFT*.\n\nWhat is the Fourier Transform?\n------------------------------\nThe Fourier Transform will decompose an image into its sinus and cosines components. In other words, it will transform an image from its spatial domain to its frequency domain. The result of the transformation is complex numbers. Displaying this is possible either via a real image and a complex image or via a magnitude and a phase image. However, throughout the image processing algorithms only the magnitude image is interesting as this contains all the information we need about the images geometric structure.\nFor this tutorial we are going to use basic gray scale image, whose values usually are between zero and 255. Therefore the Fourier Transform too needs to be of a discrete type resulting in a Discrete Fourier Transform (DFT). The DFT is the sampled Fourier Transform and therefore does not contain all frequencies forming an image, but only a set of samples which is large enough to fully describe the spatial domain image. The number of frequencies corresponds to the number of pixels in the spatial domain image, i.e. the image in the spatial and Fourier domain are of the same size.\n\nWhat we will do in this tutorial\n--------------------------------\nIn this guide, we will:\n * Load an image from a *file chooser*.\n * Apply the *DFT* to the loaded image and show it.\n * Apply the *iDFT* to the transformed image and show it.\n\nGetting Started\n---------------\nLet's create a new JavaFX project. In Scene Builder set the windows element so that we have a Border Pane with:\n\n- on the **LEFT** an ImageView to show the loaded picture:\n\n.. code-block:: xml\n\n    <ImageView fx:id=\"originalImage\" />\n\n- on the **RIGHT** two ImageViews one over the other to display the DFT and the iDFT;\n\n.. code-block:: xml\n\n    <ImageView fx:id=\"transformedImage\" />\n    <ImageView fx:id=\"antitransformedImage\" />\n\n- on the **BOTTOM** three buttons, the first one to load the picture, the second one to apply the DFT and show it, and the last one to apply the anti-transform and show it.\n\n.. code-block:: xml\n\n    <Button alignment=\"center\" text=\"Load Image\" onAction=\"#loadImage\"/>\n    <Button fx:id=\"transformButton\" alignment=\"center\" text=\"Apply transformation\" onAction=\"#transformImage\" disable=\"true\" />\n    <Button fx:id=\"antitransformButton\" alignment=\"center\" text=\"Apply anti transformation\" onAction=\"#antitransformImage\" disable=\"true\" />\n\nThe gui will look something like this one:\n\n.. image:: _static/06-00.png\n\nLoad the file\n-------------\nFirst of all you need to add to your project a folder ``resources`` with two files in it. One of them is a sine function and the other one is a circular aperture.\nIn the Controller file, in order to load the image to our program, we are going to use a *filechooser*:\n\n.. code-block:: java\n\n    private FileChooser fileChooser;\n\nWhen we click the load button we have to set the initial directory of the FC and open the dialog. The FC will return the selected file:\n\n.. code-block:: java\n\n    File file = new File(\"./resources/\");\n    this.fileChooser.setInitialDirectory(file);\n    file = this.fileChooser.showOpenDialog(this.main.getStage());\n\nOnce we've loaded the file we have to make sure that it's going to be in grayscale and display the image into the image view:\n\n.. code-block:: java\n\n    this.image = Imgcodecs.imread(file.getAbsolutePath(), Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE);\n    this.originalImage.setImage(this.mat2Image(this.image));\n\nApplying the DFT\n----------------\nFirst of all expand the image to an optimal size. The performance of a DFT is dependent of the image size. It tends to be the fastest for image sizes that are multiple of the numbers two, three and five. Therefore, to achieve maximal performance it is generally a good idea to pad border values to the image to get a size with such traits. The ``getOptimalDFTSize()`` returns this optimal size and we can use the ``copyMakeBorder()`` function to expand the borders of an image:\n\n.. code-block:: java\n\n    int addPixelRows = Core.getOptimalDFTSize(image.rows());\n    int addPixelCols = Core.getOptimalDFTSize(image.cols());\n    Core.copyMakeBorder(image, padded, 0, addPixelRows - image.rows(), 0, addPixelCols - image.cols(),Imgproc.BORDER_CONSTANT, Scalar.all(0));\n\nThe appended pixels are initialized with zeros.\n\nThe result of the DFT is complex so  we have to make place for both the complex and the real values. We store these usually at least in a float format. Therefore we'll convert our input image to this type and expand it with another channel to hold the complex values:\n\n.. code-block:: java\n\n    padded.convertTo(padded, CvType.CV_32F);\n    this.planes.add(padded);\n    this.planes.add(Mat.zeros(padded.size(), CvType.CV_32F));\n    Core.merge(this.planes, this.complexImage);\n\nNow we can apply the DFT and then get the real and the imaginary part from the complex image:\n\n.. code-block:: java\n\n    Core.dft(this.complexImage, this.complexImage);\n    Core.split(complexImage, newPlanes);\n    Core.magnitude(newPlanes.get(0), newPlanes.get(1), mag);\n\nUnfortunately the dynamic range of the Fourier coefficients is too large to be displayed on the screen. To use the gray scale values for visualization we can transform our linear scale to a logarithmic one:\n\n.. code-block:: java\n\n    Core.add(Mat.ones(mag.size(), CVType.CV_32F), mag);\n    Core.log(mag, mag);\n\nRemember, that at the first step, we expanded the image? Well, it's time to throw away the newly introduced values. For visualization purposes we may also rearrange the quadrants of the result, so that the origin (zero, zero) corresponds with the image center:\n\n.. code-block:: java\n\n    image = image.submat(new Rect(0, 0, image.cols() & -2, image.rows() & -2));\n    int cx = image.cols() / 2;\n    int cy = image.rows() / 2;\n\n    Mat q0 = new Mat(image, new Rect(0, 0, cx, cy));\n    Mat q1 = new Mat(image, new Rect(cx, 0, cx, cy));\n    Mat q2 = new Mat(image, new Rect(0, cy, cx, cy));\n    Mat q3 = new Mat(image, new Rect(cx, cy, cx, cy));\n\n    Mat tmp = new Mat();\n    q0.copyTo(tmp);\n    q3.copyTo(q0);\n    tmp.copyTo(q3);\n\n    q1.copyTo(tmp);\n    q2.copyTo(q1);\n    tmp.copyTo(q2);\n\nNow we have to normalize our values by using the ``normalize()`` function in order to transform the matrix with float values into a viewable image form:\n\n.. code-block:: java\n\n    Core.normalize(mag, mag, 0, 255, Core.NORM_MINMAX);\n\nThe last step is to show the magnitude image in the ImageView:\n\n.. code-block:: java\n\n    this.transformedImage.setImage(this.mat2Image(magnitude));\n\nApplying the inverse DFT\n------------------------\nTo apply the inverse DFT we simply use the ``idft()`` function, extract the real values from the complex image with the ``split()`` function, and normalize the result with ``normalize()``:\n\n.. code-block:: java\n\n    Core.idft(this.complexImage, this.complexImage);\n    Mat restoredImage = new Mat();\n    Core.split(this.complexImage, this.planes);\n    Core.normalize(this.planes.get(0), restoredImage, 0, 255, Core.NORM_MINMAX);\n\nFinally we can show the result on the proper ImageView:\n\n.. code-block:: java\n\n    this.antitransformedImage.setImage(this.mat2Image(restoredImage));\n\nAnalyzing the results\n---------------------\n- *sinfunction.png*\n\n.. image:: _static/06-01.png\n\nThe image is a horizontal sine of 4 cycles. Notice that the DFT just has a single component, represented by 2 bright spots symmetrically placed about the center of the DFT image. The center of the image is the origin of the frequency coordinate system. The x-axis runs left to right through the center and represents the horizontal component of frequency. The y-axis runs bottom to top through the center and represents the vertical component of frequency. There is a dot at the center that represents the (0,0) frequency term or average value of the image. Images usually have a large average value (like 128) and lots of low frequency information so FT images usually have a bright blob of components near the center. High frequencies in the horizontal direction will cause bright dots away from the center in the horizontal direction.\n\n- *circle.png*\n\n.. image:: _static/06-02.png\n\nIn this case we have a circular aperture, and what is the Fourier transform of a circular aperture? The diffraction disk and rings. A large aperture produces a compact transform, instead a small one produces a larger Airy pattern; thus the disk is greater if aperture is smaller; according to Fourier properties, from the center to the middle of the first dark ring the distance is *(1.22 x N) / d*; in this case N is the size of the image, and d is the diameter of the circle.\nAn *Airy disk* is the bright center of the diffraction pattern created from a circular aperture ideal\noptical system; nearly half of the light is contained in a diameter of *1.02 x lamba x f_number*.\n\nThe source code of the entire tutorial is available on `GitHub <https://github.com/opencv-java/fourier-transform>`_.\n"
  },
  {
    "path": "docs/source/06-face-detection-and-tracking.rst",
    "content": "=============================\nFace Detection and Tracking\n=============================\n\n.. note:: We assume that by now you have already read the previous tutorials. If not, please check previous tutorials at `<http://opencv-java-tutorials.readthedocs.org/en/latest/index.html>`_. You can also find the source code and resources at `<https://github.com/opencv-java/>`_\n\nGoal\n----\nIn this tutorial we are going to use well-known classifiers that have been already trained and distributed by OpenCV in order to detect and track a moving face into a video stream.\n\nCascade Classifiers\n-------------------\nThe object recognition process (in our case, faces) is usually efficient if it is based on the features take-over which include additional information about the object class to be taken-over. In this tutorial we are going to use the *Haar-like features* and the *Local Binary Patterns* (LBP) in order to encode the contrasts highlighted by the human face and its spatial relations with the other objects present in the picture.\nUsually these features are extracted using a *Cascade Classifier* which has to be trained in order to recognize with precision different objects: the faces' classification is going to be much different from the car's classification.\n\nWhat we will do in this tutorial\n--------------------------------\nIn this guide, we will:\n * Insert a checkbox to select the Haar Classifier, detect and track a face, and draw a green rectangle around the detected face.\n * Insert a checkbox to select the LBP Classifier, detect and track a face, and draw a green rectangle around the detected face.\n\nGetting Started\n---------------\nLet's create a new JavaFX project. In Scene Builder set the windows element so that we have a Border Pane with:\n\n- on TOP a VBox a HBox and a separator. In the HBox we are goning to need two checkboxes, the first one is to select the Haar Classifier and the second one is to select the LBP Classifier.\n\n\t.. code-block:: xml\n\n\t\t<CheckBox fx:id=\"haarClassifier\" onAction=\"#haarSelected\" text=\"Haar Classifier\"/>\n\t\t<CheckBox fx:id=\"lbpClassifier\" onAction=\"#lbpSelected\" text=\"LBP Classifier\"/>\n\n- in the CENTRE we are going to put an ImageView for the web cam stream.\n\n\t.. code-block:: xml\n\n\t\t<ImageView fx:id=\"originalFrame\" />\n\n- on the BOTTOM we can add the usual button to start/stop the stream\n\n\t.. code-block:: xml\n\n\t\t<Button fx:id=\"cameraButton\" alignment=\"center\" text=\"Start camera\" onAction=\"#startCamera\" disable=\"true\" />\n\nThe gui will look something like this one:\n\n.. image:: _static/08-00.png\n\nLoading the Classifiers\n-----------------------\nFirst of all we need to add a folder ``resource`` to our project and put the classifiers in it.\nIn order to use the classifiers we need to load them from the resource folder, so every time that we check one of the two checkboxes we will load the correct classifier.\nTo do so, let's implement the ``OnAction`` methods we already declared before:\n\n- ``haarSelected``\n\tinside this method we are going to load the desired Haar Classifier (e.g. ``haarcascade_frontalface_alt.xml``) as follows:\n\n\t.. code-block:: java\n\n\t\tthis.checkboxSelection(\"resources/lbpcascades/haarcascade_frontalface_alt.xml\");\n\t\t...\n\t\tprivate void checkboxSelection(String... classifierPath)\n\t\t{\n\t\t\t// load the classifier(s)\n\t\t\tfor (String xmlClassifier : classifierPath)\n\t\t\t{\n\t\t\t\tthis.faceCascade.load(xmlClassifier);\n\t\t\t}\n\n\t\t\t// now the capture can start\n\t\t\tthis.cameraButton.setDisable(false);\n\t\t}\n\n- ``lbpSelected``\n\tfor the LPB we can use the same method and change the path of the classifier to be loaded:\n\n\t.. code-block:: java\n\n\t\tthis.checkboxSelection(\"resources/lbpcascades/lbpcascade_frontalface.xml\");\n\nDetection and Tracking\n----------------------\nOnce we've loaded the classifiers we are ready to start the detection; we are going to implement the detection in the ``detectAndDisplay`` method.\nFirst of all we need to convert the frame in grayscale and equalize the histogram to improve the results:\n\n.. code-block:: java\n\n    Imgproc.cvtColor(frame, grayFrame, Imgproc.COLOR_BGR2GRAY);\n    Imgproc.equalizeHist(grayFrame, grayFrame);\n\nThen we have to set the minimum size of the face to be detected (this required is need in the actual detection function). Let's set the minimum size as the 20% of the frame height:\n\n.. code-block:: java\n\n    if (this.absoluteFaceSize == 0)\n    {\n\tint height = grayFrame.rows();\n\tif (Math.round(height * 0.2f) > 0)\n\t{\n\t\tthis.absoluteFaceSize = Math.round(height * 0.2f);\n\t}\n    }\n\nNow we can start the detection:\n\n.. code-block:: java\n\n    this.faceCascade.detectMultiScale(grayFrame, faces, 1.1, 2, 0 | Objdetect.CASCADE_SCALE_IMAGE, new Size(this.absoluteFaceSize, this.absoluteFaceSize), new Size());\n\nThe ``detectMultiScale`` function detects objects of different sizes in the input image. The detected objects are returned as a list of rectangles.\nThe parameters are:\n\n - **image** Matrix of the type CV_8U containing an image where objects are detected.\n - **objects** Vector of rectangles where each rectangle contains the detected object.\n - **scaleFactor** Parameter specifying how much the image size is reduced at each image scale.\n - **minNeighbors** Parameter specifying how many neighbors each candidate rectangle should have to retain it.\n - **flags** Parameter with the same meaning for an old cascade as in the function cvHaarDetectObjects. It is not used for a new cascade.\n - **minSize** Minimum possible object size. Objects smaller than that are ignored.\n - **maxSize** Maximum possible object size. Objects larger than that are ignored.\n\nSo the result of the detection is going to be in the **objects** parameter or in our case ``faces``.\n\nLet's put this result in an array of rects and draw them on the frame, by doing so we can display the detected face are:\n\n.. code-block:: java\n\n    Rect[] facesArray = faces.toArray();\n    for (int i = 0; i < facesArray.length; i++)\n\tImgproc.rectangle(frame, facesArray[i].tl(), facesArray[i].br(), new Scalar(0, 255, 0, 255), 3);\n\nAs you can see we selected the color green with a transparent background: ``Scalar(0, 255, 0, 255)``.\n``.tl()`` and ``.br()`` stand for *top-left* and *bottom-right* and they represents the two opposite vertexes.\nThe last parameter just set the thickness of the rectangle's border.\n\nThe tracking part can be implemented by calling the ``detectAndDisplay`` method for each frame.\n\n.. image:: _static/08-01.png\n\n.. image:: _static/08-02.png\n\nThe source code of the entire tutorial is available on `GitHub <https://github.com/opencv-java/face-detection>`_.\n"
  },
  {
    "path": "docs/source/07-image-segmentation.rst",
    "content": "==================\nImage Segmentation\n==================\n\n.. note:: We assume that by now you have already read the previous tutorials. If not, please check previous tutorials at `<http://opencv-java-tutorials.readthedocs.org/en/latest/index.html>`_. You can also find the source code and resources at `<https://github.com/opencv-java/>`_\n\nGoal\n----\nIn this tutorial we are going to create a JavaFX application where we can decide to apply to video stream captured from our web cam either a *Canny edge detector* or a trivial background removal using the two basic morphological operations: *dilatation* and *erosion*.\n\nCanny edge detector\n-------------------\nThe **Canny edge detector** is an edge detection operator that uses a multi-stage algorithm to detect a wide range of edges in images. It was developed by John F. Canny in 1986.\n\nCanny edge detection is a four step process:\n 1. A Gaussian blur is applied to clear any speckles and free the image of noise.\n 2. A gradient operator is applied for obtaining the gradients' intensity and direction.\n 3. Non-maximum suppression determines if the pixel is a better candidate for an edge than its neighbors.\n 4. Hysteresis thresholding finds where edges begin and end.\n\nThe Canny algorithm contains a number of adjustable parameters, which can affect the computation time and effectiveness of the algorithm.\n - The size of the Gaussian filter: the smoothing filter used in the first stage directly affects the results of the Canny algorithm. Smaller filters cause less blurring, and allow detection of small, sharp lines. A larger filter causes more blurring, smearing out the value of a given pixel over a larger area of the image.\n - Thresholds: A threshold set too high can miss important information. On the other hand, a threshold set too low will falsely identify irrelevant information (such as noise) as important. It is difficult to give a generic threshold that works well on all images. No tried and tested approach to this problem yet exists.\n\nFor our purpose we are going to set the filter size to 3 and the threshold editable by a Slider.\n\nDilatation and Erosion\n----------------------\nDilation and erosion are the most basic morphological operations. Dilation adds pixels to the boundaries of objects in an image, while erosion removes pixels on object boundaries. The number of pixels added or removed from the objects in an image depends on the size and shape of the structuring element used to process the image. In the morphological dilation and erosion operations, the state of any given pixel in the output image is determined by applying a rule to the corresponding pixel and its neighbors in the input image. The rule used to process the pixels defines the operation as a dilation or an erosion.\n\n**Dilatation**: the value of the output pixel is the maximum value of all the pixels in the input pixel's neighborhood. In a binary image, if any of the pixels is set to the value 1, the output pixel is set to 1.\n\n**Erosion**: the value of the output pixel is the minimum value of all the pixels in the input pixel's neighborhood. In a binary image, if any of the pixels is set to 0, the output pixel is set to 0.\n\nWhat we will do in this tutorial\n--------------------------------\nIn this guide, we will:\n * Add a checkbox and a *Slider* to select and control the Canny edge detector.\n * Use the Canny edge function provided by OpenCV.\n * Use the Dilatation and erosion functions provided by OpenCV.\n * Create a trivial background removal function.\n\nGetting Started\n---------------\nLet's create a new JavaFX project. In Scene Builder set the windows element so that we have a Border Pane with:\n\n- on **TOP** a VBox containing two HBox, each one followed by a separator.\n\n + In the first HBox we are goning to need a checkbox and a *slider*, the first one is to select the Canny e.d. mode and the second one is going to be used to control the value of the threshold to be passed to the Canny e.d. function.\n\n\t.. code-block:: xml\n\n    \t\t<CheckBox fx:id=\"canny\" onAction=\"#cannySelected\" text=\"Edge detection\"/>\n    \t\t<Label text=\"Canny Threshold\" />\n    \t\t<Slider fx:id=\"threshold\" disable=\"true\" />\n\n + In the second HBox we need two checkboxes, the first one to select the Backgrond removal mode and the second one to say if we want to invert the algorithm (a sort of \"foreground removal\").\n\n\t.. code-block:: xml\n\n    \t\t<CheckBox fx:id=\"dilateErode\" onAction=\"#dilateErodeSelected\" text=\"Background removal\"/>\n    \t\t<CheckBox fx:id=\"inverse\" text=\"Invert\" disable=\"true\"/>\n\n- in the **CENTRE** we are going to put an ImageView for the web cam stream.\n\n.. code-block:: xml\n\n    <ImageView fx:id=\"originalFrame\" />\n\n- on the **BOTTOM** we can add the usual button to start/stop the stream\n\n.. code-block:: xml\n\n    <Button fx:id=\"cameraButton\" alignment=\"center\" text=\"Start camera\" onAction=\"#startCamera\" disable=\"true\" />\n\nThe gui will look something like this one:\n\n.. image:: _static/07-00.png\n\nUsing the Canny edge detection\n------------------------------\nIf we selected the Canny checkbox we can perform the method ``doCanny``.\n\n.. code-block:: java\n\n    if (this.canny.isSelected()){\n\tframe = this.doCanny(frame);\n    }\n\n``doCanny`` is a method that we define to execute the edge detection.\nFirst, we convert the image into a grayscale one and blur it with a filter of kernel size 3:\n\n.. code-block:: java\n\n    Imgproc.cvtColor(frame, grayImage, Imgproc.COLOR_BGR2GRAY);\n    Imgproc.blur(grayImage, detectedEdges, new Size(3, 3));\n\nSecond, we apply the OpenCV function Canny:\n\n.. code-block:: java\n\n    Imgproc.Canny(detectedEdges, detectedEdges, this.threshold.getValue(), this.threshold.getValue() * 3, 3, false);\n\nwhere the arguments are:\n - ``detectedEdges``: Source image, grayscale\n - ``detectedEdges``: Output of the detector (can be the same as the input)\n - ``this.threshold.getValue()``: The value entered by the user moving the Slider\n - ``this.threshold.getValue() * 3``: Set in the program as three times the lower threshold (following Canny's recommendation)\n - ``3``: The size of the Sobel kernel to be used internally\n - ``false``: a flag, indicating whether to use a more accurate calculation of the magnitude gradient.\n\nThen we fill a ``dest`` image with zeros (meaning the image is completely black).\n\n.. code-block:: java\n\n    Mat dest = new Mat();\n    Core.add(dest, Scalar.all(0), dest);\n\nFinally, we will use the function copyTo to map only the areas of the image that are identified as edges (on a black background).\n\n.. code-block:: java\n\n    frame.copyTo(dest, detectedEdges);\n\n``copyTo`` copies the src image onto ``dest``. However, it will only copy the pixels in the locations where they have non-zero values.\n\n\nCanny Result\n------------\n\n.. image:: _static/07-01.png\n\nUsing the Background Removal\n----------------------------\nIf we selected the background removal checkbox we can perform the method ``doBackgroundRemoval``\n\n.. code-block:: java\n\n    else if (this.dilateErode.isSelected())\n    {\n\tframe = this.doBackgroundRemoval(frame);\n    }\n\n``doBackgroundRemoval`` is a method that we define to execute the background removal.\n\nFirst we need to convert the current frame in HSV:\n\n.. code-block:: java\n\n    hsvImg.create(frame.size(), CvType.CV_8U);\n    Imgproc.cvtColor(frame, hsvImg, Imgproc.COLOR_BGR2HSV);\n    Now let's split the three channels of the image:\n    Core.split(hsvImg, hsvPlanes);\n\nCalculate the Hue component mean value:\n\n.. code-block:: java\n\n    Imgproc.calcHist(hue, new MatOfInt(0), new Mat(), hist_hue, histSize, new MatOfFloat(0, 179));\n    for (int h = 0; h < 180; h++)\n\taverage += (hist_hue.get(h, 0)[0] * h);\n    average = average / hsvImg.size().height / hsvImg.size().width;\n\nIf the background is uniform and fills most of the frame, its value should be close to mean just calculated.\nThen we can use the mean as the threshold to separate the background from the foreground, depending on the invert checkbox we need to perform a back(fore)ground removal:\n\n.. code-block:: java\n\n    if (this.inverse.isSelected())\n\tImgproc.threshold(hsvPlanes.get(0), thresholdImg, threshValue, 179.0, Imgproc.THRESH_BINARY_INV);\n   else\n\tImgproc.threshold(hsvPlanes.get(0), thresholdImg, threshValue, 179.0, Imgproc.THRESH_BINARY);\n\nNow we apply a low pass filter (blur) with a 5x5 kernel mask to enhance the result:\n\n.. code-block:: java\n\n    Imgproc.blur(thresholdImg, thresholdImg, new Size(5, 5));\n\nFinally apply the *dilatation* then the *erosion* (**closing**) to the image:\n\n.. code-block:: java\n\n    Imgproc.dilate(thresholdImg, thresholdImg, new Mat(), new Point(-1, -1), 1);\n    Imgproc.erode(thresholdImg, thresholdImg, new Mat(), new Point(-1, -1), 3);\n\nThe functions take these parameters:\n - ``thresholdImg`` input image;\n - ``thresholdImg`` output image of the same size and type as thresholdImg;\n - ``new Mat()`` a kernel;\n - ``new Point(-1, -1)`` position of the anchor within the element; default value ( -1, -1 ) means that the anchor is at the element center.\n - ``6`` number of times the operation is applied.\n\nAfter the closing we need to do a new binary threshold:\n\n.. code-block:: java\n\n    Imgproc.threshold(thresholdImg, thresholdImg, threshValue, 179.0, Imgproc.THRESH_BINARY);\n\nAt last, we can apply the image we've just obtained as a mask to the original frame:\n\n.. code-block:: java\n\n    Mat foreground = new Mat(frame.size(), CvType.CV_8UC3, new Scalar(255, 255, 255));\n    frame.copyTo(foreground, thresholdImg);\n\nBackground Removal Result\n-------------------------\n\n.. image:: _static/07-02.png\n\nThe source code of the entire tutorial is available on `GitHub <https://github.com/opencv-java/image-segmentation>`_.\n"
  },
  {
    "path": "docs/source/08-object-detection.rst",
    "content": "=================\nObject Detection\n=================\n\n.. note:: We assume that by now you have already read the previous tutorials. If not, please check previous tutorials at `<http://opencv-java-tutorials.readthedocs.org/en/latest/index.html>`_. You can also find the source code and resources at `<https://github.com/opencv-java/>`_\n\nGoal\n----\nIn this tutorial we are going to identify and track one or more tennis balls. It performs the detection of the tennis balls upon a webcam video stream by using the color range of the balls, erosion and dilation, and the findContours method.\n\nMorphological Image Processing\n------------------------------\nIs a collection of non-linear operations related to the morphology of features in an image. The morphological operations rely only on the relative ordering of pixel values and not on their numerical values.\nSome of the fundamental morphological operations are dilation and erosion. Dilation causes objects to dilate or grow in size adding pixels to the boundaries of objects in an image and therefore the holes within different regions become smaller. The dilation allows, for example, to join parts of an object that appear separated.\nErosion causes objects to shrink by stripping away layers of pixels from the boundaries of objects in an image and therefore the holes within different regions become larger. The erosion can be used to remove noise or small errors from the image due to the scanning process.\nThe opening is a compound operation that consist in an erosion followed by a dilation using the same structuring element for both operations. This operation removes small objects from the foreground of an image and can be used to find things into which a specific structuring element can fit. The opening can open up a gap between objects connected by a thin bridge of pixels. Any regions that have survived the erosion are restored to their original size by the dilation.\n\n\nWhat we will do in this tutorial\n--------------------------------\nIn this guide, we will:\n\n * Insert 3 groups of sliders to control the quantity of HSV (Hue, Saturation and Value) of the image.\n * Capture and process the image from the web cam removing noise in order to facilitate the object recognition.\n * Finally using morphological operator such as erosion and dilation we can identify the objects using the contornous obtained after the image processing.\n\nGetting Started\n---------------\nLet's create a new JavaFX project. In Scene Builder we set the window elements so that we have a Border Pane with:\n\n- on RIGHT CENTER we can add a VBox. In this one we are going to need 6 sliders, the first couple will control hue, the next one saturation and finally brightness, with these sliders is possible to change the values of the HSV image.\n\n\t.. code-block:: xml\n\n               \t<Label text=\"Hue Start\" />\n\t\t<Slider fx:id=\"hueStart\" min=\"0\" max=\"180\" value=\"20\" blockIncrement=\"1\" />\n\t\t<Label text=\"Hue Stop\" />\n\t\t<Slider fx:id=\"hueStop\" min=\"0\" max=\"180\" value=\"50\" blockIncrement=\"1\" />\n\t\t<Label text=\"Saturation Start\" />\n\t\t<Slider fx:id=\"saturationStart\" min=\"0\" max=\"255\" value=\"60\" blockIncrement=\"1\" />\n\t\t<Label text=\"Saturation Stop\" />\n\t\t<Slider fx:id=\"saturationStop\" min=\"0\" max=\"255\" value=\"200\" blockIncrement=\"1\" />\n\t\t<Label text=\"Value Start\" />\n\t\t<Slider fx:id=\"valueStart\" min=\"0\" max=\"255\" value=\"50\" blockIncrement=\"1\" />\n\t\t<Label text=\"Value Stop\" />\n\t\t<Slider fx:id=\"valueStop\" min=\"0\" max=\"255\" value=\"255\" blockIncrement=\"1\" />\n\n\n- in the CENTER. we are going to put three ImageViews, the first one shows normal image from the web cam stream, the second one will show mask image and the last one will show morph image. The HBox is used to normal image and VBox to put the other ones.\n\n\t.. code-block:: xml\n\n\t\t<HBox alignment=\"CENTER\" spacing=\"5\">\n\t\t\t<padding>\n\t\t\t\t<Insets right=\"10\" left=\"10\" />\n\t\t\t</padding>\n\t\t\t<ImageView fx:id=\"originalFrame\" />\n\t\t\t<VBox alignment=\"CENTER\" spacing=\"5\">\n\t\t\t\t<ImageView fx:id=\"maskImage\" />\n\t\t\t\t<ImageView fx:id=\"morphImage\" />\n\t\t\t</VBox>\n\t\t</HBox>\n\n- on the BOTTOM we can add the usual button to start/stop the stream and the current values HSV selected with the sliders.\n\n\t.. code-block:: xml\n\n\t\t<Button fx:id=\"cameraButton\" alignment=\"center\" text=\"Start camera\" onAction=\"#startCamera\" />\n\t\t<Separator />\n\t\t<Label fx:id=\"hsvCurrentValues\" />\n\nThe gui will look something like this one:\n\n.. image:: _static/09-00.png\n\n\nImage processing\n----------------\nIn order to use the morphological operators and obtain good results we need to process the image and remove the noise, change the image to HSV allows to get the contours easily.\n\n- ``Remove noise``\n\tWe can remove some noise of the image using the method blur of the Imgproc class and then apply a conversion to\n\tHSV in order to facilitate the process of object recognition.\n\n\t.. code-block:: java\n\n\t\tMat blurredImage = new Mat();\n\t\tMat hsvImage = new Mat();\n\t\tMat mask = new Mat();\n\t\tMat morphOutput = new Mat();\n\n\t\t// remove some noise\n\t\tImgproc.blur(frame, blurredImage, new Size(7, 7));\n\n\t\t// convert the frame to HSV\n\t\tImgproc.cvtColor(blurredImage, hsvImage, Imgproc.COLOR_BGR2HSV);\n\n\n\n- ``Values of HSV image``\n\tWith the sliders we can modify the values of the HSV Image, the image will be updtated in real time,\n\tthat allows to increase or decrease the capactity to recognize object into the image. .\n\n\t.. code-block:: java\n\n\n\t\t// get thresholding values from the UI\n\t\t// remember: H ranges 0-180, S and V range 0-255\n\t\tScalar minValues = new Scalar(this.hueStart.getValue(), this.saturationStart.getValue(),\n\t\tthis.valueStart.getValue());\n\t\tScalar maxValues = new Scalar(this.hueStop.getValue(), this.saturationStop.getValue(),\n\t\tthis.valueStop.getValue());\n\n\t\t// show the current selected HSV range\n\t\tString valuesToPrint = \"Hue range: \" + minValues.val[0] + \"-\" + maxValues.val[0]\n\t\t+ \"\\tSaturation range: \" + minValues.val[1] + \"-\" + maxValues.val[1] + \"\\tValue range: \"\n\t\t+ minValues.val[2] + \"-\" + maxValues.val[2];\n\t\tthis.onFXThread(this.hsvValuesProp, valuesToPrint);\n\n\t\t// threshold HSV image to select tennis balls\n\t\tCore.inRange(hsvImage, minValues, maxValues, mask);\n\t\t// show the partial output\n\t\tthis.onFXThread(maskProp, this.mat2Image(mask));\n\n\nMorphological Operators\n-----------------------\nFirst of all we need to define the two matrices of morphological operator dilation and erosion, then with the methods erode and dilate of the class Imgproc we process the image twice in each operation, the result is the matrix morphOutput that will be the partial output.\n\n\n\t.. code-block:: java\n\n\t       // morphological operators\n\t       // dilate with large element, erode with small ones\n\t        Mat dilateElement = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(24, 24));\n\t\tMat erodeElement = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(12, 12));\n\n\t\tImgproc.erode(mask, morphOutput, erodeElement);\n\t\tImgproc.erode(mask, morphOutput, erodeElement);\n\n\t\tImgproc.dilate(mask, morphOutput, dilateElement);\n\t\tImgproc.dilate(mask, morphOutput, dilateElement);\n\n\t\t// show the partial output\n\t\tthis.onFXThread(this.morphProp, this.mat2Image(morphOutput));\n\n\n\nObject tracking\n------------------\nWith the partial output obtained before we can use the method findContours of the class Imgpoc to get a matrix with the mapping of the objects recognized, then we draw the contours of these objects.\n\n\n\t.. code-block:: java\n\n\t\t// init\n\t\tList<MatOfPoint> contours = new ArrayList<>();\n\t\tMat hierarchy = new Mat();\n\n\t\t// find contours\n\t\tImgproc.findContours(maskedImage, contours, hierarchy, Imgproc.RETR_CCOMP, Imgproc.CHAIN_APPROX_SIMPLE);\n\n\t\t// if any contour exist...\n\t\tif (hierarchy.size().height > 0 && hierarchy.size().width > 0)\n\t\t{\n\t\t\t// for each contour, display it in blue\n\t\t\tfor (int idx = 0; idx >= 0; idx = (int) hierarchy.get(0, idx)[0])\n\t\t\t{\n\t\t\t\tImgproc.drawContours(frame, contours, idx, new Scalar(250, 0, 0));\n\t\t\t}\n\t\t}\n\n\nFinally we can get this results:\n\n.. image:: _static/09-01.png\n\n.. image:: _static/09-02.png\n\nThe source code of the entire tutorial is available on `GitHub <https://github.com/opencv-java/object-detection>`_.\n"
  },
  {
    "path": "docs/source/09-camera-calibration.rst",
    "content": "==================\nCamera Calibration\n==================\n\n.. note:: We assume that by now you have already read the previous tutorials. If not, please check previous tutorials at `<http://opencv-java-tutorials.readthedocs.org/en/latest/index.html>`_. You can also find the source code and resources at `<https://github.com/opencv-java/>`_\n\n.. warning:: This tutorial is *not* updated to OpenCV 3.0.\n\nGoal\n----\nThe goal of this tutorial is to learn how to calibrate a camera given a set of chessboard images.\n\nWhat is the camera calibration?\n-------------------------------\nThe camera calibration is the process with which we can obtain the camera parameters such as intrinsic and extrinsic parameters, distortions and so on. The calibration of the camera is often necessary when the alignment between the lens and the optic sensors chip is not correct; the effect produced by this wrong alignment is usually more visible in low quality cameras.\n\nCalibration Pattern\n-------------------\nAs we said earlier we are going to need some sort of pattern that the program can recognize in order to make the calibration work. The pattern that we are going to use is a chessboard image.\n\n.. image:: _static/05-00.png\n\nThe reason why we use this image is because there are some OpenCV functions that can recognize this pattern and draw a scheme which highlights the intersections between each block.\nTo make the calibration work you need to print the chessboard image and show it to the cam; it is important to maintain the sheet still, better if stick to a surface.\nIn order to make a good calibration, we need to have about 20 samples of the pattern taken from different angles and distances.\n\nWhat we will do in this tutorial\n--------------------------------\nIn this guide, we will:\n * Create some TextEdit field to give some inputs to our program\n * Recognize the pattern using some OpenCV functions\n * Calibrate and show the video stream.\n\nGetting Started\n---------------\nCreate a new JavaFX project (e.g. \"CameraCalibration\") with the usual OpenCV user library.\nOpen Scene Builder and add a Border Pane with:\n\n- on **TOP** we need to have the possibility to set the number of samples for the calibration, the number of horizontal corners we have in the test image, the number of vertical corners we have in the test image and a button to update this data. To make things cleaner let's put all these elements inside a HBox.\n\n.. code-block:: xml\n\n    <HBox alignment=\"CENTER\" spacing=\"10\">\n\nLet's also add some labels before each text fields.\nEach text field is going to need an id, and let's put a standard value for them already.\n\n.. code-block:: xml\n\n    <Label text=\"Boards #\" />\n    <TextField fx:id=\"numBoards\" text=\"20\" maxWidth=\"50\" />\n    <Label text=\"Horizontal corners #\" />\n    <TextField fx:id=\"numHorCorners\" text=\"9\" maxWidth=\"50\" />\n    <Label text=\"Vertical corners #\" />\n    <TextField fx:id=\"numVertCorners\" text=\"6\" maxWidth=\"50\" />\n\nFor the button instead, set the id and a method for the onAction field:\n\n.. code-block:: xml\n\n    <Button fx:id=\"applyButton\" alignment=\"center\" text=\"Apply\" onAction=\"#updateSettings\" />\n\n- on the **LEFT** add an ImageView inside a VBox for the normal cam stream; set an id for it.\n\n.. code-block:: xml\n\n    <ImageView fx:id=\"originalFrame\" />\n\n- on the **RIGHT** add an ImageView inside a VBox for the calibrated cam stream; set an id for it.\n\n.. code-block:: xml\n\n    <ImageView fx:id=\"originalFrame\" />\n\n- in the **BOTTOM** add a start/stop cam stream button and a snapshot button inside a HBox; set an id and a action method for each one.\n\n.. code-block:: xml\n\n    <Button fx:id=\"cameraButton\" alignment=\"center\" text=\"Start camera\" onAction=\"#startCamera\" disable=\"true\" />\n    <Button fx:id=\"snapshotButton\" alignment=\"center\" text=\"Take snapshot\" onAction=\"#takeSnapshot\" disable=\"true\" />\n\nYour GUI will look something like this:\n\n.. image:: _static/05-03.png\n\nPattern Recognition\n-------------------\nThe calibration process consists on showing to the cam the chessboard pattern from different angles, depth and points of view. For each recognized pattern we need to track:\n\n - some reference system's 3D point where the chessboard is located (let's assume that the Z axe is always 0):\n\n\t.. code-block:: java\n\n\t\tfor (int j = 0; j < numSquares; j++)\n\t\t   obj.push_back(new MatOfPoint3f(new Point3(j / this.numCornersHor, j % this.numCornersVer, 0.0f)));\n\n - the image's 2D points (operation made by OpenCV with findChessboardCorners):\n\n\t.. code-block:: java\n\n\t\tboolean found = Calib3d.findChessboardCorners(grayImage, boardSize, imageCorners, Calib3d.CALIB_CB_ADAPTIVE_THRESH + Calib3d.CALIB_CB_NORMALIZE_IMAGE + Calib3d.CALIB_CB_FAST_CHECK);\n\nThe ``findChessboardCorners`` function attempts to determine whether the input image is a view of the chessboard pattern and locate the internal chessboard corners.\nIts parameters are:\n\n - **image** Source chessboard view. It must be an 8-bit grayscale or color image.\n - **patternSize** Number of inner corners per a chessboard row and column\n - **corners** Output array of detected corners.\n - **flags** Various operation flags that can be zero or a combination of the following values:\n\t- ``CV_CALIB_CB_ADAPTIVE_THRESH`` Use adaptive thresholding to convert the image to black and white, rather than a fixed threshold level (computed from the average image brightness).\n\t- ``CV_CALIB_CB_NORMALIZE_IMAGE`` Normalize the image gamma with \"equalizeHist\" before applying fixed or adaptive thresholding.\n\t- ``CV_CALIB_CB_FILTER_QUADS`` Use additional criteria (like contour area, perimeter, square-like shape) to filter out false quads extracted at the contour retrieval stage.\n\t- ``CALIB_CB_FAST_CHECK`` Run a fast check on the image that looks for chessboard corners, and shortcut the call if none is found. This can drastically speed up the call in the degenerate condition when no chessboard is observed.\n\n.. warning:: Before doing the ``findChessboardCorners`` convert the image to grayscale and save the board size into a Size variable:\n\n\t.. code-block:: java\n\n\t    Imgproc.cvtColor(frame, grayImage, Imgproc.COLOR_BGR2GRAY);\n\t    Size boardSize = new Size(this.numCornersHor, this.numCornersVer);\n\nIf the recognition went well ``found`` should be ``true``.\n\nFor square images the positions of the corners are only approximate. We may improve this by calling the ``cornerSubPix`` function. It will produce better calibration result.\n\n.. code-block:: java\n\n    TermCriteria term = new TermCriteria(TermCriteria.EPS | TermCriteria.MAX_ITER, 30, 0.1);\n    Imgproc.cornerSubPix(grayImage, imageCorners, new Size(11, 11), new Size(-1, -1), term);\n\nWe can now highlight the found points on stream:\n\n.. code-block:: java\n\n    Calib3d.drawChessboardCorners(frame, boardSize, imageCorners, found);\n\nThe function draws individual chessboard corners detected either as red circles if the board was not found, or as colored corners connected with lines if the board was found.\n\nIts parameters are:\n\n - **image** Destination image. It must be an 8-bit color image.\n - **patternSize** Number of inner corners per a chessboard row and column.\n - **corners** Array of detected corners, the output of findChessboardCorners.\n - **patternWasFound** Parameter indicating whether the complete board was found or not. The return value of ``findChessboardCorners`` should be passed here.\n\nNow we can activate the Snapshot button to save the data.\n\n.. code-block:: java\n\n    this.snapshotButton.setDisable(false);\n\n.. image:: _static/05-01.png\n\n.. image:: _static/05-02.png\n\nWe should take the set number of \"snapshots\" from different angles and depth, in order to make the calibration.\n\n.. note:: We don't actually save the image but just the data we need.\n\nSaving Data\n-----------\nBy clicking on the snapshot button we call the ``takeSnapshot`` method. Here we need to save the data (2D and 3D points)  if we did not make enough sample:\n\n.. code-block:: java\n\n    this.imagePoints.add(imageCorners);\n    this.objectPoints.add(obj);\n    this.successes++;\n\nOtherwise we can calibrate the camera.\n\nCamera Calibration\n------------------\nFor the camera calibration we should create initiate some needed variable and then call the actual calibration function:\n\n.. code-block:: java\n\n    List<Mat> rvecs = new ArrayList<>();\n    List<Mat> tvecs = new ArrayList<>();\n    intrinsic.put(0, 0, 1);\n    intrinsic.put(1, 1, 1);\n\n    Calib3d.calibrateCamera(objectPoints, imagePoints, savedImage.size(), intrinsic, distCoeffs, rvecs, tvecs);\n\nThe ``calibrateCamera`` function estimates the intrinsic camera parameters and extrinsic parameters for each of the views. The algorithm is based on [Zhang2000] and [BouguetMCT]. The coordinates of 3D object points and their corresponding 2D projections in each view must be specified.\nIts parameters are:\n\n - **objectPoints** In the new interface it is a vector of vectors of calibration pattern points in the calibration pattern coordinate space. The outer vector contains as many elements as the number of the pattern views. The points are 3D, but since they are in a pattern coordinate system, then, if the rig is planar, it may make sense to put the model to a XY coordinate plane so that Z-coordinate of each input object point is 0.\n - **imagePoints** It is a vector of vectors of the projections of calibration pattern points.\n - **imageSize** Size of the image used only to initialize the intrinsic camera matrix.\n - **cameraMatrix** Output 3x3 floating-point camera matrix *A = |fx 0 cx| |0 fy cy| |0 0 1|*. If ``CV_CALIB_USE_INTRINSIC_GUESS`` and/or ``CV_CALIB_FIX_ASPECT_RATIO`` are specified, some or all of *fx*, *fy*, *cx*, *cy* must be initialized before calling the function.\n - **distCoeffs** Output vector of distortion coefficients of 4, 5, or 8 elements.\n - **rvecs** Output vector of rotation vectors estimated for each pattern view. That is, each k-th rotation vector together with the corresponding k-th translation vector.\n - **tvecs** Output vector of translation vectors estimated for each pattern view.\n\nWe ran calibration and got camera's matrix with the distortion coefficients we may want to correct the image using ``undistort`` function:\n\n.. code-block:: java\n\n    if (this.isCalibrated)\n    {\n\t// prepare the undistored image\n\tMat undistored = new Mat();\n\tImgproc.undistort(frame, undistored, intrinsic, distCoeffs);\n\tundistoredImage = mat2Image(undistored);\n    }\n\nThe ``undistort`` function transforms an image to compensate radial and tangential lens distortion.\n\nThe source code of the entire tutorial is available on `GitHub <https://github.com/opencv-java/camera-calibration>`_.\n"
  },
  {
    "path": "docs/source/conf.py",
    "content": "# -*- coding: utf-8 -*-\n#\n# OpenCV Java Tutorials documentation build configuration file, created by\n# sphinx-quickstart on Wed Jun 17 09:26:35 2015.\n#\n# This file is execfile()d with the current directory set to its\n# containing dir.\n#\n# Note that not all possible configuration values are present in this\n# autogenerated file.\n#\n# All configuration values have a default; values that are commented out\n# serve to show the default.\n\nimport sys\nimport os\nimport shlex\n\n# If extensions (or modules to document with autodoc) are in another directory,\n# add these directories to sys.path here. If the directory is relative to the\n# documentation root, use os.path.abspath to make it absolute, like shown here.\n#sys.path.insert(0, os.path.abspath('.'))\n\n# -- General configuration ------------------------------------------------\n\n# If your documentation needs a minimal Sphinx version, state it here.\n#needs_sphinx = '1.0'\n\n# Add any Sphinx extension module names here, as strings. They can be\n# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom\n# ones.\nextensions = [\n    'sphinx.ext.autodoc',\n    'sphinx.ext.doctest',\n    'sphinx.ext.intersphinx',\n    'sphinx.ext.todo',\n    'sphinx.ext.coverage',\n    'sphinx.ext.mathjax',\n    'sphinx.ext.ifconfig',\n    'sphinx.ext.viewcode',\n]\n\n# Add any paths that contain templates here, relative to this directory.\ntemplates_path = ['_templates']\n\n# The suffix(es) of source filenames.\n# You can specify multiple suffix as a list of string:\n# source_suffix = ['.rst', '.md']\nsource_suffix = '.rst'\n\n# The encoding of source files.\n#source_encoding = 'utf-8-sig'\n\n# The master toctree document.\nmaster_doc = 'index'\n\n# General information about the project.\nproject = u'OpenCV Java Tutorials'\ncopyright = u'2014-2019, Luigi De Russis, Alberto Sacco'\nauthor = u'Luigi De Russis, Alberto Sacco, Suyash Joshi'\n\n# The version info for the project you're documenting, acts as replacement for\n# |version| and |release|, also used in various other places throughout the\n# built documents.\n#\n# The short X.Y version.\nversion = '1.0'\n# The full version, including alpha/beta/rc tags.\nrelease = '1.0'\n\n# The language for content autogenerated by Sphinx. Refer to documentation\n# for a list of supported languages.\n#\n# This is also used if you do content translation via gettext catalogs.\n# Usually you set \"language\" from the command line for these cases.\nlanguage = None\n\n# There are two options for replacing |today|: either, you set today to some\n# non-false value, then it is used:\n#today = ''\n# Else, today_fmt is used as the format for a strftime call.\n#today_fmt = '%B %d, %Y'\n\n# List of patterns, relative to source directory, that match files and\n# directories to ignore when looking for source files.\nexclude_patterns = []\n\n# The reST default role (used for this markup: `text`) to use for all\n# documents.\n#default_role = None\n\n# If true, '()' will be appended to :func: etc. cross-reference text.\n#add_function_parentheses = True\n\n# If true, the current module name will be prepended to all description\n# unit titles (such as .. function::).\n#add_module_names = True\n\n# If true, sectionauthor and moduleauthor directives will be shown in the\n# output. They are ignored by default.\n#show_authors = False\n\n# The name of the Pygments (syntax highlighting) style to use.\npygments_style = 'sphinx'\n\n# A list of ignored prefixes for module index sorting.\n#modindex_common_prefix = []\n\n# If true, keep warnings as \"system message\" paragraphs in the built documents.\n#keep_warnings = False\n\n# If true, `todo` and `todoList` produce output, else they produce nothing.\ntodo_include_todos = True\n\n\n# -- Options for HTML output ----------------------------------------------\n\n# The theme to use for HTML and HTML Help pages.  See the documentation for\n# a list of builtin themes.\nhtml_theme = 'sphinx_rtd_theme'\n\n# Theme options are theme-specific and customize the look and feel of a theme\n# further.  For a list of options available for each theme, see the\n# documentation.\n#html_theme_options = {}\n\n# Add any paths that contain custom themes here, relative to this directory.\n#html_theme_path = []\n\n# The name for this set of Sphinx documents.  If None, it defaults to\n# \"<project> v<release> documentation\".\n#html_title = None\n\n# A shorter title for the navigation bar.  Default is the same as html_title.\n#html_short_title = None\n\n# The name of an image file (relative to this directory) to place at the top\n# of the sidebar.\n#html_logo = None\n\n# The name of an image file (within the static path) to use as favicon of the\n# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32\n# pixels large.\n#html_favicon = None\n\n# Add any paths that contain custom static files (such as style sheets) here,\n# relative to this directory. They are copied after the builtin static files,\n# so a file named \"default.css\" will overwrite the builtin \"default.css\".\nhtml_static_path = ['_static']\n\n# Add any extra paths that contain custom files (such as robots.txt or\n# .htaccess) here, relative to this directory. These files are copied\n# directly to the root of the documentation.\n#html_extra_path = []\n\n# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,\n# using the given strftime format.\n#html_last_updated_fmt = '%b %d, %Y'\n\n# If true, SmartyPants will be used to convert quotes and dashes to\n# typographically correct entities.\n#html_use_smartypants = True\n\n# Custom sidebar templates, maps document names to template names.\n#html_sidebars = {}\n\n# Additional templates that should be rendered to pages, maps page names to\n# template names.\n#html_additional_pages = {}\n\n# If false, no module index is generated.\n#html_domain_indices = True\n\n# If false, no index is generated.\n#html_use_index = True\n\n# If true, the index is split into individual pages for each letter.\n#html_split_index = False\n\n# If true, links to the reST sources are added to the pages.\n#html_show_sourcelink = True\n\n# If true, \"Created using Sphinx\" is shown in the HTML footer. Default is True.\n#html_show_sphinx = True\n\n# If true, \"(C) Copyright ...\" is shown in the HTML footer. Default is True.\n#html_show_copyright = True\n\n# If true, an OpenSearch description file will be output, and all pages will\n# contain a <link> tag referring to it.  The value of this option must be the\n# base URL from which the finished HTML is served.\n#html_use_opensearch = ''\n\n# This is the file name suffix for HTML files (e.g. \".xhtml\").\n#html_file_suffix = None\n\n# Language to be used for generating the HTML full-text search index.\n# Sphinx supports the following languages:\n#   'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'\n#   'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'\n#html_search_language = 'en'\n\n# A dictionary with options for the search language support, empty by default.\n# Now only 'ja' uses this config value\n#html_search_options = {'type': 'default'}\n\n# The name of a javascript file (relative to the configuration directory) that\n# implements a search results scorer. If empty, the default will be used.\n#html_search_scorer = 'scorer.js'\n\n# Output file base name for HTML help builder.\nhtmlhelp_basename = 'OpenCVJavaTutorialsdoc'\n\n# -- Options for LaTeX output ---------------------------------------------\n\nlatex_elements = {\n# The paper size ('letterpaper' or 'a4paper').\n#'papersize': 'letterpaper',\n\n# The font size ('10pt', '11pt' or '12pt').\n#'pointsize': '10pt',\n\n# Additional stuff for the LaTeX preamble.\n#'preamble': '',\n\n# Latex figure (float) alignment\n#'figure_align': 'htbp',\n}\n\n# Grouping the document tree into LaTeX files. List of tuples\n# (source start file, target name, title,\n#  author, documentclass [howto, manual, or own class]).\nlatex_documents = [\n  (master_doc, 'OpenCVJavaTutorials.tex', u'OpenCV Java Tutorials Documentation',\n   u'Luigi De Russis, Alberto Sacco', 'manual'),\n]\n\n# The name of an image file (relative to this directory) to place at the top of\n# the title page.\n#latex_logo = None\n\n# For \"manual\" documents, if this is true, then toplevel headings are parts,\n# not chapters.\n#latex_use_parts = False\n\n# If true, show page references after internal links.\n#latex_show_pagerefs = False\n\n# If true, show URL addresses after external links.\n#latex_show_urls = False\n\n# Documents to append as an appendix to all manuals.\n#latex_appendices = []\n\n# If false, no module index is generated.\n#latex_domain_indices = True\n\n\n# -- Options for manual page output ---------------------------------------\n\n# One entry per manual page. List of tuples\n# (source start file, name, description, authors, manual section).\nman_pages = [\n    (master_doc, 'opencvjavatutorials', u'OpenCV Java Tutorials Documentation',\n     [author], 1)\n]\n\n# If true, show URL addresses after external links.\n#man_show_urls = False\n\n\n# -- Options for Texinfo output -------------------------------------------\n\n# Grouping the document tree into Texinfo files. List of tuples\n# (source start file, target name, title, author,\n#  dir menu entry, description, category)\ntexinfo_documents = [\n  (master_doc, 'OpenCVJavaTutorials', u'OpenCV Java Tutorials Documentation',\n   author, 'OpenCVJavaTutorials', 'One line description of project.',\n   'Miscellaneous'),\n]\n\n# Documents to append as an appendix to all manuals.\n#texinfo_appendices = []\n\n# If false, no module index is generated.\n#texinfo_domain_indices = True\n\n# How to display URL addresses: 'footnote', 'no', or 'inline'.\n#texinfo_show_urls = 'footnote'\n\n# If true, do not generate a @detailmenu in the \"Top\" node's menu.\n#texinfo_no_detailmenu = False\n\n\n# -- Options for Epub output ----------------------------------------------\n\n# Bibliographic Dublin Core info.\nepub_title = project\nepub_author = author\nepub_publisher = author\nepub_copyright = copyright\n\n# The basename for the epub file. It defaults to the project name.\n#epub_basename = project\n\n# The HTML theme for the epub output. Since the default themes are not optimized\n# for small screen space, using the same theme for HTML and epub output is\n# usually not wise. This defaults to 'epub', a theme designed to save visual\n# space.\n#epub_theme = 'epub'\n\n# The language of the text. It defaults to the language option\n# or 'en' if the language is not set.\n#epub_language = ''\n\n# The scheme of the identifier. Typical schemes are ISBN or URL.\n#epub_scheme = ''\n\n# The unique identifier of the text. This can be a ISBN number\n# or the project homepage.\n#epub_identifier = ''\n\n# A unique identification for the text.\n#epub_uid = ''\n\n# A tuple containing the cover image and cover page html template filenames.\n#epub_cover = ()\n\n# A sequence of (type, uri, title) tuples for the guide element of content.opf.\n#epub_guide = ()\n\n# HTML files that should be inserted before the pages created by sphinx.\n# The format is a list of tuples containing the path and title.\n#epub_pre_files = []\n\n# HTML files shat should be inserted after the pages created by sphinx.\n# The format is a list of tuples containing the path and title.\n#epub_post_files = []\n\n# A list of files that should not be packed into the epub file.\nepub_exclude_files = ['search.html']\n\n# The depth of the table of contents in toc.ncx.\n#epub_tocdepth = 3\n\n# Allow duplicate toc entries.\n#epub_tocdup = True\n\n# Choose between 'default' and 'includehidden'.\n#epub_tocscope = 'default'\n\n# Fix unsupported image types using the Pillow.\n#epub_fix_images = False\n\n# Scale large images.\n#epub_max_image_width = 0\n\n# How to display URL addresses: 'footnote', 'no', or 'inline'.\n#epub_show_urls = 'inline'\n\n# If false, no index is generated.\n#epub_use_index = True\n\n\n# Example configuration for intersphinx: refer to the Python standard library.\nintersphinx_mapping = {'https://docs.python.org/': None}\n"
  },
  {
    "path": "docs/source/index.rst",
    "content": ".. OpenCV Java Tutorials documentation master file, created by\n   sphinx-quickstart on Wed Jun 17 09:26:35 2015.\n   You can adapt this file completely to your liking, but it should at least\n   contain the root `toctree` directive.\n\nWelcome to OpenCV Java Tutorials documentation!\n=================================================\n\n.. note:: These tutorials were last updated on 2019: they use OpenCV 3.x and Java 7-8. They are currently unmaintained: if you are interested in maintaining them, contact me on `GitHub <https://github.com/orgs/opencv-java/people>`_.\n\nContents:\n\n.. toctree::\n   :maxdepth: 2\n\n   01-installing-opencv-for-java\n   02-first-java-application-with-opencv\n   03-first-javafx-application-with-opencv\n   04-opencv-basics\n   05-fourier-transform\n   06-face-detection-and-tracking\n   07-image-segmentation\n   08-object-detection\n   09-camera-calibration\n\nIndices and tables\n==================\n\n* :ref:`genindex`\n* :ref:`modindex`\n* :ref:`search`\n"
  }
]