# This file is part of OpenCV project. # It is subject to the license terms in the LICENSE file found in the top-level directory # of this distribution and at http://opencv.org/license.html. # Copyright (C) 2026, BigVision LLC, all rights reserved. # Third party copyrights are property of their respective owners. from __future__ import annotations import os as _os, pathlib, sys as _sys # Config dir isn't on sys.path under config/source-dir separation; add it. _sys.path.insert(0, _os.path.dirname(_os.path.abspath(__file__))) from conf_helpers.state import ( DOC_ROOT, CONTRIB_ROOT, SPHINX_INPUT_ROOT, DOC_MODULES, JS_DOC_MODULES, PY_DOC_MODULES, CONTRIB_MODULES, API_MODULES, DOXYGEN_BASE_URL, _PATCHED_XML_DIR, HAVE_BREATHE, USE_INDEX_LANDING, ) import conf_helpers.build # noqa: F401 bib staging, scans, API stubs, indexes. import conf_helpers.patches # noqa: F401 Sphinx C++ xref + warning patches. from conf_helpers.translate import _source_read from conf_helpers.postprocess import _inline_coll_graphs_on_finish # -- Project ---------------------------------------------------------------- project = "OpenCV" author = "OpenCV Team" release = "5.0" # -- Sphinx core ------------------------------------------------------------ extensions = ["myst_parser"] for _ext in ("sphinx_design", "sphinx_copybutton"): try: __import__(_ext) extensions.append(_ext) except ImportError: pass # -- Breathe (Doxygen XML -> Sphinx C++ domain) ----------------------------- if HAVE_BREATHE: extensions.append("breathe") breathe_projects = {"opencv": str(_PATCHED_XML_DIR)} breathe_default_project = "opencv" breathe_default_members = () source_suffix = {".md": "markdown", ".markdown": "markdown"} # Swallow OpenCV's compatibility macros during C++ parsing, else signatures # like `... getName() const CV_OVERRIDE` raise "Invalid C++ declaration". cpp_id_attributes = [ "CV_OVERRIDE", "CV_FINAL", "CV_NOEXCEPT", "CV_NORETURN", "CV_DEPRECATED", "CV_DEPRECATED_EXTERNAL", "CV_NODISCARD_STD", "CV_NODISCARD", "CV_EXPORTS", "CV_EXPORTS_W", "CV_WRAP", # Python-binding macros prefixing decls like `CV_PROP_RW Point2f pt`. "CV_PROP", "CV_PROP_RW", "CV_PROP_W", "CV_OUT", "CV_IN_OUT", ] c_id_attributes = list(cpp_id_attributes) master_doc = "index" if USE_INDEX_LANDING else "tutorials/tutorials" # Scope: master + enabled main modules + (optionally) enabled contrib modules. include_patterns = (["index.markdown"] if USE_INDEX_LANDING else []) + [ "tutorials/tutorials.markdown", "faq.markdown", "citelist.markdown", "intro.markdown", "related_pages.markdown", "namespace_list.markdown", "class_list.markdown"] + [ f"tutorials/{m}/**" for m in DOC_MODULES ] + (["js_tutorials/js_tutorials.markdown"] if JS_DOC_MODULES else []) + [ f"js_tutorials/{m}/**" for m in JS_DOC_MODULES ] + (["py_tutorials/py_tutorials.markdown"] if PY_DOC_MODULES else []) + [ f"py_tutorials/{m}/**" for m in PY_DOC_MODULES ] if CONTRIB_MODULES and (SPHINX_INPUT_ROOT / "tutorials_contrib").is_dir(): include_patterns.append("tutorials_contrib/contrib_root.markdown") include_patterns += [f"tutorials_contrib/{m}/**" for m in CONTRIB_MODULES] if API_MODULES: # Glob: the stub file set (generated later) is unknown here. include_patterns.append("main_modules/**") include_patterns.append("extra_modules/**") # Orphan example pages; without this glob the class-page Examples links 404. include_patterns.append("examples/**") exclude_patterns = [ "**/Thumbs.db", "**/.DS_Store", "**/_old/**", "tutorials/core/how_to_use_OpenCV_parallel_for_/**", "tutorials/introduction/load_save_image/**", "tutorials/app/_old/**", ] myst_enable_extensions = [ "colon_fence", "deflist", "dollarmath", "amsmath", "attrs_inline", "attrs_block", "smartquotes", ] myst_heading_anchors = 4 # OpenCV's custom LaTeX macros (\vecthree, \cameramatrix, …) — ported from # doc/mymath.js so MathJax resolves them the same way the Doxygen site does. mathjax3_config = { "loader": {"load": ["[tex]/ams"]}, "tex": { "packages": {"[+]": ["ams"]}, "macros": { "matTT": [r"\[ \left|\begin{array}{ccc} #1 & #2 & #3\\ #4 & #5 & #6\\ #7 & #8 & #9 \end{array}\right| \]", 9], "fork": [r"\left\{ \begin{array}{l l} #1 & \mbox{#2}\\ #3 & \mbox{#4}\\ \end{array} \right.", 4], "forkthree": [r"\left\{ \begin{array}{l l} #1 & \mbox{#2}\\ #3 & \mbox{#4}\\ #5 & \mbox{#6}\\ \end{array} \right.", 6], "forkfour": [r"\left\{ \begin{array}{l l} #1 & \mbox{#2}\\ #3 & \mbox{#4}\\ #5 & \mbox{#6}\\ #7 & \mbox{#8}\\ \end{array} \right.", 8], "vecthree": [r"\begin{bmatrix} #1\\ #2\\ #3 \end{bmatrix}", 3], "vecthreethree": [r"\begin{bmatrix} #1 & #2 & #3\\ #4 & #5 & #6\\ #7 & #8 & #9 \end{bmatrix}", 9], "cameramatrix": [r"#1 = \begin{bmatrix} f_x & 0 & c_x\\ 0 & f_y & c_y\\ 0 & 0 & 1 \end{bmatrix}", 1], "distcoeffs": [r"(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \tau_x, \tau_y]]]]) \text{ of 4, 5, 8, 12 or 14 elements}"], "distcoeffsfisheye": [r"(k_1, k_2, k_3, k_4)"], "hdotsfor": [r"\dots", 1], "mathbbm": [r"\mathbb{#1}", 1], "bordermatrix": [r"\matrix{#1}", 1], }, }, } suppress_warnings = [ "myst.header", "myst.xref_missing", "toc.not_included", "misc.highlighting_failure", "image.not_readable", # Same C++ symbol legitimately appears on >1 generated page (group + namespace). "cpp.duplicate_declaration", ] # -- HTML / PyData theme ---------------------------------------------------- try: import pydata_sphinx_theme # noqa: F401 html_theme = "pydata_sphinx_theme" except ImportError: html_theme = "alabaster" html_title = "OpenCV Tutorials" html_show_sourcelink = False templates_path = ["_templates"] html_static_path = ["_static"] html_css_files = [ "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700" "&family=JetBrains+Mono:wght@400;500&display=swap", "custom.css", ] html_theme_options = { "logo": { "text": f"OpenCV {release}", "image_light": "_static/opencv-logo.svg", "image_dark": "_static/opencv-logo.svg", }, # Navbar layout: logo on the left, version switcher right beside it — # mirrors the legacy docs.opencv.org header where the version selector # sits inline with the wordmark. The switcher template reads the shared # /version.js (window.OPENCV_DOC_VERSIONS); no build-time list is generated. "navbar_start": ["navbar-logo", "opencv-version-switcher"], "header_links_before_dropdown": 6, "external_links": [ {"docname": master_doc, "name": "Main Page"}, {"docname": "related_pages", "name": "Related Pages"}, {"docname": "namespace_list", "name": "Namespaces"}, {"docname": "class_list", "name": "Classes"}, {"docname": "examples/examples_root", "name": "Examples"}, {"url": DOXYGEN_BASE_URL + "javadoc/", "name": "Java documentation", "external": True}, ], "navbar_persistent": [], "navbar_end": ["search-button-field", "theme-switcher", "navbar-icon-links"], "disable_search": True, "show_toc_level": 2, "navigation_with_keys": True, "show_prev_next": True, "show_nav_level": 2, "navigation_depth": 4, "secondary_sidebar_items": {"**": ["page-toc"], "index": []}, "back_to_top_button": True, "show_version_warning_banner": False, "icon_links": [{"name": "GitHub", "url": "https://github.com/opencv/opencv", "icon": "fa-brands fa-github"}], } html_extra_path: list[str] = [] def _in_source_tree(p: pathlib.Path) -> bool: for _root in (DOC_ROOT, CONTRIB_ROOT): try: p.relative_to(_root); return True except ValueError: pass return False if not _in_source_tree(SPHINX_INPUT_ROOT): _extras = SPHINX_INPUT_ROOT.parent / "contrib_extras" _prefix = _extras / "contrib_modules" _prefix.mkdir(parents=True, exist_ok=True) for _m in CONTRIB_MODULES: _src, _link = CONTRIB_ROOT / _m, _prefix / _m if _src.is_dir() and not _link.exists(): try: _os.symlink(_src, _link, target_is_directory=True) except (OSError, NotImplementedError): pass html_extra_path = [str(_extras)] def setup(app): app.connect("source-read", _source_read) app.connect("build-finished", _inline_coll_graphs_on_finish) return {"parallel_read_safe": True, "parallel_write_safe": True}