From 4797aea667866de41146924e996f2297a49edfb6 Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Fri, 13 Jan 2017 12:34:32 -0500 Subject: [PATCH] Moved documentation to a separate repo --- doc/generate | 5 - doc/generate.bat | 263 -------------- doc/makefile | 192 ---------- doc/requirements.txt | 13 - doc/source/accuracy_improvements.rst | 360 ------------------- doc/source/alprd.rst | 516 --------------------------- doc/source/bindings.rst | 297 --------------- doc/source/cloudapi.yaml | 323 ----------------- doc/source/commandline.rst | 109 ------ doc/source/commercial.rst | 60 ---- doc/source/compiling.rst | 226 ------------ doc/source/conf.py | 291 --------------- doc/source/index.rst | 46 --- doc/source/video_processing.rst | 126 ------- doc/source/web_server.rst | 164 --------- doc/source/web_server_api.yaml | 421 ---------------------- doc/watch_for_changes.sh | 4 - 17 files changed, 3416 deletions(-) delete mode 100755 doc/generate delete mode 100755 doc/generate.bat delete mode 100755 doc/makefile delete mode 100755 doc/requirements.txt delete mode 100644 doc/source/accuracy_improvements.rst delete mode 100755 doc/source/alprd.rst delete mode 100755 doc/source/bindings.rst delete mode 100644 doc/source/cloudapi.yaml delete mode 100755 doc/source/commandline.rst delete mode 100755 doc/source/commercial.rst delete mode 100755 doc/source/compiling.rst delete mode 100755 doc/source/conf.py delete mode 100755 doc/source/index.rst delete mode 100644 doc/source/video_processing.rst delete mode 100644 doc/source/web_server.rst delete mode 100644 doc/source/web_server_api.yaml delete mode 100755 doc/watch_for_changes.sh diff --git a/doc/generate b/doc/generate deleted file mode 100755 index 3dee28f8..00000000 --- a/doc/generate +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -make -f makefile clean && make -f makefile html -cp -R swagger/ build/html/api -cp source/*.yaml build/html/api/specs/ diff --git a/doc/generate.bat b/doc/generate.bat deleted file mode 100755 index 8369175b..00000000 --- a/doc/generate.bat +++ /dev/null @@ -1,263 +0,0 @@ -@ECHO OFF - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set BUILDDIR=build -set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source -set I18NSPHINXOPTS=%SPHINXOPTS% source -if NOT "%PAPER%" == "" ( - set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% - set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% -) - -if "%1" == "" goto help - -if "%1" == "help" ( - :help - echo.Please use `make ^` where ^ is one of - echo. html to make standalone HTML files - echo. dirhtml to make HTML files named index.html in directories - echo. singlehtml to make a single large HTML file - echo. pickle to make pickle files - echo. json to make JSON files - echo. htmlhelp to make HTML files and a HTML help project - echo. qthelp to make HTML files and a qthelp project - echo. devhelp to make HTML files and a Devhelp project - echo. epub to make an epub - echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter - echo. text to make text files - echo. man to make manual pages - echo. texinfo to make Texinfo files - echo. gettext to make PO message catalogs - echo. changes to make an overview over all changed/added/deprecated items - echo. xml to make Docutils-native XML files - echo. pseudoxml to make pseudoxml-XML files for display purposes - echo. linkcheck to check all external links for integrity - echo. doctest to run all doctests embedded in the documentation if enabled - echo. coverage to run coverage check of the documentation if enabled - goto end -) - -if "%1" == "clean" ( - for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i - del /q /s %BUILDDIR%\* - goto end -) - - -REM Check if sphinx-build is available and fallback to Python version if any -%SPHINXBUILD% 2> nul -if errorlevel 9009 goto sphinx_python -goto sphinx_ok - -:sphinx_python - -set SPHINXBUILD=python -m sphinx.__init__ -%SPHINXBUILD% 2> nul -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - exit /b 1 -) - -:sphinx_ok - - -if "%1" == "html" ( - %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/html. - goto end -) - -if "%1" == "dirhtml" ( - %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. - goto end -) - -if "%1" == "singlehtml" ( - %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. - goto end -) - -if "%1" == "pickle" ( - %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the pickle files. - goto end -) - -if "%1" == "json" ( - %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the JSON files. - goto end -) - -if "%1" == "htmlhelp" ( - %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run HTML Help Workshop with the ^ -.hhp project file in %BUILDDIR%/htmlhelp. - goto end -) - -if "%1" == "qthelp" ( - %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run "qcollectiongenerator" with the ^ -.qhcp project file in %BUILDDIR%/qthelp, like this: - echo.^> qcollectiongenerator %BUILDDIR%\qthelp\openalpr.qhcp - echo.To view the help file: - echo.^> assistant -collectionFile %BUILDDIR%\qthelp\openalpr.ghc - goto end -) - -if "%1" == "devhelp" ( - %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. - goto end -) - -if "%1" == "epub" ( - %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The epub file is in %BUILDDIR%/epub. - goto end -) - -if "%1" == "latex" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "latexpdf" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - cd %BUILDDIR%/latex - make all-pdf - cd %~dp0 - echo. - echo.Build finished; the PDF files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "latexpdfja" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - cd %BUILDDIR%/latex - make all-pdf-ja - cd %~dp0 - echo. - echo.Build finished; the PDF files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "text" ( - %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The text files are in %BUILDDIR%/text. - goto end -) - -if "%1" == "man" ( - %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The manual pages are in %BUILDDIR%/man. - goto end -) - -if "%1" == "texinfo" ( - %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. - goto end -) - -if "%1" == "gettext" ( - %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The message catalogs are in %BUILDDIR%/locale. - goto end -) - -if "%1" == "changes" ( - %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes - if errorlevel 1 exit /b 1 - echo. - echo.The overview file is in %BUILDDIR%/changes. - goto end -) - -if "%1" == "linkcheck" ( - %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck - if errorlevel 1 exit /b 1 - echo. - echo.Link check complete; look for any errors in the above output ^ -or in %BUILDDIR%/linkcheck/output.txt. - goto end -) - -if "%1" == "doctest" ( - %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest - if errorlevel 1 exit /b 1 - echo. - echo.Testing of doctests in the sources finished, look at the ^ -results in %BUILDDIR%/doctest/output.txt. - goto end -) - -if "%1" == "coverage" ( - %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage - if errorlevel 1 exit /b 1 - echo. - echo.Testing of coverage in the sources finished, look at the ^ -results in %BUILDDIR%/coverage/python.txt. - goto end -) - -if "%1" == "xml" ( - %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The XML files are in %BUILDDIR%/xml. - goto end -) - -if "%1" == "pseudoxml" ( - %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. - goto end -) - -:end diff --git a/doc/makefile b/doc/makefile deleted file mode 100755 index 1804aca4..00000000 --- a/doc/makefile +++ /dev/null @@ -1,192 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = build - -# User-friendly check for sphinx-build -ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) -$(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/) -endif - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " applehelp to make an Apple Help Book" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " xml to make Docutils-native XML files" - @echo " pseudoxml to make pseudoxml-XML files for display purposes" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - @echo " coverage to run coverage check of the documentation (if enabled)" - -clean: - rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/openalpr.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/openalpr.qhc" - -applehelp: - $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp - @echo - @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." - @echo "N.B. You won't be able to view it unless you put it in" \ - "~/Library/Documentation/Help or install it in your application" \ - "bundle." - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/openalpr" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/openalpr" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -latexpdfja: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through platex and dvipdfmx..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -texinfo: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -info: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -gettext: - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale - @echo - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." - -coverage: - $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage - @echo "Testing of coverage in the sources finished, look at the " \ - "results in $(BUILDDIR)/coverage/python.txt." - -xml: - $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml - @echo - @echo "Build finished. The XML files are in $(BUILDDIR)/xml." - -pseudoxml: - $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml - @echo - @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/doc/requirements.txt b/doc/requirements.txt deleted file mode 100755 index 31598e3e..00000000 --- a/doc/requirements.txt +++ /dev/null @@ -1,13 +0,0 @@ -Babel==2.1.1 -Jinja2==2.8 -MarkupSafe==0.23 -Pygments==2.0.2 -Sphinx==1.3.1 -alabaster==0.7.6 -argparse==1.2.1 -docutils==0.12 -pytz==2015.7 -six==1.10.0 -snowballstemmer==1.2.0 -sphinx-rtd-theme==0.1.9 -wsgiref==0.1.2 diff --git a/doc/source/accuracy_improvements.rst b/doc/source/accuracy_improvements.rst deleted file mode 100644 index 11e91337..00000000 --- a/doc/source/accuracy_improvements.rst +++ /dev/null @@ -1,360 +0,0 @@ -************************ -Accuracy Improvements -************************ - - -Calibration -============= - -Calibrating your camera improves detection accuracy in cases where vehicle plates are captured at a steep angle. For example, the the plate below is captured at 40+ degree horizontal angle, and will normally not be recognized as a license plate. - - -.. image:: images/configuration_calibration_before.jpg - :scale: 100% - :alt: Calibration before adjustments - -The camera calibration helps in cases where the camera is capturing from a fixed position, and all plates generally are seen at the same angle. This feature is best for short-angle cameras or cameras capturing at a close distance. - - -Use the tool named "openalpr-utils-calibrate" to calibrate your camera. The utility needs a single example image to begin. This image should be taken from the camera you wish to calibrate and should have a license plate that represents the typical distance/angle of plate captured on this camera. - - ./openalpr-utils-calibrate camera_image.jpg - -There are sliders at the top of the screen that control the skew. Adjust the sliders until the plate looks like it is seen from straight-on with no angle. Left-click and drag to draw a box (with the correct aspect ratio) to test if the plate is the correct size. - -You can also right-click and drag to move the image within the frame. Because we are distorting the original image, the frame will be clipped. If frames are unlikely to be seen in certain areas (on the ceiling for example) you may want to adjust the plate image to ensure that those areas will be cropped. - -.. image:: images/configuration_calibration_tool.jpg - :scale: 100% - :alt: Calibration utility - -Once you're satisified with the parameters you've chosen, press the 'o' key. This produces a line of configuration in the terminal that can be copied directly into openalpr.conf as the "prewarp" config. This will apply the camera calibration settings against each image before it is used for plate recognition. - -Now test the new settings on a few images from this camera to make sure that the new calibration improves accuracy. - - ./alpr camera_image.jpg - -.. image:: images/configuration_calibration_after.jpg - :scale: 100% - :alt: Calibration after adjustments - -Notice that the license plate is now correctly detected. You can view the calibrated image results by enabling the "prewarp" debug option in the openalpr.conf file. Test the accuracy on many different images from the camera before accepting the configuration. Other calibration angles could produce superior results. - -Pattern Matching -=================== - -The pattern matching feature runs the topN results against a Regular expression matcher to find results that match common license plate patterns. The regex patterns are customizable and can be found in runtime_data/postprocess/``*``.patterns - -For example, using a pattern against this Czechoslovakian plate results in only one possible match (which is the correct one). - -.. image:: images/configuration_patternmatch.jpg - :scale: 100% - :alt: Czechoslovakian number plate - - -The cz patterns are: - - cz #@##### - - cz #@@#### - - -Results for this plate, notice the pattern matches 4S50233: - -:: - - [mhill@mhill-linux tmp]$ alpr -c eu -p cz cz_4s50233.jpg -n 40 - plate0: 40 results - - 4S5O233 confidence: 90.947 pattern_match: 0 - - 4S5O23 confidence: 87.8683 pattern_match: 0 - - 4S5O23 confidence: 85.1644 pattern_match: 0 - - 4S5O23S confidence: 84.5445 pattern_match: 0 - - 4S5O23B confidence: 83.7395 pattern_match: 0 - - 4S5O2S3 confidence: 83.3698 pattern_match: 0 - - 4S5O23G confidence: 83.1375 pattern_match: 0 - - 4S50233 confidence: 83.0457 pattern_match: 1 - - 4S5O2B3 confidence: 82.5635 pattern_match: 0 - - 4S5O2 confidence: 82.0857 pattern_match: 0 - - 4S5O2G3 confidence: 81.5684 pattern_match: 0 - - 4S5O2J3 confidence: 81.0409 pattern_match: 0 - - 4S5O2S confidence: 80.2911 pattern_match: 0 - ... more results that do not match ... - -You can utilize this from the library code by calling "setDefaultRegion(string region)" with the name of the pattern you wish to use: - - -Configuration -================= - -The OpenALPR library is configured with the openalpr.conf file. On Linux, this is typically located in /etc/openalpr/openalpr.conf. On Windows, it is usually in the same directory as the binary. Many of the configuration options in this file are documented with comments. - - - -Training OCR -=============== - -Training the OpenALPR OCR is a quick way to improve the accuracy for a particular country. To do this, you will need: - - 1. Around 200 clear images of your country's license plates. - 2. 16 hours of free time - -`This code repository `_ provides code and data that can be used to train custom license plate fonts in support of the OpenALPR library. - -The OCR library used by OpenALPR is Tesseract. Many of the tedious aspects of OCR training have been automated via a Python script. However, the input data still needs to be in a specific format to satisfy Tesseract. - -For more information about training using Tesseract OCR, please read this tutorial: https://code.google.com/p/tesseract-ocr/wiki/TrainingTesseract3 - -To get started, first clone the repository and get familiar with the input files. In the "eu/input" folder, there are a number of tif files and box files. Each "font" will have at least one tif and box file. A country's license plate may have many fonts, each one would just use a different name. - -The naming convention is: -l[country_code].[fontname].exp[pagenumber].box - -For example, the European German license plate font would look like: -leu.germany.exp0.box - -Open up a tif file. Notice, these are a series of similar looking letters and numbers. The best way to generate these is from actual license plate images. OpenALPR has a couple utilities to help generate these input files. The first step is to find many pictures of your license plates. Make sure to separate them by font. Sometimes, even within a single region, the license plate fonts will vary (e.g., between old plates and new plates, or digital vs stamped plates, or vehicle plates vs bicycle plates). Each unique font should be a different file in order to achieve the highest accuracy. - -Adding a new Country --------------------- -If you plan on training OCR for a completely new country, you will first need to configure the dimensions of the plate and characters. Add a new file in runtime_data/config/ with your country's 2-digit code. You can copy and paste a section from another country (e.g., us or eu). - -You should tweak the following values: - - - plate_width_mm = [width of full plate in mm] - - plate_height_mm = [height of full plate in mm] - - char_width_mm = [width of a single character in mm] - - char_height_mm = [height of a single character in mm] - - char_whitespace_top_mm = [whitespace between the character and the top of the plate in mm] - - char_whitespace_bot_mm = [whitespace between the character and the bottom of the plate in mm] - - template_max_width_px = [maximum width of the plate before processing. Should be proportional to the plate dimensions] - - template_max_height_px = [maximum height of the plate before processing. Should be proportional to the plate dimensions] - - min_plate_size_width_px = [Minimum size of a plate region to consider it valid.] - - min_plate_size_height_px = [Minimum size of a plate region to consider it valid.] - - ocr_language = [name of the OCR language -- typically just the letter l followed by your country code] - -Understanding Your Country's Plates ------------------------------------- - -The first thing you need to know is how many fonts your country's license plates have. In the US, for example, many states use very different fonts for their plates. Some countries only use one font. Here is an example of New York and West Virginia,. Notice how different the "6" character is in both plates: - -.. image:: images/training_ocr_plateny.png - :scale: 100% - :alt: west virginia license plate -.. image:: images/training_ocr_platewv.png - :scale: 100% - :alt: new york license plate - -Each font needs to be trained separately. You do not want to combine characters across fonts, this will greatly decrease your accuracy. After each font is trained, they can be combined into one dataset for your entire country. - -Creating the character tiles ----------------------------- -Once you're ready to start training, you'll need to create a library of character tiles. Each tile is a small image file that contains the black-and-white character and is named after the character. For example, here are a few character tile examples: - - -.. image:: images/training_ocr_char1.png - :scale: 100% - :alt: character tile 1 - -부-0-0-2.png - -.. image:: images/training_ocr_char2.png - :scale: 100% - :alt: character tile 2 - -0-0-az2012.png - -.. image:: images/training_ocr_char3.png - :scale: 100% - :alt: character tile 3 - -c-1-az2012.png - -.. image:: images/training_ocr_char4.png - :scale: 100% - :alt: character tile 4 - -d-9-az2012.jpg - -.. image:: images/training_ocr_char5.png - :scale: 100% - :alt: character tile 5 - -d-9-2-az2012.jpg - -You will want many of these character tiles for each character and each font. The character tiles are all going to be slightly different, this is necessary for the OCR training to understand how to detect characters. Notice in the above examples, the "D" characters have pixels located in different places, but they're clearly the same character. - -Producing Tiles ----------------- -There are two good ways to produce character tiles. - - 1. Use actual images from license plates - 2. Use a TTF font that looks like the license plate font - -Producing Tiles from Actual Plates ------------------------------------- - -You should gather a large library of license plate images (At least 100). These license plate images should be cropped around the plate and the aspect ratio should match your configured width/height for your license plates. Make sure each image is at least 250px wide. The imageclipper program (separate repo) is helpful for quickly cropping large numbers of images. Save them as png files. - -Each file should be prefaced with a two character identifier for the font/region. For example, for Maryland plates, we would name the file: **md**\ plate1.png - -Create an empty output directory. - -To start classifying characters, use the classifychars utility program included in OpenALPR. - -Execute the command: - classifychars [country] [input image directory] [empty output directory] - -A GUI will open up and analyze each license plate image in your input folder. The steps to classify each plate are: - 1. Press the "Enter" key and type the letter or number for each position that you wish to classify. Pressing 'Space' will skip the character. - 2. Use the arrow keys and press 'Space' to select the rendering that you wish to extract characters for. The box will be highlighted in blue if it is selected. For each plate, there may be good characters and bad characters. You want to pick the best characters, since significant imperfections may confuse the OCR. - 3. Press the 's' key to save each character as a separate file in your out folder. - 4. Press the 'n' key to move onto the next plate and repeat this process until you've classified all the plates. - -Producing Tiles from a TTF Font -------------------------------- -A TTF font can be used to produce tiles. However, we need to add some realistic distortion to the characters. This is necessary to make a robust OCR detector. - -The process is as follows: - - 1. Figure out all the characters that could possibly be in a license plate. - 2. Create a word document with all of these characters. Make sure there is plenty of spacing between lines and characters. - 3. Copy and paste all of these characters to a text file (no spaces or line breaks) - 4. Print this word document. - 5. Take a few pictures (5 would be sufficient) of the word document with a digital camera. Vary the angle/rotation very slightly (1-2 degrees) with each picture. - 6. Save the pictures to a folder. - 7. Run the openalpr-utils-binarizefontsheet program to produce tiles from each of the images. Provide the program with the text file from step #3 and each image file. - - -Building a Tesseract Training Sheet ------------------------------------ - -Once you've classified all the characters, it may be a good idea to scan through the directory to make sure that the classifications match the images. Each image filename should be prefaced with the character that it represents. Once you've done this, it's time to create a training sheet. - -The "openalpr-utils-prepcharsfortraining" utility program in OpenALPR will create the Tesseract training sheet for you. Execute the following command: -openalpr-utils-prepcharsfortraining [output directory from above] - -The output will be: - - combined.box - - combined.tif - -Rename these files to match the naming convention used by Tesseract (explained above). For example, leu.germany.exp0.box - -You should create a training sheet for each unique license plate font that you wish to train. - -Finish OCR Training ---------------------- - -Lastly, you'll use the box/tif files created above to train your country's license plate OCR. Create a new directory using your country code, and create an input directory within it. Copy all the box/tif files created in the previous steps into this directory. - -Execute the "train.py" file. Type in your country code. - -If all went well, you should have a new file named l[countrycode].traineddata. Copy this file into your runtime_directory (runtime_data/ocr/tessdata/) and it is now ready for OpenALPR to use. - -Tesseract may report issues. Most commonly it will complain that it could not line up the boxes on the provided image. If you are getting many of these warnings, you can re-run the openalpr-utils-prepcharsfortraining utility and provide values for --tile_width and --tile_height. Using different values will change how Tesseract sees the image and potentially improve results. - -Training the Detector -======================== - -The detector finds the general location of a license plate in an image. A single detector can support many different plate styles, as long as they generally have the same aspect ratio. For example, in the USA, license plates are 12 inches by 6 inches (i.e., an aspect ratio of 2:1). - -To train a license plate detector, you will need: - - 1. 3000+ clear images of license plates - 2. 40-60 hours of free time - -`This repository `_ contains scripts that will help train a license plate detector for a particular region. Your trained region detector can then be used in OpenALPR. - -The license plate region detector uses the Local Binary Pattern (LBP) algorithm. In order to train the detector, you will need many positive and negative images. This repository already contains a collection of negative images. You will need to add your own positive images. - -To get started, you will first need many cropped plate images containing positive license plate matches. Please see the "eu" positive image folder in this repository to understand the types of plate images required. The imageclipper program is helpful for creating these cropped images. - -After you've collected many (hundreds to thousands) of positive plate images, the next step is to train the detector. First you must configure the training script to use the correct dimensions. - -Edit the prep.py script and change the WIDTH, HEIGHT, and COUNTRY variables to match the country that you are training. The width and height should be proportional to the plate size (slightly larger is OK). A total pixel area of around 650 seems to work best. Also, adjust the path to your OpenCV libraries, if that needs to be changed. - -Once you are ready to start training, enter the following commands: - - - rm ./out/``*`` (clear the out folder in case it has data from previous runs) - - ./prep.py neg - - ./prep.py pos - - ./prep.py train - - Copy the output from the above command onto the command line. You should adjust the numStages to a smaller value (usually 12 stages works well, but it will depend on your input images). You may also need to adjust the numPos value to a smaller number in order to complete the training. - - -Copy the out/cascade.xml file to your OpenALPR runtime directory (runtime_data/region/[countrycode].xml). You should now be able to use the region for plate detection. - - -Developers Guide -================= - -Accuracy can also be improved by modifying the recognition code, itself. The OpenALPR library is binary-compatible with the commercial software. Any improvements/modifications you make can be swapped in by replacing the openalpr.dll/libopenalpr.so with your modified version. The information below describes the various stages involved in recognizing license plates. - -OpenALPR Design ----------------- - -OpenALPR operates as a pipeline. The input is an image, various processing occurs in stages, and the output is the possible plate numbers in the image. - -The pipeline stages occur in the following order: - -======================= ===================================== ============================================================================================== - Pipeline Phase C++ class Description -======================= ===================================== ============================================================================================== - Detection regiondetector.cpp Finds potential license plate regions - Binarization binarizewolf.cpp Converts the plate region image into black and white - Char Analysis characteranalysis.cpp Finds character-sized "blobs" in the plate region - Plate Edges platelines.cpp and platecorners.cpp Finds the edges/shape of the license plate - Deskew licenseplatecandidate.cpp Transforms the perspective to a straight-on view based on the ideal license plate size. - Character Segmentation charactersegmenter.cpp Isolates and cleans up the characters so that they can be processed individually - OCR ocr.cpp Analyzes each character image and provides multiple possible letters/confidences - Post Processing postprocess.cpp Creates a top n list of plate possibilities based on OCR confidences. - Also performs a Regex match against region templates if requested. -======================= ===================================== ============================================================================================== - -Detection ---------- -The detection phase happens one time for each input image. It uses the LBP algorithm (generally used for face detection) to find possible license plate regions (x,y, width, height). Each of these regions is sent to the later pipeline phases for further processing. - -The detection phase is usually the most processing-intensive phase. It can be GPU accelerated to improve performance. - -Binarization ------------- -This phase (and all subsequent phases) occur multiple times -- once for each possible license plate region. - -The binarization phase creates multiple binary images for each plate region. The reason multiple binary images are used is to give us the best possible chance of finding all the characters. A single binarized image may miss characters if the image is too dark or too light for example. Binarization uses the Wolf-Jolien method as well as the Sauovola method with various parameters. Each of the binary images are processed in subsequent phases. - -Character Analysis ------------------- -Character analysis attempts to find character-sized regions in the plate region. It does this by first finding all connected blobs in the license plate region. Then it looks for blobs that are roughly the width and height of a license plate character and have tops/bottoms that are in a straight line with other blobs of similar width/height. - -This analysis is done multiple times in the region. It starts by looking for small characters, then gradually looks for larger characters. - -If nothing is found in the region, then the region is thrown out and no further processing takes place. If it finds some potential characters, then the character region is saved and further processing takes place. - -Plate Edges ------------ -The next phase is to find the edges of the license plate. Keep in mind that the detection phase is only responsible for identifying a possible region where a license plate may exist. It often is going to provide a region that is a little larger or smaller than the actual plate. The plate edges tries to find the precise top/bottom/left/right edges of the license plate. - -The first step is to find all of the hough lines for the license plate region. platelines.cpp processes the plate image and computes a list of horizontal and vertical lines. - -platecorners uses this list as well as the character height (computed in Character Analysis) to find the likeliest plate line edges. It uses a number of configurable weights to determine which edge makes the most sense. It will try using a default edge (based on the ideal width/height of the plate) to see if that makes a good match. - -Deskew ------- -Given the plate edges, the deskew stage remaps the plate region to a standard size and orientation. Ideally this will give us a correctly oriented plate image (no rotation or skew). - -Character Segmentation ----------------------- -The character segmentation phase tries to isolate all the characters that make up the plate image. It uses a vertical histogram to find gaps in the plate characters. This phase also cleans up the character boxes by removing small, disconnected speckles and disqualifying character regions that are not tall enough. It also tries to remove "edge" regions so that the edge of the license plate doesn't inappropriately get classified as a '1' or an 'I' - -OCR ---- -The OCR phase analyzes each character independently. For each character image, it computes all possible characters and their confidences. - -Post Processing ---------------- -Given a list of all possible OCR characters and confidences, post processing determines the best possible plate letter combinations. It is organized as a top N list. Post processing disqualifies all characters below a particular threshold. It also has a "soft" thresholds -- characters that are below this threshold will still be added to the possible list, but they also add a possible blank character -- since it's possible that the low confidence character is not really part of the plate. - -The post processing also handles region validation if requested. For example, if I tell OpenALPR that this is a "Missouri" plate, then it will try and match the results against a template that matches the Missouri format (e.g., [char][char][number]-[char][number][char]). So, for example, if the top 3 list was: - - CFOCIG - - CF0CIG - - CF0C1G - -The third entry matches the template, but the other two do not. So, post processing will signal that the third entry is our best match. diff --git a/doc/source/alprd.rst b/doc/source/alprd.rst deleted file mode 100755 index 938caf63..00000000 --- a/doc/source/alprd.rst +++ /dev/null @@ -1,516 +0,0 @@ -.. _alprd: - -************************ -OpenALPR Agent (alprd) -************************ - -The OpenALPR daemon allows you to monitor a camera stream for license plate numbers in the background. Alprd runs as a daemon process on Linux. The plate numbers can be streamed to another server (via HTTP posts) or can be consumed programmatically via a beanstalkd queue. - -Architecture -============= - -Alprd operates as follows: - 1. The image stream is constantly pulled from the IP camera via MJPEG over HTTP - 2. alprd processes the stream as fast as it can looking for plate images. The daemon automatically skips frames to stay in-sync with clock time. - 3. When one or more plates are detected, the information is written to a local beanstalkd queue (tube name is alprd) as JSON data. - 4. Optionally, alprd will also save the image as a jpeg and save it to a configurable location. - 5. Optionally, alprd also runs a separate process that drains the beanstalkd queue and uploads data to a remote HTTP server via POST. - -Alprd can be used in two modes: - 1. Recognition results are streamed to an HTTP server - 2. Recognition results can be read from the beanstalkd queue - -:: - - +------------------+ +-------------+ - | | MJPEG POST | | - | Network Camera | <---+ +------> | HTTP Server | - | | | | | | - +------------------+ | | +-------------+ - | | - | | - | | - +-------+------+ - | | - | alprd server | - | | - +---------+----+------------+ - | | - | Beastalkd queue | - | | - +-----------------+ - - -The diagram above shows alprd being used to stream data to another HTTP server. alprd is configured with a remote HTTP address. As plates are identified, the server sends the JSON data to the remote HTTP server. The beanstalkd queue and the alprd process are colocated on the same server. - -:: - - +------------------+ - | | MJPEG - | Network Camera | <---+ - | | | - +------------------+ | - | +----------+ - | |Processing| - | +----+-----+ - +-------+------+ | - | | | - | alprd server | | - | | | - +---------+----+------------+ | - | | | - | Beastalkd queue | <------+ - | | - +-----------------+ - - -The diagram above shows alprd being used without the HTTP server. In this case, a beanstalkd consumer can be used to drain the results from the beanstalkd queue. The beanstalkd tube name is "alprd." Beanstalkd consumers can be written in any language, and can be colocated on the alprd server or located elsewhere. - -Open Source Agent -==================== - -Configuration -------------- - -.. code-block:: ini - - [daemon] - - ; Declare each stream on a separate line - ; each unique stream should be defined as stream = [url] - - stream = http://10.1.2.3/camera1/stream.mjpeg - stream = http://10.1.2.5/camera2/stream.mjpeg - - site_id = headquarters-usa - - store_plates = 1 - store_plates_location = /var/www/html/plates/ - - ; upload address is the destination to POST to - upload_data = 0 - upload_address = http://localhost:9000/alpr/push/ - -alprd needs at least one "stream" defined. This is just the URL for the mjpeg stream. You may use multiple streams on one server -- each stream spawns a separate process that attempts to use a full CPU core. - -The site-id will be stored along with the JSON plate results. This is especially useful if you have multiple servers and need to keep track of where the results are coming from. Additionally, each result will contain a camera ID (numbered 1 to n) based on the order of your "stream" statements in the alprd.conf file - - -Results ---------- -The following is an example of the JSON results. These results are initially stored in the beanstalkd queue, and then optionally sent in an HTTP post. - -.. code-block:: json - - { - "uuid": "f11e0acc-6aaf-4817-9299-9e6773043b8e", - "camera_id": 1, - "site_id": "headquarters", - "img_width": 640, - "img_height": 480, - "epoch_time": 1402161050, - "processing_time_ms": 138.669163, - "results": [ - { - "plate": "S11FRE", - "confidence": 77.130661, - "matches_template": 0, - "region": "", - "region_confidence": 0, - "coordinates": [ - { - "x": 218, - "y": 342 - }, - { - "x": 407, - "y": 325 - }, - { - "x": 407, - "y": 413 - }, - { - "x": 218, - "y": 431 - } - ], - "candidates": [ - { - "plate": "S11FRE", - "confidence": 77.130661, - "matches_template": 0 - }, - { - "plate": "S11ERE", - "confidence": 75.496307, - "matches_template": 0 - }, - { - "plate": "S11RE", - "confidence": 75.440361, - "matches_template": 0 - }, - { - "plate": "S11CRE", - "confidence": 75.340179, - "matches_template": 0 - }, - { - "plate": "S11FHE", - "confidence": 75.240974, - "matches_template": 0 - }, - { - "plate": "S11EHE", - "confidence": 73.606621, - "matches_template": 0 - }, - { - "plate": "S11HE", - "confidence": 73.550682, - "matches_template": 0 - }, - { - "plate": "S11CHE", - "confidence": 73.450493, - "matches_template": 0 - }, - { - "plate": "S11FBE", - "confidence": 71.782944, - "matches_template": 0 - }, - { - "plate": "S11FE", - "confidence": 71.762756, - "matches_template": 0 - } - ] - }, - { - "plate": "EJLESSIE", - "epoch_time": 1402158050, - "confidence": 78.167984, - "matches_template": 0, - "region": "", - "region_confidence": 0, - "processing_time_ms": 51.650604, - "coordinates": [ - { - "x": 226, - "y": 369 - }, - { - "x": 348, - "y": 348 - }, - { - "x": 355, - "y": 406 - }, - { - "x": 231, - "y": 429 - } - ], - "candidates": [ - { - "plate": "EJLESSIE", - "confidence": 78.167984, - "matches_template": 0 - }, - { - "plate": "EDLESSIE", - "confidence": 77.61319, - "matches_template": 0 - } - ] - } - ] - } - - -Commercial Agent -==================== - -`*` Requires Commercial License - -The commercial OpenALPR Agent has a number of :ref:`enhancements `. With these enhancements, the commercial agent is significantly faster when analyzing video streams. - -Installation --------------- - -On an Ubuntu 14.04 64-bit server: - -Add the OpenALPR GPG key and setup the OpenALPR deb repository - -.. code-block:: bash - - wget -O - http://deb.openalpr.com/openalpr.gpg.key | sudo apt-key add - - echo "deb http://deb.openalpr.com/commercial/ trusty main" | sudo tee /etc/apt/sources.list.d/openalpr.list - - sudo apt-get update && sudo apt-get -y install openalpr openalpr-daemon - -Edit the configuration file - -.. code-block:: bash - - sudo nano /etc/openalpr/alprd.conf - -Configure the following properties: - - - company_id (using the value found on the web server) - - site_id (a unique text value that identifies this agent) - - stream (The mjpeg URL for the camera stream. Multiple streams are added as additional stream entries) - - analysis_threads (number of CPU cores dedicated to OpenALPR processing) - - upload_address (set this to http://[*Web_server_IP*]/push/) - - store_plates_maxsize_mb (amount of space used for storing license plate images) - -Test the daemon from the CLI to make sure your settings are correct. Press CTRL+C once you see that the video stream is connected. - - alprd -f - -If the MJPEG stream is configured correctly, the logs should show that the video is being retrieved - - DEBUG - Video FPS: 10 - -Generate a license key for the agent: - -.. code-block:: bash - - cd ~ - wget http://deb.openalpr.com/register.py - sudo openalpr-licenserequest --license_count 0 > /dev/null && sudo python register.py -u [Username] -p [Password] -c [Number of camera licenses] - -The number of camera licenses corresponds to the maximum number of simultaneous video streams that this agent will support. - -Each time you run this utility, it will transfer the requested number of licenses from our online registration server to your agent server. - -.. _commercial_config_options: - -Commercial Configuration Options ------------------------------------ - - -The /etc/openalpr/alprd.conf file has additional properties that control the commercial-only features: - -The commercial software will group similar plate numbers together and send a JSON post that contains the UUIDs of all of the plate images in the group. These configuration files control the grouping sensitivity. - -.. code-block:: ini - - plate_groups_enabled = 1 - plate_groups_time_delta_ms = 4500 - plate_groups_min_plates_to_group = 3 - - -The commercial daemon will maintain a disk quota and will automatically clean up after itself. Images stored to disk will be removed on a FIFO-basis. These parameters control the maximum size on disk and the frequency of clean-up. - -.. code-block:: ini - - store_plates_maxsize_mb = 8000 - store_plates_cleanup_interval_seconds = 120 - - -The upload threads control the number of simultaneous data uploads. Generally, the number of threads would only need to be increased if the web server is slow to respond. - -.. code-block:: ini - - upload_threads = 2 - - -Motion detection is an effective way to improve efficiency and get more plate reads from the available processors. The ALPR processing will only analyze frames with movement, and will ignore areas of the image that have not changed. This parameter controls whether motion detection is enabled (1) or disabled (0). - -.. code-block:: ini - - motion_detection = 1 - - -The ALPR processing occurs in parallel, each thread will consume an entire CPU core. Allocating more CPUs for ALPR processing will linearly increase the number of plate reads per second - -.. code-block:: ini - - analysis_threads = 2 - - -With motion detection enabled, it's possible to buffer moving images and analyze them as CPU becomes available. For example, if a car moves past the camera over 10 frames, and the CPU can only analyze 3 of those frames during that period, the buffer will allow you to analyze all 10 frames. After the movement is complete and there is no other activity, the ALPR process will drain the buffer looking for license plates during the period of movement. Increasing the buffer_size will increase the duration of this period, but will also consume more memory. The camera_buffer_size unit is number of image frames. - -.. code-block:: ini - - camera_buffer_size = 60 - - - -Group Results --------------- - -ALPR group results are sent in the following JSON format: - -.. code-block:: json - - { - "version": 1, - "data_type": "alpr_group", - "epoch_start": 1448326208789, - "epoch_end": 1448326210046, - "company_id": "44c9274f-8d57-432a-8cd7-8c991f22ead3", - "site_id": "dimitar-video", - "camera_id": 1414799424, - "uuids": [ - "dimitar-video-cam1414799424-1448326208789", - "dimitar-video-cam1414799424-1448326209041", - "dimitar-video-cam1414799424-1448326209648", - "dimitar-video-cam1414799424-1448326209975", - "dimitar-video-cam1414799424-1448326210046" - ], - "best_plate": { - "plate": "A13709", - "confidence": 92.075203, - "matches_template": 0, - "plate_index": 0, - "region": "mo", - "region_confidence": 0, - "processing_time_ms": 96.942459, - "requested_topn": 10, - "coordinates": [ - { - "x": 204, - "y": 134 - }, - { - "x": 709, - "y": 222 - }, - { - "x": 658, - "y": 500 - }, - { - "x": 167, - "y": 383 - } - ], - "candidates": [ - { - "plate": "A13709", - "confidence": 92.075203, - "matches_template": 0 - }, - { - "plate": "A137O9", - "confidence": 83.32373, - "matches_template": 0 - }, - { - "plate": "A137Q9", - "confidence": 83.001274, - "matches_template": 0 - }, - { - "plate": "A137D9", - "confidence": 82.240067, - "matches_template": 0 - }, - { - "plate": "AI3709", - "confidence": 80.574394, - "matches_template": 0 - }, - { - "plate": "A137U9", - "confidence": 80.238014, - "matches_template": 0 - }, - { - "plate": "A137G9", - "confidence": 78.271233, - "matches_template": 0 - }, - { - "plate": "A137B9", - "confidence": 78.039688, - "matches_template": 0 - }, - { - "plate": "A3709", - "confidence": 77.410858, - "matches_template": 0 - }, - { - "plate": "AI37O9", - "confidence": 71.822922, - "matches_template": 0 - } - ] - }, - "best_confidence": 92.075203, - "best_uuid": "dimitar-video-cam1414799424-1448326208789", - "best_plate_number": "A13709" - } - -Heartbeat -------------- - -Every minute, the OpenALPR agent adds a heartbeat message to the queue. The heartbeat provides general health and status information. The format is as follows: - -.. code-block:: json - - { - "version": 1, - "data_type": "heartbeat", - "company_id": "xxxxxxxx-yyyy-yyyy-yyyy-zzzzzzzzzzzz", - "site_id": "your-unique-sitename", - "timestamp": 1453426302097, - "system_uptime_seconds": 2595123, - "daemon_uptime_seconds": 2594832, - "internal_ip_address": "192.168.0.54", - "cpu_cores": 2, - "cpu_last_update": 1453426297878, - "cpu_usage_percent": 18.579235, - "disk_quota_total_bytes": 8000000000, - "disk_quota_consumed_bytes": 0, - "disk_quota_last_update": 1453408254586, - "memory_consumed_bytes": 2083704832, - "memory_last_update": 1453426297878, - "memory_swapused_bytes": 0, - "memory_swaptotal_bytes": 1608511488, - "memory_total_bytes": 2099093504, - "processing_threads_active": 1, - "processing_threads_configured": 1, - "beanstalk_queue_size": 0, - "video_streams": [ - { - "camera_id": 1630410444, - "fps": 12, - "is_streaming": true, - "url": "rtsp://192.168.0.5:554/axis-media/media.amp?videocodec=h264&resolution=1280x720&compression=30&mirror=0&rotation=0&textposition=top&text=1&clock=1&date=0&overlayimage=0&fps=11&keyframe_interval=32&videobitrate=0&maxframesize=0", - "last_update": 1453426302086 - } - ] - } - -Web Services -------------- - -The OpenALPR daemon exposes a simple web service for retrieving license plate images. Each image is referenced by a UUID that is sent along with the JSON metadata. - -Assuming that the daemon port is set to the default (8355), the full image is referenced using the following URL: - - - http://[*Agent_IP*]:8355/img/[*plate_event_uuid*].jpg - -In some cases, you may prefer to just retrieve a cropped image around the license plate. This would require significantly less bandwidth than downloading the entire source image. The X and Y coordinates can be computed from the JSON metadata x/y coordinates of the license plate. The x1/y1 coordinates reference the top-left of the license plate crop region, and the x2/y2 coordinates reference the bottom right. For example, assuming the crop is located at (477,258), (632,297): - - - http://[*Agent_IP*]:8355/crop/[*plate_event_uuid*]?x1=477&y1=258&x2=632&y2=297 - -Additionally, the web server exposes a `web service API `_ for searching license plates and groups. Detailed documentation is available in the :ref:`web server section ` - -OpenALPR Agent Docker Container ----------------------------------- - -The OpenALPR Agent Docker container runs the OpenALPR agent within Docker given a license.conf and alprd.conf file that you supply. The image is built on top of Ubuntu 14.04 64-bit. When the container is launched, it runs both Beanstalkd and the alprd daemon. The container exposes the following ports: - - 1. Port 11300 - Beanstalkd - 2. Port 8355 - The OpenALPR daemon web service - -The /var/lib/openalpr/plateimages/ folder is exposed as a volume that can be attached to the host file system. This location will contain license plate images in a rolling buffer with a maximum size specified in alprd.conf - diff --git a/doc/source/bindings.rst b/doc/source/bindings.rst deleted file mode 100755 index bc5f59c1..00000000 --- a/doc/source/bindings.rst +++ /dev/null @@ -1,297 +0,0 @@ - -.. _language_bindings: - -******************** -OpenALPR API -******************** - - -OpenALPR is available as a C/C++ library and has bindings in C#, Java, and Python. Additionally, the software can be used as a "black box" that can process video streams and make the data available to another system (using any programming language). - -C/C++ -================= - -First, download or compile the OpenALPR library onto your target platform. Make sure that the software runs by testing it using the alpr command-line executable. Pre-compiled binaries are available for 32/64-bit Windows and Ubuntu Linux. - -1. Add "alpr.h" as an include file to your project. -2. Include the openalpr.dll (Windows) or libopenalpr.so (Unix) file with your binaries -3. Include all other required shared libraries -4. Put the openalpr.conf and runtime_data directory in the same location as the binaries. Alternatively, you can specify the location of the runtime_data in openalpr.conf or directly in the code. - -Below is a simple usage example of using the OpenALPR library: - -.. code-block:: c++ - :linenos: - - // Initialize the library using United States style license plates. - // You can use other countries/regions as well (for example: "eu", "au", or "kr") - alpr::Alpr openalpr("us", "/path/to/openalpr.conf"); - - // Optionally specify the top N possible plates to return (with confidences). Default is 10 - openalpr.setTopN(20); - - // Optionally, provide the library with a region for pattern matching. This improves accuracy by - // comparing the plate text with the regional pattern. - openalpr.setDefaultRegion("md"); - - // Make sure the library loaded before continuing. - // For example, it could fail if the config/runtime_data is not found - if (openalpr.isLoaded() == false) - { - std::cerr << "Error loading OpenALPR" << std::endl; - return 1; - } - - // Recognize an image file. You could alternatively provide the image bytes in-memory. - alpr::AlprResults results = openalpr.recognize("/path/to/image.jpg"); - - // Iterate through the results. There may be multiple plates in an image, - // and each plate return sthe top N candidates. - for (int i = 0; i < results.plates.size(); i++) - { - alpr::AlprPlateResult plate = results.plates[i]; - std::cout << "plate" << i << ": " << plate.topNPlates.size() << " results" << std::endl; - - for (int k = 0; k < plate.topNPlates.size(); k++) - { - alpr::AlprPlate candidate = plate.topNPlates[k]; - std::cout << " - " << candidate.characters << "\t confidence: " << candidate.overall_confidence; - std::cout << "\t pattern_match: " << candidate.matches_template << std::endl; - } - } - - -C# and VB.NET -==================== - -.. code-block:: c# - :linenos: - - using openalprnet; - - var alpr = new AlprNet("us", "/path/to/openalpr.conf", "/path/to/runtime_data"); - if (!alpr.IsLoaded()) - { - Console.WriteLine("OpenAlpr failed to load!"); - return; - } - // Optionally apply pattern matching for a particular region - alpr.DefaultRegion = "md"; - - var results = alpr.Recognize("/path/to/image.jpg"); - - foreach (var result in results.Plates) - { - Console.WriteLine("Plate {0}: {1} result(s)", i++, result.TopNPlates.Count); - Console.WriteLine(" Processing Time: {0} msec(s)", result.ProcessingTimeMs); - foreach (var plate in result.TopNPlates) - { - Console.WriteLine(" - {0}\t Confidence: {1}\tMatches Template: {2}", plate.Characters, - plate.OverallConfidence, plate.MatchesTemplate); - } - } - - - - -Python -==================== - -.. code-block:: python - :linenos: - - from openalpr import Alpr - - alpr = Alpr("us", "/path/to/openalpr.conf", "/path/to/runtime_data") - if not alpr.is_loaded(): - print("Error loading OpenALPR") - sys.exit(1) - - alpr.set_top_n(20) - alpr.set_default_region("md") - - results = alpr.recognize_file("/path/to/image.jpg") - - i = 0 - for plate in results['results']: - i += 1 - print("Plate #%d" % i) - print(" %12s %12s" % ("Plate", "Confidence")) - for candidate in plate['candidates']: - prefix = "-" - if candidate['matches_template']: - prefix = "*" - - print(" %s %12s%12f" % (prefix, candidate['plate'], candidate['confidence'])) - - # Call when completely done to release memory - alpr.unload() - - - -Java -==================== - -.. code-block:: java - :linenos: - - import com.openalpr.jni.Alpr; - import com.openalpr.jni.AlprPlate; - import com.openalpr.jni.AlprPlateResult; - import com.openalpr.jni.AlprResults; - - Alpr alpr = new Alpr("us", "/path/to/openalpr.conf", "/path/to/runtime_data"); - - // Set top N candidates returned to 20 - alpr.setTopN(20); - - // Set pattern to Maryland - alpr.setDefaultRegion("md"); - - AlprResults results = alpr.recognize("/path/to/image.jpg"); - System.out.format(" %-15s%-8s\n", "Plate Number", "Confidence"); - for (AlprPlateResult result : results.getPlates()) - { - for (AlprPlate plate : result.getTopNPlates()) { - if (plate.isMatchesTemplate()) - System.out.print(" * "); - else - System.out.print(" - "); - System.out.format("%-15s%-8f\n", plate.getCharacters(), plate.getOverallConfidence()); - } - } - - // Make sure to call this to release memory - alpr.unload(); - - -Node.js -==================== - -A Node.js binding to OpenALPR is available here: -https://www.npmjs.com/package/node-openalpr - -The source code is available here: -https://github.com/netPark/node-openalpr - - -.. _cloud_api: - -Cloud API (Commercial) -======================= - -The OpenALPR Cloud API is a web-based service that analyzes images for license plates as well as vehicle information such as make, model, and color. -The Cloud API service is easy to integrate into your application via a web-based REST service. You send image data to the OpenALPR API, we process the data, -and return JSON data describing the license plate and vehicle. - -Check out the online demo: http://www.openalpr.com/demo-image.html - -Sign-Up ---------- - -When you're ready to get started, sign-up for an account at https://cloud.openalpr.com/ - -Once enrolled, you will automatically be assigned a free account that has a limited number of API credits per month. Each time you use the service, you use one or more -API credits. You may enter your credit card information and upgrade your plan to give you access to more credits per month. - -Integrate ----------- - -Because the OpenALPR Cloud API is REST-based, it works with any programming language on any operating system. You can make API calls using whatever method -you prefer. - -To make integration easier, the OpenALPR Cloud API also includes permissively licensed open source client libraries in a variety of languages. -The GitHub repo is available here: https://github.com/openalpr/cloudapi - -Check out the `REST API documentation `_ for more detailed information about the REST service. -This is generated from the `OpenALPR Cloud API Swagger definition `_ - - -.. _alpr_web_service: - -Docker-Based Web Service (Commercial) -====================================== - -The OpenALPR Library Docker container provides the OpenALPR image processing as a web service. In this mode, images are sent to OpenALPR via HTTP POST, and OpenALPR responds with the metadata describing all license plates in the image. This docker image exposes port 8080. - -Requests into this service are sent as HTTP POST requests to: - - http://[*ip_address*]:8080/v1/identify/plate - -The post should contain this parameter: - - image - A file containing a JPEG image - -Results will be sent back in the following JSON format: - - -.. code-block:: json - - { - "data_type": "alpr_results", - "epoch_time": 1448299357883, - "img_height": 480, - "img_width": 640, - "results": [ - { - "plate": "AKS4329", - "confidence": 86.457352, - "region_confidence": 95, - "region": "ga", - "plate_index": 0, - "processing_time_ms": 84.982811, - "candidates": [ - { - "matches_template": 0, - "plate": "AKS43Z9", - "confidence": 88.429092 - }, - { - "matches_template": 1, - "plate": "AKS4329", - "confidence": 86.457352 - }, - { - "matches_template": 0, - "plate": "AKS3Z9", - "confidence": 79.028625 - }, - { - "matches_template": 0, - "plate": "AKS329", - "confidence": 77.056877 - } - ], - "coordinates": [ - { - "y": 128, - "x": 286 - }, - { - "y": 129, - "x": 360 - }, - { - "y": 159, - "x": 360 - }, - { - "y": 157, - "x": 286 - } - ], - "matches_template": 1, - "requested_topn": 20 - } - ], - "version": 2, - "processing_time_ms": 172.226624, - "regions_of_interest": [] - } - -OpenALPR Agent -==================== - -OpenALPR can also be configured as a "black box" that makes data available to other systems. When configured in this mode, OpenALPR is installed as a Linux daemon, and is configured to monitor one or more MJPEG video streams. It automatically processes the images and produces JSON data describing the license plates found int he images. This data can either be pushed to another server (as an HTTP POST) or pulled from another server (via beanstalkd queue). - -More information about the OpenALPR agent is available here: :ref:`alprd` \ No newline at end of file diff --git a/doc/source/cloudapi.yaml b/doc/source/cloudapi.yaml deleted file mode 100644 index 1fff4ed6..00000000 --- a/doc/source/cloudapi.yaml +++ /dev/null @@ -1,323 +0,0 @@ -swagger: '2.0' - -info: - version: "1.0.1" - title: OpenALPR Cloud API -host: api.openalpr.com -basePath: /v1 -schemes: - - https -produces: - - application/json - -paths: - # Send an image to OpenALPR and get the analyzed results - /recognize: - post: - description: | - Send an image for OpenALPR to analyze and provide metadata back - consumes: - - "multipart/form-data" - produces: - - application/json - parameters: - - - name: secret_key - in: query - description: | - The secret key used to authenticate your account. You can view your - secret key by visiting - https://cloud.openalpr.com/ - required: true - type: string - - - name: tasks - in: query - description: | - Tasks to execute. You can choose to detect the license plate, - as well as additional metadata about the vehicle. Each additional - option costs an API credit. Valid values are: plate, color, make, makemodel. - Use commas to specify multiple recognition types in one pass - required: true - type: array - items: - type: string - enum: [ "plate", "color", "make", "makemodel"] - - - name: image - in: formData - description: | - The image file that you wish to analyze - At least one value for image, image_bytes, or image_url must be provided - required: true - type: file - - - name: image_bytes - in: query - description: | - The image file that you wish to analyze encoded in base64 - At least one value for image, image_bytes, or image_url must be provided - required: false - type: string - - - name: image_url - in: query - description: | - A URL to an image that you wish to analyze - At least one value for image, image_bytes, or image_url must be provided - required: false - type: string - - - name: country - in: query - description: | - Defines the training data used by OpenALPR. "us" analyzes - North-American style plates. "eu" analyzes European-style plates. - - This field is required if using the "plate" task - - You may use multiple datasets by using commas between the country - codes. For example, 'au,auwide' would analyze using both the - Australian plate styles. A full list of supported country codes - can be found here - https://github.com/openalpr/openalpr/tree/master/runtime_data/config - required: false - type: string - - - name: state - in: query - description: | - Corresponds to a US state or EU country code used by OpenALPR pattern - recognition. For example, using "md" matches US plates against the - Maryland plate patterns. Using "fr" matches European plates against - the French plate patterns. - required: false - type: string - - - name: return_image - in: query - description: | - If set to 1, the image you uploaded will be encoded in base64 and - sent back along with the response - required: false - type: integer - enum: [0, 1] - - - name: topn - in: query - description: | - The number of results you would like to be returned for plate - candidates and vehicle classifications - required: false - type: integer - minimum: 1 - maximum: 1000 - - - name: prewarp - in: query - description: | - Prewarp configuration is used to calibrate the analyses for the - angle of a particular camera. More information is available here - http://doc.openalpr.com/accuracy_improvements.html#calibration - required: false - type: string - - # Expected responses for this operation: - responses: - # Response code - 200: - description: OK - headers: - X-RateLimit-Limit: - description: Maximum number of requests allowed from your IP in a period - type: integer - X-Ratelimit-Remaining: - description: Number of remaining requests allowed during this period - type: integer - X-Ratelimit-Reset: - description: Epoch time when the next period begins - type: integer - schema: - properties: - total_processing_time: - type: number - description: Time spent processing all tasks (in milliseconds) - img_width: - type: integer - description: Width of the uploaded image in pixels - img_height: - type: integer - description: Height of the input image in pixels - credit_cost: - type: integer - description: The number of API credits that were used to process this image - credits_monthly_used: - type: integer - description: The number of API credits used this month - credits_monthly_total: - type: integer - description: The maximum number of API credits available this month according to your plan - makemodel: - type: array - description: Results from makemodel vehicle analysis task - items: - $ref: '#/definitions/classification' - make: - type: array - description: Results from make vehicle analysis task - items: - $ref: '#/definitions/classification' - color: - type: array - description: Results from color vehicle analysis task - items: - $ref: '#/definitions/classification' - plate: - $ref: '#/definitions/alpr_plate' - - - - - 400: - description: Parameter is invalid - schema: - properties: - error: - type: string - description: Text error message describing the invalid input - 401: - description: User not authorized or invalid secret_key - schema: - properties: - error: - type: string - description: Text error message describing the invalid input - - 402: - description: Monthly usage limit exceeded - schema: - properties: - error: - type: string - description: Text error message describing the invalid input - 403: - description: Temporary rate-limit exceeded - schema: - properties: - error: - type: string - description: Text error message describing the invalid input - -definitions: - classification: - type: object - properties: - confidence: - type: number - value: - type: string - - coordinate: - type: object - properties: - x: - type: integer - y: - type: integer - - region_of_interest: - type: object - properties: - x: - type: integer - y: - type: integer - width: - type: integer - height: - type: integer - - plate_candidate: - type: object - properties: - plate: - type: string - description: Plate number - confidence: - type: number - description: Confidence percentage that the plate number is correct - matches_template: - type: integer - description: Indicates whether the plate matched a regional text pattern - - plate_details: - type: object - properties: - plate: - type: string - description: Best plate number for this plate - matches_template: - type: integer - description: Indicates whether the plate matched a regional text pattern - requested_topn: - type: integer - description: The max number of results requested - processing_time_ms: - type: number - description: Number of milliseconds to process the license plate - confidence: - type: number - description: Confidence percentage that the plate number is correct - region: - type: string - description: Specified or detected region (e.g., tx for Texas) - region_confidence: - type: number - description: Confidence percentage that the plate region is correct - coordinates: - type: array - description: | - The X/Y coordinates of the license plate in the image - Four coordinates are provided that form a polygon starting - from the top-left and moving clockwise ending in the bottom left - items: - $ref: '#/definitions/coordinate' - candidates: - type: array - description: All the top N candidates that could be the correct plate number - items: - $ref: '#/definitions/plate_candidate' - - alpr_plate: - description: Results from plate analysis task - type: object - properties: - results: - type: array - items: - $ref: '#/definitions/plate_details' - img_width: - type: integer - description: Width of the uploaded image in pixels - img_height: - type: integer - description: Height of the input image in pixels - regions_of_interest: - type: array - description: Describes the areas analyzed in the input image - items: - $ref: '#/definitions/region_of_interest' - epoch_time: - # This is actually an integer, but setting to number to avoid issues with overflow - type: number - description: Epoch time that the image was processed in milliseconds - version: - type: integer - description: API format version - data_type: - type: string - enum: ["alpr_results", "alpr_group", "heartbeat"] - description: Specifies the type of data in this response - processing_time_ms: - type: number - description: Number of milliseconds to process all license plates diff --git a/doc/source/commandline.rst b/doc/source/commandline.rst deleted file mode 100755 index 0cd16cde..00000000 --- a/doc/source/commandline.rst +++ /dev/null @@ -1,109 +0,0 @@ -.. _alpr_command_line: - -************************ -Command Line Utility -************************ - - -The OpenALPR Command Line Interface (CLI) utility is a great way to quickly test ALPR against images, videos, or webcams. It is not recommended for sophisticated integration, since each time the CLI utility loads, it takes a number of seconds to initialize all of the OpenALPR recognition data. - -Usage ------- - -:: - - alpr [-c ] [--config ] [-n ] [--seek - ] [-p ] [--motion] [--clock] [-d] [-j] - [--] [--version] [-h] <> ... - - - Where: - - -c , --country - Country code to identify (either us for USA or eu for Europe). - Default=us - - --config - Path to the openalpr.conf file - - -n , --topn - Max number of possible plate numbers to return. Default=10 - - --seek - Seek to the specied millisecond in a video file. Default=0 - - -p , --pattern - Attempt to match the plate number against a plate pattern (e.g., md - for Maryland, ca for California) - - --motion - Use motion detection on video file or stream. Default=off - - --clock - Measure/print the total time to process image and all plates. - Default=off - - -d, --detect_region - Attempt to detect the region of the plate image. [Experimental] - Default=off - - -j, --json - Output recognition results in JSON format. Default=off - - --, --ignore_rest - Ignores the rest of the labeled arguments following this flag. - - --version - Displays version information and exits. - - -h, --help - Displays usage information and exits. - - <> (accepted multiple times) - (required) Image containing license plates - - -Examples ------------ - -This command will attempt to recognize number plates in the /source/image.jpg image using the European-style recognition data. The config -file is not provided on the CLI, so it will use the value in the environment variable 'OPENALPR_CONFIG_FILE' if provided, or the default -location. - -:: - - $ alpr -c eu /source/image.jpg - -This command will attempt to recognize number plates in the /source/image.png image using the default USA-style recognition data. The config -file is not provided on the CLI, so it will read the configuration data from /tmp/openalpr.conf - -:: - - $ alpr --config /tmp/openalpr.conf /source/image.png - -This command will attempt to recognize number plates in all jpeg images in the current directory image using the USA-style recognition data. - -:: - - $ alpr -c us *.jpg - -This command reads data from an input video (/source/video.mp4) and outputs recognition data as JSON. - -:: - - $ alpr -j /source/video.mp4 - -This command processes a list of image files provided in /source/imagefilelist.txt and writes JSON results to /out/recognitionresults.txt. - -:: - - $ alpr -j stdin < /source/imagefilelist.txt > /out/recognitionresults.txt - -This command processes video from your webcam. You can also use /dev/video0, /dev/video1, etc. if you have multiple webcams. - -:: - - $ alpr webcam - - - diff --git a/doc/source/commercial.rst b/doc/source/commercial.rst deleted file mode 100755 index 0d0c957e..00000000 --- a/doc/source/commercial.rst +++ /dev/null @@ -1,60 +0,0 @@ -.. _commercial: - -************************* -Commercial Enhancements -************************* - -OpenALPR is commercially supported open source software. OpenALPR is licensed under dual licenses to meet the needs of open source users as well as for-profit commercial entities. The software may be used under the terms of the Affero `GNU Public License v3 (AGPL) `_. However, this license has strong copyleft requirements that most for-profit companies cannot use. For this reason, we also offer the software under a commercial license. Please contact info@openalpr.com for license pricing and terms. - -The OpenALPR commercial license overrides the AGPL terms and allows OpenALPR to be used without copyleft requirements. The software may then be used, integrated, and distributed in closed-source proprietary applications. - -Additionally, there are a number of features and enhancements that are available exclusively to commercial customers. - -.. _commercial_enhancements: - - - Multi-core processing - - Efficient processing via motion detection - - License plate grouping - - High-accuracy US state recognition - - Support for H264 video streams - - On-Premises web server - - Video file processing - -Multi-Core Processing ------------------------ - -The OpenALPR agent utilizes multiple CPU cores in parallel to improve the analysis frame rate. Faster processing allows OpenALPR to record number plates for vehicles at higher speeds and will also contribute to higher accuracy at lower speeds due to plate grouping. The "analysis_threads" configuration property in alprd.conf controls the number of simmultaneous CPU cores used to process license plates. Additionally, if a GPU is available (either via OpenCL or Nvidia CUDA) the agent can make use of this to accelerate license plate processing. - -Efficient Processing via Motion Detection -------------------------------------------- - -Utilizing motion detection greatly increases the efficiency of the OpenALPR agent. Rather than monitoring all pixels of every frame in a video, the software ignores areas in the video that have not changed (and therefore could not contain a license plate). When motion is detected, only the portion where the vehicle is located will be analyzed. - -To provide the most possible reads, OpenALPR also utilizes a configurable image buffer. When there is lots of motion detected, the video frames are placed into this buffer and processed. Therefore, if the video has moments of inactivity, the CPU resources will remain utilized processing older video data in order to provide the most possible license plate reads. - -License Plate Grouping ------------------------ - -In a video stream, a single license plate is often seen many times as it travels past the camera. For example, if the vehicle passes the camera over the course of 2 seconds at 30 frames per second, OpenALPR may recognize that same license plate 60 times. The plate grouping feature tracks the license plate as it moves, and delivers a single result for the license plate number that is scored based on the number of recognitions. Therefore, high-speed processing produces a highly accurate license plate number. - -High-Accuracy US State Recognition ------------------------------------- - -This feature determines the US state for a given license plate. For example, OpenALPR will differentiate a Maryland license plate versus one from California. This also increases accuracy, since each state has a unique text pattern. Knowing the originating state for the license plate allows OpenALPR to match the text results against the unique state pattern. - -Support for H264 Video Streams --------------------------------- - -The OpenALPR Commercial agent has more ubiquitous support for connecting to IP camera video streams. In addition to MJPEG, OpenALPR also supports H264 over both RTSP and HTTP. - -On-Premises Web Server -------------------------- - -The commercial web server is a data repository for license plate information. License plates is browsable, searchable, and triggers e-mail alerts for matching plate numbers. - -Video File Processing ----------------------- - -OpenALPR has a utility that efficiently processes video files to produce a CSV output containing all the license plates found in the video stream. - - diff --git a/doc/source/compiling.rst b/doc/source/compiling.rst deleted file mode 100755 index fb943c0e..00000000 --- a/doc/source/compiling.rst +++ /dev/null @@ -1,226 +0,0 @@ -************************ -Compiling -************************ - -Windows -============= - -Using Precompiled Binaries ---------------------------- - -Precompiled binaries are available for Windows in both 32 and 64-bit format. You can find the latest binaries on the `GitHub releases page `_. This is the simplest option for installing OpenALPR onto a Windows machine. Included in the package are the Visual Studio 2015 runtime drivers. You must install this first in order to use the OpenALPR software. - - -Compiling OpenALPR via Build Script ------------------------------------- - -`OpenALPR Windows Build Scripts `_ - - -Compile OpenALPR and Dependencies Manually --------------------------------------------- - -`Video Tutorial `_ - -* Ensure you have a version of Visual Studio that is at least 2008 or above -* Download and install `cmake for windows `_ -* Download `OpenCV for Windows `_ (3.0.0 at this time) -* Download `Tesseract OCR source code and VS2008 project files `_ (3.04 at this time) -* Download `Leptonica vs2008 development package `_ (Tesseract requirement) -* Download `OpenALPR source code `_ from GitHub -* Create a libraries directory and put opencv and Tesseract into them -* Compile OpenCV. `cd` into the opencv directory and type cmake . to create the VisualStudio project. -* Compile Tesseract. Tesseract requires that you point it to the leptonica headers and the library binaries before it will compile. Note that tesseract needs to be compiled as a LIBRARY. Make sure also that your compile mode matches for each of the projects (e.g., Release vs Debug). -* Update the CMakeLists.txt file in the OpenALPR src directory to point to the folders for your Tesseract and OpenCV libraries -* Depending on the versions of the libraries, you may need to tweak the linked libraries in here as well (e.g., liblept168 may be liblept173 at some point in the future). These correspond to the library files for Leptonica and Tesseract. -* CD into the openalpr src directory and type "cmake ." -* Open the Visual Studio solution and compile. -* If all goes well, there should be an "alpr" executable. In order to execute it, you will need a number of DLLs from OpenCV. simply finding them in the OpenCV directories and copying them over to your executable should do the trick. - - - -Linux -============= - -OpenALPR compiles on many flavors of Linux. However, the software is officially supported on Ubuntu 14.04 64-bit. - -Using Precompiled Binaries ---------------------------- - -Precompiled binaries are available for Ubuntu 14.04 64-bit OS. This is the simplest option for installing OpenALPR onto a Linux machine. The precompiled binaries are managed via APT, so upgrades will automatically be installed when you use the *apt-get update && apt-get upgrade* command. To install the precompiled binaries, run the following commands on your Ubuntu machine. - -.. code-block:: bash - - wget -O - http://deb.openalpr.com/openalpr.gpg.key | sudo apt-key add - - echo "deb http://deb.openalpr.com/master/ trusty main" | sudo tee /etc/apt/sources.list.d/openalpr.list - sudo apt-get update - sudo apt-get install openalpr openalpr-daemon openalpr-utils libopenalpr-dev - -Test the library - -.. code-block:: bash - - # Test US plates - wget http://plates.openalpr.com/ea7the.jpg - alpr -c us ea7the.jpg - - # Test European plates - wget http://plates.openalpr.com/h786poj.jpg - alpr -c eu h786poj.jpg - -Compiling OpenALPR -------------------- - -.. code-block:: bash - - # Install prerequisites - sudo apt-get install libopencv-dev libtesseract-dev git cmake build-essential libleptonica-dev - sudo apt-get install liblog4cplus-dev libcurl3-dev - - # If using the daemon, install beanstalkd - sudo apt-get install beanstalkd - - # Clone the latest code from GitHub - git clone https://github.com/openalpr/openalpr.git - - # Setup the build directory - cd openalpr/src - mkdir build - cd build - - # setup the compile environment - cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr -DCMAKE_INSTALL_SYSCONFDIR:PATH=/etc .. - - # compile the library - make - - # Install the binaries/libraries to your local system (prefix is /usr) - sudo make install - - # Test the library - wget http://plates.openalpr.com/h786poj.jpg -O lp.jpg - alpr lp.jpg - - -Compile OpenALPR and all Dependencies --------------------------------------- - -1. Make sure that dependencies and required tools are installed - - * sudo apt-get install libpng12-dev libjpeg62-dev libtiff4-dev zlib1g-dev - * sudo apt-get install build-essential - * sudo apt-get install autoconf automake libtool - * sudo apt-get install git-core - * sudo apt-get install cmake - -2. install opencv (tutorial) - - * http://docs.opencv.org/2.4/doc/tutorials/introduction/linux_install/linux_install.html - -3. download and install leptonica and tesseract-ocr - - * tesseract-ocr requires leptonica and at least one language package. - * http://www.leptonica.org/source/leptonica-1.70.tar.gz - * https://tesseract-ocr.googlecode.com/files/tesseract-ocr-3.02.02.tar.gz - * https://tesseract-ocr.googlecode.com/files/tesseract-ocr-3.02.eng.tar.gz - * move the downloaded tarballs to some directory. I will assume that they are located at /usr/local/src/openalpr/. - -4. unpack the tarballs: - - * tar xf /usr/local/src/openalpr/tesseract-ocr-3.02.02.tar.gz - * tar xf /usr/local/src/openalpr/tesseract-ocr-3.02.02.eng.tar.gz - * tar xf /usr/local/src/openalpr/leptonica-1.70.tar.gz - -5. compile leptonica: - - * cd /usr/local/src/openalpr/leptonica-1.70/ - * ./configure --prefix=/usr/local - * make - * make install - -6. compile tesseract: - - * cd /usr/local/src/openalpr/tesseract-ocr/ - * ./autogen.sh - * ./configure - * make - * sudo make install - * sudo ldconfig - -7. clone the openalpr repo to /usr/local/src/openalpr/ directory - - * cd /usr/local/src/openalpr/ - * git clone https://github.com/openalpr/openalpr.git - -8. update CMakeLists.txt compile openalpr - - * cd /usr/local/src/openalpr/openalpr/ - * gedit CMakeLists.txt & - * SET(OpenCV_DIR "/usr/local/lib") - * SET(Tesseract_DIR "/usr/local/src/openalpr/tesseract-ocr") - * cmake ./ - * make - -Note: For Tesseract 3.04 the source files can be downloaded from the main svn branch or https://drive.google.com/folderview?id=0B7l10Bj_LprhQnpSRkpGMGV2eE0&usp=sharing#list. - - -Mac OS X -========= - -Instructions for compiling on OS X, tested on OS X 10.9.5 (Mavericks). - -Using Homebrew ---------------- - - * brew tap homebrew/science - * brew install openalpr - -Compiling OpenALPR Manually ----------------------------- - -.. code-block:: bash - - # Clone the latest code from GitHub - git clone https://github.com/openalpr/openalpr.git - - # Setup the build directory - cd openalpr/src - mkdir build - cd build - - # setup the compile environment - cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr -DCMAKE_INSTALL_SYSCONFDIR:PATH=/etc .. - - # compile the library - make - - # Install the binaries/libraries to your local system (prefix is /usr) - sudo make install - - # Test the library - wget http://easy-clan.com/ski/pics/license_plate.JPG -O lp.jpg - alpr lp.jpg - -Mobile (iOS and Android) -============================== - -The OpenALPR library compiles on Android and iOS. Example reference apps are available: - - - `Android `_ - - `iOS `_ - -Docker -============= - -OpenALPR supports containerization inside Docker. It uses Ubuntu 14.04 as a base image, and installs all the software using pre-compiled binaries. Download the OpenALPR DockerFile and run the following commands to build it: - -.. code-block:: bash - - # Build docker image - docker build -t openalpr https://github.com/openalpr/openalpr.git - - # Download test image - wget http://plates.openalpr.com/h786poj.jpg - - # Run alpr on image - docker run -it --rm -v $(pwd):/data:ro openalpr -c eu h786poj.jpg \ No newline at end of file diff --git a/doc/source/conf.py b/doc/source/conf.py deleted file mode 100755 index 6b8dd681..00000000 --- a/doc/source/conf.py +++ /dev/null @@ -1,291 +0,0 @@ -# -*- coding: utf-8 -*- -# -# openalpr documentation build configuration file, created by -# sphinx-quickstart on Sun Nov 15 23:25:01 2015. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import sys -import os -import shlex - - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) - -# -- General configuration ------------------------------------------------ - -# If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [] - - - - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# source_suffix = ['.rst', '.md'] -source_suffix = '.rst' - -# The encoding of source files. -#source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'openalpr' -copyright = u'2015, OpenALPR Technology, Inc.' -author = u'Matthew Hill' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = '2.2.0' -# The full version, including alpha/beta/rc tags. -release = '2.2.0' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = [] - -# The reST default role (used for this markup: `text`) to use for all -# documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - -# If true, keep warnings as "system message" paragraphs in the built documents. -#keep_warnings = False - -# If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = False - - -# -- Options for HTML output ---------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -html_theme = 'sphinx_rtd_theme' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -#html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -#html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# Add any extra paths that contain custom files (such as robots.txt or -# .htaccess) here, relative to this directory. These files are copied -# directly to the root of the documentation. -#html_extra_path = [] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_domain_indices = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None - -# Language to be used for generating the HTML full-text search index. -# Sphinx supports the following languages: -# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' -# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' -#html_search_language = 'en' - -# A dictionary with options for the search language support, empty by default. -# Now only 'ja' uses this config value -#html_search_options = {'type': 'default'} - -# The name of a javascript file (relative to the configuration directory) that -# implements a search results scorer. If empty, the default will be used. -#html_search_scorer = 'scorer.js' - -# Output file base name for HTML help builder. -htmlhelp_basename = 'openalprdoc' - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', - -# Latex figure (float) alignment -#'figure_align': 'htbp', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - (master_doc, 'openalpr.tex', u'openalpr Documentation', - u'Matthew Hill', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# If true, show page references after internal links. -#latex_show_pagerefs = False - -# If true, show URL addresses after external links. -#latex_show_urls = False - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_domain_indices = True - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'openalpr', u'openalpr Documentation', - [author], 1) -] - -# If true, show URL addresses after external links. -#man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - (master_doc, 'openalpr', u'openalpr Documentation', - author, 'openalpr', 'One line description of project.', - 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -#texinfo_appendices = [] - -# If false, no module index is generated. -#texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' - -# If true, do not generate a @detailmenu in the "Top" node's menu. -#texinfo_no_detailmenu = False - - - diff --git a/doc/source/index.rst b/doc/source/index.rst deleted file mode 100755 index f54683f8..00000000 --- a/doc/source/index.rst +++ /dev/null @@ -1,46 +0,0 @@ -.. openalpr documentation master file, created by - sphinx-quickstart on Sun Nov 15 23:25:01 2015. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -OpenALPR Documentation -==================================== - -Getting Started ------------------- - -OpenALPR is an open source Automatic License Plate Recognition library written in C++ with bindings in C#, Java, Node.js, and Python. The library analyzes images and video streams to identify license plates. The output is the text representation of any license plate characters. - -The software can be used in many different ways. For example, with OpenALPR you can: - - #. Recognize license plates from camera streams. The results are :ref:`browsable, searchable and can trigger alerts `. The data repository can be in the cloud or stored entirely within your network on-premises. `*` - #. Recognize license plates from camera streams and :ref:`send the results to your own application `. - #. :ref:`Process a video file ` and store the license plate results in a CSV and SQLite database. `*` - #. Analyze still images from the :ref:`command-line ` - #. Integrate license plate recognition into your application :ref:`directly in-code (C/C++, C#, VB.NET, Java, Python, Node.js) ` - #. Run OpenALPR as a :ref:`web service `. A JPG image is sent over HTTP POST, the OpenALPR web service responds with the license plate information in the image. `*` - -`*` Requires :ref:`OpenALPR Commercial License ` - -Contents: - -.. toctree:: - :maxdepth: 2 - - compiling - commandline - bindings - alprd - web_server - video_processing - accuracy_improvements - commercial - - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - diff --git a/doc/source/video_processing.rst b/doc/source/video_processing.rst deleted file mode 100644 index e2821edf..00000000 --- a/doc/source/video_processing.rst +++ /dev/null @@ -1,126 +0,0 @@ - -.. _video_processing: - -****************** -Video Processing -****************** - -`*` Requires Commercial License - -The video processing is available as both a C/C++ embeddable library as well as a command-line utility. The utility is given a video file (e.g., MPG, AVI, MP4, etc.) and processes it to find all of the license plates in the video. The output is a CSV file that lists the license plate information - -Command-Line Usage ---------------------- - -The alpr_video command line utility can be executed to analyze video. You will launch the program with a path to a video file. Also include an output directory, this is where the csv and SQLite files are saved. The threads option provides more threads to process the video simmultaneously (this should not exceed the number of CPU cores on the machine). - -.. code-block:: bash - - USAGE: - - ./alpr_video --output_dir [-c ] [--config - ] [-n ] [--threads ] [-p - ] [--save_frames] [--debug] [--motion] [--] - [--version] [-h] - - - - Where: - - --output_dir - (required) Path to the output directory - - -c , --country - Country code to identify (either us for USA or eu for Europe). - Default=us - - --config - Path to the openalpr.conf file - - -n , --topn - Max number of possible plate numbers to return. Default=10 - - --threads - Number of simmultaneous processing threads. Default=1 - - -p , --pattern - Attempt to match the plate number against a plate pattern (e.g., md - for Maryland, ca for California) - - --save_frames - Save the image frames for recognized license plates. Default=off - - --debug - Print diagnostic information to the console. Default=off - - --motion - Use motion detection on video file or stream. Default=on - - --, --ignore_rest - Ignores the rest of the labeled arguments following this flag. - - --version - Displays version information and exits. - - -h, --help - Displays usage information and exits. - - - (required) Video file containing license plates - - - OpenAlpr Video Processing Utility - - - -Library Usage --------------------- - -The library can be executed directly in C/C++. Include the alprvideo.h file, and link the openalprvideo.dll (or libopenalprvideo.so in Unix). The following example will analyze the "license_plate_video.mp4" file. - -.. code-block:: c++ - - #include "alprvideo.h" - - using namespace alpr; - - int main(int argc, char** argv) { - AlprVideo alpr_video("c:\\temp\\license_plate_video.mp4", "us", "c:\\temp\\openalpr.conf"); - - alpr_video.setOutputDir("C:\\temp\\lpdata\\"); - alpr_video.setNumThreads(2); - alpr_video.setPatternMatch("md"); - alpr_video.setSaveFrames(false); - - // Video processing can either run in the foreground or background. For background, use start_async() - alpr_video.start(); - - std::cout << "Video processing complete" << std::endl; - } - - -Results ---------- - -The results are made available in CSV files as well as a SQLite database for querying. The image frames where license plates were found are also optionally saved to a folder on the disk. - -The CSV data is exported in two files. One file shows the individual plate reads, and the other shows the plate groups. For example: - -Plate Results: - -.. csv-table:: Plate Results - - id,group_id,country,plate_number,confidence,frame_num,video_time_s,matches_pattern,tracking_hash,x1,y1,x2,y2,x3,y3,x4,y4,img_name,region,region_confidence - 1,2,gb,CV60UWK,78.4882,70,2.84,1,,36,235,176,280,169,314,29,267,,gb,0 - 2,2,gb,CV60UWK,75.4025,73,2.96,1,,134,180,269,220,260,251,127,209,,gb,0 - 3,2,gb,CV60UWK,83.4606,74,3,1,,167,159,310,199,300,238,159,196,,gb,0 - 4,2,gb,CV60UWK,82.3763,75,3.04,1,,198,141,332,180,322,215,189,177,,gb,0 - -Plate Groups: - -.. csv-table:: Plate Groups - - id,country,plate_number,matches_pattern,plate_count,frame_start,frame_end,video_time_start_s,video_time_end_s,best_plate_id,confidence,region,region_confidence - 2,gb,CV60UK,0,6,70,77,2.84,3.12,6,82.6058,gb,0 - 1,gb,GP0VZC,0,9,199,211,8,8.48,18,84.4312,gb,0 - 4,gb,GR15RYT,1,2,981,994,39.28,39.8,39,82.4912,gb,0 \ No newline at end of file diff --git a/doc/source/web_server.rst b/doc/source/web_server.rst deleted file mode 100644 index 69678027..00000000 --- a/doc/source/web_server.rst +++ /dev/null @@ -1,164 +0,0 @@ -.. _web_server: - -*********************** -OpenALPR Web Server -*********************** - -`*` Requires Commercial License - -Requirements -================ - -OpenALPR monitors video streams in real-time to gather all license plates seen by your cameras. This data is browsable, searchable, and can trigger alerts. The Web server is available either: - - #. In the cloud - #. Installed On-Premises within your network - -If you haven't seen the `live demo `_, check it out! It shows a realistic example of the type of information you will soon be collecting from your cameras. - -In order to get started, you will need: - - 1. An IP camera capable of serving MJPEG or H264 video - 2. A computer (Intel i5 or better) with network access to the IP camera. This will be your OpenALPR Agent. - -First, configure your IP camera to capture the area that you wish to monitor. The camera must be capable of capturing a clear image of the license plate in order for OpenALPR to properly identify the numbers. You may want to experiment with different angles, optical zoom levels, and resolutions to get the best image quality. A straight-on shot of the license plate is best, but that is usually not possible, so OpenALPR can work with shots at an angle. Try to angle the camera so that the plate is clearly visible, and the vehicle is seen for as long as possible. - -Once your camera is setup, make sure that it has an IP address and that you can connect to the MJPEG or H264 stream. A useful, free utility for testing the video URL is `VLC Media Player `_. You can test your video URL by selecting File -> Open Media Stream. Type in the MJPEG or H264 stream URL and you should be able to clearly see your video. - -Some cameras support arguments in the URL to control resolution, frame-rate, etc. You may reduce the frames per second (fps) of the video feed in order to reduce the stream bandwidth. Fifteen frames per second is usually more than sufficient to capture passing vehicles from a fixed-camera. The resolution also should not be too high. A resolution of 720p is generally sufficient for capturing license plates as long as the plate characters are legible. Higher resolution often results in longer processing time without a gain in accuracy. - -Architecture -============= - -The OpenALPR agent reads a video stream from your IP camera, processes it, and uploads plate metadata to the OpenALPR web server. The agent also stores all of the plate images in a rolling buffer on the hard drive. - -There is a constant stream of data flowing between the camera and the agent as well as between the agent and the web server. The data sent to the cloud is relatively low-bandwidth because it contains text metadata describing the license plates. The OpenALPR Web Server does not store your plate images, these are downloaded directly from the agent when you select a plate to view from the web server. - -OpenALPR Agent -=============================== - -The OpenALPR Agent is a service that runs as a background task on your PC. The agent analyzes video streams from one or more IP cameras and finds the license plates for the vehicles that pass by the camera. We recommend a dedicated PC for the agent due to the amount of CPU used during processing; however, it can be installed on any machine. The plate numbers may be kept completely within your network (on the On-Premise web server), or sent to the OpenALPR Cloud. - - * If you wish to use the OpenALPR Cloud to store your data, first `sign-up for an account `_. - * If you wish to use the On-Premises web server, request an evaluation key from `info@openalpr.com `_ and install the Web Server using the Linux Installer instructions below. - -Windows Installer ------------------- - - 1. Download the `OpenALPR Windows Installer `_ - 2. Install the program onto your PC - 3. Start the "Configure OpenALPR" program after the install completes - 4. Depending on how you wish to use the OpenALPR agent, you may choose one of four radio buttons - - .. image:: images/agent-windows-config.png - :scale: 100% - :alt: Windows Agent Configuration - - - a. **OpenALPR Cloud** - Type in the E-mail address and password that you used to sign-up for the OpenALPR Cloud Service - b. **OpenALPR On-Premises Web Server** -- Type in the URL of the on-premises web server and the e-mail address / password of the master account - c. **Generic HTTP URL** -- Used for :ref:`Integrating other applications with the OpenALPR Agent `. - d. **Local Queue** -- Another method for :ref:`Integrating other applications with the OpenALPR Agent `. - - You have now successfully connected the OpenALPR Agent with the OpenALPR web server. All configuration / management is performed centrally on the OpenALPR web server. The next step is to :ref:`configure the agent and add video streams to monitor ` - - -Linux Installer ----------------------- - -Download the Ubuntu 16.04 64-bit install DVD image and burn to a DVD: - - - http://releases.ubuntu.com/16.04/ubuntu-16.04.1-desktop-amd64.iso - -Follow this installation guide to install Ubuntu 16.04 64-bit: - - - http://www.ubuntu.com/download/desktop/install-ubuntu-desktop - -Run the following command from the terminal: - -.. code-block:: bash - - bash <(curl http://deb.openalpr.com/install) - - -.. image:: images/linux-install.png - :scale: 100% - :alt: OpenALPR VM installation step 4 - -- Choose one of the following: - - - To connect the agent to the OpenALPR Cloud, just choose "install agent". - - To host the data on your own web server (On-Premises configuration) choose "install webserver" - - -.. _agent_configuration: - -Configuration -=============================== - -- Login to the OpenALPR Web Server. - -- Select Configuration -> Agents from the menu on the left-hand side of the page - -- You should see your new agent on this screen. Select "Configure" to setup the camera. - -- Select **Add Stream** to connect your agent to the camera stream. - -.. image:: images/webserver_vminstall5.png - :scale: 100% - :alt: OpenALPR VM installation step 4 - -- Select the model of IP camera you wish to connect to. Fill in the IP address. If the camera requires credentials, check the box and enter your camera's username and password. -- Click **Test**. After a few seconds, you will see a window indicating whether the connection was successful or not. If it was successful, click **Save Camera**. Otherwise, try another option (such as H264 Alt1 or MJPEG) and click **Test** again until you succeed. - -.. image:: images/webserver_vminstall-testsuccess.png - :scale: 100% - :alt: OpenALPR VM installation step 4 - -- Next, configure the **Agent Parameters**. - - - Choose a sensible name for your **Site ID**. This is usually the location of the agent system (e.g., headquarters, dallas-branch, warehouse3, etc.). Each agent should be given a unique Site ID. - - Choose the **country** where the camera is located. US will recognize North American-style plates (12 inches x 6 inches). EU will recognize European-style plates. There is also support for other countries that have plates with different dimensions. - - The number of **Processing Cores** controls how much CPU is allocated to the LPR process. The more processing cores you provide (up to the number of CPU cores on the system) the more frames per second (fps) you can process. Higher fps generally contributes to better accuracy and capability to detect plates on faster moving vehicles. - - **Disk Quota** controls how much space is reserved for storing vehicle and license plate images. It operates as a rolling buffer, so once it runs out of space, the oldest images are removed. - - **Pattern** should be country (in Europe) that the camera is located in. In the US, OpenALPR uses a high-accuracy state detection algorithm to detect the state of origin, so it is better to leave the pattern set to "None" for recognition in the USA. - -- Click **Update**. - -.. image:: images/webserver_vminstall6.png - :scale: 100% - :alt: OpenALPR VM installation step 4 - -- Lastly, if you scroll to the bottom of the page you can watch the agent status. You should now see **Video FPS** and other information indicating that video is being pulled from the camera and license plates are being recognized. Now that the agent is configured, it will continue collecting data from the configured video streams. If the agent is rebooted, the OpenALPR agent will automatically start. If the camera goes down and comes back, or the network is down temporarily, the agent will retry until connectivity is restored. All results are queued, so no data is lost in the event of an outage. - -.. image:: images/webserver_vminstall7.png - :scale: 100% - :alt: OpenALPR VM installation step 4 - - -Advanced Configuration ---------------------------------------- - -The OpenALPR Agent can also be configured manually by modifying the file in /etc/openalpr/alprd.conf. This is an advanced option, and may be useful when managing dozens/hundreds of agents. The default values with description is found here: /usr/share/openalpr/config/alprd.defaults.conf. You may add any value into the alprd.conf file and restart the agent for the changes to be picked up. - -Additional documentation on these configuration options is located in the :ref:`commercial_config_options`. - -To restart services, run the command: - -.. code-block:: bash - - sudo service openalpr-daemon restart - -To watch the OpenALPR logs, run the following command: - - tail -f /var/log/alpr.log - - - - -.. _web_services_api: - -Web Services -==================== - -The `Web Services API `_ can be used to programmatically query your On-Premises server for data. The API is documented `here `_ \ No newline at end of file diff --git a/doc/source/web_server_api.yaml b/doc/source/web_server_api.yaml deleted file mode 100644 index 24261293..00000000 --- a/doc/source/web_server_api.yaml +++ /dev/null @@ -1,421 +0,0 @@ ---- -swagger: '2.0' - -info: - title: OpenALPR REST API - version: v1.0 - description: | - The OpenALPR REST API allows you to search license plate data programmatically from the - OpenALPR Web server. Using this API you can search for license plate groups, individual - reads, and alerts. You can also retrieve the plate images from the agent. - -tags: - - - name: webserver - description: REST API for the Web Server and plate metadata - - - name: agent - description: REST API for the agent and image data - -paths: - /api/search/group: - get: - tags: - - webserver - description: Search for ALPR group results - parameters: - - description: Company UUID used for authentication - in: query - name: company_id - required: true - type: string - - description: unique ID for the site - in: query - name: site - required: false - type: string - - description: unique camera number - in: query - name: camera - required: false - type: number - - description: Start time in ISO 8601 format. At least start or end must be defined. - in: query - name: start - required: false - type: string - - description: End time in ISO 8601 format. At least start or end must be defined. - in: query - name: end - required: false - type: string - - description: Plate Number to search for - in: query - name: plate - required: false - type: string - - description: Search plate using regular expression. Disabled (0) or Enabled (1) - in: query - name: wildcard - required: false - type: number - - description: Maximum number of results to return - in: query - name: topn - required: false - type: number - - description: Order can be either desc or asc - in: query - name: order - required: false - type: string - responses: - '200': - description: OK - schema: - type: array - items: - $ref: '#/definitions/group' - '400': - description: "Bad input provided. Adjust the query parameters and try again.\nThe text accompanying the error will provide more detail about which query \nparameters are incorrect.\n" - '401': - description: "Unauthorized. You must either provide a valid company_id or \nhave a logged in session\n" - /api/search/plate: - get: - tags: - - webserver - description: Search for individual plate results - parameters: - - description: Company UUID used for authentication - in: query - name: company_id - required: true - type: string - - description: unique ID for the site - in: query - name: site - required: false - type: string - - description: unique camera number - in: query - name: camera - required: false - type: number - - description: Start time in ISO 8601 format. At least start or end must be defined. - in: query - name: start - required: false - type: string - - description: End time in ISO 8601 format. At least start or end must be defined. - in: query - name: end - required: false - type: string - - description: Plate Number to search for - in: query - name: plate - required: false - type: string - - description: Search plate using regular expression. Disabled (0) or Enabled (1) - in: query - name: wildcard - required: false - type: number - - description: Maximum number of results to return - in: query - name: topn - required: false - type: number - - description: Order can be either desc or asc - in: query - name: order - required: false - type: string - responses: - '200': - description: OK - schema: - type: array - items: - $ref: '#/definitions/plate' - '400': - description: "Bad input provided. Adjust the query parameters and try again.\nThe text accompanying the error will provide more detail about which query \nparameters are incorrect.\n" - '401': - description: "Unauthorized. You must either provide a valid company_id or \nhave a logged in session\n" - '/api/detail/group/{group_id}': - get: - tags: - - webserver - description: Get detailed results for a group record - parameters: - - in: path - name: group_id - required: true - type: string - - description: Company UUID used for authentication - in: query - name: company_id - required: true - type: string - responses: - '200': - description: OK - schema: - $ref: '#/definitions/group_detail' - - '401': - description: "Unauthorized. You must either provide a valid company_id or \nhave a logged in session\n" - '404': - description: | - The requested ID was not found - '/api/detail/plate/{plate_id}': - get: - tags: - - webserver - description: Get detailed results for a plate record - parameters: - - in: path - name: plate_id - required: true - type: string - - description: Company UUID used for authentication - in: query - name: company_id - required: true - type: string - responses: - '200': - description: OK - schema: - $ref: '#/definitions/plate_detail' - '401': - description: "Unauthorized. You must either provide a valid company_id or \nhave a logged in session\n" - '404': - description: | - The requested ID was not found - '/img/{uuid}.jpg': - get: - tags: - - agent - description: Get an image for the requested plate. This web service is served on port 8355. - parameters: - - in: path - name: uuid - required: true - type: string - produces: - - image/jpeg - responses: - '200': - description: OK - schema: - type: array - items: - $ref: '#/definitions/plate' - '404': - description: not found -securityDefinitions: {} -swagger: '2.0' - -definitions: - plate: - type: object - properties: - pk: - type: integer - description: "Unique integer ID for this plate" - model: - type: string - description: "Name of the data type" - fields: - type: object - properties: - best_confidence: - type: number - description: "Percent confidence of the license plate result" - best_plate: - type: string - description: "The plate number with the highest confidence" - uuid: - type: string - description: "Unique identifier for the image where the license plate was found" - epoch_time: - type: string - description: "Time that the plate was seen in ISO-8601 format" - camera: - type: integer - description: "Unique ID of the camera" - company: - type: integer - description: "Company ID" - site: - type: string - description: "Site ID where the plate was captured" - plate_index: - type: integer - description: "Within a single image (UUID) there may be multiple plates. This is the unique ID of the single plate within an image" - img_width: - type: integer - description: "Image width in pixels" - img_height: - type: integer - description: "Image height in pixels" - processing_time_ms: - type: number - description: "Time in milliseconds taken to identify the license plate from an image" - x1: - type: integer - description: "Pixel coordinates for the license plate. x1,y1 -> x4,y4 forms a polygon starting from the top-left and working clockwise to the bottom-left corners." - y1: - type: integer - x2: - type: integer - y2: - type: integer - x3: - type: integer - y3: - type: integer - x4: - type: integer - y4: - type: integer - - group: - type: object - properties: - pk: - type: integer - description: "Unique integer ID for this plate" - model: - type: string - description: "Name of the data type" - fields: - type: object - properties: - best_confidence: - type: number - description: "Percent confidence of the license plate result" - best_plate: - type: string - description: "The plate number with the highest confidence" - best_index: - type: integer - description: "Within a single image (UUID) there may be multiple plates. This is the unique ID of the single plate within an image" - best_uuid: - type: string - description: "Unique identifier for the image where the highest confidence license plate was found" - epoch_time_start: - type: string - description: "Time that the plate was initially seen in ISO-8601 format" - epoch_time_end: - type: string - description: "Time that the plate was last seen in ISO-8601 format" - camera: - type: integer - description: "Unique ID of the camera" - company: - type: integer - description: "Company ID" - site: - type: string - description: "Site ID where the plate was captured" - - plate_detail: - type: object - properties: - best_confidence: - type: number - description: "Percent confidence of the license plate result" - best_plate: - type: string - description: "The plate number with the highest confidence" - uuid: - type: string - description: "Unique identifier for the image where the license plate was found" - epoch_time: - type: string - description: "Time that the plate was seen in ISO-8601 format" - camera: - $ref: '#/definitions/camera_info' - regions_of_interest: - type: object - description: "Areas that were analyzed. Typically wherever motion is found" - properties: - x: { type: integer } - y: { type: integer } - width: { type: integer } - height: { type: integer } - candidates: - type: array - items: - type: object - properties: - plate_number: { type: string } - confidence: { type: number } - coordinates: - type: array - items: - type: object - properties: - x: { type: integer } - y: { type: integer } - site: - type: string - description: "Site ID where the plate was captured" - plate_index: - type: integer - description: "Within a single image (UUID) there may be multiple plates. This is the unique ID of the single plate within an image" - img_width: - type: integer - description: "Image width in pixels" - img_height: - type: integer - description: "Image height in pixels" - processing_time_ms: - type: number - description: "Time in milliseconds taken to identify the license plate from an image" - - group_detail: - type: object - properties: - id: - type: integer - description: "Unique ID for the group" - camera: - $ref: '#/definitions/camera_info' - site: - type: string - description: "Site ID where the plate was captured" - epoch_time_start: - type: string - description: "Time that the plate was initially seen in ISO-8601 format" - epoch_time_end: - type: string - description: "Time that the plate was last seen in ISO-8601 format" - best_confidence: - type: number - description: "Percent confidence of the license plate result" - best_plate: - type: string - description: "The plate number with the highest confidence" - best_index: - type: integer - description: "Within a single image (UUID) there may be multiple plates. This is the unique ID of the single plate within an image" - best_uuid: - type: string - description: "Unique identifier for the image where the highest confidence license plate was found" - uuids: - type: array - items: - type: string - - camera_info: - type: object - properties: - camera_number: - type: integer - description: "Unique ID of the camera" - camera_name: - type: string - description: "Friendly name of the camera" \ No newline at end of file diff --git a/doc/watch_for_changes.sh b/doc/watch_for_changes.sh deleted file mode 100755 index c4613076..00000000 --- a/doc/watch_for_changes.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - - -find source/ | entr ./generate