From 1690f4474a6b79364848582a483af0d75d98e5c8 Mon Sep 17 00:00:00 2001 From: Anton Bagrianov Date: Thu, 16 Nov 2023 01:08:22 +0400 Subject: [PATCH 1/7] Update .gitignore --- .gitignore | 153 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 152 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 95a9ddc..933ec8b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,152 @@ -.pylintrc \ No newline at end of file +.idea/ + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class +*.code-workspace +tests/data/* +temp/* + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ +contrib/vault/file/ +/contrib/vault/keys/*.json +.local.env + +# archives +*.zip +*.gz +*.tar +*.bz2 +*.tgz +.DS_Store \ No newline at end of file From df3e08b47ab10f2d0a8665f141d849e74c81e929 Mon Sep 17 00:00:00 2001 From: Anton Bagrianov Date: Thu, 16 Nov 2023 01:08:37 +0400 Subject: [PATCH 2/7] Add Poetry --- poetry.lock | 661 +++++++++++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 22 ++ 2 files changed, 683 insertions(+) create mode 100644 poetry.lock create mode 100644 pyproject.toml diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..726f419 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,661 @@ +# This file is automatically @generated by Poetry 1.7.0 and should not be changed by hand. + +[[package]] +name = "appnope" +version = "0.1.3" +description = "Disable App Nap on macOS >= 10.9" +optional = false +python-versions = "*" +files = [ + {file = "appnope-0.1.3-py2.py3-none-any.whl", hash = "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e"}, + {file = "appnope-0.1.3.tar.gz", hash = "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24"}, +] + +[[package]] +name = "asttokens" +version = "2.4.1" +description = "Annotate AST trees with source code positions" +optional = false +python-versions = "*" +files = [ + {file = "asttokens-2.4.1-py2.py3-none-any.whl", hash = "sha256:051ed49c3dcae8913ea7cd08e46a606dba30b79993209636c4875bc1d637bc24"}, + {file = "asttokens-2.4.1.tar.gz", hash = "sha256:b03869718ba9a6eb027e134bfdf69f38a236d681c83c160d510768af11254ba0"}, +] + +[package.dependencies] +six = ">=1.12.0" + +[package.extras] +astroid = ["astroid (>=1,<2)", "astroid (>=2,<4)"] +test = ["astroid (>=1,<2)", "astroid (>=2,<4)", "pytest"] + +[[package]] +name = "backcall" +version = "0.2.0" +description = "Specifications for callback functions passed in to an API" +optional = false +python-versions = "*" +files = [ + {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, + {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, +] + +[[package]] +name = "black" +version = "23.11.0" +description = "The uncompromising code formatter." +optional = false +python-versions = ">=3.8" +files = [ + {file = "black-23.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dbea0bb8575c6b6303cc65017b46351dc5953eea5c0a59d7b7e3a2d2f433a911"}, + {file = "black-23.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:412f56bab20ac85927f3a959230331de5614aecda1ede14b373083f62ec24e6f"}, + {file = "black-23.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d136ef5b418c81660ad847efe0e55c58c8208b77a57a28a503a5f345ccf01394"}, + {file = "black-23.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:6c1cac07e64433f646a9a838cdc00c9768b3c362805afc3fce341af0e6a9ae9f"}, + {file = "black-23.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cf57719e581cfd48c4efe28543fea3d139c6b6f1238b3f0102a9c73992cbb479"}, + {file = "black-23.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:698c1e0d5c43354ec5d6f4d914d0d553a9ada56c85415700b81dc90125aac244"}, + {file = "black-23.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:760415ccc20f9e8747084169110ef75d545f3b0932ee21368f63ac0fee86b221"}, + {file = "black-23.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:58e5f4d08a205b11800332920e285bd25e1a75c54953e05502052738fe16b3b5"}, + {file = "black-23.11.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:45aa1d4675964946e53ab81aeec7a37613c1cb71647b5394779e6efb79d6d187"}, + {file = "black-23.11.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4c44b7211a3a0570cc097e81135faa5f261264f4dfaa22bd5ee2875a4e773bd6"}, + {file = "black-23.11.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a9acad1451632021ee0d146c8765782a0c3846e0e0ea46659d7c4f89d9b212b"}, + {file = "black-23.11.0-cp38-cp38-win_amd64.whl", hash = "sha256:fc7f6a44d52747e65a02558e1d807c82df1d66ffa80a601862040a43ec2e3142"}, + {file = "black-23.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7f622b6822f02bfaf2a5cd31fdb7cd86fcf33dab6ced5185c35f5db98260b055"}, + {file = "black-23.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:250d7e60f323fcfc8ea6c800d5eba12f7967400eb6c2d21ae85ad31c204fb1f4"}, + {file = "black-23.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5133f5507007ba08d8b7b263c7aa0f931af5ba88a29beacc4b2dc23fcefe9c06"}, + {file = "black-23.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:421f3e44aa67138ab1b9bfbc22ee3780b22fa5b291e4db8ab7eee95200726b07"}, + {file = "black-23.11.0-py3-none-any.whl", hash = "sha256:54caaa703227c6e0c87b76326d0862184729a69b73d3b7305b6288e1d830067e"}, + {file = "black-23.11.0.tar.gz", hash = "sha256:4c68855825ff432d197229846f971bc4d6666ce90492e5b02013bcaca4d9ab05"}, +] + +[package.dependencies] +click = ">=8.0.0" +ipython = {version = ">=7.8.0", optional = true, markers = "extra == \"jupyter\""} +mypy-extensions = ">=0.4.3" +packaging = ">=22.0" +pathspec = ">=0.9.0" +platformdirs = ">=2" +tokenize-rt = {version = ">=3.2.0", optional = true, markers = "extra == \"jupyter\""} +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} + +[package.extras] +colorama = ["colorama (>=0.4.3)"] +d = ["aiohttp (>=3.7.4)"] +jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] +uvloop = ["uvloop (>=0.15.2)"] + +[[package]] +name = "caer" +version = "2.0.8" +description = "A lightweight Computer Vision library for high-performance AI research - Modern Computer Vision on the Fly." +optional = false +python-versions = ">=3.6" +files = [ + {file = "caer-2.0.8-py3-none-any.whl", hash = "sha256:18eef7a6b4cfe203a3fe46b4fcb51abac58fd03cffb1b49c046a768b3437a00c"}, + {file = "caer-2.0.8.tar.gz", hash = "sha256:c5da1019ce15658d53f1787c637fa80b766b09656291c128e6f7cdb0598aef69"}, +] + +[package.dependencies] +mypy = "*" +numpy = "*" +opencv-contrib-python = "*" +typing-extensions = "*" + +[[package]] +name = "click" +version = "8.1.7" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "decorator" +version = "5.1.1" +description = "Decorators for Humans" +optional = false +python-versions = ">=3.5" +files = [ + {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, + {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, +] + +[[package]] +name = "executing" +version = "2.0.1" +description = "Get the currently executing AST node of a frame, and other information" +optional = false +python-versions = ">=3.5" +files = [ + {file = "executing-2.0.1-py2.py3-none-any.whl", hash = "sha256:eac49ca94516ccc753f9fb5ce82603156e590b27525a8bc32cce8ae302eb61bc"}, + {file = "executing-2.0.1.tar.gz", hash = "sha256:35afe2ce3affba8ee97f2d69927fa823b08b472b7b994e36a52a964b93d16147"}, +] + +[package.extras] +tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"] + +[[package]] +name = "flake8" +version = "6.1.0" +description = "the modular source code checker: pep8 pyflakes and co" +optional = false +python-versions = ">=3.8.1" +files = [ + {file = "flake8-6.1.0-py2.py3-none-any.whl", hash = "sha256:ffdfce58ea94c6580c77888a86506937f9a1a227dfcd15f245d694ae20a6b6e5"}, + {file = "flake8-6.1.0.tar.gz", hash = "sha256:d5b3857f07c030bdb5bf41c7f53799571d75c4491748a3adcd47de929e34cd23"}, +] + +[package.dependencies] +mccabe = ">=0.7.0,<0.8.0" +pycodestyle = ">=2.11.0,<2.12.0" +pyflakes = ">=3.1.0,<3.2.0" + +[[package]] +name = "ipython" +version = "8.12.3" +description = "IPython: Productive Interactive Computing" +optional = false +python-versions = ">=3.8" +files = [ + {file = "ipython-8.12.3-py3-none-any.whl", hash = "sha256:b0340d46a933d27c657b211a329d0be23793c36595acf9e6ef4164bc01a1804c"}, + {file = "ipython-8.12.3.tar.gz", hash = "sha256:3910c4b54543c2ad73d06579aa771041b7d5707b033bd488669b4cf544e3b363"}, +] + +[package.dependencies] +appnope = {version = "*", markers = "sys_platform == \"darwin\""} +backcall = "*" +colorama = {version = "*", markers = "sys_platform == \"win32\""} +decorator = "*" +jedi = ">=0.16" +matplotlib-inline = "*" +pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} +pickleshare = "*" +prompt-toolkit = ">=3.0.30,<3.0.37 || >3.0.37,<3.1.0" +pygments = ">=2.4.0" +stack-data = "*" +traitlets = ">=5" +typing-extensions = {version = "*", markers = "python_version < \"3.10\""} + +[package.extras] +all = ["black", "curio", "docrepr", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.21)", "pandas", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] +black = ["black"] +doc = ["docrepr", "ipykernel", "matplotlib", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] +kernel = ["ipykernel"] +nbconvert = ["nbconvert"] +nbformat = ["nbformat"] +notebook = ["ipywidgets", "notebook"] +parallel = ["ipyparallel"] +qtconsole = ["qtconsole"] +test = ["pytest (<7.1)", "pytest-asyncio", "testpath"] +test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.21)", "pandas", "pytest (<7.1)", "pytest-asyncio", "testpath", "trio"] + +[[package]] +name = "isort" +version = "5.12.0" +description = "A Python utility / library to sort Python imports." +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"}, + {file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"}, +] + +[package.extras] +colors = ["colorama (>=0.4.3)"] +pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"] +plugins = ["setuptools"] +requirements-deprecated-finder = ["pip-api", "pipreqs"] + +[[package]] +name = "jedi" +version = "0.19.1" +description = "An autocompletion tool for Python that can be used for text editors." +optional = false +python-versions = ">=3.6" +files = [ + {file = "jedi-0.19.1-py2.py3-none-any.whl", hash = "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0"}, + {file = "jedi-0.19.1.tar.gz", hash = "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd"}, +] + +[package.dependencies] +parso = ">=0.8.3,<0.9.0" + +[package.extras] +docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"] +qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] +testing = ["Django", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] + +[[package]] +name = "matplotlib-inline" +version = "0.1.6" +description = "Inline Matplotlib backend for Jupyter" +optional = false +python-versions = ">=3.5" +files = [ + {file = "matplotlib-inline-0.1.6.tar.gz", hash = "sha256:f887e5f10ba98e8d2b150ddcf4702c1e5f8b3a20005eb0f74bfdbd360ee6f304"}, + {file = "matplotlib_inline-0.1.6-py3-none-any.whl", hash = "sha256:f1f41aab5328aa5aaea9b16d083b128102f8712542f819fe7e6a420ff581b311"}, +] + +[package.dependencies] +traitlets = "*" + +[[package]] +name = "mccabe" +version = "0.7.0" +description = "McCabe checker, plugin for flake8" +optional = false +python-versions = ">=3.6" +files = [ + {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, + {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, +] + +[[package]] +name = "mypy" +version = "1.7.0" +description = "Optional static typing for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mypy-1.7.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5da84d7bf257fd8f66b4f759a904fd2c5a765f70d8b52dde62b521972a0a2357"}, + {file = "mypy-1.7.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a3637c03f4025f6405737570d6cbfa4f1400eb3c649317634d273687a09ffc2f"}, + {file = "mypy-1.7.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b633f188fc5ae1b6edca39dae566974d7ef4e9aaaae00bc36efe1f855e5173ac"}, + {file = "mypy-1.7.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d6ed9a3997b90c6f891138e3f83fb8f475c74db4ccaa942a1c7bf99e83a989a1"}, + {file = "mypy-1.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:1fe46e96ae319df21359c8db77e1aecac8e5949da4773c0274c0ef3d8d1268a9"}, + {file = "mypy-1.7.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:df67fbeb666ee8828f675fee724cc2cbd2e4828cc3df56703e02fe6a421b7401"}, + {file = "mypy-1.7.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a79cdc12a02eb526d808a32a934c6fe6df07b05f3573d210e41808020aed8b5d"}, + {file = "mypy-1.7.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f65f385a6f43211effe8c682e8ec3f55d79391f70a201575def73d08db68ead1"}, + {file = "mypy-1.7.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0e81ffd120ee24959b449b647c4b2fbfcf8acf3465e082b8d58fd6c4c2b27e46"}, + {file = "mypy-1.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:f29386804c3577c83d76520abf18cfcd7d68264c7e431c5907d250ab502658ee"}, + {file = "mypy-1.7.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:87c076c174e2c7ef8ab416c4e252d94c08cd4980a10967754f91571070bf5fbe"}, + {file = "mypy-1.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6cb8d5f6d0fcd9e708bb190b224089e45902cacef6f6915481806b0c77f7786d"}, + {file = "mypy-1.7.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d93e76c2256aa50d9c82a88e2f569232e9862c9982095f6d54e13509f01222fc"}, + {file = "mypy-1.7.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cddee95dea7990e2215576fae95f6b78a8c12f4c089d7e4367564704e99118d3"}, + {file = "mypy-1.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:d01921dbd691c4061a3e2ecdbfbfad029410c5c2b1ee88946bf45c62c6c91210"}, + {file = "mypy-1.7.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:185cff9b9a7fec1f9f7d8352dff8a4c713b2e3eea9c6c4b5ff7f0edf46b91e41"}, + {file = "mypy-1.7.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7a7b1e399c47b18feb6f8ad4a3eef3813e28c1e871ea7d4ea5d444b2ac03c418"}, + {file = "mypy-1.7.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc9fe455ad58a20ec68599139ed1113b21f977b536a91b42bef3ffed5cce7391"}, + {file = "mypy-1.7.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d0fa29919d2e720c8dbaf07d5578f93d7b313c3e9954c8ec05b6d83da592e5d9"}, + {file = "mypy-1.7.0-cp38-cp38-win_amd64.whl", hash = "sha256:2b53655a295c1ed1af9e96b462a736bf083adba7b314ae775563e3fb4e6795f5"}, + {file = "mypy-1.7.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c1b06b4b109e342f7dccc9efda965fc3970a604db70f8560ddfdee7ef19afb05"}, + {file = "mypy-1.7.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:bf7a2f0a6907f231d5e41adba1a82d7d88cf1f61a70335889412dec99feeb0f8"}, + {file = "mypy-1.7.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:551d4a0cdcbd1d2cccdcc7cb516bb4ae888794929f5b040bb51aae1846062901"}, + {file = "mypy-1.7.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:55d28d7963bef00c330cb6461db80b0b72afe2f3c4e2963c99517cf06454e665"}, + {file = "mypy-1.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:870bd1ffc8a5862e593185a4c169804f2744112b4a7c55b93eb50f48e7a77010"}, + {file = "mypy-1.7.0-py3-none-any.whl", hash = "sha256:96650d9a4c651bc2a4991cf46f100973f656d69edc7faf91844e87fe627f7e96"}, + {file = "mypy-1.7.0.tar.gz", hash = "sha256:1e280b5697202efa698372d2f39e9a6713a0395a756b1c6bd48995f8d72690dc"}, +] + +[package.dependencies] +mypy-extensions = ">=1.0.0" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typing-extensions = ">=4.1.0" + +[package.extras] +dmypy = ["psutil (>=4.0)"] +install-types = ["pip"] +mypyc = ["setuptools (>=50)"] +reports = ["lxml"] + +[[package]] +name = "mypy-extensions" +version = "1.0.0" +description = "Type system extensions for programs checked with the mypy type checker." +optional = false +python-versions = ">=3.5" +files = [ + {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, + {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, +] + +[[package]] +name = "numpy" +version = "1.24.4" +description = "Fundamental package for array computing in Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "numpy-1.24.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c0bfb52d2169d58c1cdb8cc1f16989101639b34c7d3ce60ed70b19c63eba0b64"}, + {file = "numpy-1.24.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ed094d4f0c177b1b8e7aa9cba7d6ceed51c0e569a5318ac0ca9a090680a6a1b1"}, + {file = "numpy-1.24.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79fc682a374c4a8ed08b331bef9c5f582585d1048fa6d80bc6c35bc384eee9b4"}, + {file = "numpy-1.24.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ffe43c74893dbf38c2b0a1f5428760a1a9c98285553c89e12d70a96a7f3a4d6"}, + {file = "numpy-1.24.4-cp310-cp310-win32.whl", hash = "sha256:4c21decb6ea94057331e111a5bed9a79d335658c27ce2adb580fb4d54f2ad9bc"}, + {file = "numpy-1.24.4-cp310-cp310-win_amd64.whl", hash = "sha256:b4bea75e47d9586d31e892a7401f76e909712a0fd510f58f5337bea9572c571e"}, + {file = "numpy-1.24.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f136bab9c2cfd8da131132c2cf6cc27331dd6fae65f95f69dcd4ae3c3639c810"}, + {file = "numpy-1.24.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e2926dac25b313635e4d6cf4dc4e51c8c0ebfed60b801c799ffc4c32bf3d1254"}, + {file = "numpy-1.24.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:222e40d0e2548690405b0b3c7b21d1169117391c2e82c378467ef9ab4c8f0da7"}, + {file = "numpy-1.24.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7215847ce88a85ce39baf9e89070cb860c98fdddacbaa6c0da3ffb31b3350bd5"}, + {file = "numpy-1.24.4-cp311-cp311-win32.whl", hash = "sha256:4979217d7de511a8d57f4b4b5b2b965f707768440c17cb70fbf254c4b225238d"}, + {file = "numpy-1.24.4-cp311-cp311-win_amd64.whl", hash = "sha256:b7b1fc9864d7d39e28f41d089bfd6353cb5f27ecd9905348c24187a768c79694"}, + {file = "numpy-1.24.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1452241c290f3e2a312c137a9999cdbf63f78864d63c79039bda65ee86943f61"}, + {file = "numpy-1.24.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:04640dab83f7c6c85abf9cd729c5b65f1ebd0ccf9de90b270cd61935eef0197f"}, + {file = "numpy-1.24.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5425b114831d1e77e4b5d812b69d11d962e104095a5b9c3b641a218abcc050e"}, + {file = "numpy-1.24.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd80e219fd4c71fc3699fc1dadac5dcf4fd882bfc6f7ec53d30fa197b8ee22dc"}, + {file = "numpy-1.24.4-cp38-cp38-win32.whl", hash = "sha256:4602244f345453db537be5314d3983dbf5834a9701b7723ec28923e2889e0bb2"}, + {file = "numpy-1.24.4-cp38-cp38-win_amd64.whl", hash = "sha256:692f2e0f55794943c5bfff12b3f56f99af76f902fc47487bdfe97856de51a706"}, + {file = "numpy-1.24.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2541312fbf09977f3b3ad449c4e5f4bb55d0dbf79226d7724211acc905049400"}, + {file = "numpy-1.24.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9667575fb6d13c95f1b36aca12c5ee3356bf001b714fc354eb5465ce1609e62f"}, + {file = "numpy-1.24.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3a86ed21e4f87050382c7bc96571755193c4c1392490744ac73d660e8f564a9"}, + {file = "numpy-1.24.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d11efb4dbecbdf22508d55e48d9c8384db795e1b7b51ea735289ff96613ff74d"}, + {file = "numpy-1.24.4-cp39-cp39-win32.whl", hash = "sha256:6620c0acd41dbcb368610bb2f4d83145674040025e5536954782467100aa8835"}, + {file = "numpy-1.24.4-cp39-cp39-win_amd64.whl", hash = "sha256:befe2bf740fd8373cf56149a5c23a0f601e82869598d41f8e188a0e9869926f8"}, + {file = "numpy-1.24.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:31f13e25b4e304632a4619d0e0777662c2ffea99fcae2029556b17d8ff958aef"}, + {file = "numpy-1.24.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95f7ac6540e95bc440ad77f56e520da5bf877f87dca58bd095288dce8940532a"}, + {file = "numpy-1.24.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:e98f220aa76ca2a977fe435f5b04d7b3470c0a2e6312907b37ba6068f26787f2"}, + {file = "numpy-1.24.4.tar.gz", hash = "sha256:80f5e3a4e498641401868df4208b74581206afbee7cf7b8329daae82676d9463"}, +] + +[[package]] +name = "opencv-contrib-python" +version = "4.8.1.78" +description = "Wrapper package for OpenCV python bindings." +optional = false +python-versions = ">=3.6" +files = [ + {file = "opencv-contrib-python-4.8.1.78.tar.gz", hash = "sha256:81804332299d656905d4f404fcec5f400d692c652d7a47926b7a441272ce795b"}, + {file = "opencv_contrib_python-4.8.1.78-cp37-abi3-macosx_10_16_x86_64.whl", hash = "sha256:8d97192471c7d42532103ecebf8ad9d9534b7cd655ffadbccacb9ff3d4d49b40"}, + {file = "opencv_contrib_python-4.8.1.78-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:8d6feb39d4af2cd1e8919110229bfedd13d4798a089bbe88fbd1a001b664d552"}, + {file = "opencv_contrib_python-4.8.1.78-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6cad1720ac701cb3742f48f95bef5cfa288b916b6ac5700f63d5809e3ad5999e"}, + {file = "opencv_contrib_python-4.8.1.78-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3fb62bc5967a79bce7c576ef94dea0b9172e52bab91630103e042cb5f29a148a"}, + {file = "opencv_contrib_python-4.8.1.78-cp37-abi3-win32.whl", hash = "sha256:f8737cf3055a6156c66c75432ed28ee3c1d52532b17d91ed73d508ae351b3e66"}, + {file = "opencv_contrib_python-4.8.1.78-cp37-abi3-win_amd64.whl", hash = "sha256:377936b02dcf82dc70261101381a8ad82b03d1298f185886be298d74fe35c328"}, +] + +[package.dependencies] +numpy = [ + {version = ">=1.21.0", markers = "python_version <= \"3.9\" and platform_system == \"Darwin\" and platform_machine == \"arm64\" and python_version >= \"3.8\""}, + {version = ">=1.23.5", markers = "python_version >= \"3.11\""}, + {version = ">=1.21.4", markers = "python_version >= \"3.10\" and platform_system == \"Darwin\" and python_version < \"3.11\""}, + {version = ">=1.21.2", markers = "platform_system != \"Darwin\" and python_version >= \"3.10\" and python_version < \"3.11\""}, + {version = ">=1.19.3", markers = "platform_system == \"Linux\" and platform_machine == \"aarch64\" and python_version >= \"3.8\" and python_version < \"3.10\" or python_version > \"3.9\" and python_version < \"3.10\" or python_version >= \"3.9\" and platform_system != \"Darwin\" and python_version < \"3.10\" or python_version >= \"3.9\" and platform_machine != \"arm64\" and python_version < \"3.10\""}, + {version = ">=1.17.3", markers = "(platform_system != \"Darwin\" and platform_system != \"Linux\") and python_version >= \"3.8\" and python_version < \"3.9\" or platform_system != \"Darwin\" and python_version >= \"3.8\" and python_version < \"3.9\" and platform_machine != \"aarch64\" or platform_machine != \"arm64\" and python_version >= \"3.8\" and python_version < \"3.9\" and platform_system != \"Linux\" or (platform_machine != \"arm64\" and platform_machine != \"aarch64\") and python_version >= \"3.8\" and python_version < \"3.9\""}, +] + +[[package]] +name = "opencv-python" +version = "4.8.1.78" +description = "Wrapper package for OpenCV python bindings." +optional = false +python-versions = ">=3.6" +files = [ + {file = "opencv-python-4.8.1.78.tar.gz", hash = "sha256:cc7adbbcd1112877a39274106cb2752e04984bc01a031162952e97450d6117f6"}, + {file = "opencv_python-4.8.1.78-cp37-abi3-macosx_10_16_x86_64.whl", hash = "sha256:91d5f6f5209dc2635d496f6b8ca6573ecdad051a09e6b5de4c399b8e673c60da"}, + {file = "opencv_python-4.8.1.78-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:bc31f47e05447da8b3089faa0a07ffe80e114c91ce0b171e6424f9badbd1c5cd"}, + {file = "opencv_python-4.8.1.78-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9814beca408d3a0eca1bae7e3e5be68b07c17ecceb392b94170881216e09b319"}, + {file = "opencv_python-4.8.1.78-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4c406bdb41eb21ea51b4e90dfbc989c002786c3f601c236a99c59a54670a394"}, + {file = "opencv_python-4.8.1.78-cp37-abi3-win32.whl", hash = "sha256:a7aac3900fbacf55b551e7b53626c3dad4c71ce85643645c43e91fcb19045e47"}, + {file = "opencv_python-4.8.1.78-cp37-abi3-win_amd64.whl", hash = "sha256:b983197f97cfa6fcb74e1da1802c7497a6f94ed561aba6980f1f33123f904956"}, +] + +[package.dependencies] +numpy = [ + {version = ">=1.21.0", markers = "python_version <= \"3.9\" and platform_system == \"Darwin\" and platform_machine == \"arm64\" and python_version >= \"3.8\""}, + {version = ">=1.23.5", markers = "python_version >= \"3.11\""}, + {version = ">=1.21.4", markers = "python_version >= \"3.10\" and platform_system == \"Darwin\" and python_version < \"3.11\""}, + {version = ">=1.21.2", markers = "platform_system != \"Darwin\" and python_version >= \"3.10\" and python_version < \"3.11\""}, + {version = ">=1.19.3", markers = "platform_system == \"Linux\" and platform_machine == \"aarch64\" and python_version >= \"3.8\" and python_version < \"3.10\" or python_version > \"3.9\" and python_version < \"3.10\" or python_version >= \"3.9\" and platform_system != \"Darwin\" and python_version < \"3.10\" or python_version >= \"3.9\" and platform_machine != \"arm64\" and python_version < \"3.10\""}, + {version = ">=1.17.3", markers = "(platform_system != \"Darwin\" and platform_system != \"Linux\") and python_version >= \"3.8\" and python_version < \"3.9\" or platform_system != \"Darwin\" and python_version >= \"3.8\" and python_version < \"3.9\" and platform_machine != \"aarch64\" or platform_machine != \"arm64\" and python_version >= \"3.8\" and python_version < \"3.9\" and platform_system != \"Linux\" or (platform_machine != \"arm64\" and platform_machine != \"aarch64\") and python_version >= \"3.8\" and python_version < \"3.9\""}, +] + +[[package]] +name = "packaging" +version = "23.2" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.7" +files = [ + {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, + {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, +] + +[[package]] +name = "parso" +version = "0.8.3" +description = "A Python Parser" +optional = false +python-versions = ">=3.6" +files = [ + {file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"}, + {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"}, +] + +[package.extras] +qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] +testing = ["docopt", "pytest (<6.0.0)"] + +[[package]] +name = "pathspec" +version = "0.11.2" +description = "Utility library for gitignore style pattern matching of file paths." +optional = false +python-versions = ">=3.7" +files = [ + {file = "pathspec-0.11.2-py3-none-any.whl", hash = "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20"}, + {file = "pathspec-0.11.2.tar.gz", hash = "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"}, +] + +[[package]] +name = "pexpect" +version = "4.8.0" +description = "Pexpect allows easy control of interactive console applications." +optional = false +python-versions = "*" +files = [ + {file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"}, + {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"}, +] + +[package.dependencies] +ptyprocess = ">=0.5" + +[[package]] +name = "pickleshare" +version = "0.7.5" +description = "Tiny 'shelve'-like database with concurrency support" +optional = false +python-versions = "*" +files = [ + {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"}, + {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, +] + +[[package]] +name = "platformdirs" +version = "4.0.0" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +optional = false +python-versions = ">=3.7" +files = [ + {file = "platformdirs-4.0.0-py3-none-any.whl", hash = "sha256:118c954d7e949b35437270383a3f2531e99dd93cf7ce4dc8340d3356d30f173b"}, + {file = "platformdirs-4.0.0.tar.gz", hash = "sha256:cb633b2bcf10c51af60beb0ab06d2f1d69064b43abf4c185ca6b28865f3f9731"}, +] + +[package.extras] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"] + +[[package]] +name = "prompt-toolkit" +version = "3.0.41" +description = "Library for building powerful interactive command lines in Python" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "prompt_toolkit-3.0.41-py3-none-any.whl", hash = "sha256:f36fe301fafb7470e86aaf90f036eef600a3210be4decf461a5b1ca8403d3cb2"}, + {file = "prompt_toolkit-3.0.41.tar.gz", hash = "sha256:941367d97fc815548822aa26c2a269fdc4eb21e9ec05fc5d447cf09bad5d75f0"}, +] + +[package.dependencies] +wcwidth = "*" + +[[package]] +name = "ptyprocess" +version = "0.7.0" +description = "Run a subprocess in a pseudo terminal" +optional = false +python-versions = "*" +files = [ + {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, + {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, +] + +[[package]] +name = "pure-eval" +version = "0.2.2" +description = "Safely evaluate AST nodes without side effects" +optional = false +python-versions = "*" +files = [ + {file = "pure_eval-0.2.2-py3-none-any.whl", hash = "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350"}, + {file = "pure_eval-0.2.2.tar.gz", hash = "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"}, +] + +[package.extras] +tests = ["pytest"] + +[[package]] +name = "pycodestyle" +version = "2.11.1" +description = "Python style guide checker" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pycodestyle-2.11.1-py2.py3-none-any.whl", hash = "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67"}, + {file = "pycodestyle-2.11.1.tar.gz", hash = "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f"}, +] + +[[package]] +name = "pyflakes" +version = "3.1.0" +description = "passive checker of Python programs" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pyflakes-3.1.0-py2.py3-none-any.whl", hash = "sha256:4132f6d49cb4dae6819e5379898f2b8cce3c5f23994194c24b77d5da2e36f774"}, + {file = "pyflakes-3.1.0.tar.gz", hash = "sha256:a0aae034c444db0071aa077972ba4768d40c830d9539fd45bf4cd3f8f6992efc"}, +] + +[[package]] +name = "pygments" +version = "2.16.1" +description = "Pygments is a syntax highlighting package written in Python." +optional = false +python-versions = ">=3.7" +files = [ + {file = "Pygments-2.16.1-py3-none-any.whl", hash = "sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692"}, + {file = "Pygments-2.16.1.tar.gz", hash = "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29"}, +] + +[package.extras] +plugins = ["importlib-metadata"] + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[[package]] +name = "stack-data" +version = "0.6.3" +description = "Extract data from python stack frames and tracebacks for informative displays" +optional = false +python-versions = "*" +files = [ + {file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"}, + {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"}, +] + +[package.dependencies] +asttokens = ">=2.1.0" +executing = ">=1.2.0" +pure-eval = "*" + +[package.extras] +tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] + +[[package]] +name = "tokenize-rt" +version = "5.2.0" +description = "A wrapper around the stdlib `tokenize` which roundtrips." +optional = false +python-versions = ">=3.8" +files = [ + {file = "tokenize_rt-5.2.0-py2.py3-none-any.whl", hash = "sha256:b79d41a65cfec71285433511b50271b05da3584a1da144a0752e9c621a285289"}, + {file = "tokenize_rt-5.2.0.tar.gz", hash = "sha256:9fe80f8a5c1edad2d3ede0f37481cc0cc1538a2f442c9c2f9e4feacd2792d054"}, +] + +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] + +[[package]] +name = "traitlets" +version = "5.13.0" +description = "Traitlets Python configuration system" +optional = false +python-versions = ">=3.8" +files = [ + {file = "traitlets-5.13.0-py3-none-any.whl", hash = "sha256:baf991e61542da48fe8aef8b779a9ea0aa38d8a54166ee250d5af5ecf4486619"}, + {file = "traitlets-5.13.0.tar.gz", hash = "sha256:9b232b9430c8f57288c1024b34a8f0251ddcc47268927367a0dd3eeaca40deb5"}, +] + +[package.extras] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] +test = ["argcomplete (>=3.0.3)", "mypy (>=1.6.0)", "pre-commit", "pytest (>=7.0,<7.5)", "pytest-mock", "pytest-mypy-testing"] + +[[package]] +name = "typing-extensions" +version = "4.8.0" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +files = [ + {file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"}, + {file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"}, +] + +[[package]] +name = "wcwidth" +version = "0.2.10" +description = "Measures the displayed width of unicode strings in a terminal" +optional = false +python-versions = "*" +files = [ + {file = "wcwidth-0.2.10-py2.py3-none-any.whl", hash = "sha256:aec5179002dd0f0d40c456026e74a729661c9d468e1ed64405e3a6c2176ca36f"}, + {file = "wcwidth-0.2.10.tar.gz", hash = "sha256:390c7454101092a6a5e43baad8f83de615463af459201709556b6e4b1c861f97"}, +] + +[metadata] +lock-version = "2.0" +python-versions = "^3.8.1" +content-hash = "f1140ad0423372d5c2fed73d7bad54357ef4c684735d27f1c77aba0d9758dc0d" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..f823566 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,22 @@ +[tool.poetry] +name = "OpenCV Python Course" +version = "0.1.0" +description = "Notes and code used in my Python and OpenCV course on freeCodeCamp.org." +authors = ["Jason "] +readme = "README.md" + +[tool.poetry.dependencies] +python = "^3.8.1" +opencv-python = "^4.8.1.78" +caer = "^2.0.8" + + +[tool.poetry.group.dev.dependencies] +black = {extras = ["jupyter"], version = "^23.11.0"} +isort = "^5.12.0" +flake8 = "^6.1.0" +mypy = "^1.7.0" + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" From 35fd56aab861e3fc6f3d4f923856ad25947c2c7c Mon Sep 17 00:00:00 2001 From: Anton Bagrianov Date: Thu, 16 Nov 2023 01:08:51 +0400 Subject: [PATCH 3/7] Add requirements.txt --- requirements.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..71652d9 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +opencv-python +caer \ No newline at end of file From 52b6060e0c9516fd12afa966acabab9682277ce7 Mon Sep 17 00:00:00 2001 From: Anton Bagrianov Date: Thu, 16 Nov 2023 01:08:59 +0400 Subject: [PATCH 4/7] Add Makefile --- Makefile | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..fffb18a --- /dev/null +++ b/Makefile @@ -0,0 +1,26 @@ +SOURCES = 'Section \#1 - Basics' 'Section \#2 - Advanced' 'Section \#3 - Faces' 'Section \#4 - Capstone' + +.DEFAULT_GOAL := help + +help: ## Display this help screen + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' +.PHONY: help + +install: ## Install project dependencies + poetry install --no-interaction --no-ansi --without dev --no-root +.PHONY: install + +format: ## Format the source code + poetry run black $(SOURCES) + poetry run isort $(SOURCES) +.PHONY: format + +lint: ## Lint the source code + poetry run black --check $(SOURCES) + poetry run isort --check $(SOURCES) + + poetry run flake8 $(SOURCES) + poetry run mypy $(SOURCES) + poetry run bandit -c pyproject.toml -r app + +.PHONY: lint \ No newline at end of file From bce704073fded02f0416cbcbd2735883011e8577 Mon Sep 17 00:00:00 2001 From: Anton Bagrianov Date: Thu, 16 Nov 2023 01:09:19 +0400 Subject: [PATCH 5/7] Run formatters --- .flake8 | 9 + .gitignore | 1 + Makefile | 3 - Section #1 - Basics/basic_functions.py | 30 +- Section #1 - Basics/contours.py | 26 +- Section #1 - Basics/draw.py | 38 +- Section #1 - Basics/read.py | 22 +- Section #1 - Basics/thresh.py | 24 +- Section #1 - Basics/transformations.py | 38 +- Section #2 - Advanced/bitwise.py | 22 +- Section #2 - Advanced/blurring.py | 20 +- Section #2 - Advanced/colour_spaces.py | 19 +- Section #2 - Advanced/gradients.py | 22 +- Section #2 - Advanced/histogram.py | 30 +- Section #2 - Advanced/masking.py | 22 +- Section #2 - Advanced/rescale_resize.py | 29 +- Section #2 - Advanced/splitmerge.py | 28 +- Section #3 - Faces/face_detect.py | 21 +- Section #3 - Faces/face_recognition.py | 37 +- Section #3 - Faces/faces_train.py | 35 +- Section #4 - Capstone/simpsons.ipynb | 750 ++++++++++++------------ Section #4 - Capstone/simpsons.py | 61 +- poetry.lock | 147 ++--- pyproject.toml | 17 +- 24 files changed, 740 insertions(+), 711 deletions(-) create mode 100644 .flake8 diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..7ad4c02 --- /dev/null +++ b/.flake8 @@ -0,0 +1,9 @@ +[flake8] +max-line-length = 100 +extend-ignore = E203, E704, W503 +unused-arguments-ignore-abstract-functions = True +unused-arguments-ignore-overload-functions = True + +ignore = + # An unused argument starting with an underscore + U101, diff --git a/.gitignore b/.gitignore index 933ec8b..f8308d4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .idea/ +.python-version # Byte-compiled / optimized / DLL files __pycache__/ diff --git a/Makefile b/Makefile index fffb18a..c90ffab 100644 --- a/Makefile +++ b/Makefile @@ -18,9 +18,6 @@ format: ## Format the source code lint: ## Lint the source code poetry run black --check $(SOURCES) poetry run isort --check $(SOURCES) - poetry run flake8 $(SOURCES) - poetry run mypy $(SOURCES) - poetry run bandit -c pyproject.toml -r app .PHONY: lint \ No newline at end of file diff --git a/Section #1 - Basics/basic_functions.py b/Section #1 - Basics/basic_functions.py index e1b93be..09bf234 100644 --- a/Section #1 - Basics/basic_functions.py +++ b/Section #1 - Basics/basic_functions.py @@ -1,35 +1,35 @@ -#pylint:disable=no-member +# pylint:disable=no-member import cv2 as cv # Read in an image -img = cv.imread('../Resources/Photos/park.jpg') -cv.imshow('Park', img) +img = cv.imread("../Resources/Photos/park.jpg") +cv.imshow("Park", img) # Converting to grayscale gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) -cv.imshow('Gray', gray) +cv.imshow("Gray", gray) -# Blur -blur = cv.GaussianBlur(img, (7,7), cv.BORDER_DEFAULT) -cv.imshow('Blur', blur) +# Blur +blur = cv.GaussianBlur(img, (7, 7), cv.BORDER_DEFAULT) +cv.imshow("Blur", blur) # Edge Cascade canny = cv.Canny(blur, 125, 175) -cv.imshow('Canny Edges', canny) +cv.imshow("Canny Edges", canny) # Dilating the image -dilated = cv.dilate(canny, (7,7), iterations=3) -cv.imshow('Dilated', dilated) +dilated = cv.dilate(canny, (7, 7), iterations=3) +cv.imshow("Dilated", dilated) # Eroding -eroded = cv.erode(dilated, (7,7), iterations=3) -cv.imshow('Eroded', eroded) +eroded = cv.erode(dilated, (7, 7), iterations=3) +cv.imshow("Eroded", eroded) # Resize -resized = cv.resize(img, (500,500), interpolation=cv.INTER_CUBIC) -cv.imshow('Resized', resized) +resized = cv.resize(img, (500, 500), interpolation=cv.INTER_CUBIC) +cv.imshow("Resized", resized) # Cropping cropped = img[50:200, 200:400] -cv.imshow('Cropped', cropped) \ No newline at end of file +cv.imshow("Cropped", cropped) diff --git a/Section #1 - Basics/contours.py b/Section #1 - Basics/contours.py index ebadef1..3979745 100644 --- a/Section #1 - Basics/contours.py +++ b/Section #1 - Basics/contours.py @@ -1,30 +1,30 @@ -#pylint:disable=no-member +# pylint:disable=no-member import cv2 as cv import numpy as np -img = cv.imread('../Resources/Photos/cats.jpg') -cv.imshow('Cats', img) +img = cv.imread("../Resources/Photos/cats.jpg") +cv.imshow("Cats", img) -blank = np.zeros(img.shape, dtype='uint8') -cv.imshow('Blank', blank) +blank = np.zeros(img.shape, dtype="uint8") +cv.imshow("Blank", blank) gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) -cv.imshow('Gray', gray) +cv.imshow("Gray", gray) -blur = cv.GaussianBlur(gray, (5,5), cv.BORDER_DEFAULT) -cv.imshow('Blur', blur) +blur = cv.GaussianBlur(gray, (5, 5), cv.BORDER_DEFAULT) +cv.imshow("Blur", blur) canny = cv.Canny(blur, 125, 175) -cv.imshow('Canny Edges', canny) +cv.imshow("Canny Edges", canny) # ret, thresh = cv.threshold(gray, 125, 255, cv.THRESH_BINARY) # cv.imshow('Thresh', thresh) contours, hierarchies = cv.findContours(canny, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE) -print(f'{len(contours)} contour(s) found!') +print(f"{len(contours)} contour(s) found!") -cv.drawContours(blank, contours, -1, (0,0,255), 1) -cv.imshow('Contours Drawn', blank) +cv.drawContours(blank, contours, -1, (0, 0, 255), 1) +cv.imshow("Contours Drawn", blank) -cv.waitKey(0) \ No newline at end of file +cv.waitKey(0) diff --git a/Section #1 - Basics/draw.py b/Section #1 - Basics/draw.py index a081581..12f3a43 100644 --- a/Section #1 - Basics/draw.py +++ b/Section #1 - Basics/draw.py @@ -1,29 +1,37 @@ -#pylint:disable=no-member +# pylint:disable=no-member import cv2 as cv import numpy as np -blank = np.zeros((500,500,3), dtype='uint8') -cv.imshow('Blank', blank) +blank = np.zeros((500, 500, 3), dtype="uint8") +cv.imshow("Blank", blank) # 1. Paint the image a certain colour -blank[200:300, 300:400] = 0,0,255 -cv.imshow('Green', blank) +blank[200:300, 300:400] = 0, 0, 255 +cv.imshow("Green", blank) # 2. Draw a Rectangle -cv.rectangle(blank, (0,0), (blank.shape[1]//2, blank.shape[0]//2), (0,255,0), thickness=-1) -cv.imshow('Rectangle', blank) +cv.rectangle(blank, (0, 0), (blank.shape[1] // 2, blank.shape[0] // 2), (0, 255, 0), thickness=-1) +cv.imshow("Rectangle", blank) # 3. Draw A circle -cv.circle(blank, (blank.shape[1]//2, blank.shape[0]//2), 40, (0,0,255), thickness=-1) -cv.imshow('Circle', blank) +cv.circle(blank, (blank.shape[1] // 2, blank.shape[0] // 2), 40, (0, 0, 255), thickness=-1) +cv.imshow("Circle", blank) # 4. Draw a line -cv.line(blank, (100,250), (300,400), (255,255,255), thickness=3) -cv.imshow('Line', blank) +cv.line(blank, (100, 250), (300, 400), (255, 255, 255), thickness=3) +cv.imshow("Line", blank) # 5. Write text -cv.putText(blank, 'Hello, my name is Jason!!!', (0,225), cv.FONT_HERSHEY_TRIPLEX, 1.0, (0,255,0), 2) -cv.imshow('Text', blank) - -cv.waitKey(0) \ No newline at end of file +cv.putText( + blank, + "Hello, my name is Jason!!!", + (0, 225), + cv.FONT_HERSHEY_TRIPLEX, + 1.0, + (0, 255, 0), + 2, +) +cv.imshow("Text", blank) + +cv.waitKey(0) diff --git a/Section #1 - Basics/read.py b/Section #1 - Basics/read.py index ccdbbcc..7ba56c4 100644 --- a/Section #1 - Basics/read.py +++ b/Section #1 - Basics/read.py @@ -1,26 +1,26 @@ -#pylint:disable=no-member +# pylint:disable=no-member import cv2 as cv -img = cv.imread('../Resources/Photos/cats.jpg') -cv.imshow('Cats', img) +img = cv.imread("../Resources/Photos/cats.jpg") +cv.imshow("Cats", img) cv.waitKey(0) # Reading Videos -capture = cv.VideoCapture('../Resources/Videos/dog.mp4') +capture = cv.VideoCapture("../Resources/Videos/dog.mp4") while True: isTrue, frame = capture.read() - + # if cv.waitKey(20) & 0xFF==ord('d'): - # This is the preferred way - if `isTrue` is false (the frame could + # This is the preferred way - if `isTrue` is false (the frame could # not be read, or we're at the end of the video), we immediately - # break from the loop. - if isTrue: - cv.imshow('Video', frame) - if cv.waitKey(20) & 0xFF==ord('d'): - break + # break from the loop. + if isTrue: + cv.imshow("Video", frame) + if cv.waitKey(20) & 0xFF == ord("d"): + break else: break diff --git a/Section #1 - Basics/thresh.py b/Section #1 - Basics/thresh.py index 01b325a..7eb9838 100644 --- a/Section #1 - Basics/thresh.py +++ b/Section #1 - Basics/thresh.py @@ -1,22 +1,24 @@ -#pylint:disable=no-member +# pylint:disable=no-member import cv2 as cv -img = cv.imread('../Resources/Photos/cats.jpg') -cv.imshow('Cats', img) +img = cv.imread("../Resources/Photos/cats.jpg") +cv.imshow("Cats", img) gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) -cv.imshow('Gray', gray) +cv.imshow("Gray", gray) # Simple Thresholding -threshold, thresh = cv.threshold(gray, 150, 255, cv.THRESH_BINARY ) -cv.imshow('Simple Thresholded', thresh) +threshold, thresh = cv.threshold(gray, 150, 255, cv.THRESH_BINARY) +cv.imshow("Simple Thresholded", thresh) -threshold, thresh_inv = cv.threshold(gray, 150, 255, cv.THRESH_BINARY_INV ) -cv.imshow('Simple Thresholded Inverse', thresh_inv) +threshold, thresh_inv = cv.threshold(gray, 150, 255, cv.THRESH_BINARY_INV) +cv.imshow("Simple Thresholded Inverse", thresh_inv) # Adaptive Thresholding -adaptive_thresh = cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY_INV, 11, 9) -cv.imshow('Adaptive Thresholding', adaptive_thresh) +adaptive_thresh = cv.adaptiveThreshold( + gray, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY_INV, 11, 9 +) +cv.imshow("Adaptive Thresholding", adaptive_thresh) -cv.waitKey(0) \ No newline at end of file +cv.waitKey(0) diff --git a/Section #1 - Basics/transformations.py b/Section #1 - Basics/transformations.py index 5bd2005..bcedea8 100644 --- a/Section #1 - Basics/transformations.py +++ b/Section #1 - Basics/transformations.py @@ -1,54 +1,58 @@ -#pylint:disable=no-member +# pylint:disable=no-member import cv2 as cv import numpy as np -img = cv.imread('../Resources/Photos/park.jpg') -cv.imshow('Park', img) +img = cv.imread("../Resources/Photos/park.jpg") +cv.imshow("Park", img) + # Translation -def translate(img, x, y): - transMat = np.float32([[1,0,x],[0,1,y]]) +def translate(img, x: int, y: int): + transMat = np.float32([[1, 0, x], [0, 1, y]]) dimensions = (img.shape[1], img.shape[0]) return cv.warpAffine(img, transMat, dimensions) + # -x --> Left # -y --> Up # x --> Right # y --> Down translated = translate(img, -100, 100) -cv.imshow('Translated', translated) +cv.imshow("Translated", translated) + # Rotation def rotate(img, angle, rotPoint=None): - (height,width) = img.shape[:2] + (height, width) = img.shape[:2] if rotPoint is None: - rotPoint = (width//2,height//2) - + rotPoint = (width // 2, height // 2) + rotMat = cv.getRotationMatrix2D(rotPoint, angle, 1.0) - dimensions = (width,height) + dimensions = (width, height) return cv.warpAffine(img, rotMat, dimensions) + rotated = rotate(img, -45) -cv.imshow('Rotated', rotated) +cv.imshow("Rotated", rotated) rotated_rotated = rotate(img, -90) -cv.imshow('Rotated Rotated', rotated_rotated) +cv.imshow("Rotated Rotated", rotated_rotated) # Resizing -resized = cv.resize(img, (500,500), interpolation=cv.INTER_CUBIC) -cv.imshow('Resized', resized) +resized = cv.resize(img, (500, 500), interpolation=cv.INTER_CUBIC) +cv.imshow("Resized", resized) # Flipping flip = cv.flip(img, -1) -cv.imshow('Flip', flip) +cv.imshow("Flip", flip) # Cropping cropped = img[200:400, 300:400] -cv.imshow('Cropped', cropped) +cv.imshow("Cropped", cropped) -cv.waitKey(0) \ No newline at end of file +cv.waitKey(0) diff --git a/Section #2 - Advanced/bitwise.py b/Section #2 - Advanced/bitwise.py index 221c0da..9963cdf 100644 --- a/Section #2 - Advanced/bitwise.py +++ b/Section #2 - Advanced/bitwise.py @@ -1,30 +1,30 @@ -#pylint:disable=no-member +# pylint:disable=no-member import cv2 as cv import numpy as np -blank = np.zeros((400,400), dtype='uint8') +blank = np.zeros((400, 400), dtype="uint8") -rectangle = cv.rectangle(blank.copy(), (30,30), (370,370), 255, -1) -circle = cv.circle(blank.copy(), (200,200), 200, 255, -1) +rectangle = cv.rectangle(blank.copy(), (30, 30), (370, 370), 255, -1) +circle = cv.circle(blank.copy(), (200, 200), 200, 255, -1) -cv.imshow('Rectangle', rectangle) -cv.imshow('Circle', circle) +cv.imshow("Rectangle", rectangle) +cv.imshow("Circle", circle) # bitwise AND --> intersecting regions bitwise_and = cv.bitwise_and(rectangle, circle) -cv.imshow('Bitwise AND', bitwise_and) +cv.imshow("Bitwise AND", bitwise_and) # bitwise OR --> non-intersecting and intersecting regions bitwise_or = cv.bitwise_or(rectangle, circle) -cv.imshow('Bitwise OR', bitwise_or) +cv.imshow("Bitwise OR", bitwise_or) # bitwise XOR --> non-intersecting regions bitwise_xor = cv.bitwise_xor(rectangle, circle) -cv.imshow('Bitwise XOR', bitwise_xor) +cv.imshow("Bitwise XOR", bitwise_xor) # bitwise NOT bitwise_not = cv.bitwise_not(circle) -cv.imshow('Circle NOT', bitwise_not) +cv.imshow("Circle NOT", bitwise_not) -cv.waitKey(0) \ No newline at end of file +cv.waitKey(0) diff --git a/Section #2 - Advanced/blurring.py b/Section #2 - Advanced/blurring.py index e9f58c8..1bdf498 100644 --- a/Section #2 - Advanced/blurring.py +++ b/Section #2 - Advanced/blurring.py @@ -1,24 +1,24 @@ -#pylint:disable=no-member +# pylint:disable=no-member import cv2 as cv -img = cv.imread('../Resources/Photos/cats.jpg') -cv.imshow('Cats', img) +img = cv.imread("../Resources/Photos/cats.jpg") +cv.imshow("Cats", img) # Averaging -average = cv.blur(img, (3,3)) -cv.imshow('Average Blur', average) +average = cv.blur(img, (3, 3)) +cv.imshow("Average Blur", average) # Gaussian Blur -gauss = cv.GaussianBlur(img, (3,3), 0) -cv.imshow('Gaussian Blur', gauss) +gauss = cv.GaussianBlur(img, (3, 3), 0) +cv.imshow("Gaussian Blur", gauss) # Median Blur median = cv.medianBlur(img, 3) -cv.imshow('Median Blur', median) +cv.imshow("Median Blur", median) # Bilateral bilateral = cv.bilateralFilter(img, 10, 35, 25) -cv.imshow('Bilateral', bilateral) +cv.imshow("Bilateral", bilateral) -cv.waitKey(0) \ No newline at end of file +cv.waitKey(0) diff --git a/Section #2 - Advanced/colour_spaces.py b/Section #2 - Advanced/colour_spaces.py index a150461..175af7b 100644 --- a/Section #2 - Advanced/colour_spaces.py +++ b/Section #2 - Advanced/colour_spaces.py @@ -1,32 +1,31 @@ -#pylint:disable=no-member +# pylint:disable=no-member import cv2 as cv -import matplotlib.pyplot as plt -img = cv.imread('../Resources/Photos/park.jpg') -cv.imshow('Park', img) +img = cv.imread("../Resources/Photos/park.jpg") +cv.imshow("Park", img) # plt.imshow(img) # plt.show() # BGR to Grayscale gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) -cv.imshow('Gray', gray) +cv.imshow("Gray", gray) # BGR to HSV hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV) -cv.imshow('HSV', hsv) +cv.imshow("HSV", hsv) # BGR to L*a*b lab = cv.cvtColor(img, cv.COLOR_BGR2LAB) -cv.imshow('LAB', lab) +cv.imshow("LAB", lab) # BGR to RGB rgb = cv.cvtColor(img, cv.COLOR_BGR2RGB) -cv.imshow('RGB', rgb) +cv.imshow("RGB", rgb) # HSV to BGR lab_bgr = cv.cvtColor(lab, cv.COLOR_LAB2BGR) -cv.imshow('LAB --> BGR', lab_bgr) +cv.imshow("LAB --> BGR", lab_bgr) -cv.waitKey(0) \ No newline at end of file +cv.waitKey(0) diff --git a/Section #2 - Advanced/gradients.py b/Section #2 - Advanced/gradients.py index 09c8e34..62cd1d0 100644 --- a/Section #2 - Advanced/gradients.py +++ b/Section #2 - Advanced/gradients.py @@ -1,28 +1,28 @@ -#pylint:disable=no-member +# pylint:disable=no-member import cv2 as cv import numpy as np -img = cv.imread('../Resources/Photos/park.jpg') -cv.imshow('Park', img) +img = cv.imread("../Resources/Photos/park.jpg") +cv.imshow("Park", img) gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) -cv.imshow('Gray', gray) +cv.imshow("Gray", gray) # Laplacian lap = cv.Laplacian(gray, cv.CV_64F) lap = np.uint8(np.absolute(lap)) -cv.imshow('Laplacian', lap) +cv.imshow("Laplacian", lap) -# Sobel +# Sobel sobelx = cv.Sobel(gray, cv.CV_64F, 1, 0) sobely = cv.Sobel(gray, cv.CV_64F, 0, 1) combined_sobel = cv.bitwise_or(sobelx, sobely) -cv.imshow('Sobel X', sobelx) -cv.imshow('Sobel Y', sobely) -cv.imshow('Combined Sobel', combined_sobel) +cv.imshow("Sobel X", sobelx) +cv.imshow("Sobel Y", sobely) +cv.imshow("Combined Sobel", combined_sobel) canny = cv.Canny(gray, 150, 175) -cv.imshow('Canny', canny) -cv.waitKey(0) \ No newline at end of file +cv.imshow("Canny", canny) +cv.waitKey(0) diff --git a/Section #2 - Advanced/histogram.py b/Section #2 - Advanced/histogram.py index b195e06..0560fa8 100644 --- a/Section #2 - Advanced/histogram.py +++ b/Section #2 - Advanced/histogram.py @@ -1,21 +1,21 @@ -#pylint:disable=no-member +# pylint:disable=no-member import cv2 as cv import matplotlib.pyplot as plt import numpy as np -img = cv.imread('../Resources/Photos/cats.jpg') -cv.imshow('Cats', img) +img = cv.imread("../Resources/Photos/cats.jpg") +cv.imshow("Cats", img) -blank = np.zeros(img.shape[:2], dtype='uint8') +blank = np.zeros(img.shape[:2], dtype="uint8") # gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) # cv.imshow('Gray', gray) -mask = cv.circle(blank, (img.shape[1]//2,img.shape[0]//2), 100, 255, -1) +mask = cv.circle(blank, (img.shape[1] // 2, img.shape[0] // 2), 100, 255, -1) -masked = cv.bitwise_and(img,img,mask=mask) -cv.imshow('Mask', masked) +masked = cv.bitwise_and(img, img, mask=mask) +cv.imshow("Mask", masked) # GRayscale histogram # gray_hist = cv.calcHist([gray], [0], mask, [256], [0,256] ) @@ -31,15 +31,15 @@ # Colour Histogram plt.figure() -plt.title('Colour Histogram') -plt.xlabel('Bins') -plt.ylabel('# of pixels') -colors = ('b', 'g', 'r') -for i,col in enumerate(colors): - hist = cv.calcHist([img], [i], mask, [256], [0,256]) +plt.title("Colour Histogram") +plt.xlabel("Bins") +plt.ylabel("# of pixels") +colors = ("b", "g", "r") +for i, col in enumerate(colors): + hist = cv.calcHist([img], [i], mask, [256], [0, 256]) plt.plot(hist, color=col) - plt.xlim([0,256]) + plt.xlim([0, 256]) plt.show() -cv.waitKey(0) \ No newline at end of file +cv.waitKey(0) diff --git a/Section #2 - Advanced/masking.py b/Section #2 - Advanced/masking.py index 1d018e7..68c001a 100644 --- a/Section #2 - Advanced/masking.py +++ b/Section #2 - Advanced/masking.py @@ -1,22 +1,22 @@ -#pylint:disable=no-member +# pylint:disable=no-member import cv2 as cv import numpy as np -img = cv.imread('../Resources/Photos/cats 2.jpg') -cv.imshow('Cats', img) +img = cv.imread("../Resources/Photos/cats 2.jpg") +cv.imshow("Cats", img) -blank = np.zeros(img.shape[:2], dtype='uint8') -cv.imshow('Blank Image', blank) +blank = np.zeros(img.shape[:2], dtype="uint8") +cv.imshow("Blank Image", blank) -circle = cv.circle(blank.copy(), (img.shape[1]//2 + 45,img.shape[0]//2), 100, 255, -1) +circle = cv.circle(blank.copy(), (img.shape[1] // 2 + 45, img.shape[0] // 2), 100, 255, -1) -rectangle = cv.rectangle(blank.copy(), (30,30), (370,370), 255, -1) +rectangle = cv.rectangle(blank.copy(), (30, 30), (370, 370), 255, -1) -weird_shape = cv.bitwise_and(circle,rectangle) -cv.imshow('Weird Shape', weird_shape) +weird_shape = cv.bitwise_and(circle, rectangle) +cv.imshow("Weird Shape", weird_shape) -masked = cv.bitwise_and(img,img,mask=weird_shape) -cv.imshow('Weird Shaped Masked Image', masked) +masked = cv.bitwise_and(img, img, mask=weird_shape) +cv.imshow("Weird Shaped Masked Image", masked) cv.waitKey(0) diff --git a/Section #2 - Advanced/rescale_resize.py b/Section #2 - Advanced/rescale_resize.py index c28bb76..b9395c6 100644 --- a/Section #2 - Advanced/rescale_resize.py +++ b/Section #2 - Advanced/rescale_resize.py @@ -1,37 +1,40 @@ -#pylint:disable=no-member +# pylint:disable=no-member import cv2 as cv # img = cv.imread('../Resources/Photos/cat.jpg') # cv.imshow('Cat', img) + def rescaleFrame(frame, scale=0.75): # Images, Videos and Live Video width = int(frame.shape[1] * scale) height = int(frame.shape[0] * scale) - dimensions = (width,height) + dimensions = (width, height) return cv.resize(frame, dimensions, interpolation=cv.INTER_AREA) -def changeRes(width,height): + +def changeRes(width, height): # Live video - capture.set(3,width) - capture.set(4,height) - + capture.set(3, width) + capture.set(4, height) + + # Reading Videos -capture = cv.VideoCapture('../Resources/Videos/dog.mp4') +capture = cv.VideoCapture("../Resources/Videos/dog.mp4") while True: isTrue, frame = capture.read() - frame_resized = rescaleFrame(frame, scale=.2) - - cv.imshow('Video', frame) - cv.imshow('Video Resized', frame_resized) + frame_resized = rescaleFrame(frame, scale=0.2) + + cv.imshow("Video", frame) + cv.imshow("Video Resized", frame_resized) - if cv.waitKey(20) & 0xFF==ord('d'): + if cv.waitKey(20) & 0xFF == ord("d"): break capture.release() -cv.destroyAllWindows() \ No newline at end of file +cv.destroyAllWindows() diff --git a/Section #2 - Advanced/splitmerge.py b/Section #2 - Advanced/splitmerge.py index 0652c9e..8432bdc 100644 --- a/Section #2 - Advanced/splitmerge.py +++ b/Section #2 - Advanced/splitmerge.py @@ -1,30 +1,30 @@ -#pylint:disable=no-member +# pylint:disable=no-member import cv2 as cv import numpy as np -img = cv.imread('../Resources/Photos/park.jpg') -cv.imshow('Park', img) +img = cv.imread("../Resources/Photos/park.jpg") +cv.imshow("Park", img) -blank = np.zeros(img.shape[:2], dtype='uint8') +blank = np.zeros(img.shape[:2], dtype="uint8") -b,g,r = cv.split(img) +b, g, r = cv.split(img) -blue = cv.merge([b,blank,blank]) -green = cv.merge([blank,g,blank]) -red = cv.merge([blank,blank,r]) +blue = cv.merge([b, blank, blank]) +green = cv.merge([blank, g, blank]) +red = cv.merge([blank, blank, r]) -cv.imshow('Blue', blue) -cv.imshow('Green', green) -cv.imshow('Red', red) +cv.imshow("Blue", blue) +cv.imshow("Green", green) +cv.imshow("Red", red) print(img.shape) print(b.shape) print(g.shape) print(r.shape) -merged = cv.merge([b,g,r]) -cv.imshow('Merged Image', merged) +merged = cv.merge([b, g, r]) +cv.imshow("Merged Image", merged) -cv.waitKey(0) \ No newline at end of file +cv.waitKey(0) diff --git a/Section #3 - Faces/face_detect.py b/Section #3 - Faces/face_detect.py index aea2412..c18819a 100644 --- a/Section #3 - Faces/face_detect.py +++ b/Section #3 - Faces/face_detect.py @@ -1,24 +1,23 @@ -#pylint:disable=no-member +# pylint:disable=no-member import cv2 as cv -img = cv.imread('../Resources/Photos/group 1.jpg') -cv.imshow('Group of 5 people', img) +img = cv.imread("../Resources/Photos/group 1.jpg") +cv.imshow("Group of 5 people", img) gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) -cv.imshow('Gray People', gray) +cv.imshow("Gray People", gray) -haar_cascade = cv.CascadeClassifier('haar_face.xml') +haar_cascade = cv.CascadeClassifier("haar_face.xml") faces_rect = haar_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=1) -print(f'Number of faces found = {len(faces_rect)}') +print(f"Number of faces found = {len(faces_rect)}") -for (x,y,w,h) in faces_rect: - cv.rectangle(img, (x,y), (x+w,y+h), (0,255,0), thickness=2) +for x, y, w, h in faces_rect: + cv.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), thickness=2) -cv.imshow('Detected Faces', img) +cv.imshow("Detected Faces", img) - -cv.waitKey(0) \ No newline at end of file +cv.waitKey(0) diff --git a/Section #3 - Faces/face_recognition.py b/Section #3 - Faces/face_recognition.py index 504d6de..d2592c3 100644 --- a/Section #3 - Faces/face_recognition.py +++ b/Section #3 - Faces/face_recognition.py @@ -1,34 +1,41 @@ -#pylint:disable=no-member +# pylint:disable=no-member -import numpy as np import cv2 as cv -haar_cascade = cv.CascadeClassifier('haar_face.xml') +haar_cascade = cv.CascadeClassifier("haar_face.xml") -people = ['Ben Afflek', 'Elton John', 'Jerry Seinfield', 'Madonna', 'Mindy Kaling'] +people = ["Ben Afflek", "Elton John", "Jerry Seinfield", "Madonna", "Mindy Kaling"] # features = np.load('features.npy', allow_pickle=True) # labels = np.load('labels.npy') face_recognizer = cv.face.LBPHFaceRecognizer_create() -face_recognizer.read('face_trained.yml') +face_recognizer.read("face_trained.yml") -img = cv.imread(r'../Resources\Faces\val\elton_john/1.jpg') +img = cv.imread(r"../Resources\Faces\val\elton_john/1.jpg") gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) -cv.imshow('Person', gray) +cv.imshow("Person", gray) # Detect the face in the image faces_rect = haar_cascade.detectMultiScale(gray, 1.1, 4) -for (x,y,w,h) in faces_rect: - faces_roi = gray[y:y+h,x:x+w] +for x, y, w, h in faces_rect: + faces_roi = gray[y : y + h, x : x + w] label, confidence = face_recognizer.predict(faces_roi) - print(f'Label = {people[label]} with a confidence of {confidence}') - - cv.putText(img, str(people[label]), (20,20), cv.FONT_HERSHEY_COMPLEX, 1.0, (0,255,0), thickness=2) - cv.rectangle(img, (x,y), (x+w,y+h), (0,255,0), thickness=2) - -cv.imshow('Detected Face', img) + print(f"Label = {people[label]} with a confidence of {confidence}") + + cv.putText( + img, + str(people[label]), + (20, 20), + cv.FONT_HERSHEY_COMPLEX, + 1.0, + (0, 255, 0), + thickness=2, + ) + cv.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), thickness=2) + +cv.imshow("Detected Face", img) cv.waitKey(0) diff --git a/Section #3 - Faces/faces_train.py b/Section #3 - Faces/faces_train.py index 41cf225..bff30e3 100644 --- a/Section #3 - Faces/faces_train.py +++ b/Section #3 - Faces/faces_train.py @@ -1,49 +1,52 @@ -#pylint:disable=no-member +# pylint:disable=no-member import os + import cv2 as cv import numpy as np -people = ['Ben Afflek', 'Elton John', 'Jerry Seinfield', 'Madonna', 'Mindy Kaling'] -DIR = r'..Media Files\Faces\train' +people = ["Ben Afflek", "Elton John", "Jerry Seinfield", "Madonna", "Mindy Kaling"] +DIR = r"..Media Files\Faces\train" -haar_cascade = cv.CascadeClassifier('haar_face.xml') +haar_cascade = cv.CascadeClassifier("haar_face.xml") features = [] labels = [] + def create_train(): for person in people: path = os.path.join(DIR, person) label = people.index(person) for img in os.listdir(path): - img_path = os.path.join(path,img) + img_path = os.path.join(path, img) img_array = cv.imread(img_path) if img_array is None: - continue - + continue + gray = cv.cvtColor(img_array, cv.COLOR_BGR2GRAY) faces_rect = haar_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=4) - for (x,y,w,h) in faces_rect: - faces_roi = gray[y:y+h, x:x+w] + for x, y, w, h in faces_rect: + faces_roi = gray[y : y + h, x : x + w] features.append(faces_roi) labels.append(label) + create_train() -print('Training done ---------------') +print("Training done ---------------") -features = np.array(features, dtype='object') -labels = np.array(labels) +np_features = np.array(features, dtype="object") +np_labels = np.array(labels) face_recognizer = cv.face.LBPHFaceRecognizer_create() # Train the Recognizer on the features list and the labels list -face_recognizer.train(features,labels) +face_recognizer.train(np_features, np_labels) -face_recognizer.save('face_trained.yml') -np.save('features.npy', features) -np.save('labels.npy', labels) +face_recognizer.save("face_trained.yml") +np.save("features.npy", np_features) +np.save("labels.npy", np_labels) diff --git a/Section #4 - Capstone/simpsons.ipynb b/Section #4 - Capstone/simpsons.ipynb index 3d8e127..2c55e9f 100644 --- a/Section #4 - Capstone/simpsons.ipynb +++ b/Section #4 - Capstone/simpsons.ipynb @@ -1,371 +1,385 @@ { - "nbformat": 4, - "nbformat_minor": 2, - "metadata": { - "kernelspec": { - "language": "python", - "display_name": "Python 3", - "name": "python3" - }, - "language_info": { - "pygments_lexer": "ipython3", - "nbconvert_exporter": "python", - "version": "3.6.4", - "file_extension": ".py", - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "name": "python", - "mimetype": "text/x-python" - }, - "colab": { - "name": "simpsons.ipynb", - "provenance": [] - } + "nbformat": 4, + "nbformat_minor": 2, + "metadata": { + "kernelspec": { + "language": "python", + "display_name": "Python 3", + "name": "python3" }, - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "source": [ - "# Installing `caer` and `canaro` since they don't come pre-installed\n", - "!pip install --upgrade caer canaro" - ], - "outputs": [], - "metadata": { - "_uuid": "8f2839f25d086af736a60e9eeb907d3b93b6e0e5", - "_cell_guid": "b1076dfc-b9ad-4769-8c92-a6c4dae69d19", - "trusted": true, - "id": "MQoxjirY4S5o" - } - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "import os\n", - "import caer\n", - "import canaro\n", - "import numpy as np\n", - "import cv2 as cv\n", - "import gc\n", - "#pylint:disable=no-member (Removes linting problems with cv)" - ], - "outputs": [], - "metadata": { - "_uuid": "d629ff2d2480ee46fbb7e2d37f6b5fab8052498a", - "_cell_guid": "79c7e3d0-c299-4dcb-8224-4455121ee9b0", - "trusted": true, - "id": "_yldS7bG4S58" - } - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "IMG_SIZE = (80,80)\n", - "channels = 1\n", - "char_path = r'../input/the-simpsons-characters-dataset/simpsons_dataset'" - ], - "outputs": [], - "metadata": { - "trusted": true, - "id": "TuC64gTq4S6K" - } - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "# Creating a character dictionary, sorting it in descending order\n", - "char_dict = {}\n", - "for char in os.listdir(char_path):\n", - " char_dict[char] = len(os.listdir(os.path.join(char_path,char)))\n", - "\n", - "# Sort in descending order\n", - "char_dict = caer.sort_dict(char_dict, descending=True)\n", - "char_dict" - ], - "outputs": [], - "metadata": { - "trusted": true, - "id": "RD5OHUE84S6U" - } - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "# Getting the first 10 categories with the most number of images\n", - "characters = []\n", - "count = 0\n", - "for i in char_dict:\n", - " characters.append(i[0])\n", - " count += 1\n", - " if count >= 10:\n", - " break\n", - "characters" - ], - "outputs": [], - "metadata": { - "trusted": true, - "id": "OQ09DqmI4S6g" - } - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "# Create the training data\n", - "train = caer.preprocess_from_dir(char_path, characters, channels=channels, IMG_SIZE=IMG_SIZE, isShuffle=True)" - ], - "outputs": [], - "metadata": { - "trusted": true, - "id": "X4UnTWk74S6q" - } - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "# Number of training samples\n", - "len(train)" - ], - "outputs": [], - "metadata": { - "trusted": true, - "id": "ZaSuzC2J4S6z" - } - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "# Visualizing the data (OpenCV doesn't display well in Jupyter notebooks)\n", - "import matplotlib.pyplot as plt\n", - "plt.figure(figsize=(30,30))\n", - "plt.imshow(train[0][0], cmap='gray')\n", - "plt.show()" - ], - "outputs": [], - "metadata": { - "trusted": true, - "id": "hSw-V2H24S7A" - } - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "# Separating the array and corresponding labels\n", - "featureSet, labels = caer.sep_train(train, IMG_SIZE=IMG_SIZE)" - ], - "outputs": [], - "metadata": { - "trusted": true, - "id": "arO-90034S7J" - } - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "from tensorflow.keras.utils import to_categorical\n", - "\n", - "# Normalize the featureSet ==> (0,1)\n", - "featureSet = caer.normalize(featureSet)\n", - "# Converting numerical labels to binary class vectors\n", - "labels = to_categorical(labels, len(characters))" - ], - "outputs": [], - "metadata": { - "trusted": true, - "id": "Sl8VnLCY4S7O" - } - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "x_train, x_val, y_train, y_val = caer.train_test_split(featureSet, labels, val_ratio=.2)" - ], - "outputs": [], - "metadata": { - "trusted": true, - "id": "pzXXrqbt4S7S" - } - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "del train\n", - "del featureSet\n", - "del labels \n", - "gc.collect()" - ], - "outputs": [], - "metadata": { - "trusted": true, - "id": "emsrpYWZ4S7W" - } - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "# Useful variables when training\n", - "BATCH_SIZE = 32\n", - "EPOCHS = 10" - ], - "outputs": [], - "metadata": { - "trusted": true, - "id": "NkS1ceD94S7a" - } - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "# Image data generator (introduces randomness in network ==> better accuracy)\n", - "datagen = canaro.generators.imageDataGenerator()\n", - "train_gen = datagen.flow(x_train, y_train, batch_size=BATCH_SIZE)" - ], - "outputs": [], - "metadata": { - "trusted": true, - "id": "_atEyygG4S7g" - } - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "# Create our model (returns a compiled model)\n", - "model = canaro.models.createSimpsonsModel(IMG_SIZE=IMG_SIZE, channels=channels, output_dim=len(characters), \n", - " loss='binary_crossentropy', decay=1e-7, learning_rate=0.001, momentum=0.9,\n", - " nesterov=True)" - ], - "outputs": [], - "metadata": { - "trusted": true, - "id": "Y8fjXBuH4S7m" - } - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "model.summary()" - ], - "outputs": [], - "metadata": { - "trusted": true, - "id": "CepcT54J4S7t" - } - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "# Training the model\n", - "\n", - "from tensorflow.keras.callbacks import LearningRateScheduler\n", - "callbacks_list = [LearningRateScheduler(canaro.lr_schedule)]\n", - "training = model.fit(train_gen,\n", - " steps_per_epoch=len(x_train)//BATCH_SIZE,\n", - " epochs=EPOCHS,\n", - " validation_data=(x_val,y_val),\n", - " validation_steps=len(y_val)//BATCH_SIZE,\n", - " callbacks = callbacks_list)" - ], - "outputs": [], - "metadata": { - "trusted": true, - "id": "AknG90ch4S7-" - } - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "characters" - ], - "outputs": [], - "metadata": { - "trusted": true, - "id": "CUifBqOG4S8G" - } - }, - { - "cell_type": "markdown", - "source": [ - "## Testing" - ], - "metadata": { - "id": "qiNY_zSy6Quj" - } - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "test_path = r'../input/the-simpsons-characters-dataset/kaggle_simpson_testset/kaggle_simpson_testset/charles_montgomery_burns_0.jpg'\n", - "\n", - "img = cv.imread(test_path)\n", - "\n", - "plt.imshow(img)\n", - "plt.show()" - ], - "outputs": [], - "metadata": { - "trusted": true, - "id": "ETnmB3DC4S8M" - } - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "def prepare(image):\n", - " image = cv.cvtColor(image, cv.COLOR_BGR2GRAY)\n", - " image = cv.resize(image, IMG_SIZE)\n", - " image = caer.reshape(image, IMG_SIZE, 1)\n", - " return image" - ], - "outputs": [], - "metadata": { - "trusted": true, - "id": "yJjmMuvj4S8T" - } - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "predictions = model.predict(prepare(img))" - ], - "outputs": [], - "metadata": { - "trusted": true, - "id": "hZTjUKKn4S8a" - } - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "# Getting class with the highest probability\n", - "print(characters[np.argmax(predictions[0])])" - ], - "outputs": [], - "metadata": { - "trusted": true, - "id": "3a4AW8qT4S8g" - } - } - ] + "language_info": { + "pygments_lexer": "ipython3", + "nbconvert_exporter": "python", + "version": "3.6.4", + "file_extension": ".py", + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "name": "python", + "mimetype": "text/x-python" + }, + "colab": { + "name": "simpsons.ipynb", + "provenance": [] + } + }, + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "source": [ + "# Installing `caer` and `canaro` since they don't come pre-installed\n", + "!pip install --upgrade caer canaro" + ], + "outputs": [], + "metadata": { + "_uuid": "8f2839f25d086af736a60e9eeb907d3b93b6e0e5", + "_cell_guid": "b1076dfc-b9ad-4769-8c92-a6c4dae69d19", + "trusted": true, + "id": "MQoxjirY4S5o" + } + }, + { + "cell_type": "code", + "execution_count": null, + "source": [ + "import os\n", + "import caer\n", + "import canaro\n", + "import numpy as np\n", + "import cv2 as cv\n", + "import gc\n", + "\n", + "# pylint:disable=no-member (Removes linting problems with cv)" + ], + "outputs": [], + "metadata": { + "_uuid": "d629ff2d2480ee46fbb7e2d37f6b5fab8052498a", + "_cell_guid": "79c7e3d0-c299-4dcb-8224-4455121ee9b0", + "trusted": true, + "id": "_yldS7bG4S58" + } + }, + { + "cell_type": "code", + "execution_count": null, + "source": [ + "IMG_SIZE = (80, 80)\n", + "channels = 1\n", + "char_path = r\"../input/the-simpsons-characters-dataset/simpsons_dataset\"" + ], + "outputs": [], + "metadata": { + "trusted": true, + "id": "TuC64gTq4S6K" + } + }, + { + "cell_type": "code", + "execution_count": null, + "source": [ + "# Creating a character dictionary, sorting it in descending order\n", + "char_dict = {}\n", + "for char in os.listdir(char_path):\n", + " char_dict[char] = len(os.listdir(os.path.join(char_path, char)))\n", + "\n", + "# Sort in descending order\n", + "char_dict = caer.sort_dict(char_dict, descending=True)\n", + "char_dict" + ], + "outputs": [], + "metadata": { + "trusted": true, + "id": "RD5OHUE84S6U" + } + }, + { + "cell_type": "code", + "execution_count": null, + "source": [ + "# Getting the first 10 categories with the most number of images\n", + "characters = []\n", + "count = 0\n", + "for i in char_dict:\n", + " characters.append(i[0])\n", + " count += 1\n", + " if count >= 10:\n", + " break\n", + "characters" + ], + "outputs": [], + "metadata": { + "trusted": true, + "id": "OQ09DqmI4S6g" + } + }, + { + "cell_type": "code", + "execution_count": null, + "source": [ + "# Create the training data\n", + "train = caer.preprocess_from_dir(\n", + " char_path, characters, channels=channels, IMG_SIZE=IMG_SIZE, isShuffle=True\n", + ")" + ], + "outputs": [], + "metadata": { + "trusted": true, + "id": "X4UnTWk74S6q" + } + }, + { + "cell_type": "code", + "execution_count": null, + "source": [ + "# Number of training samples\n", + "len(train)" + ], + "outputs": [], + "metadata": { + "trusted": true, + "id": "ZaSuzC2J4S6z" + } + }, + { + "cell_type": "code", + "execution_count": null, + "source": [ + "# Visualizing the data (OpenCV doesn't display well in Jupyter notebooks)\n", + "import matplotlib.pyplot as plt\n", + "\n", + "plt.figure(figsize=(30, 30))\n", + "plt.imshow(train[0][0], cmap=\"gray\")\n", + "plt.show()" + ], + "outputs": [], + "metadata": { + "trusted": true, + "id": "hSw-V2H24S7A" + } + }, + { + "cell_type": "code", + "execution_count": null, + "source": [ + "# Separating the array and corresponding labels\n", + "featureSet, labels = caer.sep_train(train, IMG_SIZE=IMG_SIZE)" + ], + "outputs": [], + "metadata": { + "trusted": true, + "id": "arO-90034S7J" + } + }, + { + "cell_type": "code", + "execution_count": null, + "source": [ + "from tensorflow.keras.utils import to_categorical\n", + "\n", + "# Normalize the featureSet ==> (0,1)\n", + "featureSet = caer.normalize(featureSet)\n", + "# Converting numerical labels to binary class vectors\n", + "labels = to_categorical(labels, len(characters))" + ], + "outputs": [], + "metadata": { + "trusted": true, + "id": "Sl8VnLCY4S7O" + } + }, + { + "cell_type": "code", + "execution_count": null, + "source": [ + "x_train, x_val, y_train, y_val = caer.train_test_split(featureSet, labels, val_ratio=0.2)" + ], + "outputs": [], + "metadata": { + "trusted": true, + "id": "pzXXrqbt4S7S" + } + }, + { + "cell_type": "code", + "execution_count": null, + "source": [ + "del train\n", + "del featureSet\n", + "del labels\n", + "gc.collect()" + ], + "outputs": [], + "metadata": { + "trusted": true, + "id": "emsrpYWZ4S7W" + } + }, + { + "cell_type": "code", + "execution_count": null, + "source": [ + "# Useful variables when training\n", + "BATCH_SIZE = 32\n", + "EPOCHS = 10" + ], + "outputs": [], + "metadata": { + "trusted": true, + "id": "NkS1ceD94S7a" + } + }, + { + "cell_type": "code", + "execution_count": null, + "source": [ + "# Image data generator (introduces randomness in network ==> better accuracy)\n", + "datagen = canaro.generators.imageDataGenerator()\n", + "train_gen = datagen.flow(x_train, y_train, batch_size=BATCH_SIZE)" + ], + "outputs": [], + "metadata": { + "trusted": true, + "id": "_atEyygG4S7g" + } + }, + { + "cell_type": "code", + "execution_count": null, + "source": [ + "# Create our model (returns a compiled model)\n", + "model = canaro.models.createSimpsonsModel(\n", + " IMG_SIZE=IMG_SIZE,\n", + " channels=channels,\n", + " output_dim=len(characters),\n", + " loss=\"binary_crossentropy\",\n", + " decay=1e-7,\n", + " learning_rate=0.001,\n", + " momentum=0.9,\n", + " nesterov=True,\n", + ")" + ], + "outputs": [], + "metadata": { + "trusted": true, + "id": "Y8fjXBuH4S7m" + } + }, + { + "cell_type": "code", + "execution_count": null, + "source": [ + "model.summary()" + ], + "outputs": [], + "metadata": { + "trusted": true, + "id": "CepcT54J4S7t" + } + }, + { + "cell_type": "code", + "execution_count": null, + "source": [ + "# Training the model\n", + "\n", + "from tensorflow.keras.callbacks import LearningRateScheduler\n", + "\n", + "callbacks_list = [LearningRateScheduler(canaro.lr_schedule)]\n", + "training = model.fit(\n", + " train_gen,\n", + " steps_per_epoch=len(x_train) // BATCH_SIZE,\n", + " epochs=EPOCHS,\n", + " validation_data=(x_val, y_val),\n", + " validation_steps=len(y_val) // BATCH_SIZE,\n", + " callbacks=callbacks_list,\n", + ")" + ], + "outputs": [], + "metadata": { + "trusted": true, + "id": "AknG90ch4S7-" + } + }, + { + "cell_type": "code", + "execution_count": null, + "source": [ + "characters" + ], + "outputs": [], + "metadata": { + "trusted": true, + "id": "CUifBqOG4S8G" + } + }, + { + "cell_type": "markdown", + "source": [ + "## Testing" + ], + "metadata": { + "id": "qiNY_zSy6Quj" + } + }, + { + "cell_type": "code", + "execution_count": null, + "source": [ + "test_path = r\"../input/the-simpsons-characters-dataset/kaggle_simpson_testset/kaggle_simpson_testset/charles_montgomery_burns_0.jpg\"\n", + "\n", + "img = cv.imread(test_path)\n", + "\n", + "plt.imshow(img)\n", + "plt.show()" + ], + "outputs": [], + "metadata": { + "trusted": true, + "id": "ETnmB3DC4S8M" + } + }, + { + "cell_type": "code", + "execution_count": null, + "source": [ + "def prepare(image):\n", + " image = cv.cvtColor(image, cv.COLOR_BGR2GRAY)\n", + " image = cv.resize(image, IMG_SIZE)\n", + " image = caer.reshape(image, IMG_SIZE, 1)\n", + " return image" + ], + "outputs": [], + "metadata": { + "trusted": true, + "id": "yJjmMuvj4S8T" + } + }, + { + "cell_type": "code", + "execution_count": null, + "source": [ + "predictions = model.predict(prepare(img))" + ], + "outputs": [], + "metadata": { + "trusted": true, + "id": "hZTjUKKn4S8a" + } + }, + { + "cell_type": "code", + "execution_count": null, + "source": [ + "# Getting class with the highest probability\n", + "print(characters[np.argmax(predictions[0])])" + ], + "outputs": [], + "metadata": { + "trusted": true, + "id": "3a4AW8qT4S8g" + } + } + ] } \ No newline at end of file diff --git a/Section #4 - Capstone/simpsons.py b/Section #4 - Capstone/simpsons.py index d96fce4..cb04adc 100644 --- a/Section #4 - Capstone/simpsons.py +++ b/Section #4 - Capstone/simpsons.py @@ -1,27 +1,28 @@ -#pylint:disable=no-member (Removes linting problems with cv) +# pylint:disable=no-member (Removes linting problems with cv) # Installing `caer` and `canaro` since they don't come pre-installed # Uncomment the following line: # !pip install --upgrade caer canaro +import gc import os + import caer import canaro -import numpy as np import cv2 as cv -import gc import matplotlib.pyplot as plt -from tensorflow.keras.utils import to_categorical +import numpy as np from tensorflow.keras.callbacks import LearningRateScheduler +from tensorflow.keras.utils import to_categorical -IMG_SIZE = (80,80) +IMG_SIZE = (80, 80) channels = 1 -char_path = r'../input/the-simpsons-characters-dataset/simpsons_dataset' +char_path = r"../input/the-simpsons-characters-dataset/simpsons_dataset" # Creating a character dictionary, sorting it in descending order char_dict = {} for char in os.listdir(char_path): - char_dict[char] = len(os.listdir(os.path.join(char_path,char))) + char_dict[char] = len(os.listdir(os.path.join(char_path, char))) # Sort in descending order char_dict = caer.sort_dict(char_dict, descending=True) @@ -38,14 +39,16 @@ characters # Create the training data -train = caer.preprocess_from_dir(char_path, characters, channels=channels, IMG_SIZE=IMG_SIZE, isShuffle=True) +train = caer.preprocess_from_dir( + char_path, characters, channels=channels, IMG_SIZE=IMG_SIZE, isShuffle=True +) # Number of training samples len(train) # Visualizing the data (OpenCV doesn't display well in Jupyter notebooks) -plt.figure(figsize=(30,30)) -plt.imshow(train[0][0], cmap='gray') +plt.figure(figsize=(30, 30)) +plt.imshow(train[0][0], cmap="gray") plt.show() # Separating the array and corresponding labels @@ -59,12 +62,12 @@ # Creating train and validation data -x_train, x_val, y_train, y_val = caer.train_test_split(featureSet, labels, val_ratio=.2) +x_train, x_val, y_train, y_val = caer.train_test_split(featureSet, labels, val_ratio=0.2) # Deleting variables to save memory del train del featureSet -del labels +del labels gc.collect() # Useful variables when training @@ -76,40 +79,54 @@ train_gen = datagen.flow(x_train, y_train, batch_size=BATCH_SIZE) # Create our model (returns the compiled model) -model = canaro.models.createSimpsonsModel(IMG_SIZE=IMG_SIZE, channels=channels, output_dim=len(characters), - loss='binary_crossentropy', decay=1e-7, learning_rate=0.001, momentum=0.9, - nesterov=True) +model = canaro.models.createSimpsonsModel( + IMG_SIZE=IMG_SIZE, + channels=channels, + output_dim=len(characters), + loss="binary_crossentropy", + decay=1e-7, + learning_rate=0.001, + momentum=0.9, + nesterov=True, +) model.summary() # Training the model callbacks_list = [LearningRateScheduler(canaro.lr_schedule)] -training = model.fit(train_gen, - steps_per_epoch=len(x_train)//BATCH_SIZE, - epochs=EPOCHS, - validation_data=(x_val,y_val), - validation_steps=len(y_val)//BATCH_SIZE, - callbacks = callbacks_list) +training = model.fit( + train_gen, + steps_per_epoch=len(x_train) // BATCH_SIZE, + epochs=EPOCHS, + validation_data=(x_val, y_val), + validation_steps=len(y_val) // BATCH_SIZE, + callbacks=callbacks_list, +) print(characters) """## Testing""" -test_path = r'../input/the-simpsons-characters-dataset/kaggle_simpson_testset/kaggle_simpson_testset/charles_montgomery_burns_0.jpg' +test_path = ( + "../input/the-simpsons-characters-dataset/kaggle_simpson_testset/" + "kaggle_simpson_testset/charles_montgomery_burns_0.jpg" +) img = cv.imread(test_path) plt.imshow(img) plt.show() + def prepare(image): image = cv.cvtColor(image, cv.COLOR_BGR2GRAY) image = cv.resize(image, IMG_SIZE) image = caer.reshape(image, IMG_SIZE, 1) return image + predictions = model.predict(prepare(img)) # Getting class with the highest probability diff --git a/poetry.lock b/poetry.lock index 726f419..cce9b4a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -29,17 +29,6 @@ six = ">=1.12.0" astroid = ["astroid (>=1,<2)", "astroid (>=2,<4)"] test = ["astroid (>=1,<2)", "astroid (>=2,<4)", "pytest"] -[[package]] -name = "backcall" -version = "0.2.0" -description = "Specifications for callback functions passed in to an API" -optional = false -python-versions = "*" -files = [ - {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, - {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, -] - [[package]] name = "black" version = "23.11.0" @@ -75,8 +64,6 @@ packaging = ">=22.0" pathspec = ">=0.9.0" platformdirs = ">=2" tokenize-rt = {version = ">=3.2.0", optional = true, markers = "extra == \"jupyter\""} -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} [package.extras] colorama = ["colorama (>=0.4.3)"] @@ -169,42 +156,39 @@ pyflakes = ">=3.1.0,<3.2.0" [[package]] name = "ipython" -version = "8.12.3" +version = "8.17.2" description = "IPython: Productive Interactive Computing" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "ipython-8.12.3-py3-none-any.whl", hash = "sha256:b0340d46a933d27c657b211a329d0be23793c36595acf9e6ef4164bc01a1804c"}, - {file = "ipython-8.12.3.tar.gz", hash = "sha256:3910c4b54543c2ad73d06579aa771041b7d5707b033bd488669b4cf544e3b363"}, + {file = "ipython-8.17.2-py3-none-any.whl", hash = "sha256:1e4d1d666a023e3c93585ba0d8e962867f7a111af322efff6b9c58062b3e5444"}, + {file = "ipython-8.17.2.tar.gz", hash = "sha256:126bb57e1895594bb0d91ea3090bbd39384f6fe87c3d57fd558d0670f50339bb"}, ] [package.dependencies] appnope = {version = "*", markers = "sys_platform == \"darwin\""} -backcall = "*" colorama = {version = "*", markers = "sys_platform == \"win32\""} decorator = "*" jedi = ">=0.16" matplotlib-inline = "*" pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} -pickleshare = "*" prompt-toolkit = ">=3.0.30,<3.0.37 || >3.0.37,<3.1.0" pygments = ">=2.4.0" stack-data = "*" traitlets = ">=5" -typing-extensions = {version = "*", markers = "python_version < \"3.10\""} [package.extras] -all = ["black", "curio", "docrepr", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.21)", "pandas", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] +all = ["black", "curio", "docrepr", "exceptiongroup", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.22)", "pandas", "pickleshare", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio (<0.22)", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] black = ["black"] -doc = ["docrepr", "ipykernel", "matplotlib", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] +doc = ["docrepr", "exceptiongroup", "ipykernel", "matplotlib", "pickleshare", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio (<0.22)", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] kernel = ["ipykernel"] nbconvert = ["nbconvert"] nbformat = ["nbformat"] notebook = ["ipywidgets", "notebook"] parallel = ["ipyparallel"] qtconsole = ["qtconsole"] -test = ["pytest (<7.1)", "pytest-asyncio", "testpath"] -test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.21)", "pandas", "pytest (<7.1)", "pytest-asyncio", "testpath", "trio"] +test = ["pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath"] +test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.22)", "pandas", "pickleshare", "pytest (<7.1)", "pytest-asyncio (<0.22)", "testpath", "trio"] [[package]] name = "isort" @@ -305,7 +289,6 @@ files = [ [package.dependencies] mypy-extensions = ">=1.0.0" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} typing-extensions = ">=4.1.0" [package.extras] @@ -327,39 +310,47 @@ files = [ [[package]] name = "numpy" -version = "1.24.4" +version = "1.26.2" description = "Fundamental package for array computing in Python" optional = false -python-versions = ">=3.8" -files = [ - {file = "numpy-1.24.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c0bfb52d2169d58c1cdb8cc1f16989101639b34c7d3ce60ed70b19c63eba0b64"}, - {file = "numpy-1.24.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ed094d4f0c177b1b8e7aa9cba7d6ceed51c0e569a5318ac0ca9a090680a6a1b1"}, - {file = "numpy-1.24.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79fc682a374c4a8ed08b331bef9c5f582585d1048fa6d80bc6c35bc384eee9b4"}, - {file = "numpy-1.24.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ffe43c74893dbf38c2b0a1f5428760a1a9c98285553c89e12d70a96a7f3a4d6"}, - {file = "numpy-1.24.4-cp310-cp310-win32.whl", hash = "sha256:4c21decb6ea94057331e111a5bed9a79d335658c27ce2adb580fb4d54f2ad9bc"}, - {file = "numpy-1.24.4-cp310-cp310-win_amd64.whl", hash = "sha256:b4bea75e47d9586d31e892a7401f76e909712a0fd510f58f5337bea9572c571e"}, - {file = "numpy-1.24.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f136bab9c2cfd8da131132c2cf6cc27331dd6fae65f95f69dcd4ae3c3639c810"}, - {file = "numpy-1.24.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e2926dac25b313635e4d6cf4dc4e51c8c0ebfed60b801c799ffc4c32bf3d1254"}, - {file = "numpy-1.24.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:222e40d0e2548690405b0b3c7b21d1169117391c2e82c378467ef9ab4c8f0da7"}, - {file = "numpy-1.24.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7215847ce88a85ce39baf9e89070cb860c98fdddacbaa6c0da3ffb31b3350bd5"}, - {file = "numpy-1.24.4-cp311-cp311-win32.whl", hash = "sha256:4979217d7de511a8d57f4b4b5b2b965f707768440c17cb70fbf254c4b225238d"}, - {file = "numpy-1.24.4-cp311-cp311-win_amd64.whl", hash = "sha256:b7b1fc9864d7d39e28f41d089bfd6353cb5f27ecd9905348c24187a768c79694"}, - {file = "numpy-1.24.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1452241c290f3e2a312c137a9999cdbf63f78864d63c79039bda65ee86943f61"}, - {file = "numpy-1.24.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:04640dab83f7c6c85abf9cd729c5b65f1ebd0ccf9de90b270cd61935eef0197f"}, - {file = "numpy-1.24.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5425b114831d1e77e4b5d812b69d11d962e104095a5b9c3b641a218abcc050e"}, - {file = "numpy-1.24.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd80e219fd4c71fc3699fc1dadac5dcf4fd882bfc6f7ec53d30fa197b8ee22dc"}, - {file = "numpy-1.24.4-cp38-cp38-win32.whl", hash = "sha256:4602244f345453db537be5314d3983dbf5834a9701b7723ec28923e2889e0bb2"}, - {file = "numpy-1.24.4-cp38-cp38-win_amd64.whl", hash = "sha256:692f2e0f55794943c5bfff12b3f56f99af76f902fc47487bdfe97856de51a706"}, - {file = "numpy-1.24.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2541312fbf09977f3b3ad449c4e5f4bb55d0dbf79226d7724211acc905049400"}, - {file = "numpy-1.24.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9667575fb6d13c95f1b36aca12c5ee3356bf001b714fc354eb5465ce1609e62f"}, - {file = "numpy-1.24.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3a86ed21e4f87050382c7bc96571755193c4c1392490744ac73d660e8f564a9"}, - {file = "numpy-1.24.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d11efb4dbecbdf22508d55e48d9c8384db795e1b7b51ea735289ff96613ff74d"}, - {file = "numpy-1.24.4-cp39-cp39-win32.whl", hash = "sha256:6620c0acd41dbcb368610bb2f4d83145674040025e5536954782467100aa8835"}, - {file = "numpy-1.24.4-cp39-cp39-win_amd64.whl", hash = "sha256:befe2bf740fd8373cf56149a5c23a0f601e82869598d41f8e188a0e9869926f8"}, - {file = "numpy-1.24.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:31f13e25b4e304632a4619d0e0777662c2ffea99fcae2029556b17d8ff958aef"}, - {file = "numpy-1.24.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95f7ac6540e95bc440ad77f56e520da5bf877f87dca58bd095288dce8940532a"}, - {file = "numpy-1.24.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:e98f220aa76ca2a977fe435f5b04d7b3470c0a2e6312907b37ba6068f26787f2"}, - {file = "numpy-1.24.4.tar.gz", hash = "sha256:80f5e3a4e498641401868df4208b74581206afbee7cf7b8329daae82676d9463"}, +python-versions = ">=3.9" +files = [ + {file = "numpy-1.26.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3703fc9258a4a122d17043e57b35e5ef1c5a5837c3db8be396c82e04c1cf9b0f"}, + {file = "numpy-1.26.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cc392fdcbd21d4be6ae1bb4475a03ce3b025cd49a9be5345d76d7585aea69440"}, + {file = "numpy-1.26.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36340109af8da8805d8851ef1d74761b3b88e81a9bd80b290bbfed61bd2b4f75"}, + {file = "numpy-1.26.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bcc008217145b3d77abd3e4d5ef586e3bdfba8fe17940769f8aa09b99e856c00"}, + {file = "numpy-1.26.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3ced40d4e9e18242f70dd02d739e44698df3dcb010d31f495ff00a31ef6014fe"}, + {file = "numpy-1.26.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b272d4cecc32c9e19911891446b72e986157e6a1809b7b56518b4f3755267523"}, + {file = "numpy-1.26.2-cp310-cp310-win32.whl", hash = "sha256:22f8fc02fdbc829e7a8c578dd8d2e15a9074b630d4da29cda483337e300e3ee9"}, + {file = "numpy-1.26.2-cp310-cp310-win_amd64.whl", hash = "sha256:26c9d33f8e8b846d5a65dd068c14e04018d05533b348d9eaeef6c1bd787f9919"}, + {file = "numpy-1.26.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b96e7b9c624ef3ae2ae0e04fa9b460f6b9f17ad8b4bec6d7756510f1f6c0c841"}, + {file = "numpy-1.26.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:aa18428111fb9a591d7a9cc1b48150097ba6a7e8299fb56bdf574df650e7d1f1"}, + {file = "numpy-1.26.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06fa1ed84aa60ea6ef9f91ba57b5ed963c3729534e6e54055fc151fad0423f0a"}, + {file = "numpy-1.26.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96ca5482c3dbdd051bcd1fce8034603d6ebfc125a7bd59f55b40d8f5d246832b"}, + {file = "numpy-1.26.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:854ab91a2906ef29dc3925a064fcd365c7b4da743f84b123002f6139bcb3f8a7"}, + {file = "numpy-1.26.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f43740ab089277d403aa07567be138fc2a89d4d9892d113b76153e0e412409f8"}, + {file = "numpy-1.26.2-cp311-cp311-win32.whl", hash = "sha256:a2bbc29fcb1771cd7b7425f98b05307776a6baf43035d3b80c4b0f29e9545186"}, + {file = "numpy-1.26.2-cp311-cp311-win_amd64.whl", hash = "sha256:2b3fca8a5b00184828d12b073af4d0fc5fdd94b1632c2477526f6bd7842d700d"}, + {file = "numpy-1.26.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a4cd6ed4a339c21f1d1b0fdf13426cb3b284555c27ac2f156dfdaaa7e16bfab0"}, + {file = "numpy-1.26.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5d5244aabd6ed7f312268b9247be47343a654ebea52a60f002dc70c769048e75"}, + {file = "numpy-1.26.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a3cdb4d9c70e6b8c0814239ead47da00934666f668426fc6e94cce869e13fd7"}, + {file = "numpy-1.26.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa317b2325f7aa0a9471663e6093c210cb2ae9c0ad824732b307d2c51983d5b6"}, + {file = "numpy-1.26.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:174a8880739c16c925799c018f3f55b8130c1f7c8e75ab0a6fa9d41cab092fd6"}, + {file = "numpy-1.26.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f79b231bf5c16b1f39c7f4875e1ded36abee1591e98742b05d8a0fb55d8a3eec"}, + {file = "numpy-1.26.2-cp312-cp312-win32.whl", hash = "sha256:4a06263321dfd3598cacb252f51e521a8cb4b6df471bb12a7ee5cbab20ea9167"}, + {file = "numpy-1.26.2-cp312-cp312-win_amd64.whl", hash = "sha256:b04f5dc6b3efdaab541f7857351aac359e6ae3c126e2edb376929bd3b7f92d7e"}, + {file = "numpy-1.26.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4eb8df4bf8d3d90d091e0146f6c28492b0be84da3e409ebef54349f71ed271ef"}, + {file = "numpy-1.26.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1a13860fdcd95de7cf58bd6f8bc5a5ef81c0b0625eb2c9a783948847abbef2c2"}, + {file = "numpy-1.26.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:64308ebc366a8ed63fd0bf426b6a9468060962f1a4339ab1074c228fa6ade8e3"}, + {file = "numpy-1.26.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baf8aab04a2c0e859da118f0b38617e5ee65d75b83795055fb66c0d5e9e9b818"}, + {file = "numpy-1.26.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d73a3abcac238250091b11caef9ad12413dab01669511779bc9b29261dd50210"}, + {file = "numpy-1.26.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b361d369fc7e5e1714cf827b731ca32bff8d411212fccd29ad98ad622449cc36"}, + {file = "numpy-1.26.2-cp39-cp39-win32.whl", hash = "sha256:bd3f0091e845164a20bd5a326860c840fe2af79fa12e0469a12768a3ec578d80"}, + {file = "numpy-1.26.2-cp39-cp39-win_amd64.whl", hash = "sha256:2beef57fb031dcc0dc8fa4fe297a742027b954949cabb52a2a376c144e5e6060"}, + {file = "numpy-1.26.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:1cc3d5029a30fb5f06704ad6b23b35e11309491c999838c31f124fee32107c79"}, + {file = "numpy-1.26.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94cc3c222bb9fb5a12e334d0479b97bb2df446fbe622b470928f5284ffca3f8d"}, + {file = "numpy-1.26.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:fe6b44fb8fcdf7eda4ef4461b97b3f63c466b27ab151bec2366db8b197387841"}, + {file = "numpy-1.26.2.tar.gz", hash = "sha256:f65738447676ab5777f11e6bbbdb8ce11b785e105f690bc45966574816b6d3ea"}, ] [[package]] @@ -379,14 +370,7 @@ files = [ ] [package.dependencies] -numpy = [ - {version = ">=1.21.0", markers = "python_version <= \"3.9\" and platform_system == \"Darwin\" and platform_machine == \"arm64\" and python_version >= \"3.8\""}, - {version = ">=1.23.5", markers = "python_version >= \"3.11\""}, - {version = ">=1.21.4", markers = "python_version >= \"3.10\" and platform_system == \"Darwin\" and python_version < \"3.11\""}, - {version = ">=1.21.2", markers = "platform_system != \"Darwin\" and python_version >= \"3.10\" and python_version < \"3.11\""}, - {version = ">=1.19.3", markers = "platform_system == \"Linux\" and platform_machine == \"aarch64\" and python_version >= \"3.8\" and python_version < \"3.10\" or python_version > \"3.9\" and python_version < \"3.10\" or python_version >= \"3.9\" and platform_system != \"Darwin\" and python_version < \"3.10\" or python_version >= \"3.9\" and platform_machine != \"arm64\" and python_version < \"3.10\""}, - {version = ">=1.17.3", markers = "(platform_system != \"Darwin\" and platform_system != \"Linux\") and python_version >= \"3.8\" and python_version < \"3.9\" or platform_system != \"Darwin\" and python_version >= \"3.8\" and python_version < \"3.9\" and platform_machine != \"aarch64\" or platform_machine != \"arm64\" and python_version >= \"3.8\" and python_version < \"3.9\" and platform_system != \"Linux\" or (platform_machine != \"arm64\" and platform_machine != \"aarch64\") and python_version >= \"3.8\" and python_version < \"3.9\""}, -] +numpy = {version = ">=1.23.5", markers = "python_version >= \"3.11\""} [[package]] name = "opencv-python" @@ -405,14 +389,7 @@ files = [ ] [package.dependencies] -numpy = [ - {version = ">=1.21.0", markers = "python_version <= \"3.9\" and platform_system == \"Darwin\" and platform_machine == \"arm64\" and python_version >= \"3.8\""}, - {version = ">=1.23.5", markers = "python_version >= \"3.11\""}, - {version = ">=1.21.4", markers = "python_version >= \"3.10\" and platform_system == \"Darwin\" and python_version < \"3.11\""}, - {version = ">=1.21.2", markers = "platform_system != \"Darwin\" and python_version >= \"3.10\" and python_version < \"3.11\""}, - {version = ">=1.19.3", markers = "platform_system == \"Linux\" and platform_machine == \"aarch64\" and python_version >= \"3.8\" and python_version < \"3.10\" or python_version > \"3.9\" and python_version < \"3.10\" or python_version >= \"3.9\" and platform_system != \"Darwin\" and python_version < \"3.10\" or python_version >= \"3.9\" and platform_machine != \"arm64\" and python_version < \"3.10\""}, - {version = ">=1.17.3", markers = "(platform_system != \"Darwin\" and platform_system != \"Linux\") and python_version >= \"3.8\" and python_version < \"3.9\" or platform_system != \"Darwin\" and python_version >= \"3.8\" and python_version < \"3.9\" and platform_machine != \"aarch64\" or platform_machine != \"arm64\" and python_version >= \"3.8\" and python_version < \"3.9\" and platform_system != \"Linux\" or (platform_machine != \"arm64\" and platform_machine != \"aarch64\") and python_version >= \"3.8\" and python_version < \"3.9\""}, -] +numpy = {version = ">=1.23.5", markers = "python_version >= \"3.11\""} [[package]] name = "packaging" @@ -465,17 +442,6 @@ files = [ [package.dependencies] ptyprocess = ">=0.5" -[[package]] -name = "pickleshare" -version = "0.7.5" -description = "Tiny 'shelve'-like database with concurrency support" -optional = false -python-versions = "*" -files = [ - {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"}, - {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, -] - [[package]] name = "platformdirs" version = "4.0.0" @@ -607,17 +573,6 @@ files = [ {file = "tokenize_rt-5.2.0.tar.gz", hash = "sha256:9fe80f8a5c1edad2d3ede0f37481cc0cc1538a2f442c9c2f9e4feacd2792d054"}, ] -[[package]] -name = "tomli" -version = "2.0.1" -description = "A lil' TOML parser" -optional = false -python-versions = ">=3.7" -files = [ - {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, - {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, -] - [[package]] name = "traitlets" version = "5.13.0" @@ -657,5 +612,5 @@ files = [ [metadata] lock-version = "2.0" -python-versions = "^3.8.1" -content-hash = "f1140ad0423372d5c2fed73d7bad54357ef4c684735d27f1c77aba0d9758dc0d" +python-versions = "^3.11.4" +content-hash = "225e96d9235212a2c17f57bc60cce470017cbc0520147c1935d795500d189a20" diff --git a/pyproject.toml b/pyproject.toml index f823566..27bca12 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,17 +6,28 @@ authors = ["Jason "] readme = "README.md" [tool.poetry.dependencies] -python = "^3.8.1" +python = "^3.11.4" opencv-python = "^4.8.1.78" caer = "^2.0.8" [tool.poetry.group.dev.dependencies] -black = {extras = ["jupyter"], version = "^23.11.0"} +black = { extras = ["jupyter"], version = "^23.11.0" } isort = "^5.12.0" flake8 = "^6.1.0" -mypy = "^1.7.0" [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" + +[tool.black] +line-length = 100 + +[tool.isort] +profile = "black" +line_length = 100 +wrap_length = 100 +multi_line_output = 3 +combine_as_imports = true +force_alphabetical_sort_within_sections = true +overwrite_in_place = true \ No newline at end of file From ed28e962d1aef377717e5ed6a2d045703924a2f2 Mon Sep 17 00:00:00 2001 From: Anton Bagrianov Date: Thu, 16 Nov 2023 01:44:55 +0400 Subject: [PATCH 6/7] Update README.md --- README.md | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d106615..25752b9 100644 --- a/README.md +++ b/README.md @@ -8,13 +8,24 @@ Notes and code used in my [**Python and OpenCV course**](https://youtu.be/oXlwWb # Course Outline (with timestamps) ## 1. Installation -Besides installing OpenCV, we cover the installation of the following package: -[**`Caer`**](https://github.com/jasmcaus/caer/) is a *lightweight, high-performance* Vision library for high-performance AI research. It simplifies your approach towards Computer Vision by abstracting away unnecessary boilerplate code giving you the **flexibility** to quickly prototype deep learning models and research ideas. +### 1. Using Poetry + +Install poetry using your package manager or [official guide](https://python-poetry.org/docs/#installation). + +The easiest way to install all required dependencies is as follows: + ```bash -$ pip install caer +make install ``` +### 2. Using pip + +```bash +$ pip install -r requirements.txt +``` + + ## 2. Basic Concepts: - Reading Images and Video ([0:04:12](https://www.youtube.com/watch?v=x3c8w2ruhjs&t=252s)) @@ -46,3 +57,7 @@ The images in the [Photos](https://github.com/jasmcaus/opencv-course/tree/master The images in the [Faces](https://github.com/jasmcaus/opencv-course/tree/master/Resources/Faces) folder were procurred from a [repo](https://www.kaggle.com/dansbecker/5-celebrity-faces-dataset) on Kaggle. + +# Contributors +Please make sure you have dev dependencies installed and your PR code formatted using `make format` and linted using +`make lint` \ No newline at end of file From 1f90b3bd665d9fbed87a233b279710d98733e739 Mon Sep 17 00:00:00 2001 From: Anton Bagrianov Date: Thu, 16 Nov 2023 01:45:05 +0400 Subject: [PATCH 7/7] Add requirements.dev.txt --- requirements.dev.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 requirements.dev.txt diff --git a/requirements.dev.txt b/requirements.dev.txt new file mode 100644 index 0000000..0ccc4d5 --- /dev/null +++ b/requirements.dev.txt @@ -0,0 +1,3 @@ +black +isort +flake8 \ No newline at end of file