diff --git a/.github/workflows/build_maixcam.yml b/.github/workflows/build_maixcam.yml new file mode 100755 index 00000000..04a04b14 --- /dev/null +++ b/.github/workflows/build_maixcam.yml @@ -0,0 +1,94 @@ +# This is a basic workflow to help you get started with Actions + +name: Build MaixCAM + +# Controls when the action will run. +on: + # Triggers the workflow on push or pull request events but only for the main branch + push: + branches: [ main ] + # pull_request: + # branches: [ main ] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +permissions: write-all + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + build: + # Only run job for specific repository + if: github.repository == 'sipeed/MaixPy' + # The type of runner that the job will run on + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.11"] # MaixCAM use 3.11 + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Build MaixPy + run: | + echo "-- Check python version must python 3.11 --" + python3 -c 'import sys;print(sys.version);assert sys.version_info >= (3, 11);assert sys.version_info < (3, 12)' + python -c 'import sys;print(sys.version);assert sys.version_info >= (3, 11);assert sys.version_info < (3, 12)' + whereis python + whereis python3 + # export PATH=~/.local/bin/:$PATH + # pull sipeed/MaixCDK repo here first + pwd_path=$(pwd) + cd ~ + git clone https://github.com/sipeed/MaixCDK --depth=1 + export MAIXCDK_PATH=`pwd`/MaixCDK + cd $pwd_path + python -m pip install -U pip setuptools wheel + python -m pip install -r $MAIXCDK_PATH/requirements.txt + python -m pip install pybind11-stubgen + echo "--------------------------------" + echo "-- Build MaixPy for Linux now --" + echo "--------------------------------" + sudo apt update -y + sudo apt install -y libopencv-dev libopencv-contrib-dev libsdl2-dev cmake + cmake --version + python setup.py bdist_wheel linux + echo "----------------------------------" + echo "-- Build MaixPy for MaixCAM now --" + echo "----------------------------------" + python setup.py bdist_wheel maixcam + + # Runs a set of commands using the runners shell + - name: Push doc to github pages + run: | + pip3 install teedoc + cd docs + echo "== install plugins ==" + teedoc install + echo "== start build ==" + teedoc build + echo "== build complete ==" + remote_addr=`git remote get-url --push origin` + remote_addr=`echo $remote_addr| awk -F'://' '{print $2}'` + user_name=`git log -1 --pretty=format:'%an'` + user_email=`git log -1 --pretty=format:'%ae'` + echo "== checkout gh-pages branch ==" + cd out + cp -r ../../.github . + git config --global init.defaultBranch gh-pages + git init + git config user.name "${user_name}" + git config user.email ${user_email} + remote_addr="https://Neutree:${{ secrets.DISPATCH_PAT }}@${remote_addr}" + echo "-- user ${user_name}" + echo "-- remote addr: ${remote_addr}" + git remote add origin "${remote_addr}" + echo "== add web files ==" + git add -A + git commit -m "Rebuild MaixPy doc by commit $GITHUB_REF" + git push origin HEAD:gh-pages --force + echo "== push complete ==" diff --git a/.github/workflows/trigger_wiki.yml b/.github/workflows/trigger_wiki.yml new file mode 100755 index 00000000..35e99749 --- /dev/null +++ b/.github/workflows/trigger_wiki.yml @@ -0,0 +1,45 @@ +# This is a basic workflow to help you get started with Actions + +name: trigger wiki + +# Controls when the action will run. +on: + push: + branches: + - gh-pages + pull_request: + branches: + - gh-pages + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +permissions: write-all + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + trigger_wiki: + name: trigger sipeed_wiki + # Only run job for specific repository + # if: github.repository == 'sipeed/MaixPy' + # The type of runner that the job will run on + runs-on: ubuntu-latest + # strategy: + # matrix: + # python-version: [3.8] + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + - name: trigger sipeed wiki request + uses: actions/github-script@v6 + with: + github-token: ${{ secrets.DISPATCH_PAT }} + script: | + const result = await github.rest.repos.createDispatchEvent({ + owner: 'sipeed', + repo: 'sipeed_wiki', + event_type: 'update_maixpy_doc', + client_payload: {"key": "value"} + }) + console.log(result); diff --git a/maixpy/404.html b/maixpy/404.html new file mode 100644 index 00000000..1653f535 --- /dev/null +++ b/maixpy/404.html @@ -0,0 +1,211 @@ + + + + + + + + + + + + + + + + + + + MaixPy + + + + + + + + + + + +
+
+
+ + +

404 页面未找到

+ + + + + +
+ 返回上一页 首页 +
+ + + +
+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/api.json b/maixpy/api/api.json new file mode 100644 index 00000000..462bb1e6 --- /dev/null +++ b/maixpy/api/api.json @@ -0,0 +1,18845 @@ +{ + "type": "top_module", + "members": { + "maix": { + "type": "module", + "doc": { + "breif": "MaixPy C/C++ API from MaixCDK" + }, + "members": { + "err": { + "type": "module", + "doc": { + "brief": "maix.err module" + }, + "members": { + "Err": { + "type": "enum", + "name": "Err", + "doc": { + "brief": "Maix Error code", + "maixpy": "maix.err.Err", + "py_doc": "Maix Error code" + }, + "values": [ + [ + "ERR_NONE", + "0", + "No error" + ], + [ + "ERR_ARGS", + "", + "Invalid arguments" + ], + [ + "ERR_NO_MEM", + "", + "No memory" + ], + [ + "ERR_NOT_IMPL", + "", + "Not implemented" + ], + [ + "ERR_NOT_READY", + "", + "Not ready" + ], + [ + "ERR_NOT_INIT", + "", + "Not initialized" + ], + [ + "ERR_NOT_OPEN", + "", + "Not opened" + ], + [ + "ERR_NOT_PERMIT", + "", + "Not permitted" + ], + [ + "ERR_REOPEN", + "", + "Re-open" + ], + [ + "ERR_BUSY", + "", + "Busy" + ], + [ + "ERR_READ", + "", + "Read error" + ], + [ + "ERR_WRITE", + "", + "Write error" + ], + [ + "ERR_TIMEOUT", + "", + "Timeout" + ], + [ + "ERR_RUNTIME", + "", + "Runtime error" + ], + [ + "ERR_IO", + "", + "IO error" + ], + [ + "ERR_NOT_FOUND", + "", + "Not found" + ], + [ + "ERR_ALREAY_EXIST", + "", + "Already exist" + ], + [ + "ERR_BUFF_FULL", + "", + "Buffer full" + ], + [ + "ERR_BUFF_EMPTY", + "", + "Buffer empty" + ], + [ + "ERR_CANCEL", + "", + "Cancel" + ], + [ + "ERR_OVERFLOW", + "", + "Overflow" + ], + [ + "ERR_MAX", + "", + "" + ] + ], + "def": "enum Err\n {\n // !!! fixed error code, DO NOT change number already defined, only append new error code\n ERR_NONE = 0, // No error\n ERR_ARGS , // Invalid arguments\n ERR_NO_MEM , // No memory\n ERR_NOT_IMPL , // Not implemented\n ERR_NOT_READY , // Not ready\n ERR_NOT_INIT , // Not initialized\n ERR_NOT_OPEN , // Not opened\n ERR_NOT_PERMIT , // Not permitted\n ERR_REOPEN , // Re-open\n ERR_BUSY , // Busy\n ERR_READ , // Read error\n ERR_WRITE , // Write error\n ERR_TIMEOUT , // Timeout\n ERR_RUNTIME , // Runtime error\n ERR_IO , // IO error\n ERR_NOT_FOUND , // Not found\n ERR_ALREAY_EXIST , // Already exist\n ERR_BUFF_FULL , // Buffer full\n ERR_BUFF_EMPTY , // Buffer empty\n ERR_CANCEL , // Cancel\n ERR_OVERFLOW , // Overflow\n ERR_MAX,\n }" + }, + "Exception": { + "type": "class", + "name": "Exception", + "doc": { + "brief": "Maix Exception", + "maixpy": "maix.err.Exception", + "py_doc": "Maix Exception" + }, + "members": {}, + "def": "class Exception : public std::exception" + }, + "to_str": { + "type": "func", + "name": "to_str", + "doc": { + "brief": "Error code to string", + "param": { + "e": "direction [in], error code, err::Err type" + }, + "return": "error string", + "maixpy": "maix.err.to_str", + "py_doc": "Error code to string\n\nArgs:\n - e: direction [in], error code, err::Err type\n\n\nReturns: error string\n" + }, + "args": [ + [ + "err::Err", + "e", + null + ] + ], + "ret_type": "std::string", + "static": false, + "def": "std::string to_str(err::Err e)", + "py_def": "def to_str(e: Err) -> str" + }, + "get_error": { + "type": "func", + "name": "get_error", + "doc": { + "brief": "get last error string", + "return": "error string", + "maixpy": "maix.err.get_error", + "py_doc": "get last error string\n\nReturns: error string\n" + }, + "args": [], + "ret_type": "std::string&", + "static": false, + "def": "std::string& get_error()", + "py_def": "def get_error() -> str" + }, + "set_error": { + "type": "func", + "name": "set_error", + "doc": { + "brief": "set last error string", + "param": { + "str": "direction [in], error string" + }, + "maixpy": "maix.err.set_error", + "py_doc": "set last error string\n\nArgs:\n - str: direction [in], error string\n" + }, + "args": [ + [ + "const std::string &", + "str", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_error(const std::string &str)", + "py_def": "def set_error(str: str) -> None" + }, + "check_raise": { + "type": "func", + "name": "check_raise", + "doc": { + "brief": "Check error code, if not ERR_NONE, raise err.Exception", + "param": { + "e": "direction [in], error code, err::Err type", + "msg": "direction [in], error message" + }, + "maixpy": "maix.err.check_raise", + "py_doc": "Check error code, if not ERR_NONE, raise err.Exception\n\nArgs:\n - e: direction [in], error code, err::Err type\n - msg: direction [in], error message\n" + }, + "args": [ + [ + "err::Err", + "e", + null + ], + [ + "const std::string &", + "msg", + "\"\"" + ] + ], + "ret_type": "void", + "static": false, + "def": "void check_raise(err::Err e, const std::string &msg = \"\")", + "py_def": "def check_raise(e: Err, msg: str = '') -> None" + }, + "check_bool_raise": { + "type": "func", + "name": "check_bool_raise", + "doc": { + "brief": "Check condition, if false, raise err.Exception", + "param": { + "ok": "direction [in], condition, if true, do nothing, if false, raise err.Exception", + "msg": "direction [in], error message" + }, + "maixpy": "maix.err.check_bool_raise", + "py_doc": "Check condition, if false, raise err.Exception\n\nArgs:\n - ok: direction [in], condition, if true, do nothing, if false, raise err.Exception\n - msg: direction [in], error message\n" + }, + "args": [ + [ + "bool", + "ok", + null + ], + [ + "const std::string &", + "msg", + "\"\"" + ] + ], + "ret_type": "void", + "static": false, + "def": "void check_bool_raise(bool ok, const std::string &msg = \"\")", + "py_def": "def check_bool_raise(ok: bool, msg: str = '') -> None" + }, + "check_null_raise": { + "type": "func", + "name": "check_null_raise", + "doc": { + "brief": "Check NULL pointer, if NULL, raise exception", + "param": { + "ptr": "direction [in], pointer", + "msg": "direction [in], error message" + }, + "maixpy": "maix.err.check_null_raise", + "py_doc": "Check NULL pointer, if NULL, raise exception\n\nArgs:\n - ptr: direction [in], pointer\n - msg: direction [in], error message\n" + }, + "args": [ + [ + "void *", + "ptr", + null + ], + [ + "const std::string &", + "msg", + "\"\"" + ] + ], + "ret_type": "void", + "static": false, + "def": "void check_null_raise(void *ptr, const std::string &msg = \"\")", + "py_def": "def check_null_raise(ptr: capsule, msg: str = '') -> None" + } + }, + "auto_add": true + }, + "tensor": { + "type": "module", + "doc": { + "brief": "maix.tensor module" + }, + "members": { + "DType": { + "type": "enum", + "name": "DType", + "doc": { + "brief": "Tensor data types", + "maixpy": "maix.tensor.DType", + "py_doc": "Tensor data types" + }, + "values": [ + [ + "UINT8", + "0", + "" + ], + [ + "INT8", + "", + "" + ], + [ + "UINT16", + "", + "" + ], + [ + "INT16", + "", + "" + ], + [ + "UINT32", + "", + "" + ], + [ + "INT32", + "", + "" + ], + [ + "FLOAT16", + "", + "" + ], + [ + "FLOAT32", + "", + "" + ], + [ + "FLOAT64", + "", + "" + ], + [ + "BOOL", + "", + "" + ], + [ + "DTYPE_MAX", + "", + "" + ] + ], + "def": "enum DType\n {\n UINT8 = 0,\n INT8,\n UINT16,\n INT16,\n UINT32,\n INT32,\n FLOAT16,\n FLOAT32,\n FLOAT64,\n BOOL,\n // STRING,\n // OBJECT,\n DTYPE_MAX\n }" + }, + "dtype_size": { + "type": "var", + "name": "", + "doc": { + "brief": "Tensor data type size in bytes", + "attention": "It's a copy of this variable in MaixPy,\nso change it in C++ (e.g. update var in hello function) will not take effect the var inMaixPy.\nSo we add const for this var to avoid this mistake.", + "maixpy": "maix.tensor.dtype_size", + "py_doc": "Tensor data type size in bytes" + }, + "value": "{\n 1, // UINT8\n 1, // INT8\n 2, // UINT16\n 2, // INT16\n 4, // UINT32\n 4, // INT32\n 2, // FLOAT16\n 4, // FLOAT32\n 8, // FLOAT64\n 1, // BOOL\n // 1, // STRING\n // 1, // OBJECT\n 0\n }", + "static": false, + "readonly": true, + "def": "const std::vector dtype_size = {\n 1, // UINT8\n 1, // INT8\n 2, // UINT16\n 2, // INT16\n 4, // UINT32\n 4, // INT32\n 2, // FLOAT16\n 4, // FLOAT32\n 8, // FLOAT64\n 1, // BOOL\n // 1, // STRING\n // 1, // OBJECT\n 0\n }" + }, + "dtype_name": { + "type": "var", + "name": "", + "doc": { + "brief": "Tensor data type name", + "maixpy": "maix.tensor.dtype_name", + "py_doc": "Tensor data type name" + }, + "value": "{\n \"uint8\",\n \"int8\",\n \"uint16\",\n \"int16\",\n \"uint32\",\n \"int32\",\n \"float16\",\n \"float32\",\n \"float64\",\n \"bool\",\n // \"string\",\n // \"object\",\n \"invalid\"\n }", + "static": false, + "readonly": true, + "def": "const std::vector dtype_name = {\n \"uint8\",\n \"int8\",\n \"uint16\",\n \"int16\",\n \"uint32\",\n \"int32\",\n \"float16\",\n \"float32\",\n \"float64\",\n \"bool\",\n // \"string\",\n // \"object\",\n \"invalid\"\n }" + }, + "Tensor": { + "type": "class", + "name": "Tensor", + "doc": { + "brief": "Tensor class", + "maixpy": "maix.tensor.Tensor", + "py_doc": "Tensor class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Tensor", + "doc": { + "brief": "Tensor constructor", + "param": { + "shape": "tensor shape, a int list", + "dtype": "tensor element data type, see DType of this module", + "data": "pointer to data content, can be nullptr, it will automatically alloc memory\nand detroy it when this object is destroyed" + }, + "maixpy": "maix.tensor.Tensor.__init__", + "py_doc": "Tensor constructor\n\nArgs:\n - shape: tensor shape, a int list\n - dtype: tensor element data type, see DType of this module\n - data: pointer to data content, can be nullptr, it will automatically alloc memory\nand detroy it when this object is destroyed\n" + }, + "args": [ + [ + "std::vector", + "shape", + null + ], + [ + "tensor::DType", + "dtype", + null + ], + [ + "void *", + "data", + "nullptr" + ] + ], + "ret_type": null, + "static": false, + "def": "Tensor(std::vector shape, tensor::DType dtype, void *data = nullptr)" + }, + "to_str": { + "type": "func", + "name": "to_str", + "doc": { + "brief": "To string", + "maixpy": "maix.tensor.Tensor.to_str", + "py_doc": "To string" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string to_str()" + }, + "__str__": { + "type": "func", + "name": "__str__", + "doc": { + "brief": "To string", + "maixpy": "maix.tensor.Tensor.__str__", + "py_doc": "To string" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string __str__()" + }, + "shape": { + "type": "func", + "name": "shape", + "doc": { + "brief": "get tensor shape", + "return": "tensor shape, a int list", + "maixpy": "maix.tensor.Tensor.shape", + "py_doc": "get tensor shape\n\nReturns: tensor shape, a int list\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector shape()" + }, + "expand_dims": { + "type": "func", + "name": "expand_dims", + "doc": { + "brief": "expand tensor shape", + "param": { + "axis": "axis to expand" + }, + "maixpy": "maix.tensor.Tensor.expand_dims", + "py_doc": "expand tensor shape\n\nArgs:\n - axis: axis to expand\n" + }, + "args": [ + [ + "int", + "axis", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void expand_dims(int axis)" + }, + "reshape": { + "type": "func", + "name": "reshape", + "doc": { + "brief": "reshape tensor shape, if size not match, it will throw an err::Exception", + "param": { + "shape": "new shape" + }, + "maixpy": "maix.tensor.Tensor.reshape", + "py_doc": "reshape tensor shape, if size not match, it will throw an err::Exception\n\nArgs:\n - shape: new shape\n" + }, + "args": [ + [ + "std::vector", + "shape", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void reshape(std::vector shape)" + }, + "flatten": { + "type": "func", + "name": "flatten", + "doc": { + "brief": "Flatten tensor shape to 1D", + "maixpy": "maix.tensor.Tensor.flatten", + "py_doc": "Flatten tensor shape to 1D" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void flatten()" + }, + "dtype": { + "type": "func", + "name": "dtype", + "doc": { + "brief": "get tensor data type", + "return": "tensor data type, see DType of this module", + "maixpy": "maix.tensor.Tensor.dtype", + "py_doc": "get tensor data type\n\nReturns: tensor data type, see DType of this module\n" + }, + "args": [], + "ret_type": "tensor::DType", + "static": false, + "def": "tensor::DType dtype()" + }, + "argmax": { + "type": "func", + "name": "argmax", + "doc": { + "brief": "argmax of tensor", + "param": { + "axis": "By default, the index is into the flattened array, otherwise along the specified axis., wrong axis will throw an err::Exception" + }, + "return": "argmax result, you need to delete it after use in C++.", + "maixpy": "maix.tensor.Tensor.argmax", + "py_doc": "argmax of tensor\n\nArgs:\n - axis: By default, the index is into the flattened array, otherwise along the specified axis., wrong axis will throw an err::Exception\n\n\nReturns: argmax result, you need to delete it after use in C++.\n" + }, + "args": [ + [ + "int", + "axis", + "0xffff" + ] + ], + "ret_type": "tensor::Tensor*", + "static": false, + "def": "tensor::Tensor *argmax(int axis = 0xffff)" + }, + "argmax1": { + "type": "func", + "name": "argmax1", + "doc": { + "brief": "argmax1, flattened data max index", + "return": "argmax result, int type", + "maixpy": "maix.tensor.Tensor.argmax1", + "py_doc": "argmax1, flattened data max index\n\nReturns: argmax result, int type\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int argmax1()" + } + }, + "def": "class Tensor" + }, + "Tensors": { + "type": "class", + "name": "Tensors", + "doc": { + "brief": "Tensors", + "maixpy": "maix.tensor.Tensors", + "py_doc": "Tensors" + }, + "members": { + "__init__": { + "type": "func", + "name": "Tensors", + "doc": { + "brief": "Constructor of Tensors", + "maixpy": "maix.tensor.Tensors.__init__", + "maixcdk": "maix.tensor.Tensors.Tensors", + "py_doc": "Constructor of Tensors" + }, + "args": [], + "ret_type": null, + "static": false, + "def": "Tensors()", + "py_def": "def __init__(self) -> None" + }, + "add_tensor": { + "type": "func", + "name": "add_tensor", + "doc": { + "brief": "Add tensor", + "maixpy": "maix.tensor.Tensors.add_tensor", + "py_doc": "Add tensor" + }, + "args": [ + [ + "const std::string &", + "key", + null + ], + [ + "tensor::Tensor *", + "tensor", + null + ], + [ + "bool", + "copy", + null + ], + [ + "bool", + "auto_delete", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void add_tensor(const std::string &key, tensor::Tensor *tensor, bool copy, bool auto_delete)", + "py_def": "def add_tensor(self, key: str, tensor: Tensor, copy: bool, auto_delete: bool) -> None" + }, + "rm_tensor": { + "type": "func", + "name": "rm_tensor", + "doc": { + "brief": "Remove tensor", + "maixpy": "maix.tensor.Tensors.rm_tensor", + "py_doc": "Remove tensor" + }, + "args": [ + [ + "const std::string &", + "key", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void rm_tensor(const std::string &key)", + "py_def": "def rm_tensor(self, key: str) -> None" + }, + "get_tensor": { + "type": "func", + "name": "get_tensor", + "doc": { + "brief": "Get tensor by key", + "maixpy": "maix.tensor.Tensors.get_tensor", + "maixcdk": "maix.tensor.Tensors.get_tensor", + "py_doc": "Get tensor by key" + }, + "args": [ + [ + "const std::string &", + "key", + null + ] + ], + "ret_type": "tensor::Tensor*", + "static": false, + "def": "tensor::Tensor *get_tensor(const std::string &key)", + "py_def": "def get_tensor(self, key: str) -> Tensor" + }, + "__getitem__": { + "type": "func", + "name": "operator[]", + "doc": { + "brief": "Operator []", + "maixpy": "maix.tensor.Tensors.__getitem__", + "maixcdk": "maix.tensor.Tensors.[]", + "py_doc": "Operator []" + }, + "args": [ + [ + "const std::string &", + "key", + null + ] + ], + "ret_type": "tensor::Tensor*", + "static": false, + "def": "tensor::Tensor *operator[](const std::string &key)", + "py_def": "def __getitem__(self, key: str) -> Tensor" + }, + "__len__": { + "type": "func", + "name": "size", + "doc": { + "brief": "Size", + "maixpy": "maix.tensor.Tensors.__len__", + "maixcdk": "maix.tensor.Tensors.size", + "py_doc": "Size" + }, + "args": [], + "ret_type": "size_t", + "static": false, + "def": "size_t size()", + "py_def": "def __len__(self) -> int" + }, + "get_names": { + "type": "func", + "name": "get_names", + "doc": { + "brief": "Get names", + "maixpy": "maix.tensor.Tensors.get_names", + "py_doc": "Get names" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector get_names()", + "py_def": "def get_names(self) -> list[str]" + }, + "tensors": { + "type": "var", + "name": "tensors", + "doc": { + "brief": "Tensors data, dict type", + "maixpy": "maix.tensor.Tensors.tensors", + "py_doc": "Tensors data, dict type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::map tensors" + } + }, + "def": "class Tensors" + } + }, + "auto_add": true + }, + "image": { + "type": "module", + "doc": { + "brief": "maix.image module, image related definition and functions", + "maixpy": "maix.image", + "py_doc": "maix.image module, image related definition and functions" + }, + "members": { + "Format": { + "type": "enum", + "name": "Format", + "doc": { + "brief": "Image formats", + "attention": "for developers, update this enum will also need to update the fmt_size in maix_image.cpp", + "maixpy": "maix.image.Format", + "py_doc": "Image formats" + }, + "values": [ + [ + "FMT_RGB888", + "0", + "RGBRGB...RGB, R at the lowest address" + ], + [ + "FMT_BGR888", + "", + "BGRBGR...BGR, B at the lowest address" + ], + [ + "FMT_RGBA8888", + "", + "RGBARGBA...RGBA, R at the lowest address" + ], + [ + "FMT_BGRA8888", + "", + "BGRABGRA...BGRA, B at the lowest address" + ], + [ + "FMT_RGB565", + "", + "" + ], + [ + "FMT_BGR565", + "", + "" + ], + [ + "FMT_YUV422SP", + "", + "YYY...UVUVUV...UVUV" + ], + [ + "FMT_YUV422P", + "", + "YYY...UUU...VVV" + ], + [ + "FMT_YVU420SP", + "", + "YYY...VUVUVU...VUVU, NV21" + ], + [ + "FMT_YUV420SP", + "", + "YYY...UVUVUV...UVUV, NV12" + ], + [ + "FMT_YVU420P", + "", + "YYY...VVV...UUU" + ], + [ + "FMT_YUV420P", + "", + "YYY...UUU...VVV" + ], + [ + "FMT_GRAYSCALE", + "", + "" + ], + [ + "FMT_UNCOMPRESSED_MAX", + "", + "" + ], + [ + "FMT_COMPRESSED_MIN", + "", + "" + ], + [ + "FMT_JPEG", + "", + "" + ], + [ + "FMT_PNG", + "", + "" + ], + [ + "FMT_COMPRESSED_MAX", + "", + "" + ], + [ + "FMT_INVALID", + "0xFF", + "format not valid" + ] + ], + "def": "enum Format\n {\n FMT_RGB888 = 0, // RGBRGB...RGB, R at the lowest address\n FMT_BGR888, // BGRBGR...BGR, B at the lowest address\n FMT_RGBA8888, // RGBARGBA...RGBA, R at the lowest address\n FMT_BGRA8888, // BGRABGRA...BGRA, B at the lowest address\n FMT_RGB565,\n FMT_BGR565,\n FMT_YUV422SP, // YYY...UVUVUV...UVUV\n FMT_YUV422P, // YYY...UUU...VVV\n FMT_YVU420SP, // YYY...VUVUVU...VUVU, NV21\n FMT_YUV420SP, // YYY...UVUVUV...UVUV, NV12\n FMT_YVU420P, // YYY...VVV...UUU\n FMT_YUV420P, // YYY...UUU...VVV\n FMT_GRAYSCALE,\n FMT_UNCOMPRESSED_MAX,\n\n // compressed format below, not compressed should define upper\n FMT_COMPRESSED_MIN,\n FMT_JPEG,\n FMT_PNG,\n FMT_COMPRESSED_MAX,\n\n FMT_INVALID = 0xFF // format not valid\n }" + }, + "fmt_size": { + "type": "var", + "name": "", + "doc": { + "brief": "Image format size in bytes", + "attention": "It's a copy of this variable in MaixPy,\nso change it in C++ (e.g. update var in hello function) will not take effect the var inMaixPy.\nSo we add const for this var to avoid this mistake.", + "maixpy": "maix.image.fmt_size", + "py_doc": "Image format size in bytes" + }, + "value": "{\n 3,\n 3,\n 4,\n 4,\n 2,\n 2,\n 2,\n 2,\n 1.5,\n 1.5,\n 1.5,\n 1.5,\n 1,\n 0,\n 0,\n 0,\n 0,\n 0\n }", + "static": false, + "readonly": true, + "def": "const std::vector fmt_size = {\n 3,\n 3,\n 4,\n 4,\n 2,\n 2,\n 2,\n 2,\n 1.5,\n 1.5,\n 1.5,\n 1.5,\n 1,\n 0,\n 0,\n 0,\n 0,\n 0\n }" + }, + "fmt_names": { + "type": "var", + "name": "", + "doc": { + "brief": "Image format string", + "maixpy": "maix.image.fmt_names", + "py_doc": "Image format string" + }, + "value": "{\n \"RGB888\",\n \"BGR888\",\n \"RGBA8888\",\n \"BGRA8888\",\n \"RGB565\",\n \"BGR565\",\n \"YUV422SP\",\n \"YUV422P\",\n \"YVU420SP\",\n \"YUV420SP\",\n \"YVU420P\"\n \"YUV420P\",\n \"GRAYSCALE\",\n \"MAX\"}", + "static": false, + "readonly": true, + "def": "const std::vector fmt_names = {\n \"RGB888\",\n \"BGR888\",\n \"RGBA8888\",\n \"BGRA8888\",\n \"RGB565\",\n \"BGR565\",\n \"YUV422SP\",\n \"YUV422P\",\n \"YVU420SP\",\n \"YUV420SP\",\n \"YVU420P\"\n \"YUV420P\",\n \"GRAYSCALE\",\n \"MAX\"}" + }, + "Size": { + "type": "class", + "name": "Size", + "doc": { + "brief": "Image size type", + "maixpy": "maix.image.Size", + "py_doc": "Image size type" + }, + "members": { + "__init__": { + "type": "func", + "name": "Size", + "doc": { + "brief": "Construct a new Size object", + "param": { + "width": "image width", + "height": "image height" + }, + "maixpy": "maix.image.Size.__init__", + "py_doc": "Construct a new Size object\n\nArgs:\n - width: image width\n - height: image height\n" + }, + "args": [ + [ + "int", + "width", + "0" + ], + [ + "int", + "height", + "0" + ] + ], + "ret_type": null, + "static": false, + "def": "Size(int width = 0, int height = 0)", + "py_def": "def __init__(self, width: int = 0, height: int = 0) -> None" + }, + "width": { + "type": "func", + "name": "width", + "doc": { + "brief": "width of size", + "param": { + "width": "set new width, if not set, only return current width" + }, + "maixpy": "maix.image.Size.width", + "py_doc": "width of size\n\nArgs:\n - width: set new width, if not set, only return current width\n" + }, + "args": [ + [ + "int", + "width", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int width(int width = -1)", + "py_def": "def width(self, width: int = -1) -> int" + }, + "height": { + "type": "func", + "name": "height", + "doc": { + "brief": "height of size", + "param": { + "height": "set new height, if not set, only return current height" + }, + "maixpy": "maix.image.Size.height", + "py_doc": "height of size\n\nArgs:\n - height: set new height, if not set, only return current height\n" + }, + "args": [ + [ + "int", + "height", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int height(int height = -1)", + "py_def": "def height(self, height: int = -1) -> int" + }, + "__getitem__": { + "type": "func", + "name": "operator[]", + "doc": { + "brief": "Subscript operator", + "param": { + "index": "0 for width, 1 for height" + }, + "return": "int& width or height", + "maixpy": "maix.image.Size.__getitem__", + "maixcdk": "maix.image.Size.[]", + "py_doc": "Subscript operator\n\nArgs:\n - index: 0 for width, 1 for height\n\n\nReturns: int& width or height\n" + }, + "args": [ + [ + "int", + "index", + null + ] + ], + "ret_type": "int&", + "static": false, + "def": "int &operator[](int index)", + "py_def": "def __getitem__(self, index: int) -> int" + }, + "__str__": { + "type": "func", + "name": "__str__", + "doc": { + "brief": "to string", + "maixpy": "maix.image.Size.__str__", + "py_doc": "to string" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string __str__()", + "py_def": "def __str__(self) -> str" + } + }, + "def": "class Size" + }, + "Fit": { + "type": "enum", + "name": "Fit", + "doc": { + "brief": "Object fit method", + "maixpy": "maix.image.Fit", + "py_doc": "Object fit method" + }, + "values": [ + [ + "FIT_NONE", + "-1", + "no object fit, keep original" + ], + [ + "FIT_FILL", + "0", + "width to new width, height to new height, may be stretch" + ], + [ + "FIT_CONTAIN", + "", + "keep aspect ratio, fill blank area with black color" + ], + [ + "FIT_COVER", + "", + "keep aspect ratio, crop image to fit new size" + ], + [ + "FIT_MAX", + "", + "" + ] + ], + "def": "enum Fit\n {\n FIT_NONE = -1, // no object fit, keep original\n FIT_FILL = 0, // width to new width, height to new height, may be stretch\n FIT_CONTAIN, // keep aspect ratio, fill blank area with black color\n FIT_COVER, // keep aspect ratio, crop image to fit new size\n FIT_MAX\n }" + }, + "ResizeMethod": { + "type": "enum", + "name": "ResizeMethod", + "doc": { + "brief": "Resize method", + "maixpy": "maix.image.ResizeMethod", + "py_doc": "Resize method" + }, + "values": [ + [ + "NEAREST", + "0", + "" + ], + [ + "BILINEAR", + "", + "" + ], + [ + "BICUBIC", + "", + "" + ], + [ + "AREA", + "", + "" + ], + [ + "LANCZOS", + "", + "" + ], + [ + "HAMMING", + "", + "" + ], + [ + "RESIZE_METHOD_MAX", + "", + "" + ] + ], + "def": "enum ResizeMethod\n {\n NEAREST = 0,\n BILINEAR,\n BICUBIC,\n AREA,\n LANCZOS,\n HAMMING,\n RESIZE_METHOD_MAX\n }" + }, + "ApriltagFamilies": { + "type": "enum", + "name": "ApriltagFamilies", + "doc": { + "brief": "Family of apriltag", + "maixpy": "maix.image.ApriltagFamilies", + "py_doc": "Family of apriltag" + }, + "values": [ + [ + "TAG16H5", + "1", + "" + ], + [ + "TAG25H7", + "2", + "" + ], + [ + "TAG25H9", + "4", + "" + ], + [ + "TAG36H10", + "8", + "" + ], + [ + "TAG36H11", + "16", + "" + ], + [ + "ARTOOLKIT", + "32", + "" + ] + ], + "def": "enum ApriltagFamilies\n {\n TAG16H5 = 1,\n TAG25H7 = 2,\n TAG25H9 = 4,\n TAG36H10 = 8,\n TAG36H11 = 16,\n ARTOOLKIT = 32\n }" + }, + "TemplateMatch": { + "type": "enum", + "name": "TemplateMatch", + "doc": { + "brief": "Template match method", + "maixpy": "maix.image.TemplateMatch", + "py_doc": "Template match method" + }, + "values": [ + [ + "SEARCH_EX", + "", + "Exhaustive search" + ], + [ + "SEARCH_DS", + "", + "Diamond search" + ] + ], + "def": "enum TemplateMatch\n {\n SEARCH_EX, // Exhaustive search\n SEARCH_DS, // Diamond search\n }" + }, + "CornerDetector": { + "type": "enum", + "name": "CornerDetector", + "doc": { + "brief": "CornerDetector class", + "maixpy": "maix.image.CornerDetector", + "py_doc": "CornerDetector class" + }, + "values": [ + [ + "CORNER_FAST", + "", + "" + ], + [ + "CORNER_AGAST", + "", + "" + ] + ], + "def": "enum CornerDetector\n {\n CORNER_FAST,\n CORNER_AGAST\n }" + }, + "EdgeDetector": { + "type": "enum", + "name": "EdgeDetector", + "doc": { + "brief": "EdgeDetector class", + "maixpy": "maix.image.EdgeDetector", + "py_doc": "EdgeDetector class" + }, + "values": [ + [ + "EDGE_CANNY", + "", + "" + ], + [ + "EDGE_SIMPLE", + "", + "" + ] + ], + "def": "enum EdgeDetector\n {\n EDGE_CANNY,\n EDGE_SIMPLE,\n }" + }, + "Line": { + "type": "class", + "name": "Line", + "doc": { + "brief": "Line class", + "maixpy": "maix.image.Line", + "py_doc": "Line class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Line", + "doc": { + "brief": "Line constructor", + "param": { + "x1": "coordinate x1 of the straight line", + "y1": "coordinate y1 of the straight line", + "x2": "coordinate x2 of the straight line", + "y2": "coordinate y2 of the straight line", + "magnitude": "magnitude of the straight line after Hough transformation", + "theta": "angle of the straight line after Hough transformation", + "rho": "p-value of the straight line after Hough transformation" + }, + "maixpy": "maix.image.Line.__init__", + "py_doc": "Line constructor\n\nArgs:\n - x1: coordinate x1 of the straight line\n - y1: coordinate y1 of the straight line\n - x2: coordinate x2 of the straight line\n - y2: coordinate y2 of the straight line\n - magnitude: magnitude of the straight line after Hough transformation\n - theta: angle of the straight line after Hough transformation\n - rho: p-value of the straight line after Hough transformation\n" + }, + "args": [ + [ + "int", + "x1", + null + ], + [ + "int", + "y1", + null + ], + [ + "int", + "x2", + null + ], + [ + "int", + "y2", + null + ], + [ + "int", + "magnitude", + "0" + ], + [ + "int", + "theta", + "0" + ], + [ + "int", + "rho", + "0" + ] + ], + "ret_type": null, + "static": false, + "def": "Line(int x1, int y1, int x2, int y2, int magnitude = 0, int theta = 0, int rho = 0)" + }, + "__getitem__": { + "type": "func", + "name": "__getitem__", + "doc": { + "brief": "Subscript operator", + "param": { + "index\n[0]": "get x1 of line\n[1] get y1 of line\n[2] get x2 of line\n[3] get y2 of line\n[4] get length of line\n[5] get magnitude of the straight line after Hough transformation\n[6] get angle of the straight line after Hough transformation (0-179 degrees)\n[7] get p-value of the straight line after Hough transformation" + }, + "return": "int&", + "maixpy": "maix.image.Line.__getitem__", + "py_doc": "Subscript operator\n\nArgs:\n - index\n[0]: get x1 of line\n[1] get y1 of line\n[2] get x2 of line\n[3] get y2 of line\n[4] get length of line\n[5] get magnitude of the straight line after Hough transformation\n[6] get angle of the straight line after Hough transformation (0-179 degrees)\n[7] get p-value of the straight line after Hough transformation\n\n\nReturns: int&\n" + }, + "args": [ + [ + "int", + "index", + null + ] + ], + "ret_type": "int&", + "static": false, + "def": "int &__getitem__(int index)" + }, + "x1": { + "type": "func", + "name": "x1", + "doc": { + "brief": "get x1 of line", + "return": "return x1 of the line, type is int", + "maixpy": "maix.image.Line.x1", + "py_doc": "get x1 of line\n\nReturns: return x1 of the line, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int x1()" + }, + "y1": { + "type": "func", + "name": "y1", + "doc": { + "brief": "get y1 of line", + "return": "return y1 of the line, type is int", + "maixpy": "maix.image.Line.y1", + "py_doc": "get y1 of line\n\nReturns: return y1 of the line, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int y1()" + }, + "x2": { + "type": "func", + "name": "x2", + "doc": { + "brief": "get x2 of line", + "return": "return x2 of the line, type is int", + "maixpy": "maix.image.Line.x2", + "py_doc": "get x2 of line\n\nReturns: return x2 of the line, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int x2()" + }, + "y2": { + "type": "func", + "name": "y2", + "doc": { + "brief": "get y2 of line", + "return": "return y2 of the line, type is int", + "maixpy": "maix.image.Line.y2", + "py_doc": "get y2 of line\n\nReturns: return y2 of the line, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int y2()" + }, + "length": { + "type": "func", + "name": "length", + "doc": { + "brief": "get length of line", + "return": "return length of the line, type is int", + "maixpy": "maix.image.Line.length", + "py_doc": "get length of line\n\nReturns: return length of the line, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int length()" + }, + "magnitude": { + "type": "func", + "name": "magnitude", + "doc": { + "brief": "get magnitude of the straight line after Hough transformation", + "return": "return magnitude, type is int", + "maixpy": "maix.image.Line.magnitude", + "py_doc": "get magnitude of the straight line after Hough transformation\n\nReturns: return magnitude, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int magnitude()" + }, + "theta": { + "type": "func", + "name": "theta", + "doc": { + "brief": "get angle of the straight line after Hough transformation (0-179 degrees)", + "return": "return angle, type is int", + "maixpy": "maix.image.Line.theta", + "py_doc": "get angle of the straight line after Hough transformation (0-179 degrees)\n\nReturns: return angle, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int theta()" + }, + "rho": { + "type": "func", + "name": "rho", + "doc": { + "brief": "get p-value of the straight line after Hough transformation", + "return": "return p-value, type is int", + "maixpy": "maix.image.Line.rho", + "py_doc": "get p-value of the straight line after Hough transformation\n\nReturns: return p-value, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int rho()" + } + }, + "def": "class Line" + }, + "Rect": { + "type": "class", + "name": "Rect", + "doc": { + "brief": "Rect class", + "maixpy": "maix.image.Rect", + "py_doc": "Rect class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Rect", + "doc": { + "brief": "Rect constructor", + "param": { + "corners": "corners of rect", + "x": "coordinate x of the straight line", + "y": "coordinate y of the straight line", + "w": "coordinate w of the straight line", + "h": "coordinate h of the straight line", + "magnitude": "magnitude of the straight line after Hough transformation" + }, + "maixpy": "maix.image.Rect.__init__", + "py_doc": "Rect constructor\n\nArgs:\n - corners: corners of rect\n - x: coordinate x of the straight line\n - y: coordinate y of the straight line\n - w: coordinate w of the straight line\n - h: coordinate h of the straight line\n - magnitude: magnitude of the straight line after Hough transformation\n" + }, + "args": [ + [ + "std::vector> &", + "corners", + null + ], + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "int", + "w", + null + ], + [ + "int", + "h", + null + ], + [ + "int", + "magnitude", + "0" + ] + ], + "ret_type": null, + "static": false, + "def": "Rect(std::vector> &corners, int x, int y, int w, int h, int magnitude = 0)", + "py_def": "def __init__(self, corners: list[list[int]], x: int, y: int, w: int, h: int, magnitude: int = 0) -> None" + }, + "__getitem__": { + "type": "func", + "name": "__getitem__", + "doc": { + "brief": "Subscript operator", + "param": { + "index\n[0]": "get x of rect\n[1] get y of rect\n[2] get w of rect\n[3] get h of rect\n[4] get magnitude of the straight line after Hough transformation" + }, + "return": "int&", + "maixpy": "maix.image.Rect.__getitem__", + "py_doc": "Subscript operator\n\nArgs:\n - index\n[0]: get x of rect\n[1] get y of rect\n[2] get w of rect\n[3] get h of rect\n[4] get magnitude of the straight line after Hough transformation\n\n\nReturns: int&\n" + }, + "args": [ + [ + "int", + "index", + null + ] + ], + "ret_type": "int&", + "static": false, + "def": "int &__getitem__(int index)", + "py_def": "def __getitem__(self, index: int) -> int" + }, + "corners": { + "type": "func", + "name": "corners", + "doc": { + "brief": "get corners of rect", + "return": "return the coordinate of the rect.", + "maixpy": "maix.image.Rect.corners", + "py_doc": "get corners of rect\n\nReturns: return the coordinate of the rect.\n" + }, + "args": [], + "ret_type": "std::vector>", + "static": false, + "def": "std::vector> corners()", + "py_def": "def corners(self) -> list[list[int]]" + }, + "rect": { + "type": "func", + "name": "rect", + "doc": { + "brief": "get rectangle of rect", + "return": "return the rectangle of the rect. format is {x, y, w, h}, type is std::vector", + "maixpy": "maix.image.Rect.rect", + "py_doc": "get rectangle of rect\n\nReturns: return the rectangle of the rect. format is {x, y, w, h}, type is std::vector\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector rect()", + "py_def": "def rect(self) -> list[int]" + }, + "x": { + "type": "func", + "name": "x", + "doc": { + "brief": "get x of rect", + "return": "return x of the rect, type is int", + "maixpy": "maix.image.Rect.x", + "py_doc": "get x of rect\n\nReturns: return x of the rect, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int x()", + "py_def": "def x(self) -> int" + }, + "y": { + "type": "func", + "name": "y", + "doc": { + "brief": "get y of rect", + "return": "return y of the rect, type is int", + "maixpy": "maix.image.Rect.y", + "py_doc": "get y of rect\n\nReturns: return y of the rect, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int y()", + "py_def": "def y(self) -> int" + }, + "w": { + "type": "func", + "name": "w", + "doc": { + "brief": "get w of rect", + "return": "return w of the rect, type is int", + "maixpy": "maix.image.Rect.w", + "py_doc": "get w of rect\n\nReturns: return w of the rect, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int w()", + "py_def": "def w(self) -> int" + }, + "h": { + "type": "func", + "name": "h", + "doc": { + "brief": "get h of rect", + "return": "return h of the rect, type is int", + "maixpy": "maix.image.Rect.h", + "py_doc": "get h of rect\n\nReturns: return h of the rect, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int h()", + "py_def": "def h(self) -> int" + }, + "magnitude": { + "type": "func", + "name": "magnitude", + "doc": { + "brief": "get magnitude of the straight line after Hough transformation", + "return": "return magnitude, type is int", + "maixpy": "maix.image.Rect.magnitude", + "py_doc": "get magnitude of the straight line after Hough transformation\n\nReturns: return magnitude, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int magnitude()", + "py_def": "def magnitude(self) -> int" + } + }, + "def": "class Rect" + }, + "Circle": { + "type": "class", + "name": "Circle", + "doc": { + "brief": "circle class", + "maixpy": "maix.image.Circle", + "py_doc": "circle class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Circle", + "doc": { + "brief": "Circle constructor", + "param": { + "x": "coordinate x of the circle", + "y": "coordinate y of the circle", + "r": "coordinate r of the circle", + "magnitude": "coordinate y2 of the straight line" + }, + "maixpy": "maix.image.Circle.__init__", + "py_doc": "Circle constructor\n\nArgs:\n - x: coordinate x of the circle\n - y: coordinate y of the circle\n - r: coordinate r of the circle\n - magnitude: coordinate y2 of the straight line\n" + }, + "args": [ + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "int", + "r", + null + ], + [ + "int", + "magnitude", + null + ] + ], + "ret_type": null, + "static": false, + "def": "Circle(int x, int y, int r, int magnitude)", + "py_def": "def __init__(self, x: int, y: int, r: int, magnitude: int) -> None" + }, + "__getitem__": { + "type": "func", + "name": "__getitem__", + "doc": { + "brief": "Subscript operator", + "param": { + "index\n[0]": "get x of circle\n[1] get y of circle\n[2] get r of circle\n[3] get magnitude of the circle after Hough transformation" + }, + "return": "int&", + "maixpy": "maix.image.Circle.__getitem__", + "py_doc": "Subscript operator\n\nArgs:\n - index\n[0]: get x of circle\n[1] get y of circle\n[2] get r of circle\n[3] get magnitude of the circle after Hough transformation\n\n\nReturns: int&\n" + }, + "args": [ + [ + "int", + "index", + null + ] + ], + "ret_type": "int&", + "static": false, + "def": "int &__getitem__(int index)", + "py_def": "def __getitem__(self, index: int) -> int" + }, + "x": { + "type": "func", + "name": "x", + "doc": { + "brief": "get x of circle", + "return": "return x of the circle, type is int", + "maixpy": "maix.image.Circle.x", + "py_doc": "get x of circle\n\nReturns: return x of the circle, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int x()", + "py_def": "def x(self) -> int" + }, + "y": { + "type": "func", + "name": "y", + "doc": { + "brief": "get y of circle", + "return": "return y of the circle, type is int", + "maixpy": "maix.image.Circle.y", + "py_doc": "get y of circle\n\nReturns: return y of the circle, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int y()", + "py_def": "def y(self) -> int" + }, + "r": { + "type": "func", + "name": "r", + "doc": { + "brief": "get r of circle", + "return": "return r of the circle, type is int", + "maixpy": "maix.image.Circle.r", + "py_doc": "get r of circle\n\nReturns: return r of the circle, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int r()", + "py_def": "def r(self) -> int" + }, + "magnitude": { + "type": "func", + "name": "magnitude", + "doc": { + "brief": "get magnitude of the circle after Hough transformation", + "return": "return magnitude, type is int", + "maixpy": "maix.image.Circle.magnitude", + "py_doc": "get magnitude of the circle after Hough transformation\n\nReturns: return magnitude, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int magnitude()", + "py_def": "def magnitude(self) -> int" + } + }, + "def": "class Circle" + }, + "Blob": { + "type": "class", + "name": "Blob", + "doc": { + "brief": "Blob class", + "maixpy": "maix.image.Blob", + "py_doc": "Blob class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Blob", + "doc": { + "brief": "Blob constructor", + "param": { + "rect": "blob rect, type is std::vector", + "corners": "blob corners, type is std::vector>", + "mini_corners": "blob mini_corners, type is std::vector>", + "cx": "blob center x, type is float", + "cy": "blob center y, type is float", + "pixels": "blob pixels, type is int", + "rotation": "blob rotation, type is float", + "code": "blob code, type is int", + "count": "blob count, type is int", + "perimeter": "blob perimeter, type is int", + "roundness": "blob roundness, type is float", + "x_hist_bins": "blob x_hist_bins, type is std::vector", + "y_hist_bins": "blob y_hist_bins, type is std::vector" + }, + "maixpy": "maix.image.Blob.__init__", + "py_doc": "Blob constructor\n\nArgs:\n - rect: blob rect, type is std::vector\n - corners: blob corners, type is std::vector>\n - mini_corners: blob mini_corners, type is std::vector>\n - cx: blob center x, type is float\n - cy: blob center y, type is float\n - pixels: blob pixels, type is int\n - rotation: blob rotation, type is float\n - code: blob code, type is int\n - count: blob count, type is int\n - perimeter: blob perimeter, type is int\n - roundness: blob roundness, type is float\n - x_hist_bins: blob x_hist_bins, type is std::vector\n - y_hist_bins: blob y_hist_bins, type is std::vector\n" + }, + "args": [ + [ + "std::vector &", + "rect", + null + ], + [ + "std::vector> &", + "corners", + null + ], + [ + "std::vector> &", + "mini_corners", + null + ], + [ + "float", + "cx", + null + ], + [ + "float", + "cy", + null + ], + [ + "int", + "pixels", + null + ], + [ + "float", + "rotation", + null + ], + [ + "int", + "code", + null + ], + [ + "int", + "count", + null + ], + [ + "int", + "perimeter", + null + ], + [ + "float", + "roundness", + null + ], + [ + "std::vector &", + "x_hist_bins", + null + ], + [ + "std::vector &", + "y_hist_bins", + null + ] + ], + "ret_type": null, + "static": false, + "def": "Blob(std::vector &rect, std::vector> &corners, std::vector> &mini_corners,float cx, float cy, int pixels, float rotation, int code, int count, int perimeter, float roundness, std::vector &x_hist_bins, std::vector &y_hist_bins)" + }, + "__getitem__": { + "type": "func", + "name": "__getitem__", + "doc": { + "brief": "Subscript operator", + "param": { + "index\n[0]": "Returns the blob\u2019s bounding box x coordinate\n[1] Returns the blob\u2019s bounding box y coordinate\n[2] Returns the blob\u2019s bounding box w coordinate\n[3] Returns the blob\u2019s bounding box h coordinate\n[4] Returns the number of pixels that are part of this blob\n[5] Returns the centroid x position of the blob\n[6] Returns the centroid y position of the blob" + }, + "return": "int& width or height", + "maixpy": "maix.image.Blob.__getitem__", + "py_doc": "Subscript operator\n\nArgs:\n - index\n[0]: Returns the blob\u2019s bounding box x coordinate\n[1] Returns the blob\u2019s bounding box y coordinate\n[2] Returns the blob\u2019s bounding box w coordinate\n[3] Returns the blob\u2019s bounding box h coordinate\n[4] Returns the number of pixels that are part of this blob\n[5] Returns the centroid x position of the blob\n[6] Returns the centroid y position of the blob\n\n\nReturns: int& width or height\n" + }, + "args": [ + [ + "int", + "index", + null + ] + ], + "ret_type": "int&", + "static": false, + "def": "int &__getitem__(int index)" + }, + "corners": { + "type": "func", + "name": "corners", + "doc": { + "brief": "get blob corners", + "return": "Returns a list of 4 (x,y) tuples of the 4 corners of the object.\n(x0, y0)___________(x1, y1)\n| |\n| |\n| |\n|___________|\n(x3, y3) (x2, y2)\nnote: the order of corners may change", + "maixpy": "maix.image.Blob.corners", + "py_doc": "get blob corners\n\nReturns: Returns a list of 4 (x,y) tuples of the 4 corners of the object.\n(x0, y0)___________(x1, y1)\n| |\n| |\n| |\n|___________|\n(x3, y3) (x2, y2)\nnote: the order of corners may change\n" + }, + "args": [], + "ret_type": "std::vector>", + "static": false, + "def": "std::vector> corners()" + }, + "mini_corners": { + "type": "func", + "name": "mini_corners", + "doc": { + "brief": "get blob mini corners", + "return": "Returns a list of 4 (x,y) tuples of the 4 corners than bound the min area rectangle of the blob.\n(x0, y0)___________(x1, y1)\n| |\n| |\n| |\n|___________|\n(x3, y3) (x2, y2)\nnote: the order of corners may change", + "maixpy": "maix.image.Blob.mini_corners", + "py_doc": "get blob mini corners\n\nReturns: Returns a list of 4 (x,y) tuples of the 4 corners than bound the min area rectangle of the blob.\n(x0, y0)___________(x1, y1)\n| |\n| |\n| |\n|___________|\n(x3, y3) (x2, y2)\nnote: the order of corners may change\n" + }, + "args": [], + "ret_type": "std::vector>", + "static": false, + "def": "std::vector> mini_corners()" + }, + "rect": { + "type": "func", + "name": "rect", + "doc": { + "brief": "get blob rect", + "return": "Returns the center coordinates and width and height of the rectangle. format is (x, y, w, h)\nw\n(x, y) ___________\n| |\n| | h\n| |\n|___________|", + "maixpy": "maix.image.Blob.rect", + "py_doc": "get blob rect\n\nReturns: Returns the center coordinates and width and height of the rectangle. format is (x, y, w, h)\nw\n(x, y) ___________\n| |\n| | h\n| |\n|___________|\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector rect()" + }, + "x": { + "type": "func", + "name": "x", + "doc": { + "brief": "get blob x of the upper left coordinate", + "return": "Returns the x coordinate of the upper left corner of the rectangle.", + "maixpy": "maix.image.Blob.x", + "py_doc": "get blob x of the upper left coordinate\n\nReturns: Returns the x coordinate of the upper left corner of the rectangle.\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int x()" + }, + "y": { + "type": "func", + "name": "y", + "doc": { + "brief": "get blob y of the upper left coordinate", + "return": "Returns the y coordinate of the upper left corner of the rectangle.", + "maixpy": "maix.image.Blob.y", + "py_doc": "get blob y of the upper left coordinate\n\nReturns: Returns the y coordinate of the upper left corner of the rectangle.\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int y()" + }, + "w": { + "type": "func", + "name": "w", + "doc": { + "brief": "get blob width", + "return": "Returns the blob\u2019s bounding box w coordinate", + "maixpy": "maix.image.Blob.w", + "py_doc": "get blob width\n\nReturns: Returns the blob\u2019s bounding box w coordinate\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int w()" + }, + "h": { + "type": "func", + "name": "h", + "doc": { + "brief": "get blob height", + "return": "Returns the blob\u2019s bounding box h coordinate", + "maixpy": "maix.image.Blob.h", + "py_doc": "get blob height\n\nReturns: Returns the blob\u2019s bounding box h coordinate\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int h()" + }, + "pixels": { + "type": "func", + "name": "pixels", + "doc": { + "brief": "get blob pixels", + "return": "Returns the number of pixels that are part of this blob.", + "maixpy": "maix.image.Blob.pixels", + "py_doc": "get blob pixels\n\nReturns: Returns the number of pixels that are part of this blob.\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int pixels()" + }, + "cx": { + "type": "func", + "name": "cx", + "doc": { + "brief": "get blob center x", + "return": "Returns the centroid x position of the blob", + "maixpy": "maix.image.Blob.cx", + "py_doc": "get blob center x\n\nReturns: Returns the centroid x position of the blob\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int cx()" + }, + "cy": { + "type": "func", + "name": "cy", + "doc": { + "brief": "get blob center y", + "return": "Returns the centroid y position of the blob", + "maixpy": "maix.image.Blob.cy", + "py_doc": "get blob center y\n\nReturns: Returns the centroid y position of the blob\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int cy()" + }, + "cxf": { + "type": "func", + "name": "cxf", + "doc": { + "brief": "get blob center x", + "return": "Returns the centroid x position of the blob", + "maixpy": "maix.image.Blob.cxf", + "py_doc": "get blob center x\n\nReturns: Returns the centroid x position of the blob\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float cxf()" + }, + "cyf": { + "type": "func", + "name": "cyf", + "doc": { + "brief": "get blob center y", + "return": "Returns the centroid y position of the blob", + "maixpy": "maix.image.Blob.cyf", + "py_doc": "get blob center y\n\nReturns: Returns the centroid y position of the blob\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float cyf()" + }, + "rotation": { + "type": "func", + "name": "rotation", + "doc": { + "brief": "get blob rotation", + "return": "Returns the rotation of the blob in radians (float). If the blob is like a pencil or pen this value will be unique for 0-180 degrees.", + "maixpy": "maix.image.Blob.rotation", + "py_doc": "get blob rotation\n\nReturns: Returns the rotation of the blob in radians (float). If the blob is like a pencil or pen this value will be unique for 0-180 degrees.\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float rotation()" + }, + "rotation_rad": { + "type": "func", + "name": "rotation_rad", + "doc": { + "brief": "get blob rotation_rad", + "return": "Returns the rotation of the blob in radians", + "maixpy": "maix.image.Blob.rotation_rad", + "py_doc": "get blob rotation_rad\n\nReturns: Returns the rotation of the blob in radians\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float rotation_rad()" + }, + "rotation_deg": { + "type": "func", + "name": "rotation_deg", + "doc": { + "brief": "get blob rotation_deg", + "return": "Returns the rotation of the blob in degrees.", + "maixpy": "maix.image.Blob.rotation_deg", + "py_doc": "get blob rotation_deg\n\nReturns: Returns the rotation of the blob in degrees.\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int rotation_deg()" + }, + "code": { + "type": "func", + "name": "code", + "doc": { + "brief": "get blob code", + "return": "Returns a 32-bit binary number with a bit set in it for each color threshold that\u2019s part of this blob", + "maixpy": "maix.image.Blob.code", + "py_doc": "get blob code\n\nReturns: Returns a 32-bit binary number with a bit set in it for each color threshold that\u2019s part of this blob\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int code()" + }, + "count": { + "type": "func", + "name": "count", + "doc": { + "brief": "get blob count", + "return": "Returns the number of blobs merged into this blob.", + "maixpy": "maix.image.Blob.count", + "py_doc": "get blob count\n\nReturns: Returns the number of blobs merged into this blob.\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int count()" + }, + "perimeter": { + "type": "func", + "name": "perimeter", + "doc": { + "brief": "get blob merge_cnt", + "return": "Returns the number of pixels on this blob\u2019s perimeter.", + "maixpy": "maix.image.Blob.perimeter", + "py_doc": "get blob merge_cnt\n\nReturns: Returns the number of pixels on this blob\u2019s perimeter.\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int perimeter()" + }, + "roundness": { + "type": "func", + "name": "roundness", + "doc": { + "brief": "get blob roundness", + "return": "Returns a value between 0 and 1 representing how round the object is", + "maixpy": "maix.image.Blob.roundness", + "py_doc": "get blob roundness\n\nReturns: Returns a value between 0 and 1 representing how round the object is\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float roundness()" + }, + "elongation": { + "type": "func", + "name": "elongation", + "doc": { + "brief": "get blob elongation", + "returnReturns": "a value between 0 and 1 representing how long (not round) the object is", + "maixpy": "maix.image.Blob.elongation", + "py_doc": "get blob elongation" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float elongation()" + }, + "area": { + "type": "func", + "name": "area", + "doc": { + "brief": "get blob area", + "return": "Returns the area of the bounding box around the blob", + "maixpy": "maix.image.Blob.area", + "py_doc": "get blob area\n\nReturns: Returns the area of the bounding box around the blob\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int area()" + }, + "density": { + "type": "func", + "name": "density", + "doc": { + "brief": "get blob density", + "return": "Returns the density ratio of the blob", + "maixpy": "maix.image.Blob.density", + "py_doc": "get blob density\n\nReturns: Returns the density ratio of the blob\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float density()" + }, + "extent": { + "type": "func", + "name": "extent", + "doc": { + "brief": "Alias for blob.density()", + "return": "Returns the density ratio of the blob", + "maixpy": "maix.image.Blob.extent", + "py_doc": "Alias for blob.density()\n\nReturns: Returns the density ratio of the blob\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float extent()" + }, + "compactness": { + "type": "func", + "name": "compactness", + "doc": { + "brief": "get blob compactness", + "return": "Returns the compactness ratio of the blob", + "maixpy": "maix.image.Blob.compactness", + "py_doc": "get blob compactness\n\nReturns: Returns the compactness ratio of the blob\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float compactness()" + }, + "solidity": { + "type": "func", + "name": "solidity", + "doc": { + "brief": "get blob solidity", + "return": "Returns the solidity ratio of the blob", + "maixpy": "maix.image.Blob.solidity", + "py_doc": "get blob solidity\n\nReturns: Returns the solidity ratio of the blob\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float solidity()" + }, + "convexity": { + "type": "func", + "name": "convexity", + "doc": { + "brief": "get blob convexity", + "return": "Returns a value between 0 and 1 representing how convex the object is", + "maixpy": "maix.image.Blob.convexity", + "py_doc": "get blob convexity\n\nReturns: Returns a value between 0 and 1 representing how convex the object is\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float convexity()" + }, + "x_hist_bins": { + "type": "func", + "name": "x_hist_bins", + "doc": { + "brief": "get blob x_hist_bins", + "return": "Returns the x_hist_bins of the blob", + "maixpy": "maix.image.Blob.x_hist_bins", + "py_doc": "get blob x_hist_bins\n\nReturns: Returns the x_hist_bins of the blob\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector x_hist_bins()" + }, + "y_hist_bins": { + "type": "func", + "name": "y_hist_bins", + "doc": { + "brief": "get blob y_hist_bins", + "return": "Returns the y_hist_bins of the blob", + "maixpy": "maix.image.Blob.y_hist_bins", + "py_doc": "get blob y_hist_bins\n\nReturns: Returns the y_hist_bins of the blob\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector y_hist_bins()" + }, + "major_axis_line": { + "type": "func", + "name": "major_axis_line", + "doc": { + "brief": "get blob major_axis_line", + "return": "Returns a line tuple (x1, y1, x2, y2) of the minor axis of the blob.", + "maixpy": "maix.image.Blob.major_axis_line", + "py_doc": "get blob major_axis_line\n\nReturns: Returns a line tuple (x1, y1, x2, y2) of the minor axis of the blob.\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector major_axis_line()" + }, + "minor_axis_line": { + "type": "func", + "name": "minor_axis_line", + "doc": { + "brief": "get blob minor_axis_line", + "return": "Returns a line tuple (x1, y1, x2, y2) of the minor axis of the blob.", + "maixpy": "maix.image.Blob.minor_axis_line", + "py_doc": "get blob minor_axis_line\n\nReturns: Returns a line tuple (x1, y1, x2, y2) of the minor axis of the blob.\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector minor_axis_line()" + }, + "enclosing_circle": { + "type": "func", + "name": "enclosing_circle", + "doc": { + "brief": "get blob enclosing_circle", + "return": "Returns a circle tuple (x, y, r) of the circle that encloses the min area rectangle of a blob.", + "maixpy": "maix.image.Blob.enclosing_circle", + "py_doc": "get blob enclosing_circle\n\nReturns: Returns a circle tuple (x, y, r) of the circle that encloses the min area rectangle of a blob.\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector enclosing_circle()" + }, + "enclosed_ellipse": { + "type": "func", + "name": "enclosed_ellipse", + "doc": { + "brief": "get blob enclosed_ellipse", + "return": "Returns an ellipse tuple (x, y, rx, ry, rotation) of the ellipse that fits inside of the min area rectangle of a blob.", + "maixpy": "maix.image.Blob.enclosed_ellipse", + "py_doc": "get blob enclosed_ellipse\n\nReturns: Returns an ellipse tuple (x, y, rx, ry, rotation) of the ellipse that fits inside of the min area rectangle of a blob.\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector enclosed_ellipse()" + } + }, + "def": "class Blob" + }, + "QRCode": { + "type": "class", + "name": "QRCode", + "doc": { + "brief": "QRCode class", + "maixpy": "maix.image.QRCode", + "py_doc": "QRCode class" + }, + "members": { + "__init__": { + "type": "func", + "name": "QRCode", + "doc": { + "brief": "QRCode constructor", + "param": { + "rect": "rect of corners, type is std::vector", + "corners": "corners of QRCode", + "payload": "payload of the QRCode", + "version": "version of the QRCode", + "ecc_level": "ecc_level of the QRCode", + "mask": "mask of the QRCode", + "data_type": "data_type of the QRCode", + "eci": "eci of the QRCode" + }, + "maixpy": "maix.image.QRCode.__init__", + "py_doc": "QRCode constructor\n\nArgs:\n - rect: rect of corners, type is std::vector\n - corners: corners of QRCode\n - payload: payload of the QRCode\n - version: version of the QRCode\n - ecc_level: ecc_level of the QRCode\n - mask: mask of the QRCode\n - data_type: data_type of the QRCode\n - eci: eci of the QRCode\n" + }, + "args": [ + [ + "std::vector &", + "rect", + null + ], + [ + "std::vector> &", + "corners", + null + ], + [ + "std::string &", + "payload", + null + ], + [ + "int", + "version", + null + ], + [ + "int", + "ecc_level", + null + ], + [ + "int", + "mask", + null + ], + [ + "int", + "data_type", + null + ], + [ + "int", + "eci", + null + ] + ], + "ret_type": null, + "static": false, + "def": "QRCode(std::vector &rect, std::vector> &corners, std::string &payload, int version, int ecc_level, int mask, int data_type, int eci)" + }, + "__getitem__": { + "type": "func", + "name": "__getitem__", + "doc": { + "brief": "Subscript operator", + "param": { + "index\n[0]": "Returns the qrcode\u2019s bounding box x coordinate\n[1] Returns the qrcode\u2019s bounding box y coordinate\n[2] Returns the qrcode\u2019s bounding box w coordinate\n[3] Returns the qrcode\u2019s bounding box h coordinate\n[4] Not support this index, try to use payload() method\n[5] Returns the version of qrcode\n[6] Returns the error correction level of qrcode\n[7] Returns the mask of qrcode\n[8] Returns the datatype of qrcode\n[9] Returns the eci of qrcode" + }, + "return": "int&", + "maixpy": "maix.image.QRCode.__getitem__", + "py_doc": "Subscript operator\n\nArgs:\n - index\n[0]: Returns the qrcode\u2019s bounding box x coordinate\n[1] Returns the qrcode\u2019s bounding box y coordinate\n[2] Returns the qrcode\u2019s bounding box w coordinate\n[3] Returns the qrcode\u2019s bounding box h coordinate\n[4] Not support this index, try to use payload() method\n[5] Returns the version of qrcode\n[6] Returns the error correction level of qrcode\n[7] Returns the mask of qrcode\n[8] Returns the datatype of qrcode\n[9] Returns the eci of qrcode\n\n\nReturns: int&\n" + }, + "args": [ + [ + "int", + "index", + null + ] + ], + "ret_type": "int&", + "static": false, + "def": "int &__getitem__(int index)" + }, + "corners": { + "type": "func", + "name": "corners", + "doc": { + "brief": "get coordinate of QRCode", + "return": "return the coordinate of the QRCode.", + "maixpy": "maix.image.QRCode.corners", + "py_doc": "get coordinate of QRCode\n\nReturns: return the coordinate of the QRCode.\n" + }, + "args": [], + "ret_type": "std::vector>", + "static": false, + "def": "std::vector> corners()" + }, + "rect": { + "type": "func", + "name": "rect", + "doc": { + "brief": "get rectangle of QRCode", + "return": "return the rectangle of the QRCode. format is {x, y, w, h}, type is std::vector", + "maixpy": "maix.image.QRCode.rect", + "py_doc": "get rectangle of QRCode\n\nReturns: return the rectangle of the QRCode. format is {x, y, w, h}, type is std::vector\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector rect()" + }, + "x": { + "type": "func", + "name": "x", + "doc": { + "brief": "get x of QRCode", + "return": "return x of the QRCode, type is int", + "maixpy": "maix.image.QRCode.x", + "py_doc": "get x of QRCode\n\nReturns: return x of the QRCode, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int x()" + }, + "y": { + "type": "func", + "name": "y", + "doc": { + "brief": "get y of QRCode", + "return": "return y of the QRCode, type is int", + "maixpy": "maix.image.QRCode.y", + "py_doc": "get y of QRCode\n\nReturns: return y of the QRCode, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int y()" + }, + "w": { + "type": "func", + "name": "w", + "doc": { + "brief": "get w of QRCode", + "return": "return w of the QRCode, type is int", + "maixpy": "maix.image.QRCode.w", + "py_doc": "get w of QRCode\n\nReturns: return w of the QRCode, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int w()" + }, + "h": { + "type": "func", + "name": "h", + "doc": { + "brief": "get h of QRCode", + "return": "return h of the QRCode, type is int", + "maixpy": "maix.image.QRCode.h", + "py_doc": "get h of QRCode\n\nReturns: return h of the QRCode, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int h()" + }, + "payload": { + "type": "func", + "name": "payload", + "doc": { + "brief": "get QRCode payload", + "return": "return area of the QRCode", + "maixpy": "maix.image.QRCode.payload", + "py_doc": "get QRCode payload\n\nReturns: return area of the QRCode\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string payload()" + }, + "version": { + "type": "func", + "name": "version", + "doc": { + "brief": "get QRCode version", + "return": "return version of the QRCode", + "maixpy": "maix.image.QRCode.version", + "py_doc": "get QRCode version\n\nReturns: return version of the QRCode\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int version()" + }, + "ecc_level": { + "type": "func", + "name": "ecc_level", + "doc": { + "brief": "get QRCode error correction level", + "return": "return error correction level of the QRCode", + "maixpy": "maix.image.QRCode.ecc_level", + "py_doc": "get QRCode error correction level\n\nReturns: return error correction level of the QRCode\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int ecc_level()" + }, + "mask": { + "type": "func", + "name": "mask", + "doc": { + "brief": "get QRCode mask", + "return": "return mask of the QRCode", + "maixpy": "maix.image.QRCode.mask", + "py_doc": "get QRCode mask\n\nReturns: return mask of the QRCode\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int mask()" + }, + "data_type": { + "type": "func", + "name": "data_type", + "doc": { + "brief": "get QRCode dataType", + "return": "return mask of the QRCode", + "maixpy": "maix.image.QRCode.data_type", + "py_doc": "get QRCode dataType\n\nReturns: return mask of the QRCode\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int data_type()" + }, + "eci": { + "type": "func", + "name": "eci", + "doc": { + "brief": "get QRCode eci", + "return": "return data of the QRCode", + "maixpy": "maix.image.QRCode.eci", + "py_doc": "get QRCode eci\n\nReturns: return data of the QRCode\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int eci()" + }, + "is_numeric": { + "type": "func", + "name": "is_numeric", + "doc": { + "brief": "check QRCode is numeric", + "return": "return true if the result type of the QRCode is numeric", + "maixpy": "maix.image.QRCode.is_numeric", + "py_doc": "check QRCode is numeric\n\nReturns: return true if the result type of the QRCode is numeric\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_numeric()" + }, + "is_alphanumeric": { + "type": "func", + "name": "is_alphanumeric", + "doc": { + "brief": "check QRCode is alphanumeric", + "return": "return true if the result type of the QRCode is alphanumeric", + "maixpy": "maix.image.QRCode.is_alphanumeric", + "py_doc": "check QRCode is alphanumeric\n\nReturns: return true if the result type of the QRCode is alphanumeric\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_alphanumeric()" + }, + "is_binary": { + "type": "func", + "name": "is_binary", + "doc": { + "brief": "check QRCode is binary", + "return": "return true if the result type of the QRCode is binary", + "maixpy": "maix.image.QRCode.is_binary", + "py_doc": "check QRCode is binary\n\nReturns: return true if the result type of the QRCode is binary\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_binary()" + }, + "is_kanji": { + "type": "func", + "name": "is_kanji", + "doc": { + "brief": "check QRCode is kanji", + "return": "return true if the result type of the QRCode is kanji", + "maixpy": "maix.image.QRCode.is_kanji", + "py_doc": "check QRCode is kanji\n\nReturns: return true if the result type of the QRCode is kanji\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_kanji()" + } + }, + "def": "class QRCode" + }, + "AprilTag": { + "type": "class", + "name": "AprilTag", + "doc": { + "brief": "AprilTag class", + "maixpy": "maix.image.AprilTag", + "py_doc": "AprilTag class" + }, + "members": { + "__init__": { + "type": "func", + "name": "AprilTag", + "doc": { + "brief": "AprilTag constructor", + "param": { + "rect": "Inlucdes the top-left corner and the width and height of the rectangle. format is {x, y, w, h}, type is std::vector", + "corners": "Includes the four corners of the rectangle. format is {{x0, y0}, {x1, y1}, {x2, y2}, {x3, y3}}, type is std::vector>", + "id": "The id of the AprilTag", + "famliy": "The family of the AprilTag", + "centroid_x": "The x coordinate of the center of the AprilTag", + "centroid_y": "The y coordinate of the center of the AprilTag", + "rotation": "The rotation of the AprilTag", + "decision_margin": "The decision_margin of the AprilTag", + "hamming": "The hamming of the AprilTag", + "goodness": "The goodness of the AprilTag", + "x_translation": "The x_translation of the AprilTag", + "y_translation": "The y_translation of the AprilTag", + "z_translation": "The z_translation of the AprilTag", + "x_rotation": "The x_rotation of the AprilTag", + "y_rotation": "The y_rotation of the AprilTag", + "z_rotation": "The z_rotation of the AprilTag" + }, + "maixpy": "maix.image.AprilTag.__init__", + "py_doc": "AprilTag constructor\n\nArgs:\n - rect: Inlucdes the top-left corner and the width and height of the rectangle. format is {x, y, w, h}, type is std::vector\n - corners: Includes the four corners of the rectangle. format is {{x0, y0}, {x1, y1}, {x2, y2}, {x3, y3}}, type is std::vector>\n - id: The id of the AprilTag\n - famliy: The family of the AprilTag\n - centroid_x: The x coordinate of the center of the AprilTag\n - centroid_y: The y coordinate of the center of the AprilTag\n - rotation: The rotation of the AprilTag\n - decision_margin: The decision_margin of the AprilTag\n - hamming: The hamming of the AprilTag\n - goodness: The goodness of the AprilTag\n - x_translation: The x_translation of the AprilTag\n - y_translation: The y_translation of the AprilTag\n - z_translation: The z_translation of the AprilTag\n - x_rotation: The x_rotation of the AprilTag\n - y_rotation: The y_rotation of the AprilTag\n - z_rotation: The z_rotation of the AprilTag\n" + }, + "args": [ + [ + "std::vector &", + "rect", + null + ], + [ + "std::vector> &", + "corners", + null + ], + [ + "int", + "id", + null + ], + [ + "int", + "famliy", + null + ], + [ + "float", + "centroid_x", + null + ], + [ + "float", + "centroid_y", + null + ], + [ + "float", + "rotation", + null + ], + [ + "float", + "decision_margin", + null + ], + [ + "int", + "hamming", + null + ], + [ + "float", + "goodness", + null + ], + [ + "float", + "x_translation", + null + ], + [ + "float", + "y_translation", + null + ], + [ + "float", + "z_translation", + null + ], + [ + "float", + "x_rotation", + null + ], + [ + "float", + "y_rotation", + null + ], + [ + "float", + "z_rotation", + null + ] + ], + "ret_type": null, + "static": false, + "def": "AprilTag(std::vector &rect, std::vector> &corners, int id, int famliy, float centroid_x, float centroid_y, float rotation, float decision_margin, int hamming, float goodness, float x_translation, float y_translation, float z_translation, float x_rotation, float y_rotation, float z_rotation)", + "py_def": "def __init__(self, rect: list[int], corners: list[list[int]], id: int, famliy: int, centroid_x: float, centroid_y: float, rotation: float, decision_margin: float, hamming: int, goodness: float, x_translation: float, y_translation: float, z_translation: float, x_rotation: float, y_rotation: float, z_rotation: float) -> None" + }, + "__getitem__": { + "type": "func", + "name": "__getitem__", + "doc": { + "brief": "Subscript operator", + "param": { + "index\n[0]": "Returns the apriltag\u2019s bounding box x coordinate\n[1] Returns the apriltag\u2019s bounding box y coordinate\n[2] Returns the apriltag\u2019s bounding box w coordinate\n[3] Returns the apriltag\u2019s bounding box h coordinate\n[4] Returns the apriltag\u2019s id\n[5] Returns the apriltag\u2019s family\n[6] Not support\n[7] Not support\n[8] Not support\n[9] Not support\n[10] Returns the apriltag\u2019s hamming\n[11] Not support\n[12] Not support\n[13] Not support\n[14] Not support\n[15] Not support\n[16] Not support\n[17] Not support" + }, + "return": "int&", + "maixpy": "maix.image.AprilTag.__getitem__", + "py_doc": "Subscript operator\n\nArgs:\n - index\n[0]: Returns the apriltag\u2019s bounding box x coordinate\n[1] Returns the apriltag\u2019s bounding box y coordinate\n[2] Returns the apriltag\u2019s bounding box w coordinate\n[3] Returns the apriltag\u2019s bounding box h coordinate\n[4] Returns the apriltag\u2019s id\n[5] Returns the apriltag\u2019s family\n[6] Not support\n[7] Not support\n[8] Not support\n[9] Not support\n[10] Returns the apriltag\u2019s hamming\n[11] Not support\n[12] Not support\n[13] Not support\n[14] Not support\n[15] Not support\n[16] Not support\n[17] Not support\n\n\nReturns: int&\n" + }, + "args": [ + [ + "int", + "index", + null + ] + ], + "ret_type": "int&", + "static": false, + "def": "int &__getitem__(int index)", + "py_def": "def __getitem__(self, index: int) -> int" + }, + "corners": { + "type": "func", + "name": "corners", + "doc": { + "brief": "get coordinate of AprilTag", + "return": "return the coordinate of the AprilTag.", + "maixpy": "maix.image.AprilTag.corners", + "py_doc": "get coordinate of AprilTag\n\nReturns: return the coordinate of the AprilTag.\n" + }, + "args": [], + "ret_type": "std::vector>", + "static": false, + "def": "std::vector> corners()", + "py_def": "def corners(self) -> list[list[int]]" + }, + "rect": { + "type": "func", + "name": "rect", + "doc": { + "brief": "get rectangle of AprilTag", + "return": "return the rectangle of the AprilTag. format is {x, y, w, h}, type is std::vector", + "maixpy": "maix.image.AprilTag.rect", + "py_doc": "get rectangle of AprilTag\n\nReturns: return the rectangle of the AprilTag. format is {x, y, w, h}, type is std::vector\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector rect()", + "py_def": "def rect(self) -> list[int]" + }, + "x": { + "type": "func", + "name": "x", + "doc": { + "brief": "get x of AprilTag", + "return": "return x of the AprilTag, type is int", + "maixpy": "maix.image.AprilTag.x", + "py_doc": "get x of AprilTag\n\nReturns: return x of the AprilTag, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int x()", + "py_def": "def x(self) -> int" + }, + "y": { + "type": "func", + "name": "y", + "doc": { + "brief": "get y of AprilTag", + "return": "return y of the AprilTag, type is int", + "maixpy": "maix.image.AprilTag.y", + "py_doc": "get y of AprilTag\n\nReturns: return y of the AprilTag, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int y()", + "py_def": "def y(self) -> int" + }, + "w": { + "type": "func", + "name": "w", + "doc": { + "brief": "get w of AprilTag", + "return": "return w of the AprilTag, type is int", + "maixpy": "maix.image.AprilTag.w", + "py_doc": "get w of AprilTag\n\nReturns: return w of the AprilTag, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int w()", + "py_def": "def w(self) -> int" + }, + "h": { + "type": "func", + "name": "h", + "doc": { + "brief": "get h of AprilTag", + "return": "return h of the AprilTag, type is int", + "maixpy": "maix.image.AprilTag.h", + "py_doc": "get h of AprilTag\n\nReturns: return h of the AprilTag, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int h()", + "py_def": "def h(self) -> int" + }, + "id": { + "type": "func", + "name": "id", + "doc": { + "brief": "get id of AprilTag", + "return": "return id of the AprilTag, type is int", + "maixpy": "maix.image.AprilTag.id", + "py_doc": "get id of AprilTag\n\nReturns: return id of the AprilTag, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int id()", + "py_def": "def id(self) -> int" + }, + "family": { + "type": "func", + "name": "family", + "doc": { + "brief": "get family of AprilTag", + "return": "return family of the AprilTag, type is int", + "maixpy": "maix.image.AprilTag.family", + "py_doc": "get family of AprilTag\n\nReturns: return family of the AprilTag, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int family()", + "py_def": "def family(self) -> int" + }, + "cx": { + "type": "func", + "name": "cx", + "doc": { + "brief": "get cx of AprilTag", + "return": "return cx of the AprilTag, type is int", + "maixpy": "maix.image.AprilTag.cx", + "py_doc": "get cx of AprilTag\n\nReturns: return cx of the AprilTag, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int cx()", + "py_def": "def cx(self) -> int" + }, + "cxf": { + "type": "func", + "name": "cxf", + "doc": { + "brief": "get cxf of AprilTag", + "return": "return cxf of the AprilTag, type is float", + "maixpy": "maix.image.AprilTag.cxf", + "py_doc": "get cxf of AprilTag\n\nReturns: return cxf of the AprilTag, type is float\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float cxf()", + "py_def": "def cxf(self) -> float" + }, + "cy": { + "type": "func", + "name": "cy", + "doc": { + "brief": "get cy of AprilTag", + "return": "return cy of the AprilTag, type is int", + "maixpy": "maix.image.AprilTag.cy", + "py_doc": "get cy of AprilTag\n\nReturns: return cy of the AprilTag, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int cy()", + "py_def": "def cy(self) -> int" + }, + "cyf": { + "type": "func", + "name": "cyf", + "doc": { + "brief": "get cyf of AprilTag", + "return": "return cyf of the AprilTag, type is float", + "maixpy": "maix.image.AprilTag.cyf", + "py_doc": "get cyf of AprilTag\n\nReturns: return cyf of the AprilTag, type is float\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float cyf()", + "py_def": "def cyf(self) -> float" + }, + "rotation": { + "type": "func", + "name": "rotation", + "doc": { + "brief": "get rotation of AprilTag", + "return": "return rotation of the AprilTag, type is float", + "maixpy": "maix.image.AprilTag.rotation", + "py_doc": "get rotation of AprilTag\n\nReturns: return rotation of the AprilTag, type is float\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float rotation()", + "py_def": "def rotation(self) -> float" + }, + "decision_margin": { + "type": "func", + "name": "decision_margin", + "doc": { + "brief": "Get decision_margin of AprilTag", + "return": "Returns the quality of the apriltag match (0.0 - 1.0) where 1.0 is the best.", + "maixpy": "maix.image.AprilTag.decision_margin", + "py_doc": "Get decision_margin of AprilTag\n\nReturns: Returns the quality of the apriltag match (0.0 - 1.0) where 1.0 is the best.\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float decision_margin()", + "py_def": "def decision_margin(self) -> float" + }, + "hamming": { + "type": "func", + "name": "hamming", + "doc": { + "brief": "get hamming of AprilTag", + "return": "Returns the number of accepted bit errors for this tag.\nreturn 0, means 0 bit errors will be accepted.\n1 is TAG25H7, means up to 1 bit error may be accepted\n2 is TAG25H9, means up to 3 bit errors may be accepted\n3 is TAG36H10, means up to 3 bit errors may be accepted\n4 is TAG36H11, means up to 4 bit errors may be accepted\n5 is ARTOOLKIT, means 0 bit errors will be accepted", + "maixpy": "maix.image.AprilTag.hamming", + "py_doc": "get hamming of AprilTag\n\nReturns: Returns the number of accepted bit errors for this tag.\nreturn 0, means 0 bit errors will be accepted.\n1 is TAG25H7, means up to 1 bit error may be accepted\n2 is TAG25H9, means up to 3 bit errors may be accepted\n3 is TAG36H10, means up to 3 bit errors may be accepted\n4 is TAG36H11, means up to 4 bit errors may be accepted\n5 is ARTOOLKIT, means 0 bit errors will be accepted\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int hamming()", + "py_def": "def hamming(self) -> int" + }, + "goodness": { + "type": "func", + "name": "goodness", + "doc": { + "brief": "get goodness of AprilTag", + "return": "return goodness of the AprilTag, type is float\nNote: This value is always 0.0 for now.", + "maixpy": "maix.image.AprilTag.goodness", + "py_doc": "get goodness of AprilTag\n\nReturns: return goodness of the AprilTag, type is float\nNote: This value is always 0.0 for now.\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float goodness()", + "py_def": "def goodness(self) -> float" + }, + "x_translation": { + "type": "func", + "name": "x_translation", + "doc": { + "brief": "get x_translation of AprilTag", + "return": "return x_translation of the AprilTag, type is float", + "maixpy": "maix.image.AprilTag.x_translation", + "py_doc": "get x_translation of AprilTag\n\nReturns: return x_translation of the AprilTag, type is float\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float x_translation()", + "py_def": "def x_translation(self) -> float" + }, + "y_translation": { + "type": "func", + "name": "y_translation", + "doc": { + "brief": "get y_translation of AprilTag", + "return": "return y_translation of the AprilTag, type is float", + "maixpy": "maix.image.AprilTag.y_translation", + "py_doc": "get y_translation of AprilTag\n\nReturns: return y_translation of the AprilTag, type is float\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float y_translation()", + "py_def": "def y_translation(self) -> float" + }, + "z_translation": { + "type": "func", + "name": "z_translation", + "doc": { + "brief": "get z_translation of AprilTag", + "return": "return z_translation of the AprilTag, type is float", + "maixpy": "maix.image.AprilTag.z_translation", + "py_doc": "get z_translation of AprilTag\n\nReturns: return z_translation of the AprilTag, type is float\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float z_translation()", + "py_def": "def z_translation(self) -> float" + }, + "x_rotation": { + "type": "func", + "name": "x_rotation", + "doc": { + "brief": "get x_rotation of AprilTag", + "return": "return x_rotation of the AprilTag, type is float", + "maixpy": "maix.image.AprilTag.x_rotation", + "py_doc": "get x_rotation of AprilTag\n\nReturns: return x_rotation of the AprilTag, type is float\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float x_rotation()", + "py_def": "def x_rotation(self) -> float" + }, + "y_rotation": { + "type": "func", + "name": "y_rotation", + "doc": { + "brief": "get y_rotation of AprilTag", + "return": "return y_rotation of the AprilTag, type is float", + "maixpy": "maix.image.AprilTag.y_rotation", + "py_doc": "get y_rotation of AprilTag\n\nReturns: return y_rotation of the AprilTag, type is float\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float y_rotation()", + "py_def": "def y_rotation(self) -> float" + }, + "z_rotation": { + "type": "func", + "name": "z_rotation", + "doc": { + "brief": "get z_rotation of AprilTag", + "return": "return z_rotation of the AprilTag, type is float", + "maixpy": "maix.image.AprilTag.z_rotation", + "py_doc": "get z_rotation of AprilTag\n\nReturns: return z_rotation of the AprilTag, type is float\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float z_rotation()", + "py_def": "def z_rotation(self) -> float" + } + }, + "def": "class AprilTag" + }, + "DataMatrix": { + "type": "class", + "name": "DataMatrix", + "doc": { + "brief": "DataMatrix class", + "maixpy": "maix.image.DataMatrix", + "py_doc": "DataMatrix class" + }, + "members": { + "__init__": { + "type": "func", + "name": "DataMatrix", + "doc": { + "brief": "DataMatrix constructor", + "param": { + "rect": "Inlucdes the top-left corner and the width and height of the rectangle. format is {x, y, w, h}, type is std::vector", + "corners": "Includes the four corners of the rectangle. format is {{x0, y0}, {x1, y1}, {x2, y2}, {x3, y3}}, type is std::vector>", + "payload": "The payload of the DataMatrix", + "rotation": "The rotation of the DataMatrix", + "rows": "The rows of the DataMatrix", + "columns": "The columns of the DataMatrix", + "capacity": "The capacity of the DataMatrix", + "padding": "The padding of the DataMatrix" + }, + "maixpy": "maix.image.DataMatrix.__init__", + "py_doc": "DataMatrix constructor\n\nArgs:\n - rect: Inlucdes the top-left corner and the width and height of the rectangle. format is {x, y, w, h}, type is std::vector\n - corners: Includes the four corners of the rectangle. format is {{x0, y0}, {x1, y1}, {x2, y2}, {x3, y3}}, type is std::vector>\n - payload: The payload of the DataMatrix\n - rotation: The rotation of the DataMatrix\n - rows: The rows of the DataMatrix\n - columns: The columns of the DataMatrix\n - capacity: The capacity of the DataMatrix\n - padding: The padding of the DataMatrix\n" + }, + "args": [ + [ + "std::vector &", + "rect", + null + ], + [ + "std::vector> &", + "corners", + null + ], + [ + "std::string &", + "payload", + null + ], + [ + "float", + "rotation", + null + ], + [ + "int", + "rows", + null + ], + [ + "int", + "columns", + null + ], + [ + "int", + "capacity", + null + ], + [ + "int", + "padding", + null + ] + ], + "ret_type": null, + "static": false, + "def": "DataMatrix(std::vector &rect, std::vector> &corners, std::string &payload, float rotation, int rows, int columns, int capacity, int padding)" + }, + "__getitem__": { + "type": "func", + "name": "__getitem__", + "doc": { + "brief": "Subscript operator", + "param": { + "index\n[0]": "get x of DataMatrix\n[1] get y of DataMatrix\n[2] get w of DataMatrix\n[3] get h of DataMatrix\n[4] Not support this index, try to use payload() method\n[5] Not support this index, try to use rotation() method\n[6] get rows of DataMatrix\n[7] get columns of DataMatrix\n[8] get capacity of DataMatrix\n[9] get padding of DataMatrix" + }, + "return": "int&", + "maixpy": "maix.image.DataMatrix.__getitem__", + "py_doc": "Subscript operator\n\nArgs:\n - index\n[0]: get x of DataMatrix\n[1] get y of DataMatrix\n[2] get w of DataMatrix\n[3] get h of DataMatrix\n[4] Not support this index, try to use payload() method\n[5] Not support this index, try to use rotation() method\n[6] get rows of DataMatrix\n[7] get columns of DataMatrix\n[8] get capacity of DataMatrix\n[9] get padding of DataMatrix\n\n\nReturns: int&\n" + }, + "args": [ + [ + "int", + "index", + null + ] + ], + "ret_type": "int&", + "static": false, + "def": "int &__getitem__(int index)" + }, + "corners": { + "type": "func", + "name": "corners", + "doc": { + "brief": "get coordinate of DataMatrix", + "return": "return the coordinate of the DataMatrix.", + "maixpy": "maix.image.DataMatrix.corners", + "py_doc": "get coordinate of DataMatrix\n\nReturns: return the coordinate of the DataMatrix.\n" + }, + "args": [], + "ret_type": "std::vector>", + "static": false, + "def": "std::vector> corners()" + }, + "rect": { + "type": "func", + "name": "rect", + "doc": { + "brief": "get rectangle of DataMatrix", + "return": "return the rectangle of the DataMatrix. format is {x, y, w, h}, type is std::vector", + "maixpy": "maix.image.DataMatrix.rect", + "py_doc": "get rectangle of DataMatrix\n\nReturns: return the rectangle of the DataMatrix. format is {x, y, w, h}, type is std::vector\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector rect()" + }, + "x": { + "type": "func", + "name": "x", + "doc": { + "brief": "get x of DataMatrix", + "return": "return x of the DataMatrix, type is int", + "maixpy": "maix.image.DataMatrix.x", + "py_doc": "get x of DataMatrix\n\nReturns: return x of the DataMatrix, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int x()" + }, + "y": { + "type": "func", + "name": "y", + "doc": { + "brief": "get y of DataMatrix", + "return": "return y of the DataMatrix, type is int", + "maixpy": "maix.image.DataMatrix.y", + "py_doc": "get y of DataMatrix\n\nReturns: return y of the DataMatrix, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int y()" + }, + "w": { + "type": "func", + "name": "w", + "doc": { + "brief": "get w of DataMatrix", + "return": "return w of the DataMatrix, type is int", + "maixpy": "maix.image.DataMatrix.w", + "py_doc": "get w of DataMatrix\n\nReturns: return w of the DataMatrix, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int w()" + }, + "h": { + "type": "func", + "name": "h", + "doc": { + "brief": "get h of DataMatrix", + "return": "return h of the DataMatrix, type is int", + "maixpy": "maix.image.DataMatrix.h", + "py_doc": "get h of DataMatrix\n\nReturns: return h of the DataMatrix, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int h()" + }, + "payload": { + "type": "func", + "name": "payload", + "doc": { + "brief": "get payload of DataMatrix", + "return": "return payload of the DataMatrix, type is std::string", + "maixpy": "maix.image.DataMatrix.payload", + "py_doc": "get payload of DataMatrix\n\nReturns: return payload of the DataMatrix, type is std::string\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string payload()" + }, + "rotation": { + "type": "func", + "name": "rotation", + "doc": { + "brief": "get rotation of DataMatrix", + "return": "return rotation of the DataMatrix, type is float", + "maixpy": "maix.image.DataMatrix.rotation", + "py_doc": "get rotation of DataMatrix\n\nReturns: return rotation of the DataMatrix, type is float\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float rotation()" + }, + "rows": { + "type": "func", + "name": "rows", + "doc": { + "brief": "get rows of DataMatrix", + "return": "return rows of the DataMatrix, type is int", + "maixpy": "maix.image.DataMatrix.rows", + "py_doc": "get rows of DataMatrix\n\nReturns: return rows of the DataMatrix, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int rows()" + }, + "columns": { + "type": "func", + "name": "columns", + "doc": { + "brief": "get columns of DataMatrix", + "return": "return columns of the DataMatrix, type is int", + "maixpy": "maix.image.DataMatrix.columns", + "py_doc": "get columns of DataMatrix\n\nReturns: return columns of the DataMatrix, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int columns()" + }, + "capacity": { + "type": "func", + "name": "capacity", + "doc": { + "brief": "get capacity of DataMatrix", + "return": "returns how many characters could fit in this data matrix, type is int", + "maixpy": "maix.image.DataMatrix.capacity", + "py_doc": "get capacity of DataMatrix\n\nReturns: returns how many characters could fit in this data matrix, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int capacity()" + }, + "padding": { + "type": "func", + "name": "padding", + "doc": { + "brief": "get padding of DataMatrix", + "return": "returns how many unused characters are in this data matrix, type is int", + "maixpy": "maix.image.DataMatrix.padding", + "py_doc": "get padding of DataMatrix\n\nReturns: returns how many unused characters are in this data matrix, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int padding()" + } + }, + "def": "class DataMatrix" + }, + "BarCode": { + "type": "class", + "name": "BarCode", + "doc": { + "brief": "BarCode class", + "maixpy": "maix.image.BarCode", + "py_doc": "BarCode class" + }, + "members": { + "__init__": { + "type": "func", + "name": "BarCode", + "doc": { + "brief": "BarCode constructor", + "param": { + "rect": "Inlucdes the top-left corner and the width and height of the rectangle. format is {x, y, w, h}, type is std::vector", + "corners": "Includes the four corners of the rectangle. format is {{x0, y0}, {x1, y1}, {x2, y2}, {x3, y3}}, type is std::vector>", + "payload": "The payload of the BarCode", + "type": "The type of the BarCode", + "rotation": "The rotation of the BarCode", + "quality": "The quality of the BarCode" + }, + "maixpy": "maix.image.BarCode.__init__", + "py_doc": "BarCode constructor\n\nArgs:\n - rect: Inlucdes the top-left corner and the width and height of the rectangle. format is {x, y, w, h}, type is std::vector\n - corners: Includes the four corners of the rectangle. format is {{x0, y0}, {x1, y1}, {x2, y2}, {x3, y3}}, type is std::vector>\n - payload: The payload of the BarCode\n - type: The type of the BarCode\n - rotation: The rotation of the BarCode\n - quality: The quality of the BarCode\n" + }, + "args": [ + [ + "std::vector &", + "rect", + null + ], + [ + "std::vector> &", + "corners", + null + ], + [ + "std::string &", + "payload", + null + ], + [ + "int", + "type", + null + ], + [ + "float", + "rotation", + null + ], + [ + "int", + "quality", + null + ] + ], + "ret_type": null, + "static": false, + "def": "BarCode(std::vector &rect, std::vector> &corners, std::string &payload, int type, float rotation, int quality)", + "py_def": "def __init__(self, rect: list[int], corners: list[list[int]], payload: str, type: int, rotation: float, quality: int) -> None" + }, + "__getitem__": { + "type": "func", + "name": "__getitem__", + "doc": { + "brief": "Subscript operator", + "param": { + "index\n[0]": "get x of BarCode\n[1] get y of BarCode\n[2] get w of BarCode\n[3] get h of BarCode\n[4] Not support this index, try to use payload() method\n[5] get type of BarCode\n[6] Not support this index, try to use rotation() method\n[7] get quality of BarCode" + }, + "return": "int&", + "maixpy": "maix.image.BarCode.__getitem__", + "py_doc": "Subscript operator\n\nArgs:\n - index\n[0]: get x of BarCode\n[1] get y of BarCode\n[2] get w of BarCode\n[3] get h of BarCode\n[4] Not support this index, try to use payload() method\n[5] get type of BarCode\n[6] Not support this index, try to use rotation() method\n[7] get quality of BarCode\n\n\nReturns: int&\n" + }, + "args": [ + [ + "int", + "index", + null + ] + ], + "ret_type": "int&", + "static": false, + "def": "int &__getitem__(int index)", + "py_def": "def __getitem__(self, index: int) -> int" + }, + "corners": { + "type": "func", + "name": "corners", + "doc": { + "brief": "get coordinate of BarCode", + "return": "return the coordinate of the BarCode.", + "maixpy": "maix.image.BarCode.corners", + "py_doc": "get coordinate of BarCode\n\nReturns: return the coordinate of the BarCode.\n" + }, + "args": [], + "ret_type": "std::vector>", + "static": false, + "def": "std::vector> corners()", + "py_def": "def corners(self) -> list[list[int]]" + }, + "rect": { + "type": "func", + "name": "rect", + "doc": { + "brief": "get rectangle of BarCode", + "return": "return the rectangle of the BarCode. format is {x, y, w, h}, type is std::vector", + "maixpy": "maix.image.BarCode.rect", + "py_doc": "get rectangle of BarCode\n\nReturns: return the rectangle of the BarCode. format is {x, y, w, h}, type is std::vector\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector rect()", + "py_def": "def rect(self) -> list[int]" + }, + "x": { + "type": "func", + "name": "x", + "doc": { + "brief": "get x of BarCode", + "return": "return x of the BarCode, type is int", + "maixpy": "maix.image.BarCode.x", + "py_doc": "get x of BarCode\n\nReturns: return x of the BarCode, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int x()", + "py_def": "def x(self) -> int" + }, + "y": { + "type": "func", + "name": "y", + "doc": { + "brief": "get y of BarCode", + "return": "return y of the BarCode, type is int", + "maixpy": "maix.image.BarCode.y", + "py_doc": "get y of BarCode\n\nReturns: return y of the BarCode, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int y()", + "py_def": "def y(self) -> int" + }, + "w": { + "type": "func", + "name": "w", + "doc": { + "brief": "get w of BarCode", + "return": "return w of the BarCode, type is int", + "maixpy": "maix.image.BarCode.w", + "py_doc": "get w of BarCode\n\nReturns: return w of the BarCode, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int w()", + "py_def": "def w(self) -> int" + }, + "h": { + "type": "func", + "name": "h", + "doc": { + "brief": "get h of BarCode", + "return": "return h of the BarCode, type is int", + "maixpy": "maix.image.BarCode.h", + "py_doc": "get h of BarCode\n\nReturns: return h of the BarCode, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int h()", + "py_def": "def h(self) -> int" + }, + "payload": { + "type": "func", + "name": "payload", + "doc": { + "brief": "get payload of BarCode", + "return": "return payload of the BarCode, type is std::string", + "maixpy": "maix.image.BarCode.payload", + "py_doc": "get payload of BarCode\n\nReturns: return payload of the BarCode, type is std::string\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string payload()", + "py_def": "def payload(self) -> str" + }, + "type": { + "type": "func", + "name": "type", + "doc": { + "brief": "get type of BarCode", + "return": "return type of the BarCode, type is int", + "maixpy": "maix.image.BarCode.type", + "py_doc": "get type of BarCode\n\nReturns: return type of the BarCode, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int type()", + "py_def": "def type(self) -> int" + }, + "rotation": { + "type": "func", + "name": "rotation", + "doc": { + "brief": "get rotation of BarCode", + "return": "return rotation of the BarCode, type is float. FIXME: always return 0.0", + "maixpy": "maix.image.BarCode.rotation", + "py_doc": "get rotation of BarCode\n\nReturns: return rotation of the BarCode, type is float. FIXME: always return 0.0\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float rotation()", + "py_def": "def rotation(self) -> float" + }, + "quality": { + "type": "func", + "name": "quality", + "doc": { + "brief": "get quality of BarCode", + "return": "return quality of the BarCode, type is int", + "maixpy": "maix.image.BarCode.quality", + "py_doc": "get quality of BarCode\n\nReturns: return quality of the BarCode, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int quality()", + "py_def": "def quality(self) -> int" + } + }, + "def": "class BarCode" + }, + "Statistics": { + "type": "class", + "name": "Statistics", + "doc": { + "brief": "Statistics class", + "maixpy": "maix.image.Statistics", + "py_doc": "Statistics class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Statistics", + "doc": { + "brief": "Statistics constructor", + "param": { + "format": "The statistics source image format", + "l_statistics": "The statistics of the L channel. format is {mean, median, mode, std_dev, min, max, lq, uq}, type is std::vector", + "a_statistics": "The statistics of the A channel. format is {mean, median, mode, std_dev, min, max, lq, uq}, type is std::vector", + "b_statistics": "The statistics of the B channel. format is {mean, median, mode, std_dev, min, max, lq, uq}, type is std::vector" + }, + "maixpy": "maix.image.Statistics.__init__", + "py_doc": "Statistics constructor\n\nArgs:\n - format: The statistics source image format\n - l_statistics: The statistics of the L channel. format is {mean, median, mode, std_dev, min, max, lq, uq}, type is std::vector\n - a_statistics: The statistics of the A channel. format is {mean, median, mode, std_dev, min, max, lq, uq}, type is std::vector\n - b_statistics: The statistics of the B channel. format is {mean, median, mode, std_dev, min, max, lq, uq}, type is std::vector\n" + }, + "args": [ + [ + "image::Format", + "format", + null + ], + [ + "std::vector &", + "l_statistics", + null + ], + [ + "std::vector &", + "a_statistics", + null + ], + [ + "std::vector &", + "b_statistics", + null + ] + ], + "ret_type": null, + "static": false, + "def": "Statistics(image::Format format, std::vector &l_statistics, std::vector &a_statistics, std::vector &b_statistics)" + }, + "__getitem__": { + "type": "func", + "name": "__getitem__", + "doc": { + "brief": "Subscript operator", + "param": { + "index": "array index" + }, + "return": "int&", + "maixpy": "maix.image.Statistics.__getitem__", + "py_doc": "Subscript operator\n\nArgs:\n - index: array index\n\n\nReturns: int&\n" + }, + "args": [ + [ + "int", + "index", + null + ] + ], + "ret_type": "int&", + "static": false, + "def": "int &__getitem__(int index)" + }, + "format": { + "type": "func", + "name": "format", + "doc": { + "brief": "get format of Statistics source image", + "return": "return format of the Statistics source image, type is image::Format", + "maixpy": "maix.image.Statistics.format", + "py_doc": "get format of Statistics source image\n\nReturns: return format of the Statistics source image, type is image::Format\n" + }, + "args": [], + "ret_type": "image::Format", + "static": false, + "def": "image::Format format()" + }, + "l_mean": { + "type": "func", + "name": "l_mean", + "doc": { + "brief": "get L channel mean", + "return": "return L channel mean, type is int", + "maixpy": "maix.image.Statistics.l_mean", + "py_doc": "get L channel mean\n\nReturns: return L channel mean, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int l_mean()" + }, + "l_median": { + "type": "func", + "name": "l_median", + "doc": { + "brief": "get L channel median", + "return": "return L channel median, type is int", + "maixpy": "maix.image.Statistics.l_median", + "py_doc": "get L channel median\n\nReturns: return L channel median, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int l_median()" + }, + "l_mode": { + "type": "func", + "name": "l_mode", + "doc": { + "brief": "get L channel mode", + "return": "return L channel mode, type is int", + "maixpy": "maix.image.Statistics.l_mode", + "py_doc": "get L channel mode\n\nReturns: return L channel mode, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int l_mode()" + }, + "l_std_dev": { + "type": "func", + "name": "l_std_dev", + "doc": { + "brief": "get L channel std_dev", + "return": "return L channel std_dev, type is int", + "maixpy": "maix.image.Statistics.l_std_dev", + "py_doc": "get L channel std_dev\n\nReturns: return L channel std_dev, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int l_std_dev()" + }, + "l_min": { + "type": "func", + "name": "l_min", + "doc": { + "brief": "get L channel min", + "return": "return L channel min, type is int", + "maixpy": "maix.image.Statistics.l_min", + "py_doc": "get L channel min\n\nReturns: return L channel min, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int l_min()" + }, + "l_max": { + "type": "func", + "name": "l_max", + "doc": { + "brief": "get L channel max", + "return": "return L channel max, type is int", + "maixpy": "maix.image.Statistics.l_max", + "py_doc": "get L channel max\n\nReturns: return L channel max, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int l_max()" + }, + "l_lq": { + "type": "func", + "name": "l_lq", + "doc": { + "brief": "get L channel lq", + "return": "return L channel lq, type is int", + "maixpy": "maix.image.Statistics.l_lq", + "py_doc": "get L channel lq\n\nReturns: return L channel lq, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int l_lq()" + }, + "l_uq": { + "type": "func", + "name": "l_uq", + "doc": { + "brief": "get L channel uq", + "return": "return L channel uq, type is int", + "maixpy": "maix.image.Statistics.l_uq", + "py_doc": "get L channel uq\n\nReturns: return L channel uq, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int l_uq()" + }, + "a_mean": { + "type": "func", + "name": "a_mean", + "doc": { + "brief": "get A channel mean", + "return": "return A channel mean, type is int", + "maixpy": "maix.image.Statistics.a_mean", + "py_doc": "get A channel mean\n\nReturns: return A channel mean, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int a_mean()" + }, + "a_median": { + "type": "func", + "name": "a_median", + "doc": { + "brief": "get A channea median", + "return": "return A channel median, type is int", + "maixpy": "maix.image.Statistics.a_median", + "py_doc": "get A channea median\n\nReturns: return A channel median, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int a_median()" + }, + "a_mode": { + "type": "func", + "name": "a_mode", + "doc": { + "brief": "get A channel mode", + "return": "return A channel mode, type is int", + "maixpy": "maix.image.Statistics.a_mode", + "py_doc": "get A channel mode\n\nReturns: return A channel mode, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int a_mode()" + }, + "a_std_dev": { + "type": "func", + "name": "a_std_dev", + "doc": { + "brief": "get A channel std_dev", + "return": "return A channel std_dev, type is int", + "maixpy": "maix.image.Statistics.a_std_dev", + "py_doc": "get A channel std_dev\n\nReturns: return A channel std_dev, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int a_std_dev()" + }, + "a_min": { + "type": "func", + "name": "a_min", + "doc": { + "brief": "get A channel min", + "return": "return A channel min, type is int", + "maixpy": "maix.image.Statistics.a_min", + "py_doc": "get A channel min\n\nReturns: return A channel min, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int a_min()" + }, + "a_max": { + "type": "func", + "name": "a_max", + "doc": { + "brief": "get A channel max", + "return": "return A channel max, type is int", + "maixpy": "maix.image.Statistics.a_max", + "py_doc": "get A channel max\n\nReturns: return A channel max, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int a_max()" + }, + "a_lq": { + "type": "func", + "name": "a_lq", + "doc": { + "brief": "get A channel lq", + "return": "return A channel lq, type is int", + "maixpy": "maix.image.Statistics.a_lq", + "py_doc": "get A channel lq\n\nReturns: return A channel lq, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int a_lq()" + }, + "a_uq": { + "type": "func", + "name": "a_uq", + "doc": { + "brief": "get A channel uq", + "return": "return A channel uq, type is int", + "maixpy": "maix.image.Statistics.a_uq", + "py_doc": "get A channel uq\n\nReturns: return A channel uq, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int a_uq()" + }, + "b_mean": { + "type": "func", + "name": "b_mean", + "doc": { + "brief": "get B channel mean", + "return": "return B channel mean, type is int", + "maixpy": "maix.image.Statistics.b_mean", + "py_doc": "get B channel mean\n\nReturns: return B channel mean, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int b_mean()" + }, + "b_median": { + "type": "func", + "name": "b_median", + "doc": { + "brief": "get B channea median", + "return": "return B channel median, type is int", + "maixpy": "maix.image.Statistics.b_median", + "py_doc": "get B channea median\n\nReturns: return B channel median, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int b_median()" + }, + "b_mode": { + "type": "func", + "name": "b_mode", + "doc": { + "brief": "get B channel mode", + "return": "return B channel mode, type is int", + "maixpy": "maix.image.Statistics.b_mode", + "py_doc": "get B channel mode\n\nReturns: return B channel mode, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int b_mode()" + }, + "b_std_dev": { + "type": "func", + "name": "b_std_dev", + "doc": { + "brief": "get B channel std_dev", + "return": "return B channel std_dev, type is int", + "maixpy": "maix.image.Statistics.b_std_dev", + "py_doc": "get B channel std_dev\n\nReturns: return B channel std_dev, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int b_std_dev()" + }, + "b_min": { + "type": "func", + "name": "b_min", + "doc": { + "brief": "get B channel min", + "return": "return B channel min, type is int", + "maixpy": "maix.image.Statistics.b_min", + "py_doc": "get B channel min\n\nReturns: return B channel min, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int b_min()" + }, + "b_max": { + "type": "func", + "name": "b_max", + "doc": { + "brief": "get B channel max", + "return": "return B channel max, type is int", + "maixpy": "maix.image.Statistics.b_max", + "py_doc": "get B channel max\n\nReturns: return B channel max, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int b_max()" + }, + "b_lq": { + "type": "func", + "name": "b_lq", + "doc": { + "brief": "get B channel lq", + "return": "return B channel lq, type is int", + "maixpy": "maix.image.Statistics.b_lq", + "py_doc": "get B channel lq\n\nReturns: return B channel lq, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int b_lq()" + }, + "b_uq": { + "type": "func", + "name": "b_uq", + "doc": { + "brief": "get B channel uq", + "return": "return B channel uq, type is int", + "maixpy": "maix.image.Statistics.b_uq", + "py_doc": "get B channel uq\n\nReturns: return B channel uq, type is int\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int b_uq()" + } + }, + "def": "class Statistics" + }, + "Displacement": { + "type": "class", + "name": "Displacement", + "doc": { + "brief": "Displacement class", + "maixpy": "maix.image.Displacement", + "py_doc": "Displacement class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Displacement", + "doc": { + "brief": "Displacement constructor", + "param": { + "x_translation": "The x_translation of the Displacement", + "y_translation": "The y_translation of the Displacement", + "rotation": "The rotation of the Displacement", + "scale": "The scale of the Displacement", + "response": "The response of the Displacement" + }, + "maixpy": "maix.image.Displacement.__init__", + "py_doc": "Displacement constructor\n\nArgs:\n - x_translation: The x_translation of the Displacement\n - y_translation: The y_translation of the Displacement\n - rotation: The rotation of the Displacement\n - scale: The scale of the Displacement\n - response: The response of the Displacement\n" + }, + "args": [ + [ + "float", + "x_translation", + null + ], + [ + "float", + "y_translation", + null + ], + [ + "float", + "rotation", + null + ], + [ + "float", + "scale", + null + ], + [ + "float", + "response", + null + ] + ], + "ret_type": null, + "static": false, + "def": "Displacement(float x_translation, float y_translation, float rotation, float scale, float response)", + "py_def": "def __init__(self, x_translation: float, y_translation: float, rotation: float, scale: float, response: float) -> None" + }, + "__getitem__": { + "type": "func", + "name": "__getitem__", + "doc": { + "brief": "Subscript operator", + "param": { + "index": "array index" + }, + "return": "int&", + "maixpy": "maix.image.Displacement.__getitem__", + "py_doc": "Subscript operator\n\nArgs:\n - index: array index\n\n\nReturns: int&\n" + }, + "args": [ + [ + "int", + "index", + null + ] + ], + "ret_type": "int&", + "static": false, + "def": "int &__getitem__(int index)", + "py_def": "def __getitem__(self, index: int) -> int" + }, + "x_translation": { + "type": "func", + "name": "x_translation", + "doc": { + "brief": "get x_translation of Displacement", + "return": "return x_translation of the Displacement, type is float", + "maixpy": "maix.image.Displacement.x_translation", + "py_doc": "get x_translation of Displacement\n\nReturns: return x_translation of the Displacement, type is float\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float x_translation()", + "py_def": "def x_translation(self) -> float" + }, + "y_translation": { + "type": "func", + "name": "y_translation", + "doc": { + "brief": "get y_translation of Displacement", + "return": "return y_translation of the Displacement, type is float", + "maixpy": "maix.image.Displacement.y_translation", + "py_doc": "get y_translation of Displacement\n\nReturns: return y_translation of the Displacement, type is float\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float y_translation()", + "py_def": "def y_translation(self) -> float" + }, + "rotation": { + "type": "func", + "name": "rotation", + "doc": { + "brief": "get rotation of Displacement", + "return": "return rotation of the Displacement, type is float", + "maixpy": "maix.image.Displacement.rotation", + "py_doc": "get rotation of Displacement\n\nReturns: return rotation of the Displacement, type is float\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float rotation()", + "py_def": "def rotation(self) -> float" + }, + "scale": { + "type": "func", + "name": "scale", + "doc": { + "brief": "get scale of Displacement", + "return": "return scale of the Displacement, type is float", + "maixpy": "maix.image.Displacement.scale", + "py_doc": "get scale of Displacement\n\nReturns: return scale of the Displacement, type is float\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float scale()", + "py_def": "def scale(self) -> float" + }, + "response": { + "type": "func", + "name": "response", + "doc": { + "brief": "get response of Displacement", + "return": "return response of the Displacement, type is float", + "maixpy": "maix.image.Displacement.response", + "py_doc": "get response of Displacement\n\nReturns: return response of the Displacement, type is float\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float response()", + "py_def": "def response(self) -> float" + } + }, + "def": "class Displacement" + }, + "LBPKeyPoint": { + "type": "class", + "name": "LBPKeyPoint", + "doc": { + "brief": "LBPKeyPoint class", + "maixpy": "maix.image.LBPKeyPoint", + "py_doc": "LBPKeyPoint class" + }, + "members": { + "__init__": { + "type": "func", + "name": "LBPKeyPoint", + "doc": { + "brief": "LBPKeyPoint constructor", + "param": { + "data": "The data of the LBPKeyPoint" + }, + "maixpy": "maix.image.LBPKeyPoint.__init__", + "py_doc": "LBPKeyPoint constructor\n\nArgs:\n - data: The data of the LBPKeyPoint\n" + }, + "args": [ + [ + "std::valarray &", + "data", + null + ] + ], + "ret_type": null, + "static": false, + "def": "LBPKeyPoint(std::valarray &data)", + "py_def": "def __init__(self, data: list[int]) -> None" + } + }, + "def": "class LBPKeyPoint" + }, + "KeyPoint": { + "type": "class", + "name": "KeyPoint", + "doc": { + "brief": "KeyPoint class", + "maixpy": "maix.image.KeyPoint", + "py_doc": "KeyPoint class" + }, + "members": { + "__init__": { + "type": "func", + "name": "KeyPoint", + "doc": { + "brief": "KeyPoint constructor", + "param": { + "x": "The x of the KeyPoint", + "y": "The y of the KeyPoint", + "score": "The score of the KeyPoint", + "octave": "The octave of the KeyPoint", + "angle": "The angle of the KeyPoint", + "matched": "The matched of the KeyPoint", + "desc": "The desc of the KeyPoint" + }, + "maixpy": "maix.image.KeyPoint.__init__", + "py_doc": "KeyPoint constructor\n\nArgs:\n - x: The x of the KeyPoint\n - y: The y of the KeyPoint\n - score: The score of the KeyPoint\n - octave: The octave of the KeyPoint\n - angle: The angle of the KeyPoint\n - matched: The matched of the KeyPoint\n - desc: The desc of the KeyPoint\n" + }, + "args": [ + [ + "uint16_t", + "x", + null + ], + [ + "uint16_t", + "y", + null + ], + [ + "uint16_t", + "score", + null + ], + [ + "uint16_t", + "octave", + null + ], + [ + "uint16_t", + "angle", + null + ], + [ + "uint16_t", + "matched", + null + ], + [ + "std::vector &", + "desc", + null + ] + ], + "ret_type": null, + "static": false, + "def": "KeyPoint(uint16_t x, uint16_t y, uint16_t score, uint16_t octave, uint16_t angle, uint16_t matched, std::vector &desc)" + } + }, + "def": "class KeyPoint" + }, + "KPTMatch": { + "type": "class", + "name": "KPTMatch", + "doc": { + "brief": "KPTMatch class", + "maixpy": "maix.image.KPTMatch", + "py_doc": "KPTMatch class" + }, + "members": { + "__init__": { + "type": "func", + "name": "KPTMatch", + "doc": { + "brief": "KPTMatch constructor", + "param": { + "cx": "The cx of the KPTMatch", + "cy": "The cy of the KPTMatch", + "x": "The x of the KPTMatch", + "y": "The y of the KPTMatch", + "w": "The w of the KPTMatch", + "h": "The h of the KPTMatch", + "score": "The score of the KPTMatch", + "theta": "The theta of the KPTMatch", + "match": "The match of the KPTMatch" + }, + "maixpy": "maix.image.KPTMatch.__init__", + "py_doc": "KPTMatch constructor\n\nArgs:\n - cx: The cx of the KPTMatch\n - cy: The cy of the KPTMatch\n - x: The x of the KPTMatch\n - y: The y of the KPTMatch\n - w: The w of the KPTMatch\n - h: The h of the KPTMatch\n - score: The score of the KPTMatch\n - theta: The theta of the KPTMatch\n - match: The match of the KPTMatch\n" + }, + "args": [ + [ + "int", + "cx", + null + ], + [ + "int", + "cy", + null + ], + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "int", + "w", + null + ], + [ + "int", + "h", + null + ], + [ + "int", + "score", + null + ], + [ + "int", + "theta", + null + ], + [ + "int", + "match", + null + ] + ], + "ret_type": null, + "static": false, + "def": "KPTMatch(int cx, int cy, int x, int y, int w, int h, int score, int theta, int match)", + "py_def": "def __init__(self, cx: int, cy: int, x: int, y: int, w: int, h: int, score: int, theta: int, match: int) -> None" + } + }, + "def": "class KPTMatch" + }, + "ORBKeyPoint": { + "type": "class", + "name": "ORBKeyPoint", + "doc": { + "brief": "ORBKeyPoint class", + "maixpy": "maix.image.ORBKeyPoint", + "py_doc": "ORBKeyPoint class" + }, + "members": { + "__init__": { + "type": "func", + "name": "ORBKeyPoint", + "doc": { + "brief": "ORBKeyPoint constructor", + "param": { + "data": "The data of the ORBKeyPoint", + "threshold": "The threshold of the ORBKeyPoint", + "normalized": "The normalized of the ORBKeyPoint" + }, + "maixpy": "maix.image.ORBKeyPoint.__init__", + "py_doc": "ORBKeyPoint constructor\n\nArgs:\n - data: The data of the ORBKeyPoint\n - threshold: The threshold of the ORBKeyPoint\n - normalized: The normalized of the ORBKeyPoint\n" + }, + "args": [ + [ + "std::vector &", + "data", + null + ], + [ + "int", + "threshold", + null + ], + [ + "bool", + "normalized", + null + ] + ], + "ret_type": null, + "static": false, + "def": "ORBKeyPoint(std::vector &data, int threshold, bool normalized)", + "py_def": "def __init__(self, data: list[KeyPoint], threshold: int, normalized: bool) -> None" + }, + "get_data": { + "type": "func", + "name": "get_data", + "doc": { + "brief": "get data of ORBKeyPoint", + "return": "return data of the ORBKeyPoint, type is std::vector", + "maixpy": "maix.image.ORBKeyPoint.get_data", + "py_doc": "get data of ORBKeyPoint\n\nReturns: return data of the ORBKeyPoint, type is std::vector\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector get_data()", + "py_def": "def get_data(self) -> list[KeyPoint]" + } + }, + "def": "class ORBKeyPoint" + }, + "HaarCascade": { + "type": "class", + "name": "HaarCascade", + "doc": { + "brief": "HaarCascade class", + "maixpy": "maix.image.HaarCascade", + "py_doc": "HaarCascade class" + }, + "members": { + "__init__": { + "type": "func", + "name": "HaarCascade", + "doc": { + "brief": "HaarCascade constructor", + "param": { + "data": "The data of the HaarCascade", + "threshold": "The threshold of the HaarCascade", + "normalized": "The normalized of the HaarCascade" + }, + "maixpy": "maix.image.HaarCascade.__init__", + "py_doc": "HaarCascade constructor\n\nArgs:\n - data: The data of the HaarCascade\n - threshold: The threshold of the HaarCascade\n - normalized: The normalized of the HaarCascade\n" + }, + "args": [], + "ret_type": null, + "static": false, + "def": "HaarCascade()", + "py_def": "def __init__(self) -> None" + } + }, + "def": "class HaarCascade" + }, + "Color": { + "type": "class", + "name": "Color", + "doc": { + "brief": "Color class", + "maixpy": "maix.image.Color", + "py_doc": "Color class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Color", + "doc": { + "brief": "Color constructor", + "param": { + "alpha": "alpha channel, value range: 0 ~ 1" + }, + "maixpy": "maix.image.Color.__init__", + "py_doc": "Color constructor\n\nArgs:\n - alpha: alpha channel, value range: 0 ~ 1\n" + }, + "args": [ + [ + "uint8_t", + "ch1", + null + ], + [ + "uint8_t", + "ch2", + "0" + ], + [ + "uint8_t", + "ch3", + "0" + ], + [ + "float", + "alpha", + "0" + ], + [ + "image::Format", + "format", + "image::FMT_GRAYSCALE" + ] + ], + "ret_type": null, + "static": false, + "def": "Color(uint8_t ch1, uint8_t ch2 = 0, uint8_t ch3 = 0, float alpha = 0, image::Format format = image::FMT_GRAYSCALE)" + }, + "r": { + "type": "var", + "name": "r", + "doc": { + "brief": "Color red channel", + "maixpy": "maix.image.Color.r", + "py_doc": "Color red channel" + }, + "value": null, + "static": false, + "readonly": false, + "def": "uint8_t r" + }, + "g": { + "type": "var", + "name": "g", + "doc": { + "brief": "Color green channel", + "maixpy": "maix.image.Color.g", + "py_doc": "Color green channel" + }, + "value": null, + "static": false, + "readonly": false, + "def": "uint8_t g" + }, + "b": { + "type": "var", + "name": "b", + "doc": { + "brief": "Color blue channel", + "maixpy": "maix.image.Color.b", + "py_doc": "Color blue channel" + }, + "value": null, + "static": false, + "readonly": false, + "def": "uint8_t b" + }, + "alpha": { + "type": "var", + "name": "alpha", + "doc": { + "brief": "Color alpha channel, value from 0.0 to 1.0, float value", + "maixpy": "maix.image.Color.alpha", + "py_doc": "Color alpha channel, value from 0.0 to 1.0, float value" + }, + "value": null, + "static": false, + "readonly": false, + "def": "float alpha" + }, + "gray": { + "type": "var", + "name": "gray", + "doc": { + "brief": "Color gray channel", + "maixpy": "maix.image.Color.gray", + "py_doc": "Color gray channel" + }, + "value": null, + "static": false, + "readonly": false, + "def": "uint8_t gray" + }, + "format": { + "type": "var", + "name": "format", + "doc": { + "brief": "Color format", + "maixpy": "maix.image.Color.format", + "py_doc": "Color format" + }, + "value": null, + "static": false, + "readonly": false, + "def": "image::Format format" + }, + "hex": { + "type": "func", + "name": "hex", + "doc": { + "brief": "Get color's hex value", + "maixpy": "maix.image.Color.hex", + "py_doc": "Get color's hex value" + }, + "args": [], + "ret_type": "uint32_t", + "static": false, + "def": "uint32_t hex()" + }, + "from_rgb": { + "type": "func", + "name": "from_rgb", + "doc": { + "brief": "Create Color object from RGB channels", + "maixpy": "maix.image.Color.from_rgb", + "py_doc": "Create Color object from RGB channels" + }, + "args": [ + [ + "uint8_t", + "r", + null + ], + [ + "uint8_t", + "g", + null + ], + [ + "uint8_t", + "b", + null + ] + ], + "ret_type": "image::Color", + "static": true, + "def": "static image::Color from_rgb(uint8_t r, uint8_t g, uint8_t b)" + }, + "from_bgr": { + "type": "func", + "name": "from_bgr", + "doc": { + "brief": "Create Color object from BGR channels", + "maixpy": "maix.image.Color.from_bgr", + "py_doc": "Create Color object from BGR channels" + }, + "args": [ + [ + "uint8_t", + "b", + null + ], + [ + "uint8_t", + "g", + null + ], + [ + "uint8_t", + "r", + null + ] + ], + "ret_type": "image::Color", + "static": true, + "def": "static image::Color from_bgr(uint8_t b, uint8_t g, uint8_t r)" + }, + "from_gray": { + "type": "func", + "name": "from_gray", + "doc": { + "brief": "Create Color object from gray channel", + "maixpy": "maix.image.Color.from_gray", + "py_doc": "Create Color object from gray channel" + }, + "args": [ + [ + "uint8_t", + "gray", + null + ] + ], + "ret_type": "image::Color", + "static": true, + "def": "static image::Color from_gray(uint8_t gray)" + }, + "from_rgba": { + "type": "func", + "name": "from_rgba", + "doc": { + "brief": "Create Color object from RGBA channels", + "param": { + "alpha": "alpha channel, float value, value range: 0 ~ 1" + }, + "maixpy": "maix.image.Color.from_rgba", + "py_doc": "Create Color object from RGBA channels\n\nArgs:\n - alpha: alpha channel, float value, value range: 0 ~ 1\n" + }, + "args": [ + [ + "uint8_t", + "r", + null + ], + [ + "uint8_t", + "g", + null + ], + [ + "uint8_t", + "b", + null + ], + [ + "float", + "alpha", + null + ] + ], + "ret_type": "image::Color", + "static": true, + "def": "static image::Color from_rgba(uint8_t r, uint8_t g, uint8_t b, float alpha)" + }, + "from_bgra": { + "type": "func", + "name": "from_bgra", + "doc": { + "brief": "Create Color object from BGRA channels", + "param": { + "alpha": "alpha channel, float value, value range: 0 ~ 1" + }, + "maixpy": "maix.image.Color.from_bgra", + "py_doc": "Create Color object from BGRA channels\n\nArgs:\n - alpha: alpha channel, float value, value range: 0 ~ 1\n" + }, + "args": [ + [ + "uint8_t", + "b", + null + ], + [ + "uint8_t", + "g", + null + ], + [ + "uint8_t", + "r", + null + ], + [ + "float", + "alpha", + null + ] + ], + "ret_type": "image::Color", + "static": true, + "def": "static image::Color from_bgra(uint8_t b, uint8_t g, uint8_t r, float alpha)" + }, + "from_hex": { + "type": "func", + "name": "from_hex", + "doc": { + "brief": "Create Color object from hex value", + "param": { + "hex": "hex value, e.g. 0x0000FF00, lower address if first channel", + "format": "color format, @see image::Format" + }, + "maixpy": "maix.image.Color.from_hex", + "py_doc": "Create Color object from hex value\n\nArgs:\n - hex: hex value, e.g. 0x0000FF00, lower address if first channel\n - format: color format, @see image::Format\n" + }, + "args": [ + [ + "uint32_t", + "hex", + null + ], + [ + "image::Format &", + "format", + null + ] + ], + "ret_type": "image::Color", + "static": true, + "def": "static image::Color from_hex(uint32_t hex, image::Format &format)" + }, + "to_format": { + "type": "func", + "name": "to_format", + "doc": { + "brief": "Convert Color format", + "param": { + "format": "format want to convert to, @see image::Format, only support RGB888, BGR888, RGBA8888, BGRA8888, GRAYSCALE." + }, + "maixpy": "maix.image.Color.to_format", + "py_doc": "Convert Color format\n\nArgs:\n - format: format want to convert to, @see image::Format, only support RGB888, BGR888, RGBA8888, BGRA8888, GRAYSCALE.\n" + }, + "args": [ + [ + "const image::Format &", + "format", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void to_format(const image::Format &format)" + }, + "to_format2": { + "type": "func", + "name": "to_format2", + "doc": { + "brief": "Convert color format and return a new Color object", + "param": { + "format": "format want to convert to, @see image::Format, only support RGB888, BGR888, RGBA8888, BGRA8888, GRAYSCALE." + }, + "return": "new Color object, you need to delete it manually in C++.", + "maixpy": "maix.image.Color.to_format2", + "py_doc": "Convert color format and return a new Color object\n\nArgs:\n - format: format want to convert to, @see image::Format, only support RGB888, BGR888, RGBA8888, BGRA8888, GRAYSCALE.\n\n\nReturns: new Color object, you need to delete it manually in C++.\n" + }, + "args": [ + [ + "const image::Format &", + "format", + null + ] + ], + "ret_type": "image::Color*", + "static": false, + "def": "image::Color *to_format2(const image::Format &format)" + } + }, + "def": "class Color" + }, + "COLOR_WHITE": { + "type": "var", + "name": "", + "doc": { + "brief": "Predefined color white", + "maixpy": "maix.image.COLOR_WHITE", + "py_doc": "Predefined color white" + }, + "value": "image::Color::from_rgb(255, 255, 255)", + "static": false, + "readonly": true, + "def": "const image::Color COLOR_WHITE = image::Color::from_rgb(255, 255, 255)" + }, + "COLOR_BLACK": { + "type": "var", + "name": "", + "doc": { + "brief": "Predefined color black", + "maixpy": "maix.image.COLOR_BLACK", + "py_doc": "Predefined color black" + }, + "value": "image::Color::from_rgb(0, 0, 0)", + "static": false, + "readonly": true, + "def": "const image::Color COLOR_BLACK = image::Color::from_rgb(0, 0, 0)" + }, + "COLOR_RED": { + "type": "var", + "name": "", + "doc": { + "brief": "Predefined color red", + "maixpy": "maix.image.COLOR_RED", + "py_doc": "Predefined color red" + }, + "value": "image::Color::from_rgb(255, 0, 0)", + "static": false, + "readonly": true, + "def": "const image::Color COLOR_RED = image::Color::from_rgb(255, 0, 0)" + }, + "COLOR_GREEN": { + "type": "var", + "name": "", + "doc": { + "brief": "Predefined color green", + "maixpy": "maix.image.COLOR_GREEN", + "py_doc": "Predefined color green" + }, + "value": "image::Color::from_rgb(0, 255, 0)", + "static": false, + "readonly": true, + "def": "const image::Color COLOR_GREEN = image::Color::from_rgb(0, 255, 0)" + }, + "COLOR_BLUE": { + "type": "var", + "name": "", + "doc": { + "brief": "Predefined color blue", + "maixpy": "maix.image.COLOR_BLUE", + "py_doc": "Predefined color blue" + }, + "value": "image::Color::from_rgb(0, 0, 255)", + "static": false, + "readonly": true, + "def": "const image::Color COLOR_BLUE = image::Color::from_rgb(0, 0, 255)" + }, + "COLOR_YELLOW": { + "type": "var", + "name": "", + "doc": { + "brief": "Predefined color yellow", + "maixpy": "maix.image.COLOR_YELLOW", + "py_doc": "Predefined color yellow" + }, + "value": "image::Color::from_rgb(255, 255, 0)", + "static": false, + "readonly": true, + "def": "const image::Color COLOR_YELLOW = image::Color::from_rgb(255, 255, 0)" + }, + "COLOR_PURPLE": { + "type": "var", + "name": "", + "doc": { + "brief": "Predefined color purple", + "maixpy": "maix.image.COLOR_PURPLE", + "py_doc": "Predefined color purple" + }, + "value": "image::Color::from_rgb(143, 0, 255)", + "static": false, + "readonly": true, + "def": "const image::Color COLOR_PURPLE = image::Color::from_rgb(143, 0, 255)" + }, + "COLOR_ORANGE": { + "type": "var", + "name": "", + "doc": { + "brief": "Predefined color orange", + "maixpy": "maix.image.COLOR_ORANGE", + "py_doc": "Predefined color orange" + }, + "value": "image::Color::from_rgb(255, 127, 0)", + "static": false, + "readonly": true, + "def": "const image::Color COLOR_ORANGE = image::Color::from_rgb(255, 127, 0)" + }, + "COLOR_GRAY": { + "type": "var", + "name": "", + "doc": { + "brief": "Predefined color gray", + "maixpy": "maix.image.COLOR_GRAY", + "py_doc": "Predefined color gray" + }, + "value": "image::Color::from_rgb(127, 127, 127)", + "static": false, + "readonly": true, + "def": "const image::Color COLOR_GRAY = image::Color::from_rgb(127, 127, 127)" + }, + "Image": { + "type": "class", + "name": "Image", + "doc": { + "brief": "Image class", + "maixpy": "maix.image.Image", + "py_doc": "Image class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Image", + "doc": { + "brief": "Image constructor", + "param": { + "width": "image width, should > 0", + "height": "image height, should > 0", + "format": "image format @see image::Format" + }, + "maixpy": "maix.image.Image.__init__", + "maixcdk": "maix.image.Image.Image", + "py_doc": "Image constructor\n\nArgs:\n - width: image width, should > 0\n - height: image height, should > 0\n - format: image format @see image::Format\n" + }, + "args": [ + [ + "int", + "width", + null + ], + [ + "int", + "height", + null + ], + [ + "image::Format", + "format", + "image::Format::FMT_RGB888" + ] + ], + "ret_type": null, + "static": false, + "def": "Image(int width, int height, image::Format format = image::Format::FMT_RGB888)" + }, + "format": { + "type": "func", + "name": "format", + "doc": { + "brief": "Get image's format", + "see": "image.Format", + "maixpy": "maix.image.Image.format", + "py_doc": "Get image's format" + }, + "args": [], + "ret_type": "image::Format", + "static": false, + "def": "image::Format format()" + }, + "size": { + "type": "func", + "name": "size", + "doc": { + "brief": "Get image's size, [width, height]", + "maixpy": "maix.image.Image.size", + "py_doc": "Get image's size, [width, height]" + }, + "args": [], + "ret_type": "image::Size", + "static": false, + "def": "image::Size size()" + }, + "data_size": { + "type": "func", + "name": "data_size", + "doc": { + "brief": "Get image's data size", + "maixpy": "maix.image.Image.data_size", + "py_doc": "Get image's data size" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int data_size()" + }, + "width": { + "type": "func", + "name": "width", + "doc": { + "brief": "Get image's width", + "maixpy": "maix.image.Image.width", + "py_doc": "Get image's width" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int width()" + }, + "height": { + "type": "func", + "name": "height", + "doc": { + "brief": "Get image's height", + "maixpy": "maix.image.Image.height", + "py_doc": "Get image's height" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int height()" + }, + "data": { + "type": "func", + "name": "data", + "doc": { + "brief": "Get image's data pointer.\\nIn MaixPy is capsule object.", + "maixpy": "maix.image.Image.data", + "py_doc": "Get image's data pointer.\nIn MaixPy is capsule object." + }, + "args": [], + "ret_type": "void*", + "static": false, + "def": "void *data()" + }, + "__str__": { + "type": "func", + "name": "__str__", + "doc": { + "brief": "To string method", + "maixpy": "maix.image.Image.__str__", + "py_doc": "To string method" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string __str__()" + }, + "to_str": { + "type": "func", + "name": "to_str", + "doc": { + "brief": "To string method", + "maixpy": "maix.image.Image.to_str", + "py_doc": "To string method" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string to_str()" + }, + "get_pixel": { + "type": "func", + "name": "get_pixel", + "doc": { + "brief": "Get pixel of image", + "param": { + "x": "pixel's coordinate x. x must less than image's width", + "y": "pixel's coordinate y. y must less than image's height", + "rgbtuple": "switch return value method. rgbtuple decides whether to split the return or not. default is false." + }, + "return": "pixel value,\nAccording to image format and rgbtuple, return different value:\nformat is FMT_RGB888, rgbtuple is true, return [R, G, B]; rgbtuple is false, return [RGB]\nforamt is FMT_BGR888, rgbtuple is true, return [B, G, R]; rgbtuple is false, return [BGR]\nformat is FMT_GRAYSCALE, return [GRAY];", + "maixpy": "maix.image.Image.get_pixel", + "py_doc": "Get pixel of image\n\nArgs:\n - x: pixel's coordinate x. x must less than image's width\n - y: pixel's coordinate y. y must less than image's height\n - rgbtuple: switch return value method. rgbtuple decides whether to split the return or not. default is false.\n\n\nReturns: pixel value,\nAccording to image format and rgbtuple, return different value:\nformat is FMT_RGB888, rgbtuple is true, return [R, G, B]; rgbtuple is false, return [RGB]\nforamt is FMT_BGR888, rgbtuple is true, return [B, G, R]; rgbtuple is false, return [BGR]\nformat is FMT_GRAYSCALE, return [GRAY];\n" + }, + "args": [ + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "bool", + "rgbtuple", + "false" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector get_pixel(int x, int y, bool rgbtuple = false)" + }, + "set_pixel": { + "type": "func", + "name": "set_pixel", + "doc": { + "brief": "Set pixel of image", + "param": { + "x": "pixel's coordinate x. x must less than image's width", + "y": "pixel's coordinate y. y must less than image's height", + "pixel": "pixel value, according to image format and size of pixel, has different operation:\nformat is FMT_RGB888, pixel size must be 1 or 3, if size is 1, will split pixel[0] to [R, G, B]; if size is 3, will use pixel directly\nformat is FMT_BGR888, pixel size must be 1 or 3, if size is 1, will split pixel[0] to [B, G, R]; if size is 3, will use pixel directly\nformat is FMT_GRAYSCALE, pixel size must be 1, will use pixel directly" + }, + "return": "error code, Err::ERR_NONE is ok, other is error", + "maixpy": "maix.image.Image.set_pixel", + "py_doc": "Set pixel of image\n\nArgs:\n - x: pixel's coordinate x. x must less than image's width\n - y: pixel's coordinate y. y must less than image's height\n - pixel: pixel value, according to image format and size of pixel, has different operation:\nformat is FMT_RGB888, pixel size must be 1 or 3, if size is 1, will split pixel[0] to [R, G, B]; if size is 3, will use pixel directly\nformat is FMT_BGR888, pixel size must be 1 or 3, if size is 1, will split pixel[0] to [B, G, R]; if size is 3, will use pixel directly\nformat is FMT_GRAYSCALE, pixel size must be 1, will use pixel directly\n\n\nReturns: error code, Err::ERR_NONE is ok, other is error\n" + }, + "args": [ + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "std::vector", + "pixel", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err set_pixel(int x, int y, std::vector pixel)" + }, + "to_tensor": { + "type": "func", + "name": "to_tensor", + "doc": { + "brief": "Convert Image object to tensor::Tensor object", + "param": { + "chw": "if true, the shape of tensor is [C, H, W], else [H, W, C]", + "copy": "if true, will alloc memory for tensor data, else will use the memory of Image object" + }, + "return": "tensor::Tensor object pointer, an allocated tensor object", + "maixpy": "maix.image.Image.to_tensor", + "py_doc": "Convert Image object to tensor::Tensor object\n\nArgs:\n - chw: if true, the shape of tensor is [C, H, W], else [H, W, C]\n - copy: if true, will alloc memory for tensor data, else will use the memory of Image object\n\n\nReturns: tensor::Tensor object pointer, an allocated tensor object\n" + }, + "args": [ + [ + "bool", + "chw", + "false" + ], + [ + "bool", + "copy", + "true" + ] + ], + "ret_type": "tensor::Tensor*", + "static": false, + "def": "tensor::Tensor *to_tensor(bool chw = false, bool copy = true)" + }, + "to_bytes": { + "type": "func", + "name": "to_bytes", + "doc": { + "brief": "Get image's data and convert to array bytes", + "param": { + "copy": "if true, will alloc memory and copy data to new buffer,\nelse will use the memory of Image object, delete bytes object will not affect Image object\uff0c\nbut delete Image object will make bytes object invalid, it may cause program crash !!!!\nSo use this param carefully." + }, + "return": "image's data bytes, need be delete by caller in C++.", + "maixpy": "maix.image.Image.to_bytes", + "py_doc": "Get image's data and convert to array bytes\n\nArgs:\n - copy: if true, will alloc memory and copy data to new buffer,\nelse will use the memory of Image object, delete bytes object will not affect Image object\uff0c\nbut delete Image object will make bytes object invalid, it may cause program crash !!!!\nSo use this param carefully.\n\n\nReturns: image's data bytes, need be delete by caller in C++.\n" + }, + "args": [ + [ + "bool", + "copy", + "true" + ] + ], + "ret_type": "Bytes*", + "static": false, + "def": "Bytes *to_bytes(bool copy = true)" + }, + "to_format": { + "type": "func", + "name": "to_format", + "doc": { + "brief": "Convert image to specific format", + "param": { + "format": "format want to convert to, @see image::Format, only support RGB888, BGR888, RGBA8888, BGRA8888, GRAYSCALE, JPEG." + }, + "return": "new image object. Need be delete by caller in C++.", + "throw": "err.Exception, if two images' format not support, **or already the format**, will raise exception", + "maixpy": "maix.image.Image.to_format", + "py_doc": "Convert image to specific format\n\nArgs:\n - format: format want to convert to, @see image::Format, only support RGB888, BGR888, RGBA8888, BGRA8888, GRAYSCALE, JPEG.\n\n\nReturns: new image object. Need be delete by caller in C++.\n" + }, + "args": [ + [ + "const image::Format &", + "format", + null + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *to_format(const image::Format &format)" + }, + "to_jpeg": { + "type": "func", + "name": "to_jpeg", + "doc": { + "brief": "Convert image to jpeg", + "param": { + "quality": "the quality of jpg, default is 95. range is (50, 100]." + }, + "return": "new image object. Need be delete by caller in C++.", + "throw": "err.Exception, if two images' format not support, **or already the format**, will raise exception", + "maixpy": "maix.image.Image.to_jpeg", + "py_doc": "Convert image to jpeg\n\nArgs:\n - quality: the quality of jpg, default is 95. range is (50, 100].\n\n\nReturns: new image object. Need be delete by caller in C++.\n" + }, + "args": [ + [ + "int", + "quality", + "95" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *to_jpeg(int quality = 95)" + }, + "draw_image": { + "type": "func", + "name": "draw_image", + "doc": { + "brief": "Draw image on this image", + "param": { + "x": "left top corner of image point's coordinate x", + "y": "left top corner of image point's coordinate y", + "img": "image object to draw, the caller's channel must <= the args' channel,\ne.g. caller is RGB888, args is RGBA8888, will throw exception, but caller is RGBA8888, args is RGB888 or RGBA8888 is ok" + }, + "return": "this image object self", + "maixpy": "maix.image.Image.draw_image", + "py_doc": "Draw image on this image\n\nArgs:\n - x: left top corner of image point's coordinate x\n - y: left top corner of image point's coordinate y\n - img: image object to draw, the caller's channel must <= the args' channel,\ne.g. caller is RGB888, args is RGBA8888, will throw exception, but caller is RGBA8888, args is RGB888 or RGBA8888 is ok\n\n\nReturns: this image object self\n" + }, + "args": [ + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "image::Image &", + "img", + null + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *draw_image(int x, int y, image::Image &img)" + }, + "draw_rect": { + "type": "func", + "name": "draw_rect", + "doc": { + "brief": "Fill rectangle color to image", + "param": { + "x": "left top corner of rectangle point's coordinate x", + "y": "left top corner of rectangle point's coordinate y", + "w": "rectangle width", + "h": "rectangle height", + "color": "rectangle color", + "thickness": "rectangle thickness(line width), by default(value is 1), -1 means fill rectangle" + }, + "return": "this image object self", + "maixpy": "maix.image.Image.draw_rect", + "py_doc": "Fill rectangle color to image\n\nArgs:\n - x: left top corner of rectangle point's coordinate x\n - y: left top corner of rectangle point's coordinate y\n - w: rectangle width\n - h: rectangle height\n - color: rectangle color\n - thickness: rectangle thickness(line width), by default(value is 1), -1 means fill rectangle\n\n\nReturns: this image object self\n" + }, + "args": [ + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "int", + "w", + null + ], + [ + "int", + "h", + null + ], + [ + "const image::Color &", + "color", + null + ], + [ + "int", + "thickness", + "1" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *draw_rect(int x, int y, int w, int h, const image::Color &color, int thickness = 1)" + }, + "draw_line": { + "type": "func", + "name": "draw_line", + "doc": { + "brief": "Draw line on image", + "param": { + "x1": "start point's coordinate x", + "y1": "start point's coordinate y", + "x2": "end point's coordinate x", + "y2": "end point's coordinate y", + "color": "line color @see image::Color", + "thickness": "line thickness(line width), by default(value is 1)" + }, + "return": "this image object self", + "maixpy": "maix.image.Image.draw_line", + "py_doc": "Draw line on image\n\nArgs:\n - x1: start point's coordinate x\n - y1: start point's coordinate y\n - x2: end point's coordinate x\n - y2: end point's coordinate y\n - color: line color @see image::Color\n - thickness: line thickness(line width), by default(value is 1)\n\n\nReturns: this image object self\n" + }, + "args": [ + [ + "int", + "x1", + null + ], + [ + "int", + "y1", + null + ], + [ + "int", + "x2", + null + ], + [ + "int", + "y2", + null + ], + [ + "const image::Color &", + "color", + null + ], + [ + "int", + "thickness", + "1" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *draw_line(int x1, int y1, int x2, int y2, const image::Color &color, int thickness = 1)" + }, + "draw_circle": { + "type": "func", + "name": "draw_circle", + "doc": { + "brief": "Draw circle on image", + "param": { + "x": "circle center point's coordinate x", + "y": "circle center point's coordinate y", + "radius": "circle radius", + "color": "circle color @see image::Color", + "thickness": "circle thickness(line width), by default(value is 1), -1 means fill circle" + }, + "return": "this image object self", + "maixpy": "maix.image.Image.draw_circle", + "py_doc": "Draw circle on image\n\nArgs:\n - x: circle center point's coordinate x\n - y: circle center point's coordinate y\n - radius: circle radius\n - color: circle color @see image::Color\n - thickness: circle thickness(line width), by default(value is 1), -1 means fill circle\n\n\nReturns: this image object self\n" + }, + "args": [ + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "int", + "radius", + null + ], + [ + "const image::Color &", + "color", + null + ], + [ + "int", + "thickness", + "1" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *draw_circle(int x, int y, int radius, const image::Color &color, int thickness = 1)" + }, + "draw_ellipse": { + "type": "func", + "name": "draw_ellipse", + "doc": { + "brief": "Draw ellipse on image", + "param": { + "x": "ellipse center point's coordinate x", + "y": "ellipse center point's coordinate y", + "a": "ellipse major axis length", + "b": "ellipse minor axis length", + "angle": "ellipse rotation angle", + "start_angle": "ellipse start angle", + "end_angle": "ellipse end angle", + "color": "ellipse color @see image::Color", + "thickness": "ellipse thickness(line width), by default(value is 1), -1 means fill ellipse" + }, + "return": "this image object self", + "maixpy": "maix.image.Image.draw_ellipse", + "py_doc": "Draw ellipse on image\n\nArgs:\n - x: ellipse center point's coordinate x\n - y: ellipse center point's coordinate y\n - a: ellipse major axis length\n - b: ellipse minor axis length\n - angle: ellipse rotation angle\n - start_angle: ellipse start angle\n - end_angle: ellipse end angle\n - color: ellipse color @see image::Color\n - thickness: ellipse thickness(line width), by default(value is 1), -1 means fill ellipse\n\n\nReturns: this image object self\n" + }, + "args": [ + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "int", + "a", + null + ], + [ + "int", + "b", + null + ], + [ + "float", + "angle", + null + ], + [ + "float", + "start_angle", + null + ], + [ + "float", + "end_angle", + null + ], + [ + "const image::Color &", + "color", + null + ], + [ + "int", + "thickness", + "1" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *draw_ellipse(int x, int y, int a, int b, float angle, float start_angle, float end_angle, const image::Color &color, int thickness = 1)" + }, + "draw_string": { + "type": "func", + "name": "draw_string", + "doc": { + "brief": "Draw text on image", + "param": { + "x": "text left top point's coordinate x", + "y": "text left top point's coordinate y", + "string": "text content", + "color": "text color @see image::Color, default is white", + "scale": "font scale, by default(value is 1)", + "thickness": "text thickness(line width), if negative, the glyph is filled, by default(value is -1)", + "wrap": "if true, will auto wrap text to next line if text width > image width, by default(value is true)" + }, + "return": "this image object self", + "maixpy": "maix.image.Image.draw_string", + "py_doc": "Draw text on image\n\nArgs:\n - x: text left top point's coordinate x\n - y: text left top point's coordinate y\n - string: text content\n - color: text color @see image::Color, default is white\n - scale: font scale, by default(value is 1)\n - thickness: text thickness(line width), if negative, the glyph is filled, by default(value is -1)\n - wrap: if true, will auto wrap text to next line if text width > image width, by default(value is true)\n\n\nReturns: this image object self\n" + }, + "args": [ + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "const std::string &", + "textstring", + null + ], + [ + "const image::Color &", + "color", + "image::COLOR_WHITE" + ], + [ + "float", + "scale", + "1" + ], + [ + "int", + "thickness", + "-1" + ], + [ + "bool", + "wrap", + "true" + ], + [ + "int", + "wrap_space", + "4" + ], + [ + "const std::string &", + "font", + "\"\"" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *draw_string(int x, int y, const std::string &textstring, const image::Color &color = image::COLOR_WHITE, float scale = 1, int thickness = -1,\n bool wrap = true, int wrap_space = 4, const std::string &font = \"\")" + }, + "draw_cross": { + "type": "func", + "name": "draw_cross", + "doc": { + "brief": "Draw cross on image", + "param": { + "x": "cross center point's coordinate x", + "y": "cross center point's coordinate y", + "color": "cross color @see image::Color", + "size": "how long the lines of the cross extend, by default(value is 5). So the line length is `2 * size + thickness`", + "thickness": "cross thickness(line width), by default(value is 1)" + }, + "maixpy": "maix.image.Image.draw_cross", + "py_doc": "Draw cross on image\n\nArgs:\n - x: cross center point's coordinate x\n - y: cross center point's coordinate y\n - color: cross color @see image::Color\n - size: how long the lines of the cross extend, by default(value is 5). So the line length is `2 * size + thickness`\n - thickness: cross thickness(line width), by default(value is 1)\n" + }, + "args": [ + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "const image::Color &", + "color", + null + ], + [ + "int", + "size", + "5" + ], + [ + "int", + "thickness", + "1" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *draw_cross(int x, int y, const image::Color &color, int size = 5, int thickness = 1)" + }, + "draw_arrow": { + "type": "func", + "name": "draw_arrow", + "doc": { + "brief": "Draw arrow on image", + "param": { + "x0": "start coordinate of the arrow x0", + "y0": "start coordinate of the arrow y0", + "x1": "end coordinate of the arrow x1", + "y1": "end coordinate of the arrow y1", + "color": "cross color @see image::Color", + "thickness": "cross thickness(line width), by default(value is 1)" + }, + "return": "this image object self", + "maixpy": "maix.image.Image.draw_arrow", + "py_doc": "Draw arrow on image\n\nArgs:\n - x0: start coordinate of the arrow x0\n - y0: start coordinate of the arrow y0\n - x1: end coordinate of the arrow x1\n - y1: end coordinate of the arrow y1\n - color: cross color @see image::Color\n - thickness: cross thickness(line width), by default(value is 1)\n\n\nReturns: this image object self\n" + }, + "args": [ + [ + "int", + "x0", + null + ], + [ + "int", + "y0", + null + ], + [ + "int", + "x1", + null + ], + [ + "int", + "y1", + null + ], + [ + "const image::Color &", + "color", + null + ], + [ + "int", + "thickness", + "1" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *draw_arrow(int x0, int y0, int x1, int y1, const image::Color &color, int thickness = 1)" + }, + "draw_edges": { + "type": "func", + "name": "draw_edges", + "doc": { + "brief": "Draw edges on image", + "param": { + "corners": "edges, [[x0, y0], [x1, y1], [x2, y2], [x3, y3]]", + "color": "edges color @see image::Color", + "size": "the circle of radius size. TODO: support in the feature", + "thickness": "edges thickness(line width), by default(value is 1)", + "fill": "if true, will fill edges, by default(value is false)" + }, + "return": "this image object self", + "maixpy": "maix.image.Image.draw_edges", + "py_doc": "Draw edges on image\n\nArgs:\n - corners: edges, [[x0, y0], [x1, y1], [x2, y2], [x3, y3]]\n - color: edges color @see image::Color\n - size: the circle of radius size. TODO: support in the feature\n - thickness: edges thickness(line width), by default(value is 1)\n - fill: if true, will fill edges, by default(value is false)\n\n\nReturns: this image object self\n" + }, + "args": [ + [ + "std::vector>", + "corners", + null + ], + [ + "const image::Color &", + "color", + null + ], + [ + "int", + "size", + "0" + ], + [ + "int", + "thickness", + "1" + ], + [ + "bool", + "fill", + "false" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *draw_edges(std::vector> corners, const image::Color &color, int size = 0, int thickness = 1, bool fill = false)" + }, + "draw_keypoints": { + "type": "func", + "name": "draw_keypoints", + "doc": { + "brief": "Draw keypoints on image", + "param": { + "keypoints": "keypoints, [x, y, rotation_andle_in_degrees], TODO: rotation_andle_in_degrees support in the feature", + "color": "keypoints color @see image::Color", + "size": "size of keypoints", + "thickness": "keypoints thickness(line width), by default(value is 1)", + "fill": "if true, will fill keypoints, by default(value is false)" + }, + "return": "this image object self", + "maixpy": "maix.image.Image.draw_keypoints", + "py_doc": "Draw keypoints on image\n\nArgs:\n - keypoints: keypoints, [x, y, rotation_andle_in_degrees], TODO: rotation_andle_in_degrees support in the feature\n - color: keypoints color @see image::Color\n - size: size of keypoints\n - thickness: keypoints thickness(line width), by default(value is 1)\n - fill: if true, will fill keypoints, by default(value is false)\n\n\nReturns: this image object self\n" + }, + "args": [ + [ + "std::vector", + "keypoints", + null + ], + [ + "const image::Color &", + "color", + null + ], + [ + "int", + "size", + "10" + ], + [ + "int", + "thickness", + "1" + ], + [ + "bool", + "fill", + "false" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *draw_keypoints(std::vector keypoints, const image::Color &color, int size = 10, int thickness = 1, bool fill = false)" + }, + "resize": { + "type": "func", + "name": "resize", + "doc": { + "brief": "Resize image, will create a new resized image object", + "param": { + "width": "new width, if value is -1, will use height to calculate aspect ratio", + "height": "new height, if value is -1, will use width to calculate aspect ratio", + "object_fit": "fill, contain, cover, by default is fill", + "method": "resize method, by default is bilinear" + }, + "return": "Always return a new resized image object even size not change, So in C++ you should take care of the return value to avoid memory leak.\nAnd it's better to judge whether the size has changed before calling this function to make the program more efficient.\ne.g.\nif img->width() != width || img->height() != height:\nimg = img->resize(width, height);", + "maixpy": "maix.image.Image.resize", + "py_doc": "Resize image, will create a new resized image object\n\nArgs:\n - width: new width, if value is -1, will use height to calculate aspect ratio\n - height: new height, if value is -1, will use width to calculate aspect ratio\n - object_fit: fill, contain, cover, by default is fill\n - method: resize method, by default is bilinear\n\n\nReturns: Always return a new resized image object even size not change, So in C++ you should take care of the return value to avoid memory leak.\nAnd it's better to judge whether the size has changed before calling this function to make the program more efficient.\ne.g.\nif img->width() != width || img->height() != height:\nimg = img->resize(width, height);\n" + }, + "args": [ + [ + "int", + "width", + null + ], + [ + "int", + "height", + null + ], + [ + "image::Fit", + "object_fit", + "image::Fit::FIT_FILL" + ], + [ + "image::ResizeMethod", + "method", + "image::ResizeMethod::NEAREST" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *resize(int width, int height, image::Fit object_fit = image::Fit::FIT_FILL, image::ResizeMethod method = image::ResizeMethod::NEAREST)" + }, + "affine": { + "type": "func", + "name": "affine", + "doc": { + "brief": "Affine transform image, will create a new transformed image object", + "param": { + "src_points": "three source points, [x1, y1, x2, y2, x3, y3]", + "dst_points": "three destination points, [x1, y1, x2, y2, x3, y3]", + "width": "new width, if value is -1, will use height to calculate aspect ratio", + "height": "new height, if value is -1, will use width to calculate aspect ratio", + "method": "resize method, by default is bilinear" + }, + "return": "new transformed image object", + "maixpy": "maix.image.Image.affine", + "py_doc": "Affine transform image, will create a new transformed image object\n\nArgs:\n - src_points: three source points, [x1, y1, x2, y2, x3, y3]\n - dst_points: three destination points, [x1, y1, x2, y2, x3, y3]\n - width: new width, if value is -1, will use height to calculate aspect ratio\n - height: new height, if value is -1, will use width to calculate aspect ratio\n - method: resize method, by default is bilinear\n\n\nReturns: new transformed image object\n" + }, + "args": [ + [ + "std::vector", + "src_points", + null + ], + [ + "std::vector", + "dst_points", + null + ], + [ + "int", + "width", + "-1" + ], + [ + "int", + "height", + "-1" + ], + [ + "image::ResizeMethod", + "method", + "image::ResizeMethod::BILINEAR" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *affine(std::vector src_points, std::vector dst_points, int width = -1, int height = -1, image::ResizeMethod method = image::ResizeMethod::BILINEAR)" + }, + "copy": { + "type": "func", + "name": "copy", + "doc": { + "brief": "Copy image, will create a new copied image object", + "return": "new copied image object", + "maixpy": "maix.image.Image.copy", + "py_doc": "Copy image, will create a new copied image object\n\nReturns: new copied image object\n" + }, + "args": [], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *copy()" + }, + "crop": { + "type": "func", + "name": "crop", + "doc": { + "brief": "Crop image, will create a new cropped image object", + "param": { + "x": "left top corner of crop rectangle point's coordinate x", + "y": "left top corner of crop rectangle point's coordinate y", + "w": "crop rectangle width", + "h": "crop rectangle height" + }, + "return": "new cropped image object", + "maixpy": "maix.image.Image.crop", + "py_doc": "Crop image, will create a new cropped image object\n\nArgs:\n - x: left top corner of crop rectangle point's coordinate x\n - y: left top corner of crop rectangle point's coordinate y\n - w: crop rectangle width\n - h: crop rectangle height\n\n\nReturns: new cropped image object\n" + }, + "args": [ + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "int", + "w", + null + ], + [ + "int", + "h", + null + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *crop(int x, int y, int w, int h)" + }, + "rotate": { + "type": "func", + "name": "rotate", + "doc": { + "brief": "Rotate image, will create a new rotated image object", + "param": { + "angle": "anti-clock wise rotate angle, if angle is 90 or 270, and width or height is -1, will swap width and height, or will throw exception", + "width": "new width, if value is -1, will use height to calculate aspect ratio", + "height": "new height, if value is -1, will use width to calculate aspect ratio", + "method": "resize method, by default is bilinear" + }, + "return": "new rotated image object", + "maixpy": "maix.image.Image.rotate", + "py_doc": "Rotate image, will create a new rotated image object\n\nArgs:\n - angle: anti-clock wise rotate angle, if angle is 90 or 270, and width or height is -1, will swap width and height, or will throw exception\n - width: new width, if value is -1, will use height to calculate aspect ratio\n - height: new height, if value is -1, will use width to calculate aspect ratio\n - method: resize method, by default is bilinear\n\n\nReturns: new rotated image object\n" + }, + "args": [ + [ + "float", + "angle", + null + ], + [ + "int", + "width", + "-1" + ], + [ + "int", + "height", + "-1" + ], + [ + "image::ResizeMethod", + "method", + "image::ResizeMethod::BILINEAR" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *rotate(float angle, int width = -1, int height = -1, image::ResizeMethod method = image::ResizeMethod::BILINEAR)" + }, + "mean_pool": { + "type": "func", + "name": "mean_pool", + "doc": { + "brief": "Finds the mean of x_div * y_div squares in the image and returns the modified image composed of the mean of each square.", + "param": { + "x_div": "The width of the squares.", + "y_div": "The height of the squares.", + "copy": "Select whether to return a new image or modify the original image. default is false.\nIf true, returns a new image composed of the mean of each square; If false, returns the modified image composed of the mean of each square." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.mean_pool", + "py_doc": "Finds the mean of x_div * y_div squares in the image and returns the modified image composed of the mean of each square.\n\nArgs:\n - x_div: The width of the squares.\n - y_div: The height of the squares.\n - copy: Select whether to return a new image or modify the original image. default is false.\nIf true, returns a new image composed of the mean of each square; If false, returns the modified image composed of the mean of each square.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "x_div", + null + ], + [ + "int", + "y_div", + null + ], + [ + "bool", + "copy", + "false" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *mean_pool(int x_div, int y_div, bool copy = false)" + }, + "midpoint_pool": { + "type": "func", + "name": "midpoint_pool", + "doc": { + "brief": "Finds the midpoint of x_div * y_div squares in the image and returns the modified image composed of the mean of each square.", + "param": { + "x_div": "The width of the squares.", + "y_div": "The height of the squares.", + "bias": "The bias of the midpoint. default is 0.5.\nmidpoint value is equal to (max * bias + min * (1 - bias))", + "copy": "Select whether to return a new image or modify the original image. default is false.\nIf true, returns a new image composed of the midpoint of each square; If false, returns the modified image composed of the midpoint of each square." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.midpoint_pool", + "py_doc": "Finds the midpoint of x_div * y_div squares in the image and returns the modified image composed of the mean of each square.\n\nArgs:\n - x_div: The width of the squares.\n - y_div: The height of the squares.\n - bias: The bias of the midpoint. default is 0.5.\nmidpoint value is equal to (max * bias + min * (1 - bias))\n - copy: Select whether to return a new image or modify the original image. default is false.\nIf true, returns a new image composed of the midpoint of each square; If false, returns the modified image composed of the midpoint of each square.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "x_div", + null + ], + [ + "int", + "y_div", + null + ], + [ + "double", + "bias", + "0.5" + ], + [ + "bool", + "copy", + "false" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *midpoint_pool(int x_div, int y_div, double bias = 0.5, bool copy = false)" + }, + "compress": { + "type": "func", + "name": "compress", + "doc": { + "brief": "JPEG compresses the image in place, the same as to_jpeg functioin, it's recommend to use to_jpeg instead.", + "param": { + "quality": "The quality of the compressed image. default is 95." + }, + "return": "Returns the compressed JPEG image", + "maixpy": "maix.image.Image.compress", + "py_doc": "JPEG compresses the image in place, the same as to_jpeg functioin, it's recommend to use to_jpeg instead.\n\nArgs:\n - quality: The quality of the compressed image. default is 95.\n\n\nReturns: Returns the compressed JPEG image\n" + }, + "args": [ + [ + "int", + "quality", + "95" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *compress(int quality = 95)" + }, + "clear": { + "type": "func", + "name": "clear", + "doc": { + "brief": "Sets all pixels in the image to zero", + "param": { + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.clear", + "py_doc": "Sets all pixels in the image to zero\n\nArgs:\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *clear(image::Image *mask = nullptr)" + }, + "mask_rectange": { + "type": "func", + "name": "mask_rectange", + "doc": { + "brief": "Zeros a rectangular part of the image. If no arguments are supplied this method zeros the center of the image.", + "param": { + "x": "The x coordinate of the top left corner of the rectangle.", + "y": "The y coordinate of the top left corner of the rectangle.", + "w": "The width of the rectangle.", + "h": "The height of the rectangle." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.mask_rectange", + "py_doc": "Zeros a rectangular part of the image. If no arguments are supplied this method zeros the center of the image.\n\nArgs:\n - x: The x coordinate of the top left corner of the rectangle.\n - y: The y coordinate of the top left corner of the rectangle.\n - w: The width of the rectangle.\n - h: The height of the rectangle.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "x", + "-1" + ], + [ + "int", + "y", + "-1" + ], + [ + "int", + "w", + "-1" + ], + [ + "int", + "h", + "-1" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *mask_rectange(int x = -1, int y = -1, int w = -1, int h = -1)" + }, + "mask_circle": { + "type": "func", + "name": "mask_circle", + "doc": { + "brief": "Zeros a circular part of the image. If no arguments are supplied this method zeros the center of the image.", + "param": { + "x": "The x coordinate of the center of the circle.", + "y": "The y coordinate of the center of the circle.", + "radius": "The radius of the circle." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.mask_circle", + "py_doc": "Zeros a circular part of the image. If no arguments are supplied this method zeros the center of the image.\n\nArgs:\n - x: The x coordinate of the center of the circle.\n - y: The y coordinate of the center of the circle.\n - radius: The radius of the circle.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "x", + "-1" + ], + [ + "int", + "y", + "-1" + ], + [ + "int", + "radius", + "-1" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *mask_circle(int x = -1, int y = -1, int radius = -1)" + }, + "mask_ellipse": { + "type": "func", + "name": "mask_ellipse", + "doc": { + "brief": "Zeros a ellipse part of the image. If no arguments are supplied this method zeros the center of the image.", + "param": { + "x": "The x coordinate of the center of the ellipse.", + "y": "The y coordinate of the center of the ellipse.", + "radius_x": "The radius of the ellipse in the x direction.", + "radius_y": "The radius of the ellipse in the y direction.", + "rotation_angle_in_degrees": "The rotation angle of the ellipse in degrees." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.mask_ellipse", + "py_doc": "Zeros a ellipse part of the image. If no arguments are supplied this method zeros the center of the image.\n\nArgs:\n - x: The x coordinate of the center of the ellipse.\n - y: The y coordinate of the center of the ellipse.\n - radius_x: The radius of the ellipse in the x direction.\n - radius_y: The radius of the ellipse in the y direction.\n - rotation_angle_in_degrees: The rotation angle of the ellipse in degrees.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "x", + "-1" + ], + [ + "int", + "y", + "-1" + ], + [ + "int", + "radius_x", + "-1" + ], + [ + "int", + "radius_y", + "-1" + ], + [ + "float", + "rotation_angle_in_degrees", + "0" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *mask_ellipse(int x = -1, int y = -1, int radius_x = -1, int radius_y = -1, float rotation_angle_in_degrees = 0)" + }, + "binary": { + "type": "func", + "name": "binary", + "doc": { + "brief": "Sets all pixels in the image to black or white depending on if the pixel is inside of a threshold in the threshold list thresholds or not.", + "param": { + "thresholds": "You can define multiple thresholds.\nFor GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.\nFor RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.\nWhere the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.", + "invert": "If true, the thresholds will be inverted before the operation. default is false.", + "zero": "If zero is true, the image will be set the pixels within the threshold to 0, other pixels remain unchanged. If zero is false, the image will be set to black or white. default is false.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.", + "to_bitmap": "If true, the image will be converted to a bitmap image before thresholding. default is false. TODO: support in the feature", + "copy": "Select whether to return a new image or modify the original image. default is false." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.binary", + "py_doc": "Sets all pixels in the image to black or white depending on if the pixel is inside of a threshold in the threshold list thresholds or not.\n\nArgs:\n - thresholds: You can define multiple thresholds.\nFor GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.\nFor RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.\nWhere the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.\n - invert: If true, the thresholds will be inverted before the operation. default is false.\n - zero: If zero is true, the image will be set the pixels within the threshold to 0, other pixels remain unchanged. If zero is false, the image will be set to black or white. default is false.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n - to_bitmap: If true, the image will be converted to a bitmap image before thresholding. default is false. TODO: support in the feature\n - copy: Select whether to return a new image or modify the original image. default is false.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "std::vector>", + "thresholds", + "std::vector>()" + ], + [ + "bool", + "invert", + "false" + ], + [ + "bool", + "zero", + "false" + ], + [ + "image::Image *", + "mask", + "nullptr" + ], + [ + "bool", + "to_bitmap", + "false" + ], + [ + "bool", + "copy", + "false" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *binary(std::vector> thresholds = std::vector>(), bool invert = false, bool zero = false, image::Image *mask = nullptr, bool to_bitmap = false, bool copy = false)" + }, + "invert": { + "type": "func", + "name": "invert", + "doc": { + "brief": "Inverts the image in place.", + "return": "Returns the image after the operation is completed", + "maixpy": "maix.image.Image.invert", + "py_doc": "Inverts the image in place.\n\nReturns: Returns the image after the operation is completed\n" + }, + "args": [], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *invert()" + }, + "b_and": { + "type": "func", + "name": "b_and", + "doc": { + "brief": "Performs a bitwise and operation between the image and the other image.", + "param": { + "other": "The other image should be an image and should be the same size as the image being operated on. TODO: support path?", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.b_and", + "py_doc": "Performs a bitwise and operation between the image and the other image.\n\nArgs:\n - other: The other image should be an image and should be the same size as the image being operated on. TODO: support path?\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "image::Image *", + "other", + null + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *b_and(image::Image *other, image::Image *mask = nullptr)" + }, + "b_nand": { + "type": "func", + "name": "b_nand", + "doc": { + "brief": "Performs a bitwise nand operation between the image and the other image.", + "param": { + "other": "The other image should be an image and should be the same size as the image being operated on. TODO: support path?", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.b_nand", + "py_doc": "Performs a bitwise nand operation between the image and the other image.\n\nArgs:\n - other: The other image should be an image and should be the same size as the image being operated on. TODO: support path?\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "image::Image *", + "other", + null + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *b_nand(image::Image *other, image::Image *mask = nullptr)" + }, + "b_or": { + "type": "func", + "name": "b_or", + "doc": { + "brief": "Performs a bitwise or operation between the image and the other image.", + "param": { + "other": "The other image should be an image and should be the same size as the image being operated on. TODO: support path?", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.b_or", + "py_doc": "Performs a bitwise or operation between the image and the other image.\n\nArgs:\n - other: The other image should be an image and should be the same size as the image being operated on. TODO: support path?\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "image::Image *", + "other", + null + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *b_or(image::Image *other, image::Image *mask = nullptr)" + }, + "b_nor": { + "type": "func", + "name": "b_nor", + "doc": { + "brief": "Performs a bitwise nor operation between the image and the other image.", + "param": { + "other": "The other image should be an image and should be the same size as the image being operated on. TODO: support path?", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.b_nor", + "py_doc": "Performs a bitwise nor operation between the image and the other image.\n\nArgs:\n - other: The other image should be an image and should be the same size as the image being operated on. TODO: support path?\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "image::Image *", + "other", + null + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *b_nor(image::Image *other, image::Image *mask = nullptr)" + }, + "b_xor": { + "type": "func", + "name": "b_xor", + "doc": { + "brief": "Performs a bitwise xor operation between the image and the other image.", + "param": { + "other": "The other image should be an image and should be the same size as the image being operated on. TODO: support path?", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.b_xor", + "py_doc": "Performs a bitwise xor operation between the image and the other image.\n\nArgs:\n - other: The other image should be an image and should be the same size as the image being operated on. TODO: support path?\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "image::Image *", + "other", + null + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *b_xor(image::Image *other, image::Image *mask = nullptr)" + }, + "b_xnor": { + "type": "func", + "name": "b_xnor", + "doc": { + "brief": "Performs a bitwise xnor operation between the image and the other image.", + "param": { + "other": "The other image should be an image and should be the same size as the image being operated on. TODO: support path?", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.b_xnor", + "py_doc": "Performs a bitwise xnor operation between the image and the other image.\n\nArgs:\n - other: The other image should be an image and should be the same size as the image being operated on. TODO: support path?\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "image::Image *", + "other", + null + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *b_xnor(image::Image *other, image::Image *mask = nullptr)" + }, + "awb": { + "type": "func", + "name": "awb", + "doc": { + "brief": "Performs an auto white balance operation on the image. TODO: support in the feature", + "param": { + "max": "if True uses the white-patch algorithm instead. default is false." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.awb", + "py_doc": "Performs an auto white balance operation on the image. TODO: support in the feature\n\nArgs:\n - max: if True uses the white-patch algorithm instead. default is false.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "bool", + "max", + "false" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *awb(bool max = false)" + }, + "ccm": { + "type": "func", + "name": "ccm", + "doc": { + "brief": "Multiples the passed (3x3) or (4x3) floating-point color-correction-matrix with the image.\\nnote: Grayscale format is not support.", + "param": { + "matrix": "The color correction matrix to use. 3x3 or 4x3 matrix.\nWeights may either be positive or negative, and the sum of each column in the 3x3 matrix should generally be 1.\nexample:\n{\n1, 0, 0,\n0, 1, 0,\n0, 0, 1,\n}\nWhere the last row of the 4x3 matrix is an offset per color channel. If you add an offset you may wish to make the\nweights sum to less than 1 to account for the offset.\nexample:\n{\n1, 0, 0,\n0, 1, 0,\n0, 0, 1,\n0, 0, 0,\n}" + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.ccm", + "py_doc": "Multiples the passed (3x3) or (4x3) floating-point color-correction-matrix with the image.\nnote: Grayscale format is not support.\n\nArgs:\n - matrix: The color correction matrix to use. 3x3 or 4x3 matrix.\nWeights may either be positive or negative, and the sum of each column in the 3x3 matrix should generally be 1.\nexample:\n{\n1, 0, 0,\n0, 1, 0,\n0, 0, 1,\n}\nWhere the last row of the 4x3 matrix is an offset per color channel. If you add an offset you may wish to make the\nweights sum to less than 1 to account for the offset.\nexample:\n{\n1, 0, 0,\n0, 1, 0,\n0, 0, 1,\n0, 0, 0,\n}\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "std::vector &", + "matrix", + null + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *ccm(std::vector &matrix)" + }, + "gamma": { + "type": "func", + "name": "gamma", + "doc": { + "brief": "Quickly changes the image gamma, contrast, and brightness. Create a array whose size is usually 255,\\nand use the parameters gamma, contrast, and brightness to calculate the value of the array, and then map the\\nimage pixel value through the value of the array.\\nThe calculation method for array is: array[array_idx] = (powf((array_idx / 255.0), (1 / gamma)) * contrast + brightness) * scale,\\n`powf` is a function used to calculate floating point power.\\n`array` is the array used for mapping.\\n`array_idx` is the index of the array, the maximum value is determined according to the image format, usually 255.\\n`scale` is a constant, the value is determined by the image format, usually 255.\\nMapping method:\\nAssume that a pixel value in the image is 128, then map the pixel value to the value of array[128]\\nUsers can adjust the value of the array through the gamma, contrast, and brightness parameters.", + "param": { + "gamma": "The contrast gamma greater than 1.0 makes the image darker in a non-linear manner while less than 1.0 makes the image brighter. default is 1.0.", + "contrast": "The contrast value greater than 1.0 makes the image brighter in a linear manner while less than 1.0 makes the image darker. default is 1.0.", + "brightness": "The brightness value greater than 0.0 makes the image brighter in a constant manner while less than 0.0 makes the image darker. default is 0.0." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.gamma", + "py_doc": "Quickly changes the image gamma, contrast, and brightness. Create a array whose size is usually 255,\nand use the parameters gamma, contrast, and brightness to calculate the value of the array, and then map the\nimage pixel value through the value of the array.\nThe calculation method for array is: array[array_idx] = (powf((array_idx / 255.0), (1 / gamma)) * contrast + brightness) * scale,\n`powf` is a function used to calculate floating point power.\n`array` is the array used for mapping.\n`array_idx` is the index of the array, the maximum value is determined according to the image format, usually 255.\n`scale` is a constant, the value is determined by the image format, usually 255.\nMapping method:\nAssume that a pixel value in the image is 128, then map the pixel value to the value of array[128]\nUsers can adjust the value of the array through the gamma, contrast, and brightness parameters.\n\nArgs:\n - gamma: The contrast gamma greater than 1.0 makes the image darker in a non-linear manner while less than 1.0 makes the image brighter. default is 1.0.\n - contrast: The contrast value greater than 1.0 makes the image brighter in a linear manner while less than 1.0 makes the image darker. default is 1.0.\n - brightness: The brightness value greater than 0.0 makes the image brighter in a constant manner while less than 0.0 makes the image darker. default is 0.0.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "double", + "gamma", + "1.0" + ], + [ + "double", + "contrast", + "1.0" + ], + [ + "double", + "brightness", + "0.0" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *gamma(double gamma = 1.0, double contrast = 1.0, double brightness = 0.0)" + }, + "gamma_corr": { + "type": "func", + "name": "gamma_corr", + "doc": { + "brief": "Alias for Image.gamma.", + "param": { + "gamma": "The contrast gamma greater than 1.0 makes the image darker in a non-linear manner while less than 1.0 makes the image brighter. default is 1.0.", + "contrast": "The contrast value greater than 1.0 makes the image brighter in a linear manner while less than 1.0 makes the image darker. default is 1.0.", + "brightness": "The brightness value greater than 0.0 makes the image brighter in a constant manner while less than 0.0 makes the image darker. default is 0.0." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.gamma_corr", + "py_doc": "Alias for Image.gamma.\n\nArgs:\n - gamma: The contrast gamma greater than 1.0 makes the image darker in a non-linear manner while less than 1.0 makes the image brighter. default is 1.0.\n - contrast: The contrast value greater than 1.0 makes the image brighter in a linear manner while less than 1.0 makes the image darker. default is 1.0.\n - brightness: The brightness value greater than 0.0 makes the image brighter in a constant manner while less than 0.0 makes the image darker. default is 0.0.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "double", + "gamma", + null + ], + [ + "double", + "contrast", + "1.0" + ], + [ + "double", + "brightness", + "0.0" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *gamma_corr(double gamma, double contrast = 1.0, double brightness = 0.0)" + }, + "negate": { + "type": "func", + "name": "negate", + "doc": { + "brief": "Flips (numerically inverts) all pixels values in an image", + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.negate", + "py_doc": "Flips (numerically inverts) all pixels values in an image\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *negate()" + }, + "replace": { + "type": "func", + "name": "replace", + "doc": { + "brief": "Replaces all pixels in the image with the corresponding pixels in the other image.", + "param": { + "other": "The other image should be an image and should be the same size as the image being operated on.", + "hmirror": "If true, the image will be horizontally mirrored before the operation. default is false.", + "vflip": "If true, the image will be vertically flipped before the operation. default is false.", + "transpose": "If true, the image can be used to rotate 90 degrees or 270 degrees.\nhmirror = false, vflip = false, transpose = false, the image will not be rotated.\nhmirror = false, vflip = true, transpose = true, the image will be rotated 90 degrees.\nhmirror = true, vflip = true, transpose = false, the image will be rotated 180 degrees.\nhmirror = true, vflip = false, transpose = true, the image will be rotated 270 degrees.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.replace", + "py_doc": "Replaces all pixels in the image with the corresponding pixels in the other image.\n\nArgs:\n - other: The other image should be an image and should be the same size as the image being operated on.\n - hmirror: If true, the image will be horizontally mirrored before the operation. default is false.\n - vflip: If true, the image will be vertically flipped before the operation. default is false.\n - transpose: If true, the image can be used to rotate 90 degrees or 270 degrees.\nhmirror = false, vflip = false, transpose = false, the image will not be rotated.\nhmirror = false, vflip = true, transpose = true, the image will be rotated 90 degrees.\nhmirror = true, vflip = true, transpose = false, the image will be rotated 180 degrees.\nhmirror = true, vflip = false, transpose = true, the image will be rotated 270 degrees.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "image::Image *", + "other", + "nullptr" + ], + [ + "bool", + "hmirror", + "false" + ], + [ + "bool", + "vflip", + "false" + ], + [ + "bool", + "transpose", + "false" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *replace(image::Image *other = nullptr, bool hmirror = false, bool vflip = false, bool transpose = false, image::Image *mask = nullptr)" + }, + "set": { + "type": "func", + "name": "set", + "doc": { + "brief": "Alias for Image::replace.", + "param": { + "other": "The other image should be an image and should be the same size as the image being operated on.", + "hmirror": "If true, the image will be horizontally mirrored before the operation. default is false.", + "vflip": "If true, the image will be vertically flipped before the operation. default is false.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.set", + "py_doc": "Alias for Image::replace.\n\nArgs:\n - other: The other image should be an image and should be the same size as the image being operated on.\n - hmirror: If true, the image will be horizontally mirrored before the operation. default is false.\n - vflip: If true, the image will be vertically flipped before the operation. default is false.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "image::Image *", + "other", + null + ], + [ + "bool", + "hmirror", + "false" + ], + [ + "bool", + "vflip", + "false" + ], + [ + "bool", + "transpose", + "false" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *set(image::Image *other, bool hmirror = false, bool vflip = false, bool transpose = false, image::Image *mask = nullptr)" + }, + "add": { + "type": "func", + "name": "add", + "doc": { + "brief": "Adds the other image to the image.", + "param": { + "other": "The other image should be an image and should be the same size as the image being operated on. TODO: support path?", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.add", + "py_doc": "Adds the other image to the image.\n\nArgs:\n - other: The other image should be an image and should be the same size as the image being operated on. TODO: support path?\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "image::Image *", + "other", + null + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *add(image::Image *other, image::Image *mask = nullptr)" + }, + "sub": { + "type": "func", + "name": "sub", + "doc": { + "brief": "Subtracts the other image from the image.", + "param": { + "other": "The other image should be an image and should be the same size as the image being operated on. TODO: support path?", + "reverse": "If true, the image will be reversed before the operation. default is false.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.sub", + "py_doc": "Subtracts the other image from the image.\n\nArgs:\n - other: The other image should be an image and should be the same size as the image being operated on. TODO: support path?\n - reverse: If true, the image will be reversed before the operation. default is false.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "image::Image *", + "other", + null + ], + [ + "bool", + "reverse", + "false" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *sub(image::Image *other, bool reverse = false, image::Image *mask = nullptr)" + }, + "mul": { + "type": "func", + "name": "mul", + "doc": { + "brief": "Multiplies the image by the other image.\\nNote: This method is meant for image blending and cannot multiply the pixels in the image by a scalar like 2.", + "param": { + "other": "The other image should be an image and should be the same size as the image being operated on. TODO: support path?", + "invert": "If true, the image will be change the multiplication operation from a*b to 1/((1/a)*(1/b)).\nIn particular, this lightens the image instead of darkening it (e.g. multiply versus burn operations). default is false.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.mul", + "py_doc": "Multiplies the image by the other image.\nNote: This method is meant for image blending and cannot multiply the pixels in the image by a scalar like 2.\n\nArgs:\n - other: The other image should be an image and should be the same size as the image being operated on. TODO: support path?\n - invert: If true, the image will be change the multiplication operation from a*b to 1/((1/a)*(1/b)).\nIn particular, this lightens the image instead of darkening it (e.g. multiply versus burn operations). default is false.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "image::Image *", + "other", + null + ], + [ + "bool", + "invert", + "false" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *mul(image::Image *other, bool invert = false, image::Image *mask = nullptr)" + }, + "div": { + "type": "func", + "name": "div", + "doc": { + "brief": "Divides the image by the other image.\\nThis method is meant for image blending and cannot divide the pixels in the image by a scalar like 2.", + "param": { + "other": "The other image should be an image and should be the same size as the image being operated on. TODO: support path?", + "invert": "If true, the image will be change the division direction from a/b to b/a. default is false.", + "mod": "If true, the image will be change the division operation to the modulus operation. default is false.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.div", + "py_doc": "Divides the image by the other image.\nThis method is meant for image blending and cannot divide the pixels in the image by a scalar like 2.\n\nArgs:\n - other: The other image should be an image and should be the same size as the image being operated on. TODO: support path?\n - invert: If true, the image will be change the division direction from a/b to b/a. default is false.\n - mod: If true, the image will be change the division operation to the modulus operation. default is false.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "image::Image *", + "other", + null + ], + [ + "bool", + "invert", + "false" + ], + [ + "bool", + "mod", + "false" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *div(image::Image *other, bool invert = false, bool mod = false, image::Image *mask = nullptr)" + }, + "min": { + "type": "func", + "name": "min", + "doc": { + "brief": "Caculate the minimum of each pixel in the image and the other image.", + "param": { + "other": "The other image should be an image and should be the same size as the image being operated on.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.min", + "py_doc": "Caculate the minimum of each pixel in the image and the other image.\n\nArgs:\n - other: The other image should be an image and should be the same size as the image being operated on.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "image::Image *", + "other", + null + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *min(image::Image *other, image::Image *mask = nullptr)" + }, + "max": { + "type": "func", + "name": "max", + "doc": { + "brief": "Caculate the maximum of each pixel in the image and the other image.", + "param": { + "other": "The other image should be an image and should be the same size as the image being operated on.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.max", + "py_doc": "Caculate the maximum of each pixel in the image and the other image.\n\nArgs:\n - other: The other image should be an image and should be the same size as the image being operated on.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "image::Image *", + "other", + null + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *max(image::Image *other, image::Image *mask = nullptr)" + }, + "difference": { + "type": "func", + "name": "difference", + "doc": { + "brief": "Caculate the absolute value of the difference between each pixel in the image and the other image.", + "param": { + "other": "The other image should be an image and should be the same size as the image being operated on.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.difference", + "py_doc": "Caculate the absolute value of the difference between each pixel in the image and the other image.\n\nArgs:\n - other: The other image should be an image and should be the same size as the image being operated on.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "image::Image *", + "other", + null + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *difference(image::Image *other, image::Image *mask = nullptr)" + }, + "blend": { + "type": "func", + "name": "blend", + "doc": { + "brief": "Blends the image with the other image.\\nres = alpha * this_img / 256 + (256 - alpha) * other_img / 256", + "param": { + "other": "The other image should be an image and should be the same size as the image being operated on.", + "alpha": "The alpha value of the blend, the value range is [0, 256],default is 128.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.blend", + "py_doc": "Blends the image with the other image.\nres = alpha * this_img / 256 + (256 - alpha) * other_img / 256\n\nArgs:\n - other: The other image should be an image and should be the same size as the image being operated on.\n - alpha: The alpha value of the blend, the value range is [0, 256],default is 128.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "image::Image *", + "other", + null + ], + [ + "int", + "alpha", + "128" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *blend(image::Image *other, int alpha = 128, image::Image *mask = nullptr)" + }, + "histeq": { + "type": "func", + "name": "histeq", + "doc": { + "brief": "Runs the histogram equalization algorithm on the image.", + "param": { + "adaptive": "If true, an adaptive histogram equalization method will be run on the image instead which as generally better results than non-adaptive histogram qualization but a longer run time. default is false.", + "clip_limit": "Provides a way to limit the contrast of the adaptive histogram qualization. Use a small value for this, like 10, to produce good histogram equalized contrast limited images. default is -1.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.histeq", + "py_doc": "Runs the histogram equalization algorithm on the image.\n\nArgs:\n - adaptive: If true, an adaptive histogram equalization method will be run on the image instead which as generally better results than non-adaptive histogram qualization but a longer run time. default is false.\n - clip_limit: Provides a way to limit the contrast of the adaptive histogram qualization. Use a small value for this, like 10, to produce good histogram equalized contrast limited images. default is -1.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "bool", + "adaptive", + "false" + ], + [ + "int", + "clip_limit", + "-1" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *histeq(bool adaptive = false, int clip_limit = -1, image::Image *mask = nullptr)" + }, + "mean": { + "type": "func", + "name": "mean", + "doc": { + "brief": "Standard mean blurring filter using a box filter.\\nThe parameters offset and invert are valid when threshold is True.", + "param": { + "size": "Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).", + "threshold": "If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel\u2019s brightness in relation to the brightness of the kernel of pixels around them.\ndefault is false.", + "offset": "The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.", + "invert": "If true, the image will be inverted before the operation. default is false.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.mean", + "py_doc": "Standard mean blurring filter using a box filter.\nThe parameters offset and invert are valid when threshold is True.\n\nArgs:\n - size: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).\n - threshold: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel\u2019s brightness in relation to the brightness of the kernel of pixels around them.\ndefault is false.\n - offset: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.\n - invert: If true, the image will be inverted before the operation. default is false.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "size", + null + ], + [ + "bool", + "threshold", + "false" + ], + [ + "int", + "offset", + "0" + ], + [ + "bool", + "invert", + "false" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *mean(int size, bool threshold = false, int offset = 0, bool invert = false, image::Image *mask = nullptr)" + }, + "median": { + "type": "func", + "name": "median", + "doc": { + "brief": "Runs the median filter on the image. The median filter is the best filter for smoothing surfaces while preserving edges but it is very slow.", + "param": { + "size": "Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).", + "percentile": "This parameter controls the percentile of the value used in the kernel. You can set this to 0 for a min filter, 0.25 for a lower quartile filter, 0.75 for an upper quartile filter, and 1.0 for a max filter. default is 0.5.", + "threshold": "If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel\u2019s brightness in relation to the brightness of the kernel of pixels around them.\ndefault is false.", + "offset": "The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.", + "invert": "If true, the image will be inverted before the operation. default is false.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.median", + "py_doc": "Runs the median filter on the image. The median filter is the best filter for smoothing surfaces while preserving edges but it is very slow.\n\nArgs:\n - size: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).\n - percentile: This parameter controls the percentile of the value used in the kernel. You can set this to 0 for a min filter, 0.25 for a lower quartile filter, 0.75 for an upper quartile filter, and 1.0 for a max filter. default is 0.5.\n - threshold: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel\u2019s brightness in relation to the brightness of the kernel of pixels around them.\ndefault is false.\n - offset: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.\n - invert: If true, the image will be inverted before the operation. default is false.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "size", + null + ], + [ + "double", + "percentile", + "0.5" + ], + [ + "bool", + "threshold", + "false" + ], + [ + "int", + "offset", + "0" + ], + [ + "bool", + "invert", + "false" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *median(int size, double percentile = 0.5, bool threshold = false, int offset = 0, bool invert = false, image::Image *mask = nullptr)" + }, + "mode": { + "type": "func", + "name": "mode", + "doc": { + "brief": "Runs the mode filter on the image by replacing each pixel with the mode of their neighbors.", + "param": { + "size": "Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).", + "threshold": "If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel\u2019s brightness in relation to the brightness of the kernel of pixels around them.\ndefault is false.", + "offset": "The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.", + "invert": "If true, the image will be inverted before the operation. default is false.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.mode", + "py_doc": "Runs the mode filter on the image by replacing each pixel with the mode of their neighbors.\n\nArgs:\n - size: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).\n - threshold: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel\u2019s brightness in relation to the brightness of the kernel of pixels around them.\ndefault is false.\n - offset: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.\n - invert: If true, the image will be inverted before the operation. default is false.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "size", + null + ], + [ + "bool", + "threshold", + "false" + ], + [ + "int", + "offset", + "0" + ], + [ + "bool", + "invert", + "false" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *mode(int size, bool threshold = false, int offset = 0, bool invert = false, image::Image *mask = nullptr)" + }, + "midpoint": { + "type": "func", + "name": "midpoint", + "doc": { + "brief": "Runs the midpoint filter on the image.This filter finds the midpoint (max * bias + min * (1 - bias)) of each pixel neighborhood in the image.", + "param": { + "size": "Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).", + "bias": "The bias of the midpoint. default is 0.5.", + "threshold": "If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel\u2019s brightness in relation to the brightness of the kernel of pixels around them.\ndefault is false.", + "offset": "The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.", + "invert": "If true, the image will be inverted before the operation. default is false.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.midpoint", + "py_doc": "Runs the midpoint filter on the image.This filter finds the midpoint (max * bias + min * (1 - bias)) of each pixel neighborhood in the image.\n\nArgs:\n - size: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).\n - bias: The bias of the midpoint. default is 0.5.\n - threshold: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel\u2019s brightness in relation to the brightness of the kernel of pixels around them.\ndefault is false.\n - offset: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.\n - invert: If true, the image will be inverted before the operation. default is false.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "size", + null + ], + [ + "double", + "bias", + "0.5" + ], + [ + "bool", + "threshold", + "false" + ], + [ + "int", + "offset", + "0" + ], + [ + "bool", + "invert", + "false" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *midpoint(int size, double bias = 0.5, bool threshold = false, int offset = 0, bool invert = false, image::Image *mask = nullptr)" + }, + "morph": { + "type": "func", + "name": "morph", + "doc": { + "brief": "Convolves the image by a filter kernel. This allows you to do general purpose convolutions on an image.", + "param": { + "size": "Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).", + "kernel": "The kernel used for convolution. The kernel should be a list of lists of numbers. The kernel should be the same size as the actual kernel size.", + "mul": "This parameter is used to multiply the convolved pixel results. default is auto.", + "add": "This parameter is the value to be added to each convolution pixel result. default is 0.0.", + "threshold": "If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel\u2019s brightness in relation to the brightness of the kernel of pixels around them.\ndefault is false.", + "offset": "The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.", + "invert": "If true, the image will be inverted before the operation. default is false.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.morph", + "py_doc": "Convolves the image by a filter kernel. This allows you to do general purpose convolutions on an image.\n\nArgs:\n - size: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).\n - kernel: The kernel used for convolution. The kernel should be a list of lists of numbers. The kernel should be the same size as the actual kernel size.\n - mul: This parameter is used to multiply the convolved pixel results. default is auto.\n - add: This parameter is the value to be added to each convolution pixel result. default is 0.0.\n - threshold: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel\u2019s brightness in relation to the brightness of the kernel of pixels around them.\ndefault is false.\n - offset: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.\n - invert: If true, the image will be inverted before the operation. default is false.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "size", + null + ], + [ + "std::vector", + "kernel", + null + ], + [ + "float", + "mul", + "-1" + ], + [ + "float", + "add", + "0.0" + ], + [ + "bool", + "threshold", + "false" + ], + [ + "int", + "offset", + "0" + ], + [ + "bool", + "invert", + "false" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *morph(int size, std::vector kernel, float mul = -1, float add = 0.0, bool threshold = false, int offset = 0, bool invert = false, image::Image *mask = nullptr)" + }, + "gaussian": { + "type": "func", + "name": "gaussian", + "doc": { + "brief": "Convolves the image by a smoothing guassian kernel.", + "param": { + "size": "Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).", + "unsharp": "If true, this method will perform an unsharp mask operation instead of gaussian filtering operation, this improves the clarity of image edges. default is false.", + "mul": "This parameter is used to multiply the convolved pixel results. default is auto.", + "add": "This parameter is the value to be added to each convolution pixel result. default is 0.0.", + "threshold": "If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel\u2019s brightness in relation to the brightness of the kernel of pixels around them.\ndefault is false.", + "offset": "The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.", + "invert": "If true, the image will be inverted before the operation. default is false.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.gaussian", + "py_doc": "Convolves the image by a smoothing guassian kernel.\n\nArgs:\n - size: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).\n - unsharp: If true, this method will perform an unsharp mask operation instead of gaussian filtering operation, this improves the clarity of image edges. default is false.\n - mul: This parameter is used to multiply the convolved pixel results. default is auto.\n - add: This parameter is the value to be added to each convolution pixel result. default is 0.0.\n - threshold: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel\u2019s brightness in relation to the brightness of the kernel of pixels around them.\ndefault is false.\n - offset: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.\n - invert: If true, the image will be inverted before the operation. default is false.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "size", + null + ], + [ + "bool", + "unsharp", + "false" + ], + [ + "float", + "mul", + "-1" + ], + [ + "float", + "add", + "0.0" + ], + [ + "bool", + "threshold", + "false" + ], + [ + "int", + "offset", + "0" + ], + [ + "bool", + "invert", + "false" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *gaussian(int size, bool unsharp = false, float mul = -1, float add = 0.0, bool threshold = false, int offset = 0, bool invert = false, image::Image *mask = nullptr)" + }, + "laplacian": { + "type": "func", + "name": "laplacian", + "doc": { + "brief": "Convolves the image by a edge detecting laplacian kernel.", + "param": { + "size": "Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).", + "sharpen": "If True, this method will sharpen the image instead of an unthresholded edge detection image. Then increase the kernel size to improve image clarity. default is false.", + "mul": "This parameter is used to multiply the convolved pixel results. default is auto.", + "add": "This parameter is the value to be added to each convolution pixel result. default is 0.0.", + "threshold": "If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel\u2019s brightness in relation to the brightness of the kernel of pixels around them.\ndefault is false.", + "offset": "The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.", + "invert": "If true, the image will be inverted before the operation. default is false.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.laplacian", + "py_doc": "Convolves the image by a edge detecting laplacian kernel.\n\nArgs:\n - size: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).\n - sharpen: If True, this method will sharpen the image instead of an unthresholded edge detection image. Then increase the kernel size to improve image clarity. default is false.\n - mul: This parameter is used to multiply the convolved pixel results. default is auto.\n - add: This parameter is the value to be added to each convolution pixel result. default is 0.0.\n - threshold: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel\u2019s brightness in relation to the brightness of the kernel of pixels around them.\ndefault is false.\n - offset: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.\n - invert: If true, the image will be inverted before the operation. default is false.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "size", + null + ], + [ + "bool", + "sharpen", + "false" + ], + [ + "float", + "mul", + "-1" + ], + [ + "float", + "add", + "0.0" + ], + [ + "bool", + "threshold", + "false" + ], + [ + "int", + "offset", + "0" + ], + [ + "bool", + "invert", + "false" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *laplacian(int size, bool sharpen = false, float mul = -1, float add = 0.0, bool threshold = false, int offset = 0, bool invert = false, image::Image *mask = nullptr)" + }, + "bilateral": { + "type": "func", + "name": "bilateral", + "doc": { + "brief": "Convolves the image by a bilateral filter.", + "param": { + "size": "Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).", + "color_sigma": "Controls how closely colors are matched using the bilateral filter. default is 0.1.", + "space_sigma": "Controls how closely pixels space-wise are blurred with each other. default is 1.", + "threshold": "If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel\u2019s brightness in relation to the brightness of the kernel of pixels around them.\ndefault is false.", + "offset": "The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.", + "invert": "If true, the image will be inverted before the operation. default is false.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.bilateral", + "py_doc": "Convolves the image by a bilateral filter.\n\nArgs:\n - size: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).\n - color_sigma: Controls how closely colors are matched using the bilateral filter. default is 0.1.\n - space_sigma: Controls how closely pixels space-wise are blurred with each other. default is 1.\n - threshold: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel\u2019s brightness in relation to the brightness of the kernel of pixels around them.\ndefault is false.\n - offset: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.\n - invert: If true, the image will be inverted before the operation. default is false.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "size", + null + ], + [ + "double", + "color_sigma", + "0.1" + ], + [ + "double", + "space_sigma", + "1" + ], + [ + "bool", + "threshold", + "false" + ], + [ + "int", + "offset", + "0" + ], + [ + "bool", + "invert", + "false" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *bilateral(int size, double color_sigma = 0.1, double space_sigma = 1, bool threshold = false, int offset = 0, bool invert = false, image::Image *mask = nullptr)" + }, + "linpolar": { + "type": "func", + "name": "linpolar", + "doc": { + "brief": "Re-project\u2019s and image from cartessian coordinates to linear polar coordinates.", + "param": { + "reverse": "If true, the image will be reverse polar transformed. default is false." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.linpolar", + "py_doc": "Re-project\u2019s and image from cartessian coordinates to linear polar coordinates.\n\nArgs:\n - reverse: If true, the image will be reverse polar transformed. default is false.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "bool", + "reverse", + "false" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *linpolar(bool reverse = false)" + }, + "logpolar": { + "type": "func", + "name": "logpolar", + "doc": { + "brief": "Re-project\u2019s and image from cartessian coordinates to log polar coordinates.", + "param": { + "reverse": "If true, the image will be reverse polar transformed. default is false." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.logpolar", + "py_doc": "Re-project\u2019s and image from cartessian coordinates to log polar coordinates.\n\nArgs:\n - reverse: If true, the image will be reverse polar transformed. default is false.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "bool", + "reverse", + "false" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *logpolar(bool reverse = false)" + }, + "lens_corr": { + "type": "func", + "name": "lens_corr", + "doc": { + "brief": "Performs a lens correction operation on the image. TODO: support in the feature", + "param": { + "strength": "The strength of the lens correction. default is 1.8.", + "zoom": "The zoom of the lens correction. default is 1.0.", + "x_corr": "The x correction of the lens correction. default is 0.5.", + "y_corr": "The y correction of the lens correction. default is 0.5." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.lens_corr", + "py_doc": "Performs a lens correction operation on the image. TODO: support in the feature\n\nArgs:\n - strength: The strength of the lens correction. default is 1.8.\n - zoom: The zoom of the lens correction. default is 1.0.\n - x_corr: The x correction of the lens correction. default is 0.5.\n - y_corr: The y correction of the lens correction. default is 0.5.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "double", + "strength", + "1.8" + ], + [ + "double", + "zoom", + "1.0" + ], + [ + "double", + "x_corr", + "0.5" + ], + [ + "double", + "y_corr", + "0.5" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *lens_corr(double strength = 1.8, double zoom = 1.0, double x_corr = 0.5, double y_corr = 0.5)" + }, + "rotation_corr": { + "type": "func", + "name": "rotation_corr", + "doc": { + "brief": "Performs a rotation correction operation on the image. TODO: support in the feature", + "param": { + "x_rotation": "The x rotation of the rotation correction. default is 0.0.", + "y_rotation": "The y rotation of the rotation correction. default is 0.0.", + "z_rotation": "The z rotation of the rotation correction. default is 0.0.", + "x_translation": "The x translation of the rotation correction. default is 0.0.", + "y_translation": "The y translation of the rotation correction. default is 0.0.", + "zoom": "The zoom of the rotation correction. default is 1.0.", + "fov": "The fov of the rotation correction. default is 60.0.", + "corners": "The corners of the rotation correction. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.rotation_corr", + "py_doc": "Performs a rotation correction operation on the image. TODO: support in the feature\n\nArgs:\n - x_rotation: The x rotation of the rotation correction. default is 0.0.\n - y_rotation: The y rotation of the rotation correction. default is 0.0.\n - z_rotation: The z rotation of the rotation correction. default is 0.0.\n - x_translation: The x translation of the rotation correction. default is 0.0.\n - y_translation: The y translation of the rotation correction. default is 0.0.\n - zoom: The zoom of the rotation correction. default is 1.0.\n - fov: The fov of the rotation correction. default is 60.0.\n - corners: The corners of the rotation correction. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "double", + "x_rotation", + "0.0" + ], + [ + "double", + "y_rotation", + "0.0" + ], + [ + "double", + "z_rotation", + "0.0" + ], + [ + "double", + "x_translation", + "0.0" + ], + [ + "double", + "y_translation", + "0.0" + ], + [ + "double", + "zoom", + "1.0" + ], + [ + "double", + "fov", + "60.0" + ], + [ + "std::vector", + "corners", + "std::vector()" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *rotation_corr(double x_rotation = 0.0, double y_rotation = 0.0, double z_rotation = 0.0, double x_translation = 0.0, double y_translation = 0.0, double zoom = 1.0, double fov = 60.0, std::vector corners = std::vector())" + }, + "get_histogram": { + "type": "func", + "name": "get_histogram", + "doc": { + "brief": "Gets the histogram of the image.", + "param": { + "thresholds": "You can define multiple thresholds.\nFor GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.\nFor RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.\nWhere the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.", + "invert": "If true, the thresholds will be inverted before the operation. default is false.", + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.", + "bins": "The number of bins to use for the histogram.\nIn GRAYSCALE format, setting range is [2, 256], default is 100.\nIn rgb888 format, setting range is [2, 100], default is 100.", + "l_bins": "The number of bins to use for the l channel of the histogram. Only valid in RGB888 format.\nIf an invalid value is set, bins will be used instead. The setting range is [2, 100], default is 100.", + "a_bins": "The number of bins to use for the a channel of the histogram.\nOnly valid in RGB888 format.The setting range is [2, 256], default is 256.", + "b_bins": "The number of bins to use for the b channel of the histogram.\nOnly valid in RGB888 format. The setting range is [2, 256], default is 256.", + "difference": "difference may be set to an image object to cause this method to operate on the difference image between the current image and the difference image object.\ndefault is None." + }, + "return": "Returns the histogram of the image", + "maixpy": "maix.image.Image.get_histogram", + "py_doc": "Gets the histogram of the image.\n\nArgs:\n - thresholds: You can define multiple thresholds.\nFor GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.\nFor RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.\nWhere the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.\n - invert: If true, the thresholds will be inverted before the operation. default is false.\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n - bins: The number of bins to use for the histogram.\nIn GRAYSCALE format, setting range is [2, 256], default is 100.\nIn rgb888 format, setting range is [2, 100], default is 100.\n - l_bins: The number of bins to use for the l channel of the histogram. Only valid in RGB888 format.\nIf an invalid value is set, bins will be used instead. The setting range is [2, 100], default is 100.\n - a_bins: The number of bins to use for the a channel of the histogram.\nOnly valid in RGB888 format.The setting range is [2, 256], default is 256.\n - b_bins: The number of bins to use for the b channel of the histogram.\nOnly valid in RGB888 format. The setting range is [2, 256], default is 256.\n - difference: difference may be set to an image object to cause this method to operate on the difference image between the current image and the difference image object.\ndefault is None.\n\n\nReturns: Returns the histogram of the image\n" + }, + "args": [ + [ + "std::vector>", + "thresholds", + "std::vector>()" + ], + [ + "bool", + "invert", + "false" + ], + [ + "std::vector", + "roi", + "std::vector()" + ], + [ + "int", + "bins", + "-1" + ], + [ + "int", + "l_bins", + "100" + ], + [ + "int", + "a_bins", + "256" + ], + [ + "int", + "b_bins", + "256" + ], + [ + "image::Image *", + "difference", + "nullptr" + ] + ], + "ret_type": "std::map>", + "static": false, + "def": "std::map> get_histogram(std::vector> thresholds = std::vector>(), bool invert = false, std::vector roi = std::vector(), int bins = -1, int l_bins = 100, int a_bins = 256, int b_bins = 256, image::Image *difference = nullptr)" + }, + "get_statistics": { + "type": "func", + "name": "get_statistics", + "doc": { + "brief": "Gets the statistics of the image. TODO: support in the feature", + "param": { + "thresholds": "You can define multiple thresholds.\nFor GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.\nFor RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.\nWhere the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.", + "invert": "If true, the image will be inverted before the operation. default is false.", + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.", + "bins": "The number of bins to use for the statistics. default is -1.", + "l_bins": "The number of bins to use for the l channel of the statistics. default is -1.", + "a_bins": "The number of bins to use for the a channel of the statistics. default is -1.", + "b_bins": "The number of bins to use for the b channel of the statistics. default is -1.", + "difference": "The difference image to use for the statistics. default is None." + }, + "return": "Returns the statistics of the image", + "maixpy": "maix.image.Image.get_statistics", + "py_doc": "Gets the statistics of the image. TODO: support in the feature\n\nArgs:\n - thresholds: You can define multiple thresholds.\nFor GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.\nFor RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.\nWhere the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.\n - invert: If true, the image will be inverted before the operation. default is false.\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n - bins: The number of bins to use for the statistics. default is -1.\n - l_bins: The number of bins to use for the l channel of the statistics. default is -1.\n - a_bins: The number of bins to use for the a channel of the statistics. default is -1.\n - b_bins: The number of bins to use for the b channel of the statistics. default is -1.\n - difference: The difference image to use for the statistics. default is None.\n\n\nReturns: Returns the statistics of the image\n" + }, + "args": [ + [ + "std::vector>", + "thresholds", + "std::vector>()" + ], + [ + "bool", + "invert", + "false" + ], + [ + "std::vector", + "roi", + "std::vector()" + ], + [ + "int", + "bins", + "-1" + ], + [ + "int", + "l_bins", + "-1" + ], + [ + "int", + "a_bins", + "-1" + ], + [ + "int", + "b_bins", + "-1" + ], + [ + "image::Image *", + "difference", + "nullptr" + ] + ], + "ret_type": "image::Statistics", + "static": false, + "def": "image::Statistics get_statistics(std::vector> thresholds = std::vector>(), bool invert = false, std::vector roi = std::vector(), int bins = -1, int l_bins = -1, int a_bins = -1, int b_bins = -1, image::Image *difference = nullptr)" + }, + "get_regression": { + "type": "func", + "name": "get_regression", + "doc": { + "brief": "Gets the regression of the image.", + "param": { + "thresholds": "You can define multiple thresholds.\nFor GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.\nFor RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.\nWhere the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.", + "invert": "If true, the image will be inverted before the operation. default is false.", + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.", + "x_stride": "The x stride to use for the regression. default is 2.", + "y_stride": "The y stride to use for the regression. default is 1.", + "area_threshold": "The area threshold to use for the regression. default is 10.", + "pixels_threshold": "The pixels threshold to use for the regression. default is 10.", + "robust": "If true, the regression will be robust. default is false." + }, + "return": "Returns the regression of the image", + "maixpy": "maix.image.Image.get_regression", + "py_doc": "Gets the regression of the image.\n\nArgs:\n - thresholds: You can define multiple thresholds.\nFor GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.\nFor RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.\nWhere the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.\n - invert: If true, the image will be inverted before the operation. default is false.\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n - x_stride: The x stride to use for the regression. default is 2.\n - y_stride: The y stride to use for the regression. default is 1.\n - area_threshold: The area threshold to use for the regression. default is 10.\n - pixels_threshold: The pixels threshold to use for the regression. default is 10.\n - robust: If true, the regression will be robust. default is false.\n\n\nReturns: Returns the regression of the image\n" + }, + "args": [ + [ + "std::vector>", + "thresholds", + "std::vector>()" + ], + [ + "bool", + "invert", + "false" + ], + [ + "std::vector", + "roi", + "std::vector()" + ], + [ + "int", + "x_stride", + "2" + ], + [ + "int", + "y_stride", + "1" + ], + [ + "int", + "area_threshold", + "10" + ], + [ + "int", + "pixels_threshold", + "10" + ], + [ + "bool", + "robust", + "false" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector get_regression(std::vector> thresholds = std::vector>(), bool invert = false, std::vector roi = std::vector(), int x_stride = 2, int y_stride = 1, int area_threshold = 10, int pixels_threshold = 10, bool robust = false)" + }, + "save": { + "type": "func", + "name": "save", + "doc": { + "brief": "Save image to file", + "param": { + "path": "file path", + "quality": "image quality, by default(value is 95), support jpeg and png format" + }, + "return": "error code, err::ERR_NONE is ok, other is error", + "maixpy": "maix.image.Image.save", + "py_doc": "Save image to file\n\nArgs:\n - path: file path\n - quality: image quality, by default(value is 95), support jpeg and png format\n\n\nReturns: error code, err::ERR_NONE is ok, other is error\n" + }, + "args": [ + [ + "const char *", + "path", + null + ], + [ + "int", + "quality", + "95" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err save(const char *path, int quality = 95)" + }, + "flood_fill": { + "type": "func", + "name": "flood_fill", + "doc": { + "brief": "Flood fills a region of the image starting from location x, y.", + "param": { + "x": "The x coordinate of the seed point.", + "y": "The y coordinate of the seed point.", + "seed_threshold": "The seed_threshold value controls how different any pixel in the fill area may be from the original starting pixel. default is 0.05.", + "floating_threshold": "The floating_threshold value controls how different any pixel in the fill area may be from any neighbor pixels. default is 0.05.", + "color": "The color to fill the region with. default is white.", + "invert": "If true, the image will be inverted before the operation. default is false.", + "clear_background": "If true, the background will be cleared before the operation. default is false.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None. FIXME: the mask image works abnormally" + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.flood_fill", + "py_doc": "Flood fills a region of the image starting from location x, y.\n\nArgs:\n - x: The x coordinate of the seed point.\n - y: The y coordinate of the seed point.\n - seed_threshold: The seed_threshold value controls how different any pixel in the fill area may be from the original starting pixel. default is 0.05.\n - floating_threshold: The floating_threshold value controls how different any pixel in the fill area may be from any neighbor pixels. default is 0.05.\n - color: The color to fill the region with. default is white.\n - invert: If true, the image will be inverted before the operation. default is false.\n - clear_background: If true, the background will be cleared before the operation. default is false.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None. FIXME: the mask image works abnormally\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "float", + "seed_threshold", + "0.05" + ], + [ + "float", + "floating_threshold", + "0.05" + ], + [ + "image::Color", + "color", + "image::COLOR_WHITE" + ], + [ + "bool", + "invert", + "false" + ], + [ + "bool", + "clear_background", + "false" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *flood_fill(int x, int y, float seed_threshold = 0.05, float floating_threshold = 0.05, image::Color color = image::COLOR_WHITE, bool invert = false, bool clear_background = false, image::Image *mask = nullptr)" + }, + "erode": { + "type": "func", + "name": "erode", + "doc": { + "brief": "Erodes the image in place.", + "param": { + "size": "Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).", + "threshold": "The number of pixels in the kernel that are not 0. If it is less than or equal to the threshold, set the center pixel to black. default is (kernel_size - 1).", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.erode", + "py_doc": "Erodes the image in place.\n\nArgs:\n - size: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).\n - threshold: The number of pixels in the kernel that are not 0. If it is less than or equal to the threshold, set the center pixel to black. default is (kernel_size - 1).\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "size", + null + ], + [ + "int", + "threshold", + "-1" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *erode(int size, int threshold = -1, image::Image *mask = nullptr)" + }, + "dilate": { + "type": "func", + "name": "dilate", + "doc": { + "brief": "Dilates the image in place.", + "param": { + "size": "Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).", + "threshold": "The number of pixels in the kernel that are not 0. If it is greater than or equal to the threshold, set the center pixel to white. default is 0.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.dilate", + "py_doc": "Dilates the image in place.\n\nArgs:\n - size: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).\n - threshold: The number of pixels in the kernel that are not 0. If it is greater than or equal to the threshold, set the center pixel to white. default is 0.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "size", + null + ], + [ + "int", + "threshold", + "0" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *dilate(int size, int threshold = 0, image::Image *mask = nullptr)" + }, + "open": { + "type": "func", + "name": "open", + "doc": { + "brief": "Performs erosion and dilation on an image in order.", + "param": { + "size": "Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).", + "threshold": "As the threshold for erosion and dilation, the actual threshold for erosion is (kernel_size - 1 - threshold), the actual threshold for dialation is threshold. default is 0.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.open", + "py_doc": "Performs erosion and dilation on an image in order.\n\nArgs:\n - size: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).\n - threshold: As the threshold for erosion and dilation, the actual threshold for erosion is (kernel_size - 1 - threshold), the actual threshold for dialation is threshold. default is 0.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "size", + null + ], + [ + "int", + "threshold", + "0" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *open(int size, int threshold = 0, image::Image *mask = nullptr)" + }, + "close": { + "type": "func", + "name": "close", + "doc": { + "brief": "Performs dilation and erosion on an image in order.", + "param": { + "size": "Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).", + "threshold": "As the threshold for erosion and dilation, the actual threshold for erosion is (kernel_size - 1 - threshold), the actual threshold for dialation is threshold. default is 0.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.close", + "py_doc": "Performs dilation and erosion on an image in order.\n\nArgs:\n - size: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).\n - threshold: As the threshold for erosion and dilation, the actual threshold for erosion is (kernel_size - 1 - threshold), the actual threshold for dialation is threshold. default is 0.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "size", + null + ], + [ + "int", + "threshold", + "0" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *close(int size, int threshold = 0, image::Image *mask = nullptr)" + }, + "top_hat": { + "type": "func", + "name": "top_hat", + "doc": { + "brief": "Returns the image difference of the image and Image.open()\u2019ed image.", + "param": { + "size": "Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).", + "threshold": "As the threshold for open method. default is 0.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.top_hat", + "py_doc": "Returns the image difference of the image and Image.open()\u2019ed image.\n\nArgs:\n - size: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).\n - threshold: As the threshold for open method. default is 0.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "size", + null + ], + [ + "int", + "threshold", + "0" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *top_hat(int size, int threshold = 0, image::Image *mask = nullptr)" + }, + "black_hat": { + "type": "func", + "name": "black_hat", + "doc": { + "brief": "Returns the image difference of the image and Image.close()\u2019ed image.", + "param": { + "size": "Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).", + "threshold": "As the threshold for close method. default is 0.", + "mask": "Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None." + }, + "return": "Returns the image after the operation is completed.", + "maixpy": "maix.image.Image.black_hat", + "py_doc": "Returns the image difference of the image and Image.close()\u2019ed image.\n\nArgs:\n - size: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).\n - threshold: As the threshold for close method. default is 0.\n - mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.\nOnly pixels set in the mask are modified. default is None.\n\n\nReturns: Returns the image after the operation is completed.\n" + }, + "args": [ + [ + "int", + "size", + null + ], + [ + "int", + "threshold", + "0" + ], + [ + "image::Image *", + "mask", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *black_hat(int size, int threshold = 0, image::Image *mask = nullptr)" + }, + "find_blobs": { + "type": "func", + "name": "find_blobs", + "doc": { + "brief": "Finds all blobs in the image and returns a list of image.Blob class which describe each Blob.\\nPlease see the image.Blob object more more information.", + "param": { + "thresholds": "You can define multiple thresholds.\nFor GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.\nFor RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.\nWhere the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.", + "invert": "if true, will invert thresholds before find blobs, default is false", + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.", + "x_stride": "x stride is the number of x pixels to skip when doing the hough transform. default is 2", + "y_stride": "y_stride is the number of y pixels to skip when doing the hough transform. default is 1", + "area_threshold": "area threshold, if the blob area is smaller than area_threshold, the blob is not returned, default is 10", + "pixels_threshold": "pixels threshold, if the blob pixels is smaller than area_threshold, the blob is not returned,, default is 10.\nwhen x_stride and y_stride is equal to 1, pixels_threshold is equivalent to area_threshold", + "merge": "if True merges all not filtered out blobs whos bounding rectangles intersect each other. default is false", + "margin": "margin can be used to increase or decrease the size of the bounding rectangles for blobs during the intersection test.\nFor example, with a margin of 1 blobs whos bounding rectangles are 1 pixel away from each other will be merged. default is 0", + "x_hist_bins_max": "if set to non-zero populates a histogram buffer in each blob object with an x_histogram projection of all columns in the object. This value then sets the number of bins for that projection.", + "y_hist_bins_max": "if set to non-zero populates a histogram buffer in each blob object with an y_histogram projection of all rows in the object. This value then sets the number of bins for that projection." + }, + "return": "Return the blob when found blobs, format is (blob1, blob2, ...), you can use blob class methods to do more operations.", + "maixpy": "maix.image.Image.find_blobs", + "py_doc": "Finds all blobs in the image and returns a list of image.Blob class which describe each Blob.\nPlease see the image.Blob object more more information.\n\nArgs:\n - thresholds: You can define multiple thresholds.\nFor GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.\nFor RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.\nWhere the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.\n - invert: if true, will invert thresholds before find blobs, default is false\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n - x_stride: x stride is the number of x pixels to skip when doing the hough transform. default is 2\n - y_stride: y_stride is the number of y pixels to skip when doing the hough transform. default is 1\n - area_threshold: area threshold, if the blob area is smaller than area_threshold, the blob is not returned, default is 10\n - pixels_threshold: pixels threshold, if the blob pixels is smaller than area_threshold, the blob is not returned,, default is 10.\nwhen x_stride and y_stride is equal to 1, pixels_threshold is equivalent to area_threshold\n - merge: if True merges all not filtered out blobs whos bounding rectangles intersect each other. default is false\n - margin: margin can be used to increase or decrease the size of the bounding rectangles for blobs during the intersection test.\nFor example, with a margin of 1 blobs whos bounding rectangles are 1 pixel away from each other will be merged. default is 0\n - x_hist_bins_max: if set to non-zero populates a histogram buffer in each blob object with an x_histogram projection of all columns in the object. This value then sets the number of bins for that projection.\n - y_hist_bins_max: if set to non-zero populates a histogram buffer in each blob object with an y_histogram projection of all rows in the object. This value then sets the number of bins for that projection.\n\n\nReturns: Return the blob when found blobs, format is (blob1, blob2, ...), you can use blob class methods to do more operations.\n" + }, + "args": [ + [ + "std::vector>", + "thresholds", + "std::vector>()" + ], + [ + "bool", + "invert", + "false" + ], + [ + "std::vector", + "roi", + "std::vector()" + ], + [ + "int", + "x_stride", + "2" + ], + [ + "int", + "y_stride", + "1" + ], + [ + "int", + "area_threshold", + "10" + ], + [ + "int", + "pixels_threshold", + "10" + ], + [ + "bool", + "merge", + "false" + ], + [ + "int", + "margin", + "0" + ], + [ + "int", + "x_hist_bins_max", + "0" + ], + [ + "int", + "y_hist_bins_max", + "0" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector find_blobs(std::vector> thresholds = std::vector>(), bool invert = false, std::vector roi = std::vector(), int x_stride = 2, int y_stride = 1, int area_threshold = 10, int pixels_threshold = 10, bool merge = false, int margin = 0, int x_hist_bins_max = 0, int y_hist_bins_max = 0)" + }, + "find_lines": { + "type": "func", + "name": "find_lines", + "doc": { + "brief": "Find lines in image", + "param": { + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.", + "x_stride": "x stride is the number of x pixels to skip when doing the hough transform. default is 2", + "y_stride": "y_stride is the number of y pixels to skip when doing the hough transform. default is 1", + "threshold": "threshold threshold controls what lines are detected from the hough transform. Only lines with a magnitude greater than or equal to threshold are returned.\nThe right value of threshold for your application is image dependent. default is 1000.", + "theta_margin": "theta_margin controls the merging of detected lines. default is 25.", + "rho_margin": "rho_margin controls the merging of detected lines. default is 25." + }, + "return": "Return the line when found lines, format is (line1, line2, ...), you can use line class methods to do more operations", + "maixpy": "maix.image.Image.find_lines", + "py_doc": "Find lines in image\n\nArgs:\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n - x_stride: x stride is the number of x pixels to skip when doing the hough transform. default is 2\n - y_stride: y_stride is the number of y pixels to skip when doing the hough transform. default is 1\n - threshold: threshold threshold controls what lines are detected from the hough transform. Only lines with a magnitude greater than or equal to threshold are returned.\nThe right value of threshold for your application is image dependent. default is 1000.\n - theta_margin: theta_margin controls the merging of detected lines. default is 25.\n - rho_margin: rho_margin controls the merging of detected lines. default is 25.\n\n\nReturns: Return the line when found lines, format is (line1, line2, ...), you can use line class methods to do more operations\n" + }, + "args": [ + [ + "std::vector", + "roi", + "std::vector()" + ], + [ + "int", + "x_stride", + "2" + ], + [ + "int", + "y_stride", + "1" + ], + [ + "double", + "threshold", + "1000" + ], + [ + "double", + "theta_margin", + "25" + ], + [ + "double", + "rho_margin", + "25" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector find_lines(std::vector roi = std::vector(), int x_stride = 2, int y_stride = 1, double threshold = 1000, double theta_margin = 25, double rho_margin = 25)" + }, + "find_line_segments": { + "type": "func", + "name": "find_line_segments", + "doc": { + "brief": "Finds all line segments in the image.", + "param": { + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.", + "merge_distance": "The maximum distance between two lines to merge them. default is 0.", + "max_theta_difference": "The maximum difference between two lines to merge them. default is 15." + }, + "return": "Return the line when found lines, format is (line1, line2, ...), you can use line class methods to do more operations", + "maixpy": "maix.image.Image.find_line_segments", + "py_doc": "Finds all line segments in the image.\n\nArgs:\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n - merge_distance: The maximum distance between two lines to merge them. default is 0.\n - max_theta_difference: The maximum difference between two lines to merge them. default is 15.\n\n\nReturns: Return the line when found lines, format is (line1, line2, ...), you can use line class methods to do more operations\n" + }, + "args": [ + [ + "std::vector", + "roi", + "std::vector()" + ], + [ + "int", + "merge_distance", + "0" + ], + [ + "int", + "max_theta_difference", + "15" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector find_line_segments(std::vector roi = std::vector(), int merge_distance = 0, int max_theta_difference = 15)" + }, + "find_circles": { + "type": "func", + "name": "find_circles", + "doc": { + "brief": "Find circles in image", + "param": { + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.", + "x_stride": "x stride is the number of x pixels to skip when doing the hough transform. default is 2", + "y_stride": "y_stride is the number of y pixels to skip when doing the hough transform. default is 1", + "threshold": "threshold controls what circles are detected from the hough transform. Only circles with a magnitude greater than or equal to threshold are returned.\nThe right value of threshold for your application is image dependent.", + "x_margin": "x_margin controls the merging of detected circles. Circles which are x_margin, y_margin, and r_margin pixels apart are merged. default is 10", + "y_margin": "y_margin controls the merging of detected circles. Circles which are x_margin, y_margin, and r_margin pixels apart are merged. default is 10", + "r_margin": "r_margin controls the merging of detected circles. Circles which are x_margin, y_margin, and r_margin pixels apart are merged. default is 10", + "r_min": "r_min controls the minimum circle radius detected. Increase this to speed up the algorithm. default is 2", + "r_max": "r_max controls the maximum circle radius detected. Decrease this to speed up the algorithm. default is min(roi.w / 2, roi.h / 2)", + "r_step": "r_step controls how to step the radius detection by. default is 2." + }, + "return": "Return the circle when found circles, format is (circle1, circle2, ...), you can use circle class methods to do more operations", + "maixpy": "maix.image.Image.find_circles", + "py_doc": "Find circles in image\n\nArgs:\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n - x_stride: x stride is the number of x pixels to skip when doing the hough transform. default is 2\n - y_stride: y_stride is the number of y pixels to skip when doing the hough transform. default is 1\n - threshold: threshold controls what circles are detected from the hough transform. Only circles with a magnitude greater than or equal to threshold are returned.\nThe right value of threshold for your application is image dependent.\n - x_margin: x_margin controls the merging of detected circles. Circles which are x_margin, y_margin, and r_margin pixels apart are merged. default is 10\n - y_margin: y_margin controls the merging of detected circles. Circles which are x_margin, y_margin, and r_margin pixels apart are merged. default is 10\n - r_margin: r_margin controls the merging of detected circles. Circles which are x_margin, y_margin, and r_margin pixels apart are merged. default is 10\n - r_min: r_min controls the minimum circle radius detected. Increase this to speed up the algorithm. default is 2\n - r_max: r_max controls the maximum circle radius detected. Decrease this to speed up the algorithm. default is min(roi.w / 2, roi.h / 2)\n - r_step: r_step controls how to step the radius detection by. default is 2.\n\n\nReturns: Return the circle when found circles, format is (circle1, circle2, ...), you can use circle class methods to do more operations\n" + }, + "args": [ + [ + "std::vector", + "roi", + "std::vector()" + ], + [ + "int", + "x_stride", + "2" + ], + [ + "int", + "y_stride", + "1" + ], + [ + "int", + "threshold", + "2000" + ], + [ + "int", + "x_margin", + "10" + ], + [ + "int", + "y_margin", + "10" + ], + [ + "int", + "r_margin", + "10" + ], + [ + "int", + "r_min", + "2" + ], + [ + "int", + "r_max", + "-1" + ], + [ + "int", + "r_step", + "2" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector find_circles(std::vector roi = std::vector(), int x_stride = 2, int y_stride = 1, int threshold = 2000, int x_margin = 10, int y_margin = 10, int r_margin = 10, int r_min = 2, int r_max = -1, int r_step = 2)" + }, + "find_rects": { + "type": "func", + "name": "find_rects", + "doc": { + "brief": "Finds all rects in the image.", + "param": { + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.", + "threshold": "The threshold to use for the rects. default is 10000." + }, + "return": "Returns the rects of the image", + "maixpy": "maix.image.Image.find_rects", + "py_doc": "Finds all rects in the image.\n\nArgs:\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n - threshold: The threshold to use for the rects. default is 10000.\n\n\nReturns: Returns the rects of the image\n" + }, + "args": [ + [ + "std::vector", + "roi", + "std::vector()" + ], + [ + "int", + "threshold", + "10000" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector find_rects(std::vector roi = std::vector(), int threshold = 10000)" + }, + "find_qrcodes": { + "type": "func", + "name": "find_qrcodes", + "doc": { + "brief": "Finds all qrcodes in the image.", + "param": { + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image." + }, + "return": "Returns the qrcodes of the image", + "maixpy": "maix.image.Image.find_qrcodes", + "py_doc": "Finds all qrcodes in the image.\n\nArgs:\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n\n\nReturns: Returns the qrcodes of the image\n" + }, + "args": [ + [ + "std::vector", + "roi", + "std::vector()" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector find_qrcodes(std::vector roi = std::vector())" + }, + "find_apriltags": { + "type": "func", + "name": "find_apriltags", + "doc": { + "brief": "Finds all apriltags in the image.", + "param": { + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.", + "families": "The families to use for the apriltags. default is TAG36H11.", + "fx": "The camera X focal length in pixels, default is -1.", + "fy": "The camera Y focal length in pixels, default is -1.", + "cx": "The camera X center in pixels, default is image.width / 2.", + "cy": "The camera Y center in pixels, default is image.height / 2." + }, + "return": "Returns the apriltags of the image", + "maixpy": "maix.image.Image.find_apriltags", + "py_doc": "Finds all apriltags in the image.\n\nArgs:\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n - families: The families to use for the apriltags. default is TAG36H11.\n - fx: The camera X focal length in pixels, default is -1.\n - fy: The camera Y focal length in pixels, default is -1.\n - cx: The camera X center in pixels, default is image.width / 2.\n - cy: The camera Y center in pixels, default is image.height / 2.\n\n\nReturns: Returns the apriltags of the image\n" + }, + "args": [ + [ + "std::vector", + "roi", + "std::vector()" + ], + [ + "image::ApriltagFamilies", + "families", + "image::ApriltagFamilies::TAG36H11" + ], + [ + "float", + "fx", + "-1" + ], + [ + "float", + "fy", + "-1" + ], + [ + "int", + "cx", + "-1" + ], + [ + "int", + "cy", + "-1" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector find_apriltags(std::vector roi = std::vector(), image::ApriltagFamilies families = image::ApriltagFamilies::TAG36H11, float fx = -1, float fy = -1, int cx = -1, int cy = -1)" + }, + "find_datamatrices": { + "type": "func", + "name": "find_datamatrices", + "doc": { + "brief": "Finds all datamatrices in the image.", + "param": { + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.", + "effort": "Controls how much time to spend trying to find data matrix matches. default is 200." + }, + "return": "Returns the datamatrices of the image", + "maixpy": "maix.image.Image.find_datamatrices", + "py_doc": "Finds all datamatrices in the image.\n\nArgs:\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n - effort: Controls how much time to spend trying to find data matrix matches. default is 200.\n\n\nReturns: Returns the datamatrices of the image\n" + }, + "args": [ + [ + "std::vector", + "roi", + "std::vector()" + ], + [ + "int", + "effort", + "200" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector find_datamatrices(std::vector roi = std::vector(), int effort = 200)" + }, + "find_barcodes": { + "type": "func", + "name": "find_barcodes", + "doc": { + "brief": "Finds all barcodes in the image.", + "param": { + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image." + }, + "return": "Returns the barcodes of the image", + "maixpy": "maix.image.Image.find_barcodes", + "py_doc": "Finds all barcodes in the image.\n\nArgs:\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n\n\nReturns: Returns the barcodes of the image\n" + }, + "args": [ + [ + "std::vector", + "roi", + "std::vector()" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector find_barcodes(std::vector roi = std::vector())" + }, + "find_displacement": { + "type": "func", + "name": "find_displacement", + "doc": { + "brief": "Finds the displacement between the image and the template. TODO: support in the feature\\nnote: this method must be used on power-of-2 image sizes", + "param": { + "template_image": "The template image.", + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.", + "template_roi": "The region-of-interest rectangle (x, y, w, h) to work in. If not specified, it is equal to the image rectangle.", + "logpolar": "If true, it will instead find rotation and scale changes between the two images. default is false." + }, + "return": "Returns the displacement of the image", + "maixpy": "maix.image.Image.find_displacement", + "py_doc": "Finds the displacement between the image and the template. TODO: support in the feature\nnote: this method must be used on power-of-2 image sizes\n\nArgs:\n - template_image: The template image.\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n - template_roi: The region-of-interest rectangle (x, y, w, h) to work in. If not specified, it is equal to the image rectangle.\n - logpolar: If true, it will instead find rotation and scale changes between the two images. default is false.\n\n\nReturns: Returns the displacement of the image\n" + }, + "args": [ + [ + "image::Image &", + "template_image", + null + ], + [ + "std::vector", + "roi", + "std::vector()" + ], + [ + "std::vector", + "template_roi", + "std::vector()" + ], + [ + "bool", + "logpolar", + "false" + ] + ], + "ret_type": "image::Displacement", + "static": false, + "def": "image::Displacement find_displacement(image::Image &template_image, std::vector roi = std::vector(), std::vector template_roi = std::vector(), bool logpolar = false)" + }, + "find_template": { + "type": "func", + "name": "find_template", + "doc": { + "brief": "Finds the template in the image.", + "param": { + "template_image": "The template image.", + "threshold": "Threshold is floating point number (0.0-1.0) where a higher threshold prevents false positives while lowering the detection rate while a lower threshold does the opposite.", + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image. Only valid in SEARCH_EX mode.", + "step": "The step size to use for the template. default is 2. Only valid in SEARCH_EX mode", + "search": "The search method to use for the template. default is SEARCH_EX." + }, + "return": "Returns a bounding box tuple (x, y, w, h) for the matching location otherwise None.", + "maixpy": "maix.image.Image.find_template", + "py_doc": "Finds the template in the image.\n\nArgs:\n - template_image: The template image.\n - threshold: Threshold is floating point number (0.0-1.0) where a higher threshold prevents false positives while lowering the detection rate while a lower threshold does the opposite.\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image. Only valid in SEARCH_EX mode.\n - step: The step size to use for the template. default is 2. Only valid in SEARCH_EX mode\n - search: The search method to use for the template. default is SEARCH_EX.\n\n\nReturns: Returns a bounding box tuple (x, y, w, h) for the matching location otherwise None.\n" + }, + "args": [ + [ + "image::Image &", + "template_image", + null + ], + [ + "float", + "threshold", + null + ], + [ + "std::vector", + "roi", + "std::vector()" + ], + [ + "int", + "step", + "2" + ], + [ + "image::TemplateMatch", + "search", + "image::TemplateMatch::SEARCH_EX" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector find_template(image::Image &template_image, float threshold, std::vector roi = std::vector(), int step = 2, image::TemplateMatch search = image::TemplateMatch::SEARCH_EX)" + }, + "find_features": { + "type": "func", + "name": "find_features", + "doc": { + "brief": "Finds the features in the image. TODO: support in the feature", + "param": { + "cascade": "The cascade to use for the features. default is CASCADE_FRONTALFACE_ALT.", + "threshold": "The threshold to use for the features. default is 0.5.", + "scale": "The scale to use for the features. default is 1.5.", + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image." + }, + "return": "Returns the features of the image", + "maixpy": "maix.image.Image.find_features", + "py_doc": "Finds the features in the image. TODO: support in the feature\n\nArgs:\n - cascade: The cascade to use for the features. default is CASCADE_FRONTALFACE_ALT.\n - threshold: The threshold to use for the features. default is 0.5.\n - scale: The scale to use for the features. default is 1.5.\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n\n\nReturns: Returns the features of the image\n" + }, + "args": [ + [ + "int", + "cascade", + null + ], + [ + "float", + "threshold", + "0.5" + ], + [ + "float", + "scale", + "1.5" + ], + [ + "std::vector", + "roi", + "std::vector()" + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector find_features(int cascade, float threshold = 0.5, float scale = 1.5, std::vector roi = std::vector())" + }, + "find_lbp": { + "type": "func", + "name": "find_lbp", + "doc": { + "brief": "Finds the lbp in the image. TODO: support in the feature.", + "param": { + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image." + }, + "return": "Returns the lbp of the image", + "maixpy": "maix.image.Image.find_lbp", + "py_doc": "Finds the lbp in the image. TODO: support in the feature.\n\nArgs:\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n\n\nReturns: Returns the lbp of the image\n" + }, + "args": [ + [ + "std::vector", + "roi", + "std::vector()" + ] + ], + "ret_type": "image::LBPKeyPoint", + "static": false, + "def": "image::LBPKeyPoint find_lbp(std::vector roi = std::vector())" + }, + "find_keypoints": { + "type": "func", + "name": "find_keypoints", + "doc": { + "brief": "Finds the keypoints in the image. TODO: support in the feature.", + "param": { + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.", + "threshold": "The threshold to use for the keypoints. default is 20.", + "normalized": "If true, the image will be normalized before the operation. default is false.", + "scale_factor": "The scale factor to use for the keypoints. default is 1.5.", + "max_keypoints": "The maximum number of keypoints to use for the keypoints. default is 100.", + "corner_detector": "The corner detector to use for the keypoints. default is CORNER_AGAST." + }, + "return": "Returns the keypoints of the image", + "maixpy": "maix.image.Image.find_keypoints", + "py_doc": "Finds the keypoints in the image. TODO: support in the feature.\n\nArgs:\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n - threshold: The threshold to use for the keypoints. default is 20.\n - normalized: If true, the image will be normalized before the operation. default is false.\n - scale_factor: The scale factor to use for the keypoints. default is 1.5.\n - max_keypoints: The maximum number of keypoints to use for the keypoints. default is 100.\n - corner_detector: The corner detector to use for the keypoints. default is CORNER_AGAST.\n\n\nReturns: Returns the keypoints of the image\n" + }, + "args": [ + [ + "std::vector", + "roi", + "std::vector()" + ], + [ + "int", + "threshold", + "20" + ], + [ + "bool", + "normalized", + "false" + ], + [ + "float", + "scale_factor", + "1.5" + ], + [ + "int", + "max_keypoints", + "100" + ], + [ + "image::CornerDetector", + "corner_detector", + "image::CornerDetector::CORNER_AGAST" + ] + ], + "ret_type": "image::ORBKeyPoint", + "static": false, + "def": "image::ORBKeyPoint find_keypoints(std::vector roi = std::vector(), int threshold = 20, bool normalized = false, float scale_factor = 1.5, int max_keypoints = 100, image::CornerDetector corner_detector = image::CornerDetector::CORNER_AGAST)" + }, + "find_edges": { + "type": "func", + "name": "find_edges", + "doc": { + "brief": "Finds the edges in the image.", + "param": { + "edge_type": "The edge type to use for the edges. default is EDGE_CANNY.", + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.", + "threshold": "The threshold to use for the edges. default is 20." + }, + "return": "Returns the edges of the image", + "maixpy": "maix.image.Image.find_edges", + "py_doc": "Finds the edges in the image.\n\nArgs:\n - edge_type: The edge type to use for the edges. default is EDGE_CANNY.\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n - threshold: The threshold to use for the edges. default is 20.\n\n\nReturns: Returns the edges of the image\n" + }, + "args": [ + [ + "image::EdgeDetector", + "edge_type", + null + ], + [ + "std::vector", + "roi", + "std::vector()" + ], + [ + "std::vector", + "threshold", + "std::vector({100, 200})" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image* find_edges(image::EdgeDetector edge_type, std::vector roi = std::vector(), std::vector threshold = std::vector({100, 200}))" + }, + "find_hog": { + "type": "func", + "name": "find_hog", + "doc": { + "brief": "Finds the hog in the image. TODO: support in the feature", + "param": { + "roi": "The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.", + "size": "The size to use for the hog. default is 8." + }, + "return": "Returns the hog of the image", + "maixpy": "maix.image.Image.find_hog", + "py_doc": "Finds the hog in the image. TODO: support in the feature\n\nArgs:\n - roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.\ndefault is None, means whole image.\n - size: The size to use for the hog. default is 8.\n\n\nReturns: Returns the hog of the image\n" + }, + "args": [ + [ + "std::vector", + "roi", + "std::vector()" + ], + [ + "int", + "size", + "8" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image* find_hog(std::vector roi = std::vector(), int size = 8)" + }, + "match_lbp_descriptor": { + "type": "func", + "name": "match_lbp_descriptor", + "doc": { + "brief": "Matches the lbp descriptor of the image. TODO: support in the feature", + "param": { + "desc1": "The descriptor to use for the match.", + "desc2": "The descriptor to use for the match." + }, + "return": "Returns the match of the image", + "maixpy": "maix.image.Image.match_lbp_descriptor", + "py_doc": "Matches the lbp descriptor of the image. TODO: support in the feature\n\nArgs:\n - desc1: The descriptor to use for the match.\n - desc2: The descriptor to use for the match.\n\n\nReturns: Returns the match of the image\n" + }, + "args": [ + [ + "image::LBPKeyPoint &", + "desc1", + null + ], + [ + "image::LBPKeyPoint &", + "desc2", + null + ] + ], + "ret_type": "int", + "static": false, + "def": "int match_lbp_descriptor(image::LBPKeyPoint &desc1, image::LBPKeyPoint &desc2)" + }, + "match_orb_descriptor": { + "type": "func", + "name": "match_orb_descriptor", + "doc": { + "brief": "Matches the orb descriptor of the image. TODO: support in the feature", + "param": { + "desc1": "The descriptor to use for the match.", + "desc2": "The descriptor to use for the match.", + "threshold": "The threshold to use for the match. default is 95.", + "filter_outliers": "If true, the image will be filter_outliers before the operation. default is false." + }, + "return": "Returns the match of the image", + "maixpy": "maix.image.Image.match_orb_descriptor", + "py_doc": "Matches the orb descriptor of the image. TODO: support in the feature\n\nArgs:\n - desc1: The descriptor to use for the match.\n - desc2: The descriptor to use for the match.\n - threshold: The threshold to use for the match. default is 95.\n - filter_outliers: If true, the image will be filter_outliers before the operation. default is false.\n\n\nReturns: Returns the match of the image\n" + }, + "args": [ + [ + "image::ORBKeyPoint &", + "desc1", + null + ], + [ + "image::ORBKeyPoint &", + "desc2", + null + ], + [ + "int", + "threshold", + "95" + ], + [ + "bool", + "filter_outliers", + "false" + ] + ], + "ret_type": "image::KPTMatch", + "static": false, + "def": "image::KPTMatch match_orb_descriptor(image::ORBKeyPoint &desc1, image::ORBKeyPoint &desc2, int threshold = 95, bool filter_outliers = false)" + } + }, + "def": "class Image" + }, + "load": { + "type": "func", + "name": "load", + "doc": { + "brief": "Load image from file, and convert to Image object", + "param": { + "path": "image file path", + "format": "read as this format, if not match, will convert to this format, by default is RGB888" + }, + "return": "Image object", + "maixpy": "maix.image.load", + "py_doc": "Load image from file, and convert to Image object\n\nArgs:\n - path: image file path\n - format: read as this format, if not match, will convert to this format, by default is RGB888\n\n\nReturns: Image object\n" + }, + "args": [ + [ + "const char *", + "path", + null + ], + [ + "image::Format", + "format", + "image::Format::FMT_RGB888" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *load(const char *path, image::Format format = image::Format::FMT_RGB888)", + "py_def": "def load(path: str, format: Format = ...) -> Image" + }, + "from_bytes": { + "type": "func", + "name": "from_bytes", + "doc": { + "brief": "Create image from bytes", + "param": { + "width": "image width", + "height": "image height", + "format": "image format", + "data": "image data, if data is None, will malloc memory for image data\nIf the image is in jpeg format, data must be filled in.", + "copy": "if true and data is not None, will copy data to new buffer, else will use data directly. default is true to avoid memory leak.\nUse it carefully!!!" + }, + "return": "Image object", + "maixpy": "maix.image.from_bytes", + "py_doc": "Create image from bytes\n\nArgs:\n - width: image width\n - height: image height\n - format: image format\n - data: image data, if data is None, will malloc memory for image data\nIf the image is in jpeg format, data must be filled in.\n - copy: if true and data is not None, will copy data to new buffer, else will use data directly. default is true to avoid memory leak.\nUse it carefully!!!\n\n\nReturns: Image object\n" + }, + "args": [ + [ + "int", + "width", + null + ], + [ + "int", + "height", + null + ], + [ + "image::Format", + "format", + null + ], + [ + "Bytes *", + "data", + null + ], + [ + "bool", + "copy", + "true" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *from_bytes(int width, int height, image::Format format, Bytes *data, bool copy = true)", + "py_def": "def from_bytes(width: int, height: int, format: Format, data: maix.Bytes(bytes), copy: bool = True) -> Image" + }, + "load_font": { + "type": "func", + "name": "load_font", + "doc": { + "brief": "Load font from file", + "param": { + "name": "font name, used to identify font", + "path": "font file path, support ttf, ttc, otf", + "size": "font size, font height, by default is 16" + }, + "return": "error code, err::ERR_NONE is ok, other is error", + "maixpy": "maix.image.load_font", + "py_doc": "Load font from file\n\nArgs:\n - name: font name, used to identify font\n - path: font file path, support ttf, ttc, otf\n - size: font size, font height, by default is 16\n\n\nReturns: error code, err::ERR_NONE is ok, other is error\n" + }, + "args": [ + [ + "const std::string &", + "name", + null + ], + [ + "const char *", + "path", + null + ], + [ + "int", + "size", + "16" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err load_font(const std::string &name, const char *path, int size = 16)", + "py_def": "def load_font(name: str, path: str, size: int = 16) -> maix.err.Err" + }, + "set_default_font": { + "type": "func", + "name": "set_default_font", + "doc": { + "brief": "Set default font, if not call this method, default is hershey_plain", + "param": { + "name": "font name, supported names can be get by fonts()" + }, + "return": "error code, err::ERR_NONE is ok, other is error", + "maixpy": "maix.image.set_default_font", + "py_doc": "Set default font, if not call this method, default is hershey_plain\n\nArgs:\n - name: font name, supported names can be get by fonts()\n\n\nReturns: error code, err::ERR_NONE is ok, other is error\n" + }, + "args": [ + [ + "const std::string &", + "name", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err set_default_font(const std::string &name)" + }, + "fonts": { + "type": "func", + "name": "fonts", + "doc": { + "brief": "Get all loaded fonts", + "return": "all loaded fonts, string list type", + "maixpy": "maix.image.fonts", + "py_doc": "Get all loaded fonts\n\nReturns: all loaded fonts, string list type\n" + }, + "args": [], + "ret_type": "std::vector*", + "static": false, + "def": "std::vector *fonts()", + "py_def": "def fonts() -> list[str]" + }, + "string_size": { + "type": "func", + "name": "string_size", + "doc": { + "brief": "Get text rendered width and height", + "param": { + "string": "text content", + "scale": "font scale, by default(value is 1)", + "thickness": "text thickness(line width), by default(value is 1)" + }, + "return": "text rendered width and height, [width, height]", + "maixpy": "maix.image.string_size", + "py_doc": "Get text rendered width and height\n\nArgs:\n - string: text content\n - scale: font scale, by default(value is 1)\n - thickness: text thickness(line width), by default(value is 1)\n\n\nReturns: text rendered width and height, [width, height]\n" + }, + "args": [ + [ + "std::string", + "string", + null + ], + [ + "float", + "scale", + "1" + ], + [ + "int", + "thickness", + "1" + ], + [ + "const std::string &", + "font", + "\"\"" + ] + ], + "ret_type": "image::Size", + "static": false, + "def": "image::Size string_size(std::string string, float scale = 1, int thickness = 1, const std::string &font = \"\")", + "py_def": "def string_size(string: str, scale: float = 1, thickness: int = 1, font: str = '') -> Size" + }, + "cv2image": { + "type": "func", + "name": "cv2image", + "doc": { + "brief": "OpenCV Mat(numpy array object) to Image object", + "param": { + "array": "numpy array object, must be a 3-dim or 2-dim continuous array with shape hwc or hw" + }, + "return": "Image object", + "maixpy": "maix.image.cv2image", + "py_doc": "OpenCV Mat(numpy array object) to Image object\n\nArgs:\n - array: numpy array object, must be a 3-dim or 2-dim continuous array with shape hwc or hw\n\n\nReturns: Image object\n" + }, + "args": [ + [ + "py::array_t", + "array", + null + ], + [ + "bool", + "bgr", + "true" + ], + [ + "bool", + "copy", + "true" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *cv2image(py::array_t array, bool bgr = true, bool copy = true)" + }, + "image2cv": { + "type": "func", + "name": "image2cv", + "doc": { + "brief": "Image object to OpenCV Mat(numpy array object)", + "param": { + "img": "Image object" + }, + "return": "numpy array object", + "maixpy": "maix.image.image2cv", + "py_doc": "Image object to OpenCV Mat(numpy array object)\n\nArgs:\n - img: Image object\n\n\nReturns: numpy array object\n" + }, + "args": [ + [ + "image::Image *", + "img", + null + ], + [ + "bool", + "bgr", + "true" + ], + [ + "bool", + "copy", + "true" + ] + ], + "ret_type": "py::array_t", + "static": false, + "def": "py::array_t image2cv(image::Image *img, bool bgr = true, bool copy = true)", + "py_def": "def image2cv(img: Image, bgr: bool = True, copy: bool = True) -> numpy.ndarray[numpy.uint8]" + } + }, + "auto_add": true + }, + "camera": { + "type": "module", + "doc": { + "brief": "maix.camera module, access camera device and get image from it", + "maixpy": "maix.camera", + "py_doc": "maix.camera module, access camera device and get image from it" + }, + "members": { + "list_devices": { + "type": "func", + "name": "list_devices", + "doc": { + "brief": "List all supported camera devices.", + "return": "Returns the path to the camera device.", + "maixpy": "maix.camera.list_devices", + "py_doc": "List all supported camera devices.\n\nReturns: Returns the path to the camera device.\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector list_devices()" + }, + "set_regs_enable": { + "type": "func", + "name": "set_regs_enable", + "doc": { + "brief": "Enable set camera registers, default is false, if set to true, will not set camera registers, you can manually set registers by write_reg API.", + "param": { + "enable": "enable/disable set camera registers" + }, + "maixpy": "maix.camera.set_regs_enable", + "py_doc": "Enable set camera registers, default is false, if set to true, will not set camera registers, you can manually set registers by write_reg API.\n\nArgs:\n - enable: enable/disable set camera registers\n" + }, + "args": [ + [ + "bool", + "enable", + "true" + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_regs_enable(bool enable = true)", + "py_def": "def set_regs_enable(enable: bool = True) -> None" + }, + "Camera": { + "type": "class", + "name": "Camera", + "doc": { + "brief": "Camera class", + "maixpy": "maix.camera.Camera", + "py_doc": "Camera class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Camera", + "doc": { + "brief": "Construct a new Camera object", + "param": { + "width": "camera width, default is -1, means auto, mostly means max width of camera support", + "height": "camera height, default is -1, means auto, mostly means max height of camera support", + "format": "camera output format, default is image.Format.FMT_RGB888", + "device": "camera device path, you can get devices by list_devices method, by default(value is NULL(None in MaixPy)) means the first device", + "fps": "camera fps, default is -1, means auto, mostly means max fps of camera support", + "buff_num": "camera buffer number, default is 3, means 3 buffer, one used by user, one used for cache the next frame,\nmore than one buffer will accelerate image read speed, but will cost more memory.", + "open": "If true, camera will automatically call open() after creation. default is true." + }, + "maixpy": "maix.camera.Camera.__init__", + "maixcdk": "maix.camera.Camera.Camera", + "py_doc": "Construct a new Camera object\n\nArgs:\n - width: camera width, default is -1, means auto, mostly means max width of camera support\n - height: camera height, default is -1, means auto, mostly means max height of camera support\n - format: camera output format, default is image.Format.FMT_RGB888\n - device: camera device path, you can get devices by list_devices method, by default(value is NULL(None in MaixPy)) means the first device\n - fps: camera fps, default is -1, means auto, mostly means max fps of camera support\n - buff_num: camera buffer number, default is 3, means 3 buffer, one used by user, one used for cache the next frame,\nmore than one buffer will accelerate image read speed, but will cost more memory.\n - open: If true, camera will automatically call open() after creation. default is true.\n" + }, + "args": [ + [ + "int", + "width", + "-1" + ], + [ + "int", + "height", + "-1" + ], + [ + "image::Format", + "format", + "image::FMT_RGB888" + ], + [ + "const char *", + "device", + "nullptr" + ], + [ + "int", + "fps", + "-1" + ], + [ + "int", + "buff_num", + "3" + ], + [ + "bool", + "open", + "true" + ] + ], + "ret_type": null, + "static": false, + "def": "Camera(int width = -1, int height = -1, image::Format format = image::FMT_RGB888, const char *device = nullptr, int fps = -1, int buff_num = 3, bool open = true)", + "py_def": "def __init__(self, width: int = -1, height: int = -1, format: maix.image.Format = ..., device: str = None, fps: int = -1, buff_num: int = 3, open: bool = True) -> None" + }, + "get_ch_nums": { + "type": "func", + "name": "get_ch_nums", + "doc": { + "brief": "Get the number of channels supported by the camera.", + "return": "Returns the maximum number of channels.", + "maixpy": "maix.camera.Camera.get_ch_nums", + "py_doc": "Get the number of channels supported by the camera.\n\nReturns: Returns the maximum number of channels.\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int get_ch_nums()", + "py_def": "def get_ch_nums(self) -> int" + }, + "open": { + "type": "func", + "name": "open", + "doc": { + "brief": "Open camera and run", + "param": { + "width": "camera width, default is -1, means auto, mostly means max width of camera support", + "height": "camera height, default is -1, means auto, mostly means max height of camera support", + "format": "camera output format, default same as the constructor's format argument", + "fps": "camera fps, default is -1, means auto, mostly means max fps of camera support", + "buff_num": "camera buffer number, default is 3, means 3 buffer, one used by user, one used for cache the next frame,\nmore than one buffer will accelerate image read speed, but will cost more memory." + }, + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.camera.Camera.open", + "py_doc": "Open camera and run\n\nArgs:\n - width: camera width, default is -1, means auto, mostly means max width of camera support\n - height: camera height, default is -1, means auto, mostly means max height of camera support\n - format: camera output format, default same as the constructor's format argument\n - fps: camera fps, default is -1, means auto, mostly means max fps of camera support\n - buff_num: camera buffer number, default is 3, means 3 buffer, one used by user, one used for cache the next frame,\nmore than one buffer will accelerate image read speed, but will cost more memory.\n\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [ + [ + "int", + "width", + "-1" + ], + [ + "int", + "height", + "-1" + ], + [ + "image::Format", + "format", + "image::FMT_INVALID" + ], + [ + "int", + "fps", + "-1" + ], + [ + "int", + "buff_num", + "-1" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err open(int width = -1, int height = -1, image::Format format = image::FMT_INVALID, int fps = -1, int buff_num = -1)", + "py_def": "def open(self, width: int = -1, height: int = -1, format: maix.image.Format = ..., fps: int = -1, buff_num: int = -1) -> maix.err.Err" + }, + "read": { + "type": "func", + "name": "read", + "doc": { + "brief": "Get one frame image from camera buffer, must call open method before read.\\nIf open method not called, will call it automatically, if open failed, will throw exception!\\nSo call open method before read is recommended.", + "param": { + "buff": "buffer to store image data, if buff is nullptr, will alloc memory automatically.\nIn MaixPy, default to None, you can create a image.Image object, then pass img.data() to buff.", + "block": "block read, default is true, means block util read image successfully,\nif set to false, will return nullptr if no image in buffer" + }, + "return": "image::Image object, if failed, return nullptr, you should delete if manually in C++", + "maixpy": "maix.camera.Camera.read", + "py_doc": "Get one frame image from camera buffer, must call open method before read.\nIf open method not called, will call it automatically, if open failed, will throw exception!\nSo call open method before read is recommended.\n\nArgs:\n - buff: buffer to store image data, if buff is nullptr, will alloc memory automatically.\nIn MaixPy, default to None, you can create a image.Image object, then pass img.data() to buff.\n - block: block read, default is true, means block util read image successfully,\nif set to false, will return nullptr if no image in buffer\n\n\nReturns: image::Image object, if failed, return nullptr, you should delete if manually in C++\n" + }, + "args": [ + [ + "void *", + "buff", + "nullptr" + ], + [ + "size_t", + "buff_size", + "0" + ], + [ + "bool", + "block", + "true" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *read(void *buff = nullptr, size_t buff_size = 0, bool block = true)", + "py_def": "def read(self, buff: capsule = None, buff_size: int = 0, block: bool = True) -> maix.image.Image" + }, + "clear_buff": { + "type": "func", + "name": "clear_buff", + "doc": { + "brief": "Clear buff to ensure the next read image is the latest image", + "maixpy": "maix.camera.Camera.clear_buff", + "py_doc": "Clear buff to ensure the next read image is the latest image" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void clear_buff()", + "py_def": "def clear_buff(self) -> None" + }, + "skip_frames": { + "type": "func", + "name": "skip_frames", + "doc": { + "brief": "Read some frames and drop, this is usually used avoid read not stable image when camera just opened.", + "param": { + "num": "number of frames to read and drop" + }, + "maixpy": "maix.camera.Camera.skip_frames", + "py_doc": "Read some frames and drop, this is usually used avoid read not stable image when camera just opened.\n\nArgs:\n - num: number of frames to read and drop\n" + }, + "args": [ + [ + "int", + "num", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void skip_frames(int num)", + "py_def": "def skip_frames(self, num: int) -> None" + }, + "close": { + "type": "func", + "name": "close", + "doc": { + "brief": "Close camera", + "maixpy": "maix.camera.Camera.close", + "py_doc": "Close camera" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void close()", + "py_def": "def close(self) -> None" + }, + "add_channel": { + "type": "func", + "name": "add_channel", + "doc": { + "brief": "Add a new channel and return a new Camera object, you can use close() to close this channel.", + "param": { + "width": "camera width, default is -1, means auto, mostly means max width of camera support", + "height": "camera height, default is -1, means auto, mostly means max height of camera support", + "format": "camera output format, default is RGB888", + "fps": "camera fps, default is -1, means auto, mostly means max fps of camera support", + "buff_num": "camera buffer number, default is 3, means 3 buffer, one used by user, one used for cache the next frame,\nmore than one buffer will accelerate image read speed, but will cost more memory.", + "open": "If true, camera will automatically call open() after creation. default is true." + }, + "return": "new Camera object", + "maixpy": "maix.camera.Camera.add_channel", + "py_doc": "Add a new channel and return a new Camera object, you can use close() to close this channel.\n\nArgs:\n - width: camera width, default is -1, means auto, mostly means max width of camera support\n - height: camera height, default is -1, means auto, mostly means max height of camera support\n - format: camera output format, default is RGB888\n - fps: camera fps, default is -1, means auto, mostly means max fps of camera support\n - buff_num: camera buffer number, default is 3, means 3 buffer, one used by user, one used for cache the next frame,\nmore than one buffer will accelerate image read speed, but will cost more memory.\n - open: If true, camera will automatically call open() after creation. default is true.\n\n\nReturns: new Camera object\n" + }, + "args": [ + [ + "int", + "width", + "-1" + ], + [ + "int", + "height", + "-1" + ], + [ + "image::Format", + "format", + "image::FMT_RGB888" + ], + [ + "int", + "fps", + "-1" + ], + [ + "int", + "buff_num", + "3" + ], + [ + "bool", + "open", + "true" + ] + ], + "ret_type": "camera::Camera*", + "static": false, + "def": "camera::Camera *add_channel(int width = -1, int height = -1, image::Format format = image::FMT_RGB888, int fps = -1, int buff_num = 3, bool open = true)", + "py_def": "def add_channel(self, width: int = -1, height: int = -1, format: maix.image.Format = ..., fps: int = -1, buff_num: int = 3, open: bool = True) -> Camera" + }, + "is_opened": { + "type": "func", + "name": "is_opened", + "doc": { + "brief": "Check if camera is opened", + "return": "true if camera is opened, false if not", + "maixpy": "maix.camera.Camera.is_opened", + "py_doc": "Check if camera is opened\n\nReturns: true if camera is opened, false if not\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_opened()", + "py_def": "def is_opened(self) -> bool" + }, + "is_closed": { + "type": "func", + "name": "is_closed", + "doc": { + "brief": "check camera device is closed or not", + "return": "closed or not, bool type", + "maixpy": "maix.camera.Camera.is_closed", + "py_doc": "check camera device is closed or not\n\nReturns: closed or not, bool type\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_closed()", + "py_def": "def is_closed(self) -> bool" + }, + "width": { + "type": "func", + "name": "width", + "doc": { + "brief": "Get camera width", + "return": "camera width", + "maixpy": "maix.camera.Camera.width", + "py_doc": "Get camera width\n\nReturns: camera width\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int width()", + "py_def": "def width(self) -> int" + }, + "height": { + "type": "func", + "name": "height", + "doc": { + "brief": "Get camera height", + "return": "camera height", + "maixpy": "maix.camera.Camera.height", + "py_doc": "Get camera height\n\nReturns: camera height\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int height()", + "py_def": "def height(self) -> int" + }, + "fps": { + "type": "func", + "name": "fps", + "doc": { + "brief": "Get camera fps", + "return": "camera fps", + "maixpy": "maix.camera.Camera.fps", + "py_doc": "Get camera fps\n\nReturns: camera fps\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int fps()", + "py_def": "def fps(self) -> int" + }, + "format": { + "type": "func", + "name": "format", + "doc": { + "brief": "Get camera output format", + "return": "camera output format, image::Format object", + "maixpy": "maix.camera.Camera.format", + "py_doc": "Get camera output format\n\nReturns: camera output format, image::Format object\n" + }, + "args": [], + "ret_type": "image::Format", + "static": false, + "def": "image::Format format()", + "py_def": "def format(self) -> maix.image.Format" + }, + "buff_num": { + "type": "func", + "name": "buff_num", + "doc": { + "brief": "Get camera buffer number", + "return": "camera buffer number", + "maixpy": "maix.camera.Camera.buff_num", + "py_doc": "Get camera buffer number\n\nReturns: camera buffer number\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int buff_num()", + "py_def": "def buff_num(self) -> int" + }, + "hmirror": { + "type": "func", + "name": "hmirror", + "doc": { + "brief": "Set/Get camera horizontal mirror", + "return": "camera horizontal mirror", + "maixpy": "maix.camera.Camera.hmirror", + "py_doc": "Set/Get camera horizontal mirror\n\nReturns: camera horizontal mirror\n" + }, + "args": [ + [ + "int", + "value", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int hmirror(int value = -1)", + "py_def": "def hmirror(self, value: int = -1) -> int" + }, + "vflip": { + "type": "func", + "name": "vflip", + "doc": { + "brief": "Set/Get camera vertical flip", + "return": "camera vertical flip", + "maixpy": "maix.camera.Camera.vflip", + "py_doc": "Set/Get camera vertical flip\n\nReturns: camera vertical flip\n" + }, + "args": [ + [ + "int", + "value", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int vflip(int value = -1)", + "py_def": "def vflip(self, value: int = -1) -> int" + }, + "device": { + "type": "func", + "name": "device", + "doc": { + "brief": "Get camera device path", + "return": "camera device path", + "maixpy": "maix.camera.Camera.device", + "py_doc": "Get camera device path\n\nReturns: camera device path\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string device()", + "py_def": "def device(self) -> str" + }, + "write_reg": { + "type": "func", + "name": "write_reg", + "doc": { + "brief": "Write camera register", + "param": { + "addr": "register address", + "data": "register data", + "bit_width": "register data bit width, default is 8" + }, + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.camera.Camera.write_reg", + "py_doc": "Write camera register\n\nArgs:\n - addr: register address\n - data: register data\n - bit_width: register data bit width, default is 8\n\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [ + [ + "int", + "addr", + null + ], + [ + "int", + "data", + null + ], + [ + "int", + "bit_width", + "8" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err write_reg(int addr, int data, int bit_width = 8)", + "py_def": "def write_reg(self, addr: int, data: int, bit_width: int = 8) -> maix.err.Err" + }, + "read_reg": { + "type": "func", + "name": "read_reg", + "doc": { + "brief": "Read camera register", + "param": { + "addr": "register address", + "bit_width": "register data bit width, default is 8" + }, + "return": "register data, -1 means failed", + "maixpy": "maix.camera.Camera.read_reg", + "py_doc": "Read camera register\n\nArgs:\n - addr: register address\n - bit_width: register data bit width, default is 8\n\n\nReturns: register data, -1 means failed\n" + }, + "args": [ + [ + "int", + "addr", + null + ], + [ + "int", + "bit_width", + "8" + ] + ], + "ret_type": "int", + "static": false, + "def": "int read_reg(int addr, int bit_width = 8)", + "py_def": "def read_reg(self, addr: int, bit_width: int = 8) -> int" + }, + "show_colorbar": { + "type": "func", + "name": "show_colorbar", + "doc": { + "brief": "Camera output color bar image for test", + "param": { + "enable": "enable/disable color bar" + }, + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.camera.Camera.show_colorbar", + "py_doc": "Camera output color bar image for test\n\nArgs:\n - enable: enable/disable color bar\n\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [ + [ + "bool", + "enable", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err show_colorbar(bool enable)", + "py_def": "def show_colorbar(self, enable: bool) -> maix.err.Err" + }, + "get_channel": { + "type": "func", + "name": "get_channel", + "doc": { + "brief": "Get channel of camera", + "return": "channel number", + "maixpy": "maix.camera.Camera.get_channel", + "py_doc": "Get channel of camera\n\nReturns: channel number\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int get_channel()", + "py_def": "def get_channel(self) -> int" + }, + "set_resolution": { + "type": "func", + "name": "set_resolution", + "doc": { + "brief": "Set camera resolution", + "param": { + "width": "new width", + "height": "new height" + }, + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.camera.Camera.set_resolution", + "py_doc": "Set camera resolution\n\nArgs:\n - width: new width\n - height: new height\n\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [ + [ + "int", + "width", + null + ], + [ + "int", + "height", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err set_resolution(int width, int height)", + "py_def": "def set_resolution(self, width: int, height: int) -> maix.err.Err" + }, + "exposure": { + "type": "func", + "name": "exposure", + "doc": { + "brief": "Set/Get camera exposure", + "attention": "This method will affect the isp and thus the image, so please be careful with it.", + "param": { + "value": "exposure time. unit: us\nIf value == -1, return exposure time.\nIf value != 0, set and return exposure time." + }, + "return": "camera exposure time", + "maixpy": "maix.camera.Camera.exposure", + "py_doc": "Set/Get camera exposure\n\nArgs:\n - value: exposure time. unit: us\nIf value == -1, return exposure time.\nIf value != 0, set and return exposure time.\n\n\nReturns: camera exposure time\n" + }, + "args": [ + [ + "uint64_t", + "value", + "-1" + ] + ], + "ret_type": "uint64_t", + "static": false, + "def": "uint64_t exposure(uint64_t value = -1)", + "py_def": "def exposure(self, value: int = -1) -> int" + }, + "gain": { + "type": "func", + "name": "gain", + "doc": { + "brief": "Set/Get camera gain", + "attention": "This method will affect the isp and thus the image, so please be careful with it.", + "param": { + "value": "camera gain.\nIf value == -1, returns camera gain.\nIf value != 0, set and return camera gain." + }, + "return": "camera gain", + "maixpy": "maix.camera.Camera.gain", + "py_doc": "Set/Get camera gain\n\nArgs:\n - value: camera gain.\nIf value == -1, returns camera gain.\nIf value != 0, set and return camera gain.\n\n\nReturns: camera gain\n" + }, + "args": [ + [ + "uint32_t", + "value", + "-1" + ] + ], + "ret_type": "uint32_t", + "static": false, + "def": "uint32_t gain(uint32_t value = -1)", + "py_def": "def gain(self, value: int = -1) -> int" + }, + "luma": { + "type": "func", + "name": "luma", + "doc": { + "brief": "Set/Get camera luma", + "attention": "This method will affect the isp and thus the image, so please be careful with it.", + "param": { + "value": "luma value, range is [0, 100]\nIf value == -1, returns luma value.\nIf value != 0, set and return luma value." + }, + "return": "returns luma value", + "maixpy": "maix.camera.Camera.luma", + "py_doc": "Set/Get camera luma\n\nArgs:\n - value: luma value, range is [0, 100]\nIf value == -1, returns luma value.\nIf value != 0, set and return luma value.\n\n\nReturns: returns luma value\n" + }, + "args": [ + [ + "uint32_t", + "value", + "-1" + ] + ], + "ret_type": "uint32_t", + "static": false, + "def": "uint32_t luma(uint32_t value = -1)", + "py_def": "def luma(self, value: int = -1) -> int" + }, + "constrast": { + "type": "func", + "name": "constrast", + "doc": { + "brief": "Set/Get camera constrast", + "attention": "This method will affect the isp and thus the image, so please be careful with it.", + "param": { + "value": "constrast value, range is [0, 100]\nIf value == -1, returns constrast value.\nIf value != 0, set and return constrast value." + }, + "return": "returns constrast value", + "maixpy": "maix.camera.Camera.constrast", + "py_doc": "Set/Get camera constrast\n\nArgs:\n - value: constrast value, range is [0, 100]\nIf value == -1, returns constrast value.\nIf value != 0, set and return constrast value.\n\n\nReturns: returns constrast value\n" + }, + "args": [ + [ + "uint32_t", + "value", + "-1" + ] + ], + "ret_type": "uint32_t", + "static": false, + "def": "uint32_t constrast(uint32_t value = -1)", + "py_def": "def constrast(self, value: int = -1) -> int" + }, + "saturation": { + "type": "func", + "name": "saturation", + "doc": { + "brief": "Set/Get camera saturation", + "attention": "This method will affect the isp and thus the image, so please be careful with it.", + "param": { + "value": "saturation value, range is [0, 100]\nIf value == -1, returns saturation value.\nIf value != 0, set and return saturation value." + }, + "return": "returns saturation value", + "maixpy": "maix.camera.Camera.saturation", + "py_doc": "Set/Get camera saturation\n\nArgs:\n - value: saturation value, range is [0, 100]\nIf value == -1, returns saturation value.\nIf value != 0, set and return saturation value.\n\n\nReturns: returns saturation value\n" + }, + "args": [ + [ + "uint32_t", + "value", + "-1" + ] + ], + "ret_type": "uint32_t", + "static": false, + "def": "uint32_t saturation(uint32_t value = -1)", + "py_def": "def saturation(self, value: int = -1) -> int" + } + }, + "def": "class Camera" + } + }, + "auto_add": false + }, + "display": { + "type": "module", + "doc": { + "brief": "maix.display module, control display device and show image on it", + "maixpy": "maix.display", + "py_doc": "maix.display module, control display device and show image on it" + }, + "members": { + "Display": { + "type": "class", + "name": "Display", + "doc": { + "brief": "Display class", + "maixpy": "maix.display.Display", + "py_doc": "Display class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Display", + "doc": { + "brief": "Construct a new Display object", + "param": { + "width": "display width, by default(value is -1) means auto detect,\nif width > max device supported width, will auto set to max device supported width", + "height": "display height, by default(value is -1) means auto detect,\nif height > max device supported height, will auto set to max device supported height", + "device": "display device name, you can get devices by list_devices method, by default(value is NULL(None in MaixPy)) means the first device", + "open": "If true, display will automatically call open() after creation. default is true." + }, + "maixpy": "maix.display.Display.__init__", + "maixcdk": "maix.display.Display.Display", + "py_doc": "Construct a new Display object\n\nArgs:\n - width: display width, by default(value is -1) means auto detect,\nif width > max device supported width, will auto set to max device supported width\n - height: display height, by default(value is -1) means auto detect,\nif height > max device supported height, will auto set to max device supported height\n - device: display device name, you can get devices by list_devices method, by default(value is NULL(None in MaixPy)) means the first device\n - open: If true, display will automatically call open() after creation. default is true.\n" + }, + "args": [ + [ + "int", + "width", + "-1" + ], + [ + "int", + "height", + "-1" + ], + [ + "image::Format", + "format", + "image::FMT_RGB888" + ], + [ + "const char *", + "device", + "nullptr" + ], + [ + "bool", + "open", + "true" + ] + ], + "ret_type": null, + "static": false, + "def": "Display(int width = -1, int height = -1, image::Format format = image::FMT_RGB888, const char *device = nullptr, bool open = true)", + "py_def": "def __init__(self, width: int = -1, height: int = -1, format: maix.image.Format = ..., device: str = None, open: bool = True) -> None" + }, + "width": { + "type": "func", + "name": "width", + "doc": { + "brief": "Get display width", + "return": "width", + "maixpy": "maix.display.Display.width", + "py_doc": "Get display width\n\nReturns: width\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int width()", + "py_def": "def width(self) -> int" + }, + "height": { + "type": "func", + "name": "height", + "doc": { + "brief": "Get display height", + "param": { + "ch": "channel to get, by default(value is 0) means the first channel" + }, + "return": "height", + "maixpy": "maix.display.Display.height", + "py_doc": "Get display height\n\nArgs:\n - ch: channel to get, by default(value is 0) means the first channel\n\n\nReturns: height\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int height()", + "py_def": "def height(self) -> int" + }, + "size": { + "type": "func", + "name": "size", + "doc": { + "brief": "Get display size", + "param": { + "ch": "channel to get, by default(value is 0) means the first channel" + }, + "return": "size A list type in MaixPy, [width, height]", + "maixpy": "maix.display.Display.size", + "py_doc": "Get display size\n\nArgs:\n - ch: channel to get, by default(value is 0) means the first channel\n\n\nReturns: size A list type in MaixPy, [width, height]\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector size()", + "py_def": "def size(self) -> list[int]" + }, + "format": { + "type": "func", + "name": "format", + "doc": { + "brief": "Get display format", + "return": "format", + "maixpy": "maix.display.Display.format", + "py_doc": "Get display format\n\nReturns: format\n" + }, + "args": [], + "ret_type": "image::Format", + "static": false, + "def": "image::Format format()", + "py_def": "def format(self) -> maix.image.Format" + }, + "open": { + "type": "func", + "name": "open", + "doc": { + "brief": "open display device, if already opened, will return err.ERR_NONE.", + "param": { + "width": "display width, default is -1, means auto, mostly means max width of display support", + "height": "display height, default is -1, means auto, mostly means max height of display support", + "format": "display output format, default is RGB888" + }, + "return": "error code", + "maixpy": "maix.display.Display.open", + "py_doc": "open display device, if already opened, will return err.ERR_NONE.\n\nArgs:\n - width: display width, default is -1, means auto, mostly means max width of display support\n - height: display height, default is -1, means auto, mostly means max height of display support\n - format: display output format, default is RGB888\n\n\nReturns: error code\n" + }, + "args": [ + [ + "int", + "width", + "-1" + ], + [ + "int", + "height", + "-1" + ], + [ + "image::Format", + "format", + "image::FMT_INVALID" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err open(int width = -1, int height = -1, image::Format format = image::FMT_INVALID)", + "py_def": "def open(self, width: int = -1, height: int = -1, format: maix.image.Format = ...) -> maix.err.Err" + }, + "close": { + "type": "func", + "name": "close", + "doc": { + "brief": "close display device", + "return": "error code", + "maixpy": "maix.display.Display.close", + "py_doc": "close display device\n\nReturns: error code\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err close()", + "py_def": "def close(self) -> maix.err.Err" + }, + "add_channel": { + "type": "func", + "name": "add_channel", + "doc": { + "brief": "Add a new channel and return a new Display object, you can use close() to close this channel.", + "param": { + "width": "display width, default is -1, means auto, mostly means max width of display support", + "height": "display height, default is -1, means auto, mostly means max height of display support", + "format": "display output format, default is RGB888", + "open": "If true, display will automatically call open() after creation. default is true." + }, + "return": "new Display object", + "maixpy": "maix.display.Display.add_channel", + "py_doc": "Add a new channel and return a new Display object, you can use close() to close this channel.\n\nArgs:\n - width: display width, default is -1, means auto, mostly means max width of display support\n - height: display height, default is -1, means auto, mostly means max height of display support\n - format: display output format, default is RGB888\n - open: If true, display will automatically call open() after creation. default is true.\n\n\nReturns: new Display object\n" + }, + "args": [ + [ + "int", + "width", + "-1" + ], + [ + "int", + "height", + "-1" + ], + [ + "image::Format", + "format", + "image::FMT_RGB888" + ], + [ + "bool", + "open", + "true" + ] + ], + "ret_type": "display::Display*", + "static": false, + "def": "display::Display *add_channel(int width = -1, int height = -1, image::Format format = image::FMT_RGB888, bool open = true)", + "py_def": "def add_channel(self, width: int = -1, height: int = -1, format: maix.image.Format = ..., open: bool = True) -> Display" + }, + "is_opened": { + "type": "func", + "name": "is_opened", + "doc": { + "brief": "check display device is opened or not", + "return": "opened or not, bool type", + "maixpy": "maix.display.Display.is_opened", + "py_doc": "check display device is opened or not\n\nReturns: opened or not, bool type\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_opened()", + "py_def": "def is_opened(self) -> bool" + }, + "is_closed": { + "type": "func", + "name": "is_closed", + "doc": { + "brief": "check display device is closed or not", + "return": "closed or not, bool type", + "maixpy": "maix.display.Display.is_closed", + "py_doc": "check display device is closed or not\n\nReturns: closed or not, bool type\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_closed()", + "py_def": "def is_closed(self) -> bool" + }, + "show": { + "type": "func", + "name": "show", + "doc": { + "brief": "show image on display device, and will also send to MaixVision work station if connected.", + "param": { + "img": "image to show, image.Image object,\nif the size of image smaller than display size, will show in the center of display;\nif the size of image bigger than display size, will auto resize to display size and keep ratio, fill blank with black color.", + "fit": "image in screen fit mode, by default(value is image.FIT_CONTAIN), @see image.Fit for more details\ne.g. image.FIT_CONTAIN means resize image to fit display size and keep ratio, fill blank with black color." + }, + "return": "error code", + "maixpy": "maix.display.Display.show", + "py_doc": "show image on display device, and will also send to MaixVision work station if connected.\n\nArgs:\n - img: image to show, image.Image object,\nif the size of image smaller than display size, will show in the center of display;\nif the size of image bigger than display size, will auto resize to display size and keep ratio, fill blank with black color.\n - fit: image in screen fit mode, by default(value is image.FIT_CONTAIN), @see image.Fit for more details\ne.g. image.FIT_CONTAIN means resize image to fit display size and keep ratio, fill blank with black color.\n\n\nReturns: error code\n" + }, + "args": [ + [ + "image::Image &", + "img", + null + ], + [ + "image::Fit", + "fit", + "image::FIT_CONTAIN" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err show(image::Image &img, image::Fit fit = image::FIT_CONTAIN)", + "py_def": "def show(self, img: maix.image.Image, fit: maix.image.Fit = ...) -> maix.err.Err" + }, + "device": { + "type": "func", + "name": "device", + "doc": { + "brief": "Get display device path", + "return": "display device path", + "maixpy": "maix.display.Display.device", + "py_doc": "Get display device path\n\nReturns: display device path\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string device()", + "py_def": "def device(self) -> str" + }, + "set_backlight": { + "type": "func", + "name": "set_backlight", + "doc": { + "brief": "Set display backlight", + "param": { + "value": "backlight value, float type, range is [0, 100]" + }, + "maixpy": "maix.display.Display.set_backlight", + "py_doc": "Set display backlight\n\nArgs:\n - value: backlight value, float type, range is [0, 100]\n" + }, + "args": [ + [ + "float", + "value", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_backlight(float value)", + "py_def": "def set_backlight(self, value: float) -> None" + }, + "get_backlight": { + "type": "func", + "name": "get_backlight", + "doc": { + "brief": "Get display backlight", + "return": "value backlight value, float type, range is [0, 100]", + "maixpy": "maix.display.Display.get_backlight", + "py_doc": "Get display backlight\n\nReturns: value backlight value, float type, range is [0, 100]\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float get_backlight()", + "py_def": "def get_backlight(self) -> float" + }, + "set_hmirror": { + "type": "func", + "name": "set_hmirror", + "doc": { + "brief": "Set display mirror", + "param": { + "en": "enable/disable mirror" + }, + "maixpy": "maix.display.Display.set_hmirror", + "py_doc": "Set display mirror\n\nArgs:\n - en: enable/disable mirror\n" + }, + "args": [ + [ + "bool", + "en", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err set_hmirror(bool en)", + "py_def": "def set_hmirror(self, en: bool) -> maix.err.Err" + }, + "set_vflip": { + "type": "func", + "name": "set_vflip", + "doc": { + "brief": "Set display flip", + "param": { + "en": "enable/disable flip" + }, + "maixpy": "maix.display.Display.set_vflip", + "py_doc": "Set display flip\n\nArgs:\n - en: enable/disable flip\n" + }, + "args": [ + [ + "bool", + "en", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err set_vflip(bool en)", + "py_def": "def set_vflip(self, en: bool) -> maix.err.Err" + } + }, + "def": "class Display" + }, + "send_to_maixvision": { + "type": "func", + "name": "send_to_maixvision", + "doc": { + "brief": "Send image to MaixVision work station if connected.\\nIf you want to debug your program an don't want to initialize display, use this method.", + "param": { + "img": "image to send, image.Image object" + }, + "maixpy": "maix.display.send_to_maixvision", + "py_doc": "Send image to MaixVision work station if connected.\nIf you want to debug your program an don't want to initialize display, use this method.\n\nArgs:\n - img: image to send, image.Image object\n" + }, + "args": [ + [ + "image::Image &", + "img", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void send_to_maixvision(image::Image &img)" + } + }, + "auto_add": false + }, + "video": { + "type": "module", + "doc": { + "brief": "maix.video module", + "maixpy": "maix.video", + "py_doc": "maix.video module" + }, + "members": { + "VideoType": { + "type": "enum", + "name": "VideoType", + "doc": { + "brief": "Video type", + "maixpy": "maix.video.VideoType", + "py_doc": "Video type" + }, + "values": [ + [ + "VIDEO_NONE", + "0", + "format invalid" + ], + [ + "VIDEO_ENC_H265_CBR", + "", + "" + ], + [ + "VIDEO_ENC_MP4_CBR", + "", + "" + ], + [ + "VIDEO_DEC_H265_CBR", + "", + "" + ], + [ + "VIDEO_DEC_MP4_CBR", + "", + "" + ] + ], + "def": "enum VideoType\n {\n VIDEO_NONE = 0, // format invalid\n VIDEO_ENC_H265_CBR,\n VIDEO_ENC_MP4_CBR,\n VIDEO_DEC_H265_CBR,\n VIDEO_DEC_MP4_CBR,\n }" + }, + "Frame": { + "type": "class", + "name": "Frame", + "doc": { + "brief": "Frame class", + "maixpy": "maix.video.Frame", + "py_doc": "Frame class" + }, + "members": {}, + "def": "class Frame" + }, + "Packet": { + "type": "class", + "name": "Packet", + "doc": { + "brief": "Packet class", + "maixpy": "maix.video.Packet", + "py_doc": "Packet class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Packet", + "doc": { + "brief": "Packet number (pair of numerator and denominator).", + "param": { + "data": "src data pointer, use pointers directly without copying.\nNote: this object will try to free this memory", + "len": "data len", + "pts": "presentation time stamp. unit: time_base", + "dts": "decoding time stamp. unit: time_base", + "duration": "packet display time. unit: time_base" + }, + "maixpy": "maix.video.Packet.__init__", + "maixcdk": "maix.video.Packet.Packet", + "py_doc": "Packet number (pair of numerator and denominator).\n\nArgs:\n - data: src data pointer, use pointers directly without copying.\nNote: this object will try to free this memory\n - len: data len\n - pts: presentation time stamp. unit: time_base\n - dts: decoding time stamp. unit: time_base\n - duration: packet display time. unit: time_base\n" + }, + "args": [ + [ + "uint8_t *", + "data", + null + ], + [ + "int", + "len", + null + ], + [ + "uint64_t", + "pts", + "-1" + ], + [ + "uint64_t", + "dts", + "-1" + ], + [ + "int64_t", + "duration", + "0" + ] + ], + "ret_type": null, + "static": false, + "def": "Packet(uint8_t *data, int len, uint64_t pts = -1, uint64_t dts = -1, int64_t duration = 0)" + }, + "get": { + "type": "func", + "name": "get", + "doc": { + "brief": "Get raw data of packet", + "return": "raw data", + "maixpy": "maix.video.Packet.get", + "py_doc": "Get raw data of packet\n\nReturns: raw data\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector get()" + }, + "data": { + "type": "func", + "name": "data", + "doc": { + "brief": "Get raw data of packet", + "return": "raw data", + "maixpy": "maix.video.Packet.data", + "py_doc": "Get raw data of packet\n\nReturns: raw data\n" + }, + "args": [], + "ret_type": "uint8_t*", + "static": false, + "def": "uint8_t *data()" + }, + "data_size": { + "type": "func", + "name": "data_size", + "doc": { + "brief": "Get raw data size of packet", + "return": "size of raw data", + "maixpy": "maix.video.Packet.data_size", + "py_doc": "Get raw data size of packet\n\nReturns: size of raw data\n" + }, + "args": [], + "ret_type": "size_t", + "static": false, + "def": "size_t data_size()" + }, + "is_valid": { + "type": "func", + "name": "is_valid", + "doc": { + "brief": "Check packet is valid", + "return": "true, packet is valid; false, packet is invalid", + "maixpy": "maix.video.Packet.is_valid", + "py_doc": "Check packet is valid\n\nReturns: true, packet is valid; false, packet is invalid\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_valid()" + }, + "set_pts": { + "type": "func", + "name": "set_pts", + "doc": { + "brief": "Set pts", + "param": { + "pts": "presentation time stamp. unit: time_base" + }, + "return": "true, packet is valid; false, packet is invalid", + "maixpy": "maix.video.Packet.set_pts", + "py_doc": "Set pts\n\nArgs:\n - pts: presentation time stamp. unit: time_base\n\n\nReturns: true, packet is valid; false, packet is invalid\n" + }, + "args": [ + [ + "uint64_t", + "pts", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_pts(uint64_t pts)" + }, + "set_dts": { + "type": "func", + "name": "set_dts", + "doc": { + "brief": "Set dts", + "param": { + "dts": "decoding time stamp. unit: time_base" + }, + "return": "true, packet is valid; false, packet is invalid", + "maixpy": "maix.video.Packet.set_dts", + "py_doc": "Set dts\n\nArgs:\n - dts: decoding time stamp. unit: time_base\n\n\nReturns: true, packet is valid; false, packet is invalid\n" + }, + "args": [ + [ + "uint64_t", + "dts", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_dts(uint64_t dts)" + }, + "set_duration": { + "type": "func", + "name": "set_duration", + "doc": { + "brief": "Set duration", + "param": { + "duration": "packet display time. unit: time_base" + }, + "return": "true, packet is valid; false, packet is invalid", + "maixpy": "maix.video.Packet.set_duration", + "py_doc": "Set duration\n\nArgs:\n - duration: packet display time. unit: time_base\n\n\nReturns: true, packet is valid; false, packet is invalid\n" + }, + "args": [ + [ + "uint64_t", + "duration", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_duration(uint64_t duration)" + } + }, + "def": "class Packet" + }, + "Video": { + "type": "class", + "name": "Video", + "doc": { + "brief": "Video class", + "maixpy": "maix.video.Video", + "py_doc": "Video class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Video", + "doc": { + "brief": "Construct a new Video object", + "param": { + "path": "video path. the path determines the location where you load or save the file, if path is none, the video module will not save or load file.\nxxx.h265 means video format is H265, xxx.mp4 means video format is MP4", + "width": "picture width. this value may be set automatically. default is 2560.", + "height": "picture height. this value may be set automatically. default is 1440.", + "format": "picture pixel format. this value may be set automatically. default is FMT_YVU420SP.", + "time_base": "frame time base. time_base default is 30, means 1/30 ms", + "framerate": "frame rate. framerate default is 30, means 30 frames per second\nfor video. 1/time_base is not the average frame rate if the frame rate is not constant.", + "capture": "enable capture, if true, you can use capture() function to get an image object", + "open": "If true, video will automatically call open() after creation. default is true." + }, + "maixpy": "maix.video.Video.__init__", + "maixcdk": "maix.video.Video.Video", + "py_doc": "Construct a new Video object\n\nArgs:\n - path: video path. the path determines the location where you load or save the file, if path is none, the video module will not save or load file.\nxxx.h265 means video format is H265, xxx.mp4 means video format is MP4\n - width: picture width. this value may be set automatically. default is 2560.\n - height: picture height. this value may be set automatically. default is 1440.\n - format: picture pixel format. this value may be set automatically. default is FMT_YVU420SP.\n - time_base: frame time base. time_base default is 30, means 1/30 ms\n - framerate: frame rate. framerate default is 30, means 30 frames per second\nfor video. 1/time_base is not the average frame rate if the frame rate is not constant.\n - capture: enable capture, if true, you can use capture() function to get an image object\n - open: If true, video will automatically call open() after creation. default is true.\n" + }, + "args": [ + [ + "std::string", + "path", + "std::string()" + ], + [ + "int", + "width", + "2560" + ], + [ + "int", + "height", + "1440" + ], + [ + "image::Format", + "format", + "image::Format::FMT_YVU420SP" + ], + [ + "int", + "time_base", + "30" + ], + [ + "int", + "framerate", + "30" + ], + [ + "bool", + "capture", + "false" + ], + [ + "bool", + "open", + "true" + ] + ], + "ret_type": null, + "static": false, + "def": "Video(std::string path = std::string(), int width = 2560, int height = 1440, image::Format format = image::Format::FMT_YVU420SP, int time_base = 30, int framerate = 30, bool capture = false, bool open = true)", + "py_def": "def __init__(self, path: str = '', width: int = 2560, height: int = 1440, format: maix.image.Format = ..., time_base: int = 30, framerate: int = 30, capture: bool = False, open: bool = True) -> None" + }, + "open": { + "type": "func", + "name": "open", + "doc": { + "brief": "Open video and run", + "param": { + "path": "video path. the path determines the location where you load or save the file, if path is none, the video module will not save or load file.\nxxx.h265 means video format is H265, xxx.mp4 means video format is MP4", + "fps": "video fps" + }, + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.video.Video.open", + "py_doc": "Open video and run\n\nArgs:\n - path: video path. the path determines the location where you load or save the file, if path is none, the video module will not save or load file.\nxxx.h265 means video format is H265, xxx.mp4 means video format is MP4\n - fps: video fps\n\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [ + [ + "std::string", + "path", + "std::string()" + ], + [ + "double", + "fps", + "30.0" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err open(std::string path = std::string(), double fps = 30.0)", + "py_def": "def open(self, path: str = '', fps: float = 30.0) -> maix.err.Err" + }, + "close": { + "type": "func", + "name": "close", + "doc": { + "brief": "Close video", + "maixpy": "maix.video.Video.close", + "py_doc": "Close video" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void close()", + "py_def": "def close(self) -> None" + }, + "bind_camera": { + "type": "func", + "name": "bind_camera", + "doc": { + "brief": "Bind camera", + "param": { + "camera": "camera object" + }, + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.video.Video.bind_camera", + "py_doc": "Bind camera\n\nArgs:\n - camera: camera object\n\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [ + [ + "camera::Camera *", + "camera", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err bind_camera(camera::Camera *camera)", + "py_def": "def bind_camera(self, camera: maix.camera.Camera) -> maix.err.Err" + }, + "encode": { + "type": "func", + "name": "encode", + "doc": { + "brief": "Encode image.", + "param": { + "img": "the image will be encode.\nif the img is NULL, this function will try to get image from camera, you must use bind_camera() function to bind the camera." + }, + "return": "encode result", + "maixpy": "maix.video.Video.encode", + "py_doc": "Encode image.\n\nArgs:\n - img: the image will be encode.\nif the img is NULL, this function will try to get image from camera, you must use bind_camera() function to bind the camera.\n\n\nReturns: encode result\n" + }, + "args": [ + [ + "image::Image *", + "img", + "maix::video::Video::NoneImage" + ] + ], + "ret_type": "video::Packet*", + "static": false, + "def": "video::Packet *encode(image::Image *img = maix::video::Video::NoneImage)", + "py_def": "def encode(self, img: maix.image.Image = ...) -> Packet" + }, + "decode": { + "type": "func", + "name": "decode", + "doc": { + "brief": "Decode frame", + "param": { + "frame": "the frame will be decode" + }, + "return": "decode result", + "maixpy": "maix.video.Video.decode", + "py_doc": "Decode frame\n\nArgs:\n - frame: the frame will be decode\n\n\nReturns: decode result\n" + }, + "args": [ + [ + "video::Frame *", + "frame", + "nullptr" + ] + ], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *decode(video::Frame *frame = nullptr)", + "py_def": "def decode(self, frame: Frame = None) -> maix.image.Image" + }, + "finish": { + "type": "func", + "name": "finish", + "doc": { + "brief": "Encode or decode finish", + "return": "error code", + "maixpy": "maix.video.Video.finish", + "py_doc": "Encode or decode finish\n\nReturns: error code\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err finish()", + "py_def": "def finish(self) -> maix.err.Err" + }, + "capture": { + "type": "func", + "name": "capture", + "doc": { + "brief": "Capture image", + "attention": "Each time encode is called, the last captured image will be released.", + "return": "error code", + "maixpy": "maix.video.Video.capture", + "py_doc": "Capture image\n\nReturns: error code\n" + }, + "args": [], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *capture()", + "py_def": "def capture(self) -> maix.image.Image" + }, + "is_recording": { + "type": "func", + "name": "is_recording", + "doc": { + "brief": "Check if video is recording", + "return": "true if video is recording, false if not", + "maixpy": "maix.video.Video.is_recording", + "py_doc": "Check if video is recording\n\nReturns: true if video is recording, false if not\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_recording()", + "py_def": "def is_recording(self) -> bool" + }, + "is_opened": { + "type": "func", + "name": "is_opened", + "doc": { + "brief": "Check if video is opened", + "return": "true if video is opened, false if not", + "maixpy": "maix.video.Video.is_opened", + "py_doc": "Check if video is opened\n\nReturns: true if video is opened, false if not\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_opened()", + "py_def": "def is_opened(self) -> bool" + }, + "is_closed": { + "type": "func", + "name": "is_closed", + "doc": { + "brief": "check video device is closed or not", + "return": "closed or not, bool type", + "maixpy": "maix.video.Video.is_closed", + "py_doc": "check video device is closed or not\n\nReturns: closed or not, bool type\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_closed()", + "py_def": "def is_closed(self) -> bool" + }, + "width": { + "type": "func", + "name": "width", + "doc": { + "brief": "Get video width", + "return": "video width", + "maixpy": "maix.video.Video.width", + "py_doc": "Get video width\n\nReturns: video width\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int width()", + "py_def": "def width(self) -> int" + }, + "height": { + "type": "func", + "name": "height", + "doc": { + "brief": "Get video height", + "return": "video height", + "maixpy": "maix.video.Video.height", + "py_doc": "Get video height\n\nReturns: video height\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int height()", + "py_def": "def height(self) -> int" + } + }, + "def": "class Video" + } + }, + "auto_add": false + }, + "touchscreen": { + "type": "module", + "doc": { + "brief": "maix.touchscreen module" + }, + "members": { + "TouchScreen": { + "type": "class", + "name": "TouchScreen", + "doc": { + "brief": "TouchScreen class", + "maixpy": "maix.touchscreen.TouchScreen", + "py_doc": "TouchScreen class" + }, + "members": { + "__init__": { + "type": "func", + "name": "TouchScreen", + "doc": { + "brief": "Construct a new TouchScreen object", + "param": { + "device": "touchscreen device path, you can get devices by list_devices method, by default(value is NULL(None in MaixPy)) means the first device", + "open": "If true, touchscreen will automatically call open() after creation. default is true." + }, + "maixpy": "maix.touchscreen.TouchScreen.__init__", + "maixcdk": "maix.touchscreen.TouchScreen.TouchScreen", + "py_doc": "Construct a new TouchScreen object\n\nArgs:\n - device: touchscreen device path, you can get devices by list_devices method, by default(value is NULL(None in MaixPy)) means the first device\n - open: If true, touchscreen will automatically call open() after creation. default is true.\n" + }, + "args": [ + [ + "const std::string &", + "device", + "\"\"" + ], + [ + "bool", + "open", + "true" + ] + ], + "ret_type": null, + "static": false, + "def": "TouchScreen(const std::string &device = \"\", bool open = true)" + }, + "open": { + "type": "func", + "name": "open", + "doc": { + "brief": "open touchscreen device", + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.touchscreen.TouchScreen.open", + "py_doc": "open touchscreen device\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err open()" + }, + "close": { + "type": "func", + "name": "close", + "doc": { + "brief": "close touchscreen device", + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.touchscreen.TouchScreen.close", + "py_doc": "close touchscreen device\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err close()" + }, + "read": { + "type": "func", + "name": "read", + "doc": { + "brief": "read touchscreen device", + "attention": "This method will discard same event in buffer, that is:\nif too many move event in buffer when call this method, it will only return the last one,\nand if read pressed or released event, it will return immediately.", + "return": "Returns a list include x, y, pressed state", + "maixpy": "maix.touchscreen.TouchScreen.read", + "py_doc": "read touchscreen device\n\nReturns: Returns a list include x, y, pressed state\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector read()", + "overload": [ + { + "type": "func", + "name": "read0", + "doc": { + "brief": "read touchscreen device", + "attention": "This method will return immediately if have event, so it's better to use available() to check if have more event in buffer,\nor too much event in buffer when your program call this read() interval is too long will make your program slow.", + "return": "Returns a list include x, y, pressed state", + "maixpy": "maix.touchscreen.TouchScreen.read", + "py_doc": "read touchscreen device\n\nReturns: Returns a list include x, y, pressed state\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector read0()" + } + ] + }, + "available": { + "type": "func", + "name": "available", + "doc": { + "brief": "If we need to read from touchscreen, for event driven touchscreen means have event or not", + "param": { + "timeout": "-1 means block, 0 means no block, >0 means timeout, default is 0, unit is ms." + }, + "return": "true if need to read(have event), false if not", + "maixpy": "maix.touchscreen.TouchScreen.available", + "py_doc": "If we need to read from touchscreen, for event driven touchscreen means have event or not\n\nArgs:\n - timeout: -1 means block, 0 means no block, >0 means timeout, default is 0, unit is ms.\n\n\nReturns: true if need to read(have event), false if not\n" + }, + "args": [ + [ + "int", + "timeout", + "0" + ] + ], + "ret_type": "bool", + "static": false, + "def": "bool available(int timeout = 0)" + }, + "is_opened": { + "type": "func", + "name": "is_opened", + "doc": { + "brief": "Check if touchscreen is opened", + "return": "true if touchscreen is opened, false if not", + "maixpy": "maix.touchscreen.TouchScreen.is_opened", + "py_doc": "Check if touchscreen is opened\n\nReturns: true if touchscreen is opened, false if not\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_opened()" + } + }, + "def": "class TouchScreen" + } + }, + "auto_add": true + }, + "rtsp": { + "type": "module", + "doc": { + "brief": "maix.rtsp module" + }, + "members": { + "RtspStreamType": { + "type": "enum", + "name": "RtspStreamType", + "doc": { + "brief": "The stream type of rtsp", + "maixpy": "maix.rtsp.RtspStreamType", + "py_doc": "The stream type of rtsp" + }, + "values": [ + [ + "RTSP_STREAM_NONE", + "0", + "format invalid" + ], + [ + "RTSP_STREAM_H265", + "", + "" + ] + ], + "def": "enum RtspStreamType\n {\n RTSP_STREAM_NONE = 0, // format invalid\n RTSP_STREAM_H265,\n }" + }, + "Region": { + "type": "class", + "name": "Region", + "doc": { + "brief": "Region class", + "maixpy": "maix.rtsp.Region", + "py_doc": "Region class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Region", + "doc": { + "brief": "Construct a new Region object", + "param": { + "x": "region coordinate x", + "y": "region coordinate y", + "width": "region width", + "height": "region height", + "format": "region format", + "camera": "bind region to camera" + }, + "maixpy": "maix.rtsp.Region.__init__", + "maixcdk": "maix.rtsp.Region.Region", + "py_doc": "Construct a new Region object\n\nArgs:\n - x: region coordinate x\n - y: region coordinate y\n - width: region width\n - height: region height\n - format: region format\n - camera: bind region to camera\n" + }, + "args": [ + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "int", + "width", + null + ], + [ + "int", + "height", + null + ], + [ + "image::Format", + "format", + null + ], + [ + "camera::Camera *", + "camera", + null + ] + ], + "ret_type": null, + "static": false, + "def": "Region(int x, int y, int width, int height, image::Format format, camera::Camera *camera)", + "py_def": "def __init__(self, x: int, y: int, width: int, height: int, format: maix.image.Format, camera: maix.camera.Camera) -> None" + }, + "get_canvas": { + "type": "func", + "name": "get_canvas", + "doc": { + "brief": "Return an image object from region", + "return": "image object", + "maixpy": "maix.rtsp.Region.get_canvas", + "py_doc": "Return an image object from region\n\nReturns: image object\n" + }, + "args": [], + "ret_type": "image::Image*", + "static": false, + "def": "image::Image *get_canvas()", + "py_def": "def get_canvas(self) -> maix.image.Image" + }, + "update_canvas": { + "type": "func", + "name": "update_canvas", + "doc": { + "brief": "Update canvas", + "return": "error code", + "maixpy": "maix.rtsp.Region.update_canvas", + "py_doc": "Update canvas\n\nReturns: error code\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err update_canvas()", + "py_def": "def update_canvas(self) -> maix.err.Err" + } + }, + "def": "class Region" + }, + "Rtsp": { + "type": "class", + "name": "Rtsp", + "doc": { + "brief": "Rtsp class", + "maixpy": "maix.rtsp.Rtsp", + "py_doc": "Rtsp class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Rtsp", + "doc": { + "brief": "Construct a new Video object", + "param": { + "ip": "rtsp ip", + "port": "rtsp port", + "fps": "rtsp fps", + "stream_type": "rtsp stream type" + }, + "maixpy": "maix.rtsp.Rtsp.__init__", + "maixcdk": "maix.rtsp.Rtsp.Rtsp", + "py_doc": "Construct a new Video object\n\nArgs:\n - ip: rtsp ip\n - port: rtsp port\n - fps: rtsp fps\n - stream_type: rtsp stream type\n" + }, + "args": [ + [ + "std::string", + "ip", + "std::string()" + ], + [ + "int", + "port", + "8554" + ], + [ + "int", + "fps", + "30" + ], + [ + "rtsp::RtspStreamType", + "stream_type", + "rtsp::RtspStreamType::RTSP_STREAM_H265" + ] + ], + "ret_type": null, + "static": false, + "def": "Rtsp(std::string ip = std::string(), int port = 8554, int fps = 30, rtsp::RtspStreamType stream_type = rtsp::RtspStreamType::RTSP_STREAM_H265)" + }, + "start": { + "type": "func", + "name": "start", + "doc": { + "brief": "start rtsp", + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.rtsp.Rtsp.start", + "py_doc": "start rtsp\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err start()", + "overload": [ + { + "type": "func", + "name": "stop", + "doc": { + "brief": "stop rtsp", + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.rtsp.Rtsp.start", + "py_doc": "stop rtsp\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err stop()" + } + ] + }, + "bind_camera": { + "type": "func", + "name": "bind_camera", + "doc": { + "brief": "Bind camera", + "param": { + "camera": "camera object" + }, + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.rtsp.Rtsp.bind_camera", + "py_doc": "Bind camera\n\nArgs:\n - camera: camera object\n\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [ + [ + "camera::Camera *", + "camera", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err bind_camera(camera::Camera *camera)" + }, + "write": { + "type": "func", + "name": "write", + "doc": { + "brief": "Write data to rtsp", + "param": { + "type": "rtsp stream type", + "data": "rtsp stream data", + "fps": "rtsp stream data size" + }, + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.rtsp.Rtsp.write", + "py_doc": "Write data to rtsp\n\nArgs:\n - type: rtsp stream type\n - data: rtsp stream data\n - fps: rtsp stream data size\n\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [ + [ + "video::Frame &", + "stream", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err write(video::Frame &stream)" + }, + "get_url": { + "type": "func", + "name": "get_url", + "doc": { + "brief": "Get url of rtsp", + "return": "url of rtsp", + "maixpy": "maix.rtsp.Rtsp.get_url", + "py_doc": "Get url of rtsp\n\nReturns: url of rtsp\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string get_url()" + }, + "to_camera": { + "type": "func", + "name": "to_camera", + "doc": { + "brief": "Get camera object from rtsp", + "return": "camera object", + "maixpy": "maix.rtsp.Rtsp.to_camera", + "py_doc": "Get camera object from rtsp\n\nReturns: camera object\n" + }, + "args": [], + "ret_type": "camera::Camera*", + "static": false, + "def": "camera::Camera *to_camera()" + }, + "rtsp_is_start": { + "type": "func", + "name": "rtsp_is_start", + "doc": { + "brief": "return rtsp start status", + "return": "true means rtsp is start, false means rtsp is stop.", + "maixpy": "maix.rtsp.Rtsp.rtsp_is_start", + "py_doc": "return rtsp start status\n\nReturns: true means rtsp is start, false means rtsp is stop.\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool rtsp_is_start()" + }, + "add_region": { + "type": "func", + "name": "add_region", + "doc": { + "brief": "return a region object, you can draw image on the region.", + "param": { + "x": "region coordinate x", + "y": "region coordinate y", + "width": "region width", + "height": "region height", + "format": "region format, support Format::FMT_BGRA8888 only" + }, + "return": "the reigon object", + "maixpy": "maix.rtsp.Rtsp.add_region", + "py_doc": "return a region object, you can draw image on the region.\n\nArgs:\n - x: region coordinate x\n - y: region coordinate y\n - width: region width\n - height: region height\n - format: region format, support Format::FMT_BGRA8888 only\n\n\nReturns: the reigon object\n" + }, + "args": [ + [ + "int", + "x", + null + ], + [ + "int", + "y", + null + ], + [ + "int", + "width", + null + ], + [ + "int", + "height", + null + ], + [ + "image::Format", + "format", + "image::Format::FMT_BGRA8888" + ] + ], + "ret_type": "rtsp::Region*", + "static": false, + "def": "rtsp::Region *add_region(int x, int y, int width, int height, image::Format format = image::Format::FMT_BGRA8888)" + }, + "update_region": { + "type": "func", + "name": "update_region", + "doc": { + "brief": "update and show region", + "return": "error code", + "maixpy": "maix.rtsp.Rtsp.update_region", + "py_doc": "update and show region\n\nReturns: error code\n" + }, + "args": [ + [ + "rtsp::Region &", + "region", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err update_region(rtsp::Region ®ion)" + } + }, + "def": "class Rtsp" + } + }, + "auto_add": true + }, + "network": { + "type": "module", + "doc": { + "brief": "maix.network module" + }, + "members": { + "wifi": { + "type": "module", + "doc": { + "brief": "maix.network.wifi module" + }, + "members": { + "AP_Info": { + "type": "class", + "name": "AP_Info", + "doc": { + "brief": "WiFi AP info", + "maixpy": "maix.network.wifi.AP_Info", + "py_doc": "WiFi AP info" + }, + "members": { + "ssid": { + "type": "var", + "name": "ssid", + "doc": { + "brief": "WiFi AP info SSID", + "maixpy": "maix.network.wifi.AP_Info.ssid", + "py_doc": "WiFi AP info SSID" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector ssid" + }, + "bssid": { + "type": "var", + "name": "bssid", + "doc": { + "brief": "WiFi AP info BSSID", + "maixpy": "maix.network.wifi.AP_Info.bssid", + "py_doc": "WiFi AP info BSSID" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::string bssid" + }, + "security": { + "type": "var", + "name": "security", + "doc": { + "brief": "WiFi AP info security", + "maixpy": "maix.network.wifi.AP_Info.security", + "py_doc": "WiFi AP info security" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::string security" + }, + "channel": { + "type": "var", + "name": "channel", + "doc": { + "brief": "WiFi AP info channel", + "maixpy": "maix.network.wifi.AP_Info.channel", + "py_doc": "WiFi AP info channel" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int channel" + }, + "frequency": { + "type": "var", + "name": "frequency", + "doc": { + "brief": "WiFi AP info frequency", + "maixpy": "maix.network.wifi.AP_Info.frequency", + "py_doc": "WiFi AP info frequency" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int frequency" + }, + "rssi": { + "type": "var", + "name": "rssi", + "doc": { + "brief": "WiFi AP info rssi", + "maixpy": "maix.network.wifi.AP_Info.rssi", + "py_doc": "WiFi AP info rssi" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int rssi" + }, + "ssid_str": { + "type": "func", + "name": "ssid_str", + "doc": { + "brief": "WiFi AP info ssid_str", + "maixpy": "maix.network.wifi.AP_Info.ssid_str", + "py_doc": "WiFi AP info ssid_str" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string ssid_str()", + "py_def": "def ssid_str(self) -> str" + } + }, + "def": "class AP_Info" + }, + "list_devices": { + "type": "func", + "name": "list_devices", + "doc": { + "brief": "List WiFi interfaces", + "return": "WiFi interface list, string type", + "maixpy": "maix.network.wifi.list_devices", + "py_doc": "List WiFi interfaces\n\nReturns: WiFi interface list, string type\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector list_devices()", + "py_def": "def list_devices() -> list[str]" + }, + "Wifi": { + "type": "class", + "name": "Wifi", + "doc": { + "brief": "Wifi class", + "maixpy": "maix.network.wifi.Wifi", + "py_doc": "Wifi class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Wifi", + "doc": { + "brief": "Wifi class", + "param": { + "iface": "wifi interface name, default is wlan0" + }, + "maixpy": "maix.network.wifi.Wifi.__init__", + "maixcdk": "maix.network.wifi.Wifi.Wifi", + "py_doc": "Wifi class\n\nArgs:\n - iface: wifi interface name, default is wlan0\n" + }, + "args": [ + [ + "std::string", + "iface", + "\"wlan0\"" + ] + ], + "ret_type": null, + "static": false, + "def": "Wifi(std::string iface = \"wlan0\")" + }, + "get_ip": { + "type": "func", + "name": "get_ip", + "doc": { + "brief": "Get current WiFi ip", + "return": "ip, string type, if network not connected, will return empty string.", + "maixpy": "maix.network.wifi.Wifi.get_ip", + "py_doc": "Get current WiFi ip\n\nReturns: ip, string type, if network not connected, will return empty string.\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string get_ip()" + }, + "get_mac": { + "type": "func", + "name": "get_mac", + "doc": { + "brief": "Get current WiFi MAC address", + "return": "ip, string type.", + "maixpy": "maix.network.wifi.Wifi.get_mac", + "py_doc": "Get current WiFi MAC address\n\nReturns: ip, string type.\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string get_mac()" + }, + "get_gateway": { + "type": "func", + "name": "get_gateway", + "doc": { + "brief": "Get current WiFi ip", + "return": "ip, string type, if network not connected, will return empty string.", + "maixpy": "maix.network.wifi.Wifi.get_gateway", + "py_doc": "Get current WiFi ip\n\nReturns: ip, string type, if network not connected, will return empty string.\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string get_gateway()" + }, + "start_scan": { + "type": "func", + "name": "start_scan", + "doc": { + "brief": "WiFi start scan AP info around in background.", + "return": "If success, return err.Err.ERR_NONE, else means failed.", + "maixpy": "maix.network.wifi.Wifi.start_scan", + "py_doc": "WiFi start scan AP info around in background.\n\nReturns: If success, return err.Err.ERR_NONE, else means failed.\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err start_scan()" + }, + "get_scan_result": { + "type": "func", + "name": "get_scan_result", + "doc": { + "brief": "Get WiFi scan AP info.", + "return": "wifi.AP_Info list.", + "maixpy": "maix.network.wifi.Wifi.get_scan_result", + "py_doc": "Get WiFi scan AP info.\n\nReturns: wifi.AP_Info list.\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector get_scan_result()" + }, + "stop_scan": { + "type": "func", + "name": "stop_scan", + "doc": { + "brief": "Stop WiFi scan AP info.", + "maixpy": "maix.network.wifi.Wifi.stop_scan", + "py_doc": "Stop WiFi scan AP info." + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void stop_scan()" + }, + "connect": { + "type": "func", + "name": "connect", + "doc": { + "brief": "Connect to WiFi AP.", + "param": { + "ssid": "SSID of AP", + "password": "password of AP, if no password, leave it empty.", + "wait": "wait for got IP or failed or timeout.", + "timeout": "connect timeout internal, unit second." + }, + "return": "If success, return err.Err.ERR_NONE, else means failed.", + "maixpy": "maix.network.wifi.Wifi.connect", + "py_doc": "Connect to WiFi AP.\n\nArgs:\n - ssid: SSID of AP\n - password: password of AP, if no password, leave it empty.\n - wait: wait for got IP or failed or timeout.\n - timeout: connect timeout internal, unit second.\n\n\nReturns: If success, return err.Err.ERR_NONE, else means failed.\n" + }, + "args": [ + [ + "const std::string &", + "ssid", + null + ], + [ + "const std::string &", + "password", + null + ], + [ + "bool", + "wait", + "true" + ], + [ + "int", + "timeout", + "60" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err connect(const std::string &ssid, const std::string &password, bool wait = true, int timeout = 60)" + }, + "disconnect": { + "type": "func", + "name": "disconnect", + "doc": { + "brief": "Disconnect from WiFi AP.", + "return": "If success, return err.Err.ERR_NONE, else means failed.", + "maixpy": "maix.network.wifi.Wifi.disconnect", + "py_doc": "Disconnect from WiFi AP.\n\nReturns: If success, return err.Err.ERR_NONE, else means failed.\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err disconnect()" + }, + "is_connected": { + "type": "func", + "name": "is_connected", + "doc": { + "brief": "See if WiFi is connected to AP.", + "return": "If connected return true, else false.", + "maixpy": "maix.network.wifi.Wifi.is_connected", + "py_doc": "See if WiFi is connected to AP.\n\nReturns: If connected return true, else false.\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_connected()" + } + }, + "def": "class Wifi" + } + }, + "auto_add": true + }, + "have_network": { + "type": "func", + "name": "have_network", + "doc": { + "brief": "Return if device have network(WiFi/Eth etc.)", + "return": "True if have network, else False.", + "maixpy": "maix.network.have_network", + "py_doc": "Return if device have network(WiFi/Eth etc.)\n\nReturns: True if have network, else False.\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool have_network()", + "py_def": "def have_network() -> bool" + } + }, + "auto_add": true + }, + "comm": { + "type": "module", + "doc": { + "brief": "maix.comm module" + }, + "members": { + "CommProtocol": { + "type": "class", + "name": "CommProtocol", + "doc": { + "brief": "Class for communication protocol", + "maixpy": "maix.comm.CommProtocol", + "py_doc": "Class for communication protocol" + }, + "members": { + "__init__": { + "type": "func", + "name": "CommProtocol", + "doc": { + "brief": "Construct a new CommProtocol object", + "param": { + "buff_size": "buffer size, default to 1024 bytes" + }, + "maixpy": "maix.comm.CommProtocol.__init__", + "maixcdk": "maix.comm.CommProtocol.CommProtocol", + "py_doc": "Construct a new CommProtocol object\n\nArgs:\n - buff_size: buffer size, default to 1024 bytes\n" + }, + "args": [ + [ + "int", + "buff_size", + "1024" + ] + ], + "ret_type": null, + "static": false, + "def": "CommProtocol(int buff_size = 1024)" + }, + "get_msg": { + "type": "func", + "name": "get_msg", + "doc": { + "brief": "Read data to buffer, and try to decode it as maix.protocol.MSG object", + "return": "decoded data, if nullptr, means no valid frame found.\nAttentioin, delete it after use in C++.", + "maixpy": "maix.comm.CommProtocol.get_msg", + "py_doc": "Read data to buffer, and try to decode it as maix.protocol.MSG object\n\nReturns: decoded data, if nullptr, means no valid frame found.\nAttentioin, delete it after use in C++.\n" + }, + "args": [], + "ret_type": "protocol::MSG*", + "static": false, + "def": "protocol::MSG *get_msg()" + }, + "resp_ok": { + "type": "func", + "name": "resp_ok", + "doc": { + "brief": "Send response ok(success) message", + "param": { + "cmd": "CMD value", + "body": "response body, can be null" + }, + "return": "encoded data, if nullptr, means error, and the error code is -err.Err.\nAttentioin, delete it after use in C++.", + "maixpy": "maix.comm.CommProtocol.resp_ok", + "py_doc": "Send response ok(success) message\n\nArgs:\n - cmd: CMD value\n - body: response body, can be null\n\n\nReturns: encoded data, if nullptr, means error, and the error code is -err.Err.\nAttentioin, delete it after use in C++.\n" + }, + "args": [ + [ + "uint8_t", + "cmd", + null + ], + [ + "Bytes *", + "body", + "nullptr" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err resp_ok(uint8_t cmd, Bytes *body = nullptr)" + }, + "report": { + "type": "func", + "name": "report", + "doc": { + "brief": "Send report message", + "param": { + "cmd": "CMD value", + "body": "report body, can be null" + }, + "return": "encoded data, if nullptr, means error, and the error code is -err.Err.\nAttentioin, delete it after use in C++.", + "maixpy": "maix.comm.CommProtocol.report", + "py_doc": "Send report message\n\nArgs:\n - cmd: CMD value\n - body: report body, can be null\n\n\nReturns: encoded data, if nullptr, means error, and the error code is -err.Err.\nAttentioin, delete it after use in C++.\n" + }, + "args": [ + [ + "uint8_t", + "cmd", + null + ], + [ + "Bytes *", + "body", + "nullptr" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err report(uint8_t cmd, Bytes *body = nullptr)" + }, + "resp_err": { + "type": "func", + "name": "resp_err", + "doc": { + "brief": "Encode response error message to buffer", + "param": { + "cmd": "CMD value", + "code": "error code", + "msg": "error message" + }, + "return": "encoded data, if nullptr, means error, and the error code is -err.Err.\nAttentioin, delete it after use in C++.", + "maixpy": "maix.comm.CommProtocol.resp_err", + "py_doc": "Encode response error message to buffer\n\nArgs:\n - cmd: CMD value\n - code: error code\n - msg: error message\n\n\nReturns: encoded data, if nullptr, means error, and the error code is -err.Err.\nAttentioin, delete it after use in C++.\n" + }, + "args": [ + [ + "uint8_t", + "cmd", + null + ], + [ + "err::Err", + "code", + null + ], + [ + "const std::string &", + "msg", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err resp_err(uint8_t cmd, err::Err code, const std::string &msg)" + } + }, + "def": "class CommProtocol" + } + }, + "auto_add": true + }, + "peripheral": { + "type": "module", + "doc": { + "brief": "Chip's peripheral driver", + "maixpy": "maix.peripheral", + "py_doc": "Chip's peripheral driver" + }, + "members": { + "adc": { + "type": "module", + "doc": { + "brief": "maix.peripheral.adc module" + }, + "members": { + "RES_BIT_8": { + "type": "var", + "name": "", + "doc": { + "brief": "8-bit resolution, supported by the actual hardware", + "maixpy": "maix.peripheral.adc.RES_BIT_8", + "py_doc": "8-bit resolution, supported by the actual hardware" + }, + "value": "8", + "static": false, + "readonly": true, + "def": "const int RES_BIT_8 = 8" + }, + "RES_BIT_10": { + "type": "var", + "name": "", + "doc": { + "brief": "10-bit resolution, supported by the actual hardware", + "maixpy": "maix.peripheral.adc.RES_BIT_10", + "py_doc": "10-bit resolution, supported by the actual hardware" + }, + "value": "10", + "static": false, + "readonly": true, + "def": "const int RES_BIT_10 = 10" + }, + "RES_BIT_12": { + "type": "var", + "name": "", + "doc": { + "brief": "12-bit resolution, supported by the actual hardware", + "maixpy": "maix.peripheral.adc.RES_BIT_12", + "py_doc": "12-bit resolution, supported by the actual hardware" + }, + "value": "12", + "static": false, + "readonly": true, + "def": "const int RES_BIT_12 = 12" + }, + "RES_BIT_16": { + "type": "var", + "name": "", + "doc": { + "brief": "16-bit resolution, supported by the actual hardware", + "maixpy": "maix.peripheral.adc.RES_BIT_16", + "py_doc": "16-bit resolution, supported by the actual hardware" + }, + "value": "16", + "static": false, + "readonly": true, + "def": "const int RES_BIT_16 = 16" + }, + "ADC": { + "type": "class", + "name": "ADC", + "doc": { + "brief": "Peripheral adc class", + "maixpy": "maix.peripheral.adc.ADC", + "py_doc": "Peripheral adc class" + }, + "members": { + "__init__": { + "type": "func", + "name": "ADC", + "doc": { + "brief": "ADC constructor", + "param": { + "pin": "direction [in], adc pin, int type", + "resolution": "direction [in], adc resolution. default is -1, means use default resolution\noption:\nresolution = adc.RES_BIT_8, means 8-bit resolution\nresolution = adc.RES_BIT_10, means 10-bit resolution\nresolution = adc.RES_BIT_12, means 12-bit resolution\nresolution = adc.RES_BIT_16, means 16-bit resolution\nthe default resolution is determined by actual hardware.", + "vref": "direction [in], adc refer voltage. default is -1, means use default refer voltage.\nthe default vref is determined by actual hardware. range: [0.0, 10.0]" + }, + "maixpy": "maix.peripheral.adc.ADC.__init__", + "py_doc": "ADC constructor\n\nArgs:\n - pin: direction [in], adc pin, int type\n - resolution: direction [in], adc resolution. default is -1, means use default resolution\noption:\nresolution = adc.RES_BIT_8, means 8-bit resolution\nresolution = adc.RES_BIT_10, means 10-bit resolution\nresolution = adc.RES_BIT_12, means 12-bit resolution\nresolution = adc.RES_BIT_16, means 16-bit resolution\nthe default resolution is determined by actual hardware.\n - vref: direction [in], adc refer voltage. default is -1, means use default refer voltage.\nthe default vref is determined by actual hardware. range: [0.0, 10.0]\n" + }, + "args": [ + [ + "int", + "pin", + null + ], + [ + "int", + "resolution", + null + ], + [ + "float", + "vref", + "-1" + ] + ], + "ret_type": null, + "static": false, + "def": "ADC(int pin, int resolution, float vref = -1)", + "py_def": "def __init__(self, pin: int, resolution: int, vref: float = -1) -> None" + }, + "read": { + "type": "func", + "name": "read", + "doc": { + "brief": "read adc value", + "return": "adc data, int type\nif resolution is 8-bit, return value range is [0, 255]\nif resolution is 10-bit, return value range is [0, 1023]\nif resolution is 12-bit, return value range is [0, 4095]\nif resolution is 16-bit, return value range is [0, 65535]", + "maixpy": "maix.peripheral.adc.ADC.read", + "py_doc": "read adc value\n\nReturns: adc data, int type\nif resolution is 8-bit, return value range is [0, 255]\nif resolution is 10-bit, return value range is [0, 1023]\nif resolution is 12-bit, return value range is [0, 4095]\nif resolution is 16-bit, return value range is [0, 65535]\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int read()", + "py_def": "def read(self) -> int" + }, + "read_vol": { + "type": "func", + "name": "read_vol", + "doc": { + "brief": "read adc voltage", + "return": "adc voltage, float type\u3002the range is [0.0, vref]", + "maixpy": "maix.peripheral.adc.ADC.read_vol", + "py_doc": "read adc voltage\n\nReturns: adc voltage, float type\u3002the range is [0.0, vref]\n" + }, + "args": [], + "ret_type": "float", + "static": false, + "def": "float read_vol()", + "py_def": "def read_vol(self) -> float" + } + }, + "def": "class ADC" + } + }, + "auto_add": true + }, + "spi": { + "type": "module", + "doc": { + "brief": "maix.peripheral.spi module" + }, + "members": { + "Mode": { + "type": "enum", + "name": "Mode", + "doc": { + "brief": "SPI mode enum", + "maixpy": "maix.peripheral.spi.Mode", + "py_doc": "SPI mode enum" + }, + "values": [ + [ + "MASTER", + "0x0", + "spi master mode" + ], + [ + "SLAVE", + "0x1", + "spi slave mode" + ] + ], + "def": "enum Mode\n {\n MASTER = 0x0, // spi master mode\n SLAVE = 0x1, // spi slave mode\n }" + }, + "SPI": { + "type": "class", + "name": "SPI", + "doc": { + "brief": "Peripheral spi class", + "maixpy": "maix.peripheral.spi.SPI", + "py_doc": "Peripheral spi class" + }, + "members": { + "__init__": { + "type": "func", + "name": "SPI", + "doc": { + "brief": "SPI constructor", + "param": { + "id": "direction [in], spi bus id, int type", + "freq": "direction [in], freq of spi, int type", + "soft_cs": "direction [in], not use hardware cs, bool type, if set true, you can operate cs pin use gpio manually.", + "mode": "direction [in], mode of spi, spi.Mode type, spi.Mode.MASTER or spi.Mode.SLAVE.", + "polarity": "direction [in], polarity of spi, 0 means idle level of clock is low, 1 means high, int type, default is 0.", + "phase": "direction [in], phase of spi, 0 means data is captured on the first edge of the SPI clock cycle, 1 means second, int type, default is 0.", + "bits": "direction [in], bits of spi, int type, default is 8.", + "cs": "direction [in], cs pin number, int type, default is 0, if SPI support multi hardware cs, you can set it to other value." + }, + "maixpy": "maix.peripheral.spi.SPI.__init__", + "py_doc": "SPI constructor\n\nArgs:\n - id: direction [in], spi bus id, int type\n - freq: direction [in], freq of spi, int type\n - soft_cs: direction [in], not use hardware cs, bool type, if set true, you can operate cs pin use gpio manually.\n - mode: direction [in], mode of spi, spi.Mode type, spi.Mode.MASTER or spi.Mode.SLAVE.\n - polarity: direction [in], polarity of spi, 0 means idle level of clock is low, 1 means high, int type, default is 0.\n - phase: direction [in], phase of spi, 0 means data is captured on the first edge of the SPI clock cycle, 1 means second, int type, default is 0.\n - bits: direction [in], bits of spi, int type, default is 8.\n - cs: direction [in], cs pin number, int type, default is 0, if SPI support multi hardware cs, you can set it to other value.\n" + }, + "args": [ + [ + "int", + "id", + null + ], + [ + "spi::Mode", + "mode", + null + ], + [ + "int", + "freq", + null + ], + [ + "bool", + "soft_cs", + "false" + ], + [ + "int", + "polarity", + "0" + ], + [ + "int", + "phase", + "0" + ], + [ + "int", + "bits", + "8" + ], + [ + "int", + "cs", + "0" + ] + ], + "ret_type": null, + "static": false, + "def": "SPI(int id, spi::Mode mode, int freq, bool soft_cs = false, int polarity = 0, int phase = 0, int bits = 8, int cs = 0)" + }, + "read": { + "type": "func", + "name": "read", + "doc": { + "brief": "read data from spi", + "param": { + "length": "direction [in], read length, int type" + }, + "return": "bytes data, Bytes type in C++, bytes type in MaixPy. You need to delete it manually after use in C++.", + "maixpy": "maix.peripheral.spi.SPI.read", + "py_doc": "read data from spi\n\nArgs:\n - length: direction [in], read length, int type\n\n\nReturns: bytes data, Bytes type in C++, bytes type in MaixPy. You need to delete it manually after use in C++.\n" + }, + "args": [ + [ + "int", + "length", + null + ] + ], + "ret_type": "Bytes*", + "static": false, + "def": "Bytes *read(int length)" + }, + "write_read": { + "type": "func", + "name": "write_read", + "doc": { + "brief": "write data to spi and read data from spi at the same time.", + "param": { + "data": "direction [in], data to write, Bytes type in C++, bytes type in MaixPy", + "read_len": "direction [in], read length, int type, should > 0." + }, + "return": "read data, Bytes type in C++, bytes type in MaixPy. You need to delete it manually after use in C++.", + "maixpy": "maix.peripheral.spi.SPI.write_read", + "py_doc": "write data to spi and read data from spi at the same time.\n\nArgs:\n - data: direction [in], data to write, Bytes type in C++, bytes type in MaixPy\n - read_len: direction [in], read length, int type, should > 0.\n\n\nReturns: read data, Bytes type in C++, bytes type in MaixPy. You need to delete it manually after use in C++.\n" + }, + "args": [ + [ + "Bytes *", + "data", + null + ], + [ + "int", + "read_len", + null + ] + ], + "ret_type": "Bytes*", + "static": false, + "def": "Bytes *write_read(Bytes *data, int read_len)" + }, + "is_busy": { + "type": "func", + "name": "is_busy", + "doc": { + "brief": "get busy status of spi", + "return": "busy status, bool type", + "maixpy": "maix.peripheral.spi.SPI.is_busy", + "py_doc": "get busy status of spi\n\nReturns: busy status, bool type\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_busy()" + } + }, + "def": "class SPI" + } + }, + "auto_add": true + }, + "uart": { + "type": "module", + "doc": { + "brief": "maix uart peripheral driver", + "maixpy": "maix.peripheral.uart", + "py_doc": "maix uart peripheral driver" + }, + "members": { + "PARITY": { + "type": "enum", + "name": "PARITY", + "doc": { + "brief": "uart parity enum", + "maixpy": "maix.peripheral.uart.PARITY", + "py_doc": "uart parity enum" + }, + "values": [ + [ + "PARITY_NONE", + "0x00", + "no parity" + ], + [ + "PARITY_ODD", + "0x01", + "odd parity" + ], + [ + "PARITY_EVEN", + "0x02", + "even parity" + ], + [ + "PARITY_MAX", + "", + "" + ] + ], + "def": "enum PARITY\n {\n PARITY_NONE = 0x00, // no parity\n PARITY_ODD = 0x01, // odd parity\n PARITY_EVEN = 0x02, // even parity\n PARITY_MAX\n }" + }, + "STOP": { + "type": "enum", + "name": "STOP", + "doc": { + "brief": "uart stop bits", + "maixpy": "maix.peripheral.uart.STOP", + "py_doc": "uart stop bits" + }, + "values": [ + [ + "STOP_1", + "0x01", + "1 stop bit" + ], + [ + "STOP_2", + "0x02", + "2 stop bits" + ], + [ + "STOP_1_5", + "0x03", + "1.5 stop bits" + ], + [ + "STOP_MAX", + "", + "" + ] + ], + "def": "enum STOP\n {\n STOP_1 = 0x01, // 1 stop bit\n STOP_2 = 0x02, // 2 stop bits\n STOP_1_5 = 0x03, // 1.5 stop bits\n STOP_MAX\n }" + }, + "BITS": { + "type": "enum", + "name": "BITS", + "doc": { + "brief": "uart stop bits", + "maixpy": "maix.peripheral.uart.BITS", + "py_doc": "uart stop bits" + }, + "values": [ + [ + "BITS_5", + "5", + "5 data bits" + ], + [ + "BITS_6", + "6", + "6 data bits" + ], + [ + "BITS_7", + "7", + "7 data bits" + ], + [ + "BITS_8", + "8", + "8 data bits" + ], + [ + "BITS_MAX", + "", + "" + ] + ], + "def": "enum BITS\n {\n BITS_5 = 5, // 5 data bits\n BITS_6 = 6, // 6 data bits\n BITS_7 = 7, // 7 data bits\n BITS_8 = 8, // 8 data bits\n BITS_MAX\n }" + }, + "FLOW_CTRL": { + "type": "enum", + "name": "FLOW_CTRL", + "doc": { + "brief": "uart flow control", + "maixpy": "maix.peripheral.uart.FLOW_CTRL", + "py_doc": "uart flow control" + }, + "values": [ + [ + "FLOW_CTRL_NONE", + "0", + "no flow control" + ], + [ + "FLOW_CTRL_HW", + "1", + "hardware flow control" + ], + [ + "FLOW_CTRL_MAX", + "", + "" + ] + ], + "def": "enum FLOW_CTRL\n {\n FLOW_CTRL_NONE = 0, // no flow control\n FLOW_CTRL_HW = 1, // hardware flow control\n FLOW_CTRL_MAX\n }" + }, + "list_devices": { + "type": "func", + "name": "list_devices", + "doc": { + "brief": "Get supported uart ports.", + "return": "uart ports list, string type.", + "maixpy": "maix.peripheral.uart.list_devices", + "py_doc": "Get supported uart ports.\n\nReturns: uart ports list, string type.\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector list_devices()" + }, + "UART": { + "type": "class", + "name": "UART", + "doc": { + "brief": "maix uart peripheral driver", + "maixpy": "maix.peripheral.uart.UART", + "py_doc": "maix uart peripheral driver" + }, + "members": { + "__init__": { + "type": "func", + "name": "UART", + "doc": { + "brief": "UART constructor. You need to call open() to open the device.", + "param": { + "port": "uart port. string type, can get it by uart.list_devices().\nIf empty, will not open device in constructor, default empty.\nif not empty, will auto open device in constructor, open fail will throw err.Exception.", + "baudrate": "baudrate of uart. int type, default 115200.", + "databits": "databits, values @see uart.DATA_BITS", + "parity": "parity, values @see uart.PARITY", + "stopbits": "stopbits, values @see uart.STOP_BITS", + "flow_control": "flow_control, values @see uart.FLOW_CTRL" + }, + "maixpy": "maix.peripheral.uart.UART.__init__", + "py_doc": "UART constructor. You need to call open() to open the device.\n\nArgs:\n - port: uart port. string type, can get it by uart.list_devices().\nIf empty, will not open device in constructor, default empty.\nif not empty, will auto open device in constructor, open fail will throw err.Exception.\n - baudrate: baudrate of uart. int type, default 115200.\n - databits: databits, values @see uart.DATA_BITS\n - parity: parity, values @see uart.PARITY\n - stopbits: stopbits, values @see uart.STOP_BITS\n - flow_control: flow_control, values @see uart.FLOW_CTRL\n" + }, + "args": [ + [ + "const std::string &", + "port", + "\"\"" + ], + [ + "int", + "baudrate", + "115200" + ], + [ + "uart::BITS", + "databits", + "uart::BITS_8" + ], + [ + "uart::PARITY", + "parity", + "uart::PARITY_NONE" + ], + [ + "uart::STOP", + "stopbits", + "uart::STOP_1" + ], + [ + "uart::FLOW_CTRL", + "flow_ctrl", + "uart::FLOW_CTRL_NONE" + ] + ], + "ret_type": null, + "static": false, + "def": "UART(const std::string &port = \"\", int baudrate = 115200, uart::BITS databits = uart::BITS_8,\n uart::PARITY parity = uart::PARITY_NONE, uart::STOP stopbits = uart::STOP_1,\n uart::FLOW_CTRL flow_ctrl = uart::FLOW_CTRL_NONE)", + "py_def": "def __init__(self, port: str = '', baudrate: int = 115200, databits: BITS = ..., parity: PARITY = ..., stopbits: STOP = ..., flow_ctrl: FLOW_CTRL = ...) -> None" + }, + "set_port": { + "type": "func", + "name": "set_port", + "doc": { + "brief": "Set port", + "param": { + "port": "uart port. string type, can get it by uart.list_devices()." + }, + "return": "set port error code, err.Err type.", + "maixpy": "maix.peripheral.uart.UART.set_port", + "py_doc": "Set port\n\nArgs:\n - port: uart port. string type, can get it by uart.list_devices().\n\n\nReturns: set port error code, err.Err type.\n" + }, + "args": [ + [ + "const std::string &", + "port", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err set_port(const std::string &port)", + "py_def": "def set_port(self, port: str) -> maix.err.Err" + }, + "get_port": { + "type": "func", + "name": "get_port", + "doc": { + "brief": "Get port", + "return": "uart port, string type.", + "maixpy": "maix.peripheral.uart.UART.get_port", + "py_doc": "Get port\n\nReturns: uart port, string type.\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string get_port()", + "py_def": "def get_port(self) -> str" + }, + "set_baudrate": { + "type": "func", + "name": "set_baudrate", + "doc": { + "brief": "Set baud rate", + "param": { + "baudrate": "baudrate of uart. int type, default 115200." + }, + "return": "set baud rate error code, err.Err type.", + "maixpy": "maix.peripheral.uart.UART.set_baudrate", + "py_doc": "Set baud rate\n\nArgs:\n - baudrate: baudrate of uart. int type, default 115200.\n\n\nReturns: set baud rate error code, err.Err type.\n" + }, + "args": [ + [ + "int", + "baudrate", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err set_baudrate(int baudrate)", + "py_def": "def set_baudrate(self, baudrate: int) -> maix.err.Err" + }, + "get_baudrate": { + "type": "func", + "name": "get_baudrate", + "doc": { + "brief": "Get baud rate", + "return": "baud rate, int type.", + "maixpy": "maix.peripheral.uart.UART.get_baudrate", + "py_doc": "Get baud rate\n\nReturns: baud rate, int type.\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int get_baudrate()", + "py_def": "def get_baudrate(self) -> int" + }, + "open": { + "type": "func", + "name": "open", + "doc": { + "brief": "Open uart device, before open, port must be set in constructor or by set_port().\\nIf already opened, do nothing and return err.ERR_NONE.", + "return": "open device error code, err.Err type.", + "maixpy": "maix.peripheral.uart.UART.open", + "py_doc": "Open uart device, before open, port must be set in constructor or by set_port().\nIf already opened, do nothing and return err.ERR_NONE.\n\nReturns: open device error code, err.Err type.\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err open()", + "py_def": "def open(self) -> maix.err.Err" + }, + "is_open": { + "type": "func", + "name": "is_open", + "doc": { + "brief": "Check if device is opened.", + "return": "true if opened, false if not opened.", + "maixpy": "maix.peripheral.uart.UART.is_open", + "py_doc": "Check if device is opened.\n\nReturns: true if opened, false if not opened.\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_open()", + "py_def": "def is_open(self) -> bool" + }, + "close": { + "type": "func", + "name": "close", + "doc": { + "brief": "Close uart device, if already closed, do nothing and return err.ERR_NONE.", + "return": "close device error code, err.Err type.", + "maixpy": "maix.peripheral.uart.UART.close", + "py_doc": "Close uart device, if already closed, do nothing and return err.ERR_NONE.\n\nReturns: close device error code, err.Err type.\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err close()", + "py_def": "def close(self) -> maix.err.Err" + }, + "write_str": { + "type": "func", + "name": "write_str", + "doc": { + "brief": "Send string data", + "param": { + "str": "string data" + }, + "return": "sent data length, < 0 means error, value is -err.Err.", + "maixpy": "maix.peripheral.uart.UART.write_str", + "py_doc": "Send string data\n\nArgs:\n - str: string data\n\n\nReturns: sent data length, < 0 means error, value is -err.Err.\n" + }, + "args": [ + [ + "const std::string &", + "str", + null + ] + ], + "ret_type": "int", + "static": false, + "def": "int write_str(const std::string &str)", + "py_def": "def write_str(self, str: str) -> int" + }, + "write": { + "type": "func", + "name": "write", + "doc": { + "brief": "Send data to uart", + "param": { + "data": "direction [in], data to send, bytes type. If you want to send str type, use str.encode() to convert." + }, + "return": "sent length, int type, if < 0 means error, value is -err.Err.", + "maixpy": "maix.peripheral.uart.UART.write", + "py_doc": "Send data to uart\n\nArgs:\n - data: direction [in], data to send, bytes type. If you want to send str type, use str.encode() to convert.\n\n\nReturns: sent length, int type, if < 0 means error, value is -err.Err.\n" + }, + "args": [ + [ + "Bytes &", + "data", + null + ] + ], + "ret_type": "int", + "static": false, + "def": "int write(Bytes &data)", + "py_def": "def write(self, data: maix.Bytes(bytes)) -> int" + }, + "available": { + "type": "func", + "name": "available", + "doc": { + "brief": "Check if data available or wait data available.", + "param": { + "timeout": "unit ms, timeout to wait data, default 0.\n0 means check data available and return immediately,\n> 0 means wait until data available or timeout.\n- 1 means wait until data available." + }, + "return": "available data number, 0 if timeout or no data, <0 if error, value is -err.Err, can be err::ERR_IO\uff0c err::ERR_CANCEL, err::ERR_NOT_OPEN.", + "throw": "err.Exception if fatal error.", + "maixpy": "maix.peripheral.uart.UART.available", + "py_doc": "Check if data available or wait data available.\n\nArgs:\n - timeout: unit ms, timeout to wait data, default 0.\n0 means check data available and return immediately,\n> 0 means wait until data available or timeout.\n- 1 means wait until data available.\n\n\nReturns: available data number, 0 if timeout or no data, <0 if error, value is -err.Err, can be err::ERR_IO\uff0c err::ERR_CANCEL, err::ERR_NOT_OPEN.\n" + }, + "args": [ + [ + "int", + "timeout", + "0" + ] + ], + "ret_type": "int", + "static": false, + "def": "int available(int timeout = 0)", + "py_def": "def available(self, timeout: int = 0) -> int" + }, + "read": { + "type": "func", + "name": "read", + "doc": { + "brief": "Recv data from uart", + "param": { + "len": "max data length want to receive, default -1.\n-1 means read data in uart receive buffer.\n>0 means read len data want to receive.\nother values is invalid.", + "timeout": "unit ms, timeout to receive data, default 0.\n0 means read data in uart receive buffer and return immediately,\n-1 means block until read len data,\n>0 means block until read len data or timeout." + }, + "return": "received data, bytes type.\nAttention, you need to delete the returned object yourself in C++.", + "maixpy": "maix.peripheral.uart.UART.read", + "py_doc": "Recv data from uart\n\nArgs:\n - len: max data length want to receive, default -1.\n-1 means read data in uart receive buffer.\n>0 means read len data want to receive.\nother values is invalid.\n - timeout: unit ms, timeout to receive data, default 0.\n0 means read data in uart receive buffer and return immediately,\n-1 means block until read len data,\n>0 means block until read len data or timeout.\n\n\nReturns: received data, bytes type.\nAttention, you need to delete the returned object yourself in C++.\n" + }, + "args": [ + [ + "int", + "len", + "-1" + ], + [ + "int", + "timeout", + "0" + ] + ], + "ret_type": "Bytes*", + "static": false, + "def": "Bytes *read(int len = -1, int timeout = 0)", + "py_def": "def read(*args, **kwargs)" + }, + "readline": { + "type": "func", + "name": "readline", + "doc": { + "brief": "Read line from uart, that is read until '\\n' or '\\r\\n'.", + "param": { + "timeout": "unit ms, timeout to receive data, default -1 means block until read '\\n' or '\\r\\n'.\n> 0 means block until read '\\n' or '\\r\\n' or timeout." + }, + "return": "received data, bytes type. If timeout will return the current received data despite not read '\\n' or '\\r\\n'.\ne.g. If we want to read b'123\\n', but when we only read b'12', timeout, then return b'12'.", + "maixpy": "maix.peripheral.uart.UART.readline", + "py_doc": "Read line from uart, that is read until '\\n' or '\\r\\n'.\n\nArgs:\n - timeout: unit ms, timeout to receive data, default -1 means block until read '\\n' or '\\r\\n'.\n> 0 means block until read '\\n' or '\\r\\n' or timeout.\n\n\nReturns: received data, bytes type. If timeout will return the current received data despite not read '\\n' or '\\r\\n'.\ne.g. If we want to read b'123\\n', but when we only read b'12', timeout, then return b'12'.\n" + }, + "args": [ + [ + "int", + "timeout", + "-1" + ] + ], + "ret_type": "Bytes*", + "static": false, + "def": "Bytes *readline(int timeout = -1)", + "py_def": "def readline(*args, **kwargs)" + } + }, + "def": "class UART : public comm::CommBase" + } + }, + "auto_add": false + }, + "key": { + "type": "module", + "doc": { + "brief": "maix.peripheral.key module" + }, + "members": { + "Keys": { + "type": "enum", + "name": "Keys{", + "doc": { + "brief": "Keys enum, id the same as linux input.h(input-event-codes.h)", + "maixpy": "maix.peripheral.key.Keys", + "py_doc": "Keys enum, id the same as linux input.h(input-event-codes.h)" + }, + "values": [ + [ + "KEY_NONE", + "0x000", + "" + ], + [ + "KEY_ESC", + "0x001", + "" + ], + [ + "KEY_OK", + "0x160", + "" + ], + [ + "KEY_OPTION", + "0x165", + "" + ], + [ + "KEY_NEXT", + "0x197", + "" + ], + [ + "KEY_PREV", + "0x19c", + "" + ] + ], + "def": "enum Keys{\n KEY_NONE = 0x000,\n KEY_ESC = 0x001,\n KEY_OK = 0x160,\n KEY_OPTION = 0x165,\n KEY_NEXT = 0x197,\n KEY_PREV = 0x19c\n }" + }, + "State": { + "type": "enum", + "name": "State{", + "doc": { + "brief": "Key state enum", + "maixpy": "maix.peripheral.key.State", + "py_doc": "Key state enum" + }, + "values": [ + [ + "KEY_RELEASED", + "0", + "" + ], + [ + "KEY_PRESSED", + "1", + "" + ] + ], + "def": "enum State{\n KEY_RELEASED = 0,\n KEY_PRESSED = 1,\n }" + }, + "Key": { + "type": "class", + "name": "Key", + "doc": { + "brief": "Key input class", + "maixpy": "maix.peripheral.key.Key", + "py_doc": "Key input class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Key", + "doc": { + "brief": "Key Device constructor", + "param": { + "callback": "When key triggered and callback is not empty(empty In MaixPy is None, in C++ is nullptr),\ncallback will be called with args key(key.Keys) and value(key.State).\nIf set to null, you can get key value by read() function.\nThis callback called in a standalone thread, so you can block a while in callback, and you should be carefully when operate shared data.", + "open": "auto open device in constructor, if false, you need call open() to open device" + }, + "maixpy": "maix.peripheral.key.Key.__init__", + "maixcdk": "maix.peripheral.key.Key.Key", + "py_doc": "Key Device constructor\n\nArgs:\n - callback: When key triggered and callback is not empty(empty In MaixPy is None, in C++ is nullptr),\ncallback will be called with args key(key.Keys) and value(key.State).\nIf set to null, you can get key value by read() function.\nThis callback called in a standalone thread, so you can block a while in callback, and you should be carefully when operate shared data.\n - open: auto open device in constructor, if false, you need call open() to open device\n" + }, + "args": [ + [ + "std::function", + "callback", + "nullptr" + ], + [ + "bool", + "open", + "true" + ] + ], + "ret_type": null, + "static": false, + "def": "Key(std::function callback = nullptr, bool open = true)", + "py_def": "def __init__(self, callback: typing.Callable[[int, int], None] = None, open: bool = True) -> None" + }, + "open": { + "type": "func", + "name": "open", + "doc": { + "brief": "Open(Initialize) key device, if already opened, will close first and then open.", + "return": "err::Err type, err.Err.ERR_NONE means success", + "maixpy": "maix.peripheral.key.Key.open", + "py_doc": "Open(Initialize) key device, if already opened, will close first and then open.\n\nReturns: err::Err type, err.Err.ERR_NONE means success\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err open()", + "py_def": "def open(self) -> maix.err.Err" + }, + "close": { + "type": "func", + "name": "close", + "doc": { + "brief": "Close key device", + "return": "err::Err type, err.Err.ERR_NONE means success", + "maixpy": "maix.peripheral.key.Key.close", + "py_doc": "Close key device\n\nReturns: err::Err type, err.Err.ERR_NONE means success\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err close()", + "py_def": "def close(self) -> maix.err.Err" + }, + "is_opened": { + "type": "func", + "name": "is_opened", + "doc": { + "brief": "Check key device is opened", + "return": "bool type, true means opened, false means closed", + "maixpy": "maix.peripheral.key.Key.is_opened", + "py_doc": "Check key device is opened\n\nReturns: bool type, true means opened, false means closed\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_opened()", + "py_def": "def is_opened(self) -> bool" + }, + "read": { + "type": "func", + "name": "read", + "doc": { + "brief": "Read key input, and return key and value, if callback is set, DO NOT call this function manually.", + "return": "list type, first is key(maix.key.Keys), second is value(maix.key.State), if no key input, return [0, 0]", + "throw": "If read failed, will throw maix.err.Exception.", + "maixpy": "maix.peripheral.key.Key.read", + "py_doc": "Read key input, and return key and value, if callback is set, DO NOT call this function manually.\n\nReturns: list type, first is key(maix.key.Keys), second is value(maix.key.State), if no key input, return [0, 0]\n" + }, + "args": [], + "ret_type": "std::pair", + "static": false, + "def": "std::pair read()", + "py_def": "def read(self) -> tuple[int, int]" + } + }, + "def": "class Key" + }, + "add_default_listener": { + "type": "func", + "name": "add_default_listener", + "doc": { + "brief": "Add default listener, if you want to exit app when press ok button, you can just call this function.\\nThis function is auto called in MaixPy' startup code, so you don't need to call it in MaixPy.\\nCreate Key object will auto call rm_default_listener() to cancel the default ok button function.\\nWhen ok button pressed, a SIGINT signal will be raise and call app.set_exit_flag(True).", + "maixpy": "maix.peripheral.key.add_default_listener", + "py_doc": "Add default listener, if you want to exit app when press ok button, you can just call this function.\nThis function is auto called in MaixPy' startup code, so you don't need to call it in MaixPy.\nCreate Key object will auto call rm_default_listener() to cancel the default ok button function.\nWhen ok button pressed, a SIGINT signal will be raise and call app.set_exit_flag(True)." + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void add_default_listener()" + }, + "rm_default_listener": { + "type": "func", + "name": "rm_default_listener", + "doc": { + "brief": "Remove default listener, if you want to cancel the default ok button function(exit app), you can just call this function.", + "maixpy": "maix.peripheral.key.rm_default_listener", + "py_doc": "Remove default listener, if you want to cancel the default ok button function(exit app), you can just call this function." + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void rm_default_listener()" + } + }, + "auto_add": true + }, + "i2c": { + "type": "module", + "doc": { + "brief": "maix.peripheral.i2c module" + }, + "members": { + "AddrSize": { + "type": "enum", + "name": "AddrSize", + "doc": { + "brief": "Address size enum", + "maixpy": "maix.peripheral.i2c.AddrSize", + "py_doc": "Address size enum" + }, + "values": [ + [ + "SEVEN_BIT", + "7", + "7-bit address mode" + ], + [ + "TEN_BIT", + "10", + "10-bit address mode" + ] + ], + "def": "enum AddrSize\n {\n SEVEN_BIT = 7, // 7-bit address mode\n TEN_BIT = 10 // 10-bit address mode\n }" + }, + "Mode": { + "type": "enum", + "name": "Mode", + "doc": { + "brief": "I2C mode enum", + "maixpy": "maix.peripheral.i2c.Mode", + "py_doc": "I2C mode enum" + }, + "values": [ + [ + "MASTER", + "0x00", + "master mode" + ], + [ + "SLAVE", + "0x01", + "slave mode" + ] + ], + "def": "enum Mode\n {\n MASTER = 0x00, // master mode\n SLAVE = 0x01 // slave mode\n }" + }, + "list_devices": { + "type": "func", + "name": "list_devices", + "doc": { + "brief": "Get supported i2c bus devices.", + "return": "i2c bus devices list, int type, is the i2c bus id.", + "maixpy": "maix.peripheral.i2c.list_devices", + "py_doc": "Get supported i2c bus devices.\n\nReturns: i2c bus devices list, int type, is the i2c bus id.\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector list_devices()" + }, + "I2C": { + "type": "class", + "name": "I2C", + "doc": { + "brief": "Peripheral i2c class", + "maixpy": "maix.peripheral.i2c.I2C", + "py_doc": "Peripheral i2c class" + }, + "members": { + "__init__": { + "type": "func", + "name": "I2C", + "doc": { + "brief": "I2C Device constructor\\nthis constructor will be export to MaixPy as _maix.example.Example.__init__", + "param": { + "id": "direction [in], i2c bus id, int type, e.g. 0, 1, 2", + "freq": "direction [in], i2c clock, int type, default is 100000(100kbit/s), will auto set fast mode if freq > 100000.", + "mode": "direction [in], mode of i2c, i2c.Mode.SLAVE or i2c.Mode.MASTER.", + "addr_size": "direction [in], address length of i2c, i2c.AddrSize.SEVEN_BIT or i2c.AddrSize.TEN_BIT." + }, + "throw": "err::Exception if open i2c device failed.", + "maixpy": "maix.peripheral.i2c.I2C.__init__", + "py_doc": "I2C Device constructor\nthis constructor will be export to MaixPy as _maix.example.Example.__init__\n\nArgs:\n - id: direction [in], i2c bus id, int type, e.g. 0, 1, 2\n - freq: direction [in], i2c clock, int type, default is 100000(100kbit/s), will auto set fast mode if freq > 100000.\n - mode: direction [in], mode of i2c, i2c.Mode.SLAVE or i2c.Mode.MASTER.\n - addr_size: direction [in], address length of i2c, i2c.AddrSize.SEVEN_BIT or i2c.AddrSize.TEN_BIT.\n" + }, + "args": [ + [ + "int", + "id", + null + ], + [ + "i2c::Mode", + "mode", + null + ], + [ + "int", + "freq", + "100000" + ], + [ + "i2c::AddrSize", + "addr_size", + "i2c::AddrSize::SEVEN_BIT" + ] + ], + "ret_type": null, + "static": false, + "def": "I2C(int id, i2c::Mode mode, int freq = 100000, i2c::AddrSize addr_size = i2c::AddrSize::SEVEN_BIT)" + }, + "scan": { + "type": "func", + "name": "scan", + "doc": { + "brief": "scan all i2c salve address on the bus", + "return": "the list of i2c slave address, int list type.", + "maixpy": "maix.peripheral.i2c.I2C.scan", + "py_doc": "scan all i2c salve address on the bus\n\nReturns: the list of i2c slave address, int list type.\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector scan()" + }, + "writeto": { + "type": "func", + "name": "writeto", + "doc": { + "brief": "write data to i2c slave", + "param": { + "addr": "direction [in], i2c slave address, int type", + "data": "direction [in], data to write, bytes type.\nNote: The range of value should be in [0,255]." + }, + "return": "if success, return the length of written data, error occurred will return -err::Err.", + "maixpy": "maix.peripheral.i2c.I2C.writeto", + "py_doc": "write data to i2c slave\n\nArgs:\n - addr: direction [in], i2c slave address, int type\n - data: direction [in], data to write, bytes type.\nNote: The range of value should be in [0,255].\n\n\nReturns: if success, return the length of written data, error occurred will return -err::Err.\n" + }, + "args": [ + [ + "int", + "addr", + null + ], + [ + "const Bytes &", + "data", + null + ] + ], + "ret_type": "int", + "static": false, + "def": "int writeto(int addr, const Bytes &data)" + }, + "readfrom": { + "type": "func", + "name": "readfrom", + "doc": { + "brief": "read data from i2c slave", + "param": { + "addr": "direction [in], i2c slave address, int type", + "len": "direction [in], data length to read, int type" + }, + "return": "the list of data read from i2c slave, bytes type, you should delete it after use in C++.\nIf read failed, return nullptr in C++, None in MaixPy.", + "maixpy": "maix.peripheral.i2c.I2C.readfrom", + "py_doc": "read data from i2c slave\n\nArgs:\n - addr: direction [in], i2c slave address, int type\n - len: direction [in], data length to read, int type\n\n\nReturns: the list of data read from i2c slave, bytes type, you should delete it after use in C++.\nIf read failed, return nullptr in C++, None in MaixPy.\n" + }, + "args": [ + [ + "int", + "addr", + null + ], + [ + "int", + "len", + null + ] + ], + "ret_type": "Bytes*", + "static": false, + "def": "Bytes* readfrom(int addr, int len)" + }, + "writeto_mem": { + "type": "func", + "name": "writeto_mem", + "doc": { + "brief": "write data to i2c slave's memory address", + "param": { + "addr": "direction [in], i2c slave address, int type", + "mem_addr": "direction [in], memory address want to write, int type.", + "data": "direction [in], data to write, bytes type.", + "mem_addr_size": "direction [in], memory address size, default is 8.", + "mem_addr_le": "direction [in], memory address little endian, default is false, that is send high byte first." + }, + "return": "data length written if success, error occurred will return -err::Err.", + "maixpy": "maix.peripheral.i2c.I2C.writeto_mem", + "py_doc": "write data to i2c slave's memory address\n\nArgs:\n - addr: direction [in], i2c slave address, int type\n - mem_addr: direction [in], memory address want to write, int type.\n - data: direction [in], data to write, bytes type.\n - mem_addr_size: direction [in], memory address size, default is 8.\n - mem_addr_le: direction [in], memory address little endian, default is false, that is send high byte first.\n\n\nReturns: data length written if success, error occurred will return -err::Err.\n" + }, + "args": [ + [ + "int", + "addr", + null + ], + [ + "int", + "mem_addr", + null + ], + [ + "const Bytes &", + "data", + null + ], + [ + "int", + "mem_addr_size", + "8" + ], + [ + "bool", + "mem_addr_le", + "false" + ] + ], + "ret_type": "int", + "static": false, + "def": "int writeto_mem(int addr, int mem_addr, const Bytes &data, int mem_addr_size = 8, bool mem_addr_le = false)" + }, + "readfrom_mem": { + "type": "func", + "name": "readfrom_mem", + "doc": { + "brief": "read data from i2c slave", + "param": { + "addr": "direction [in], i2c slave address, int type", + "mem_addr": "direction [in], memory address want to read, int type.", + "len": "direction [in], data length to read, int type", + "mem_addr_size": "direction [in], memory address size, default is 8.", + "mem_addr_le": "direction [in], memory address little endian, default is false, that is send high byte first." + }, + "return": "the list of data read from i2c slave, bytes type, you should delete it after use in C++.\nIf read failed, return nullptr in C++, None in MaixPy.", + "maixpy": "maix.peripheral.i2c.I2C.readfrom_mem", + "py_doc": "read data from i2c slave\n\nArgs:\n - addr: direction [in], i2c slave address, int type\n - mem_addr: direction [in], memory address want to read, int type.\n - len: direction [in], data length to read, int type\n - mem_addr_size: direction [in], memory address size, default is 8.\n - mem_addr_le: direction [in], memory address little endian, default is false, that is send high byte first.\n\n\nReturns: the list of data read from i2c slave, bytes type, you should delete it after use in C++.\nIf read failed, return nullptr in C++, None in MaixPy.\n" + }, + "args": [ + [ + "int", + "addr", + null + ], + [ + "int", + "mem_addr", + null + ], + [ + "int", + "len", + null + ], + [ + "int", + "mem_addr_size", + "8" + ], + [ + "bool", + "mem_addr_le", + "false" + ] + ], + "ret_type": "Bytes*", + "static": false, + "def": "Bytes* readfrom_mem(int addr, int mem_addr, int len, int mem_addr_size = 8, bool mem_addr_le = false)" + } + }, + "def": "class I2C" + } + }, + "auto_add": true + }, + "pinmap": { + "type": "module", + "doc": { + "brief": "maix.peripheral.pinmap module" + }, + "members": { + "get_pins": { + "type": "func", + "name": "get_pins", + "doc": { + "brief": "Get all pins of devices", + "return": "pin name list, string type.", + "maixpy": "maix.peripheral.pinmap.get_pins", + "py_doc": "Get all pins of devices\n\nReturns: pin name list, string type.\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector get_pins()", + "py_def": "def get_pins() -> list[str]" + }, + "get_pin_functions": { + "type": "func", + "name": "get_pin_functions", + "doc": { + "brief": "Get all function of a pin", + "param": { + "pin": "pin name, string type." + }, + "return": "function list, function name is string type.", + "throw": "If pin name error will throwout err.Err.ERR_ARGS error.", + "maixpy": "maix.peripheral.pinmap.get_pin_functions", + "py_doc": "Get all function of a pin\n\nArgs:\n - pin: pin name, string type.\n\n\nReturns: function list, function name is string type.\n" + }, + "args": [ + [ + "const std::string &", + "pin", + null + ] + ], + "ret_type": "std::vector", + "static": false, + "def": "std::vector get_pin_functions(const std::string &pin)", + "py_def": "def get_pin_functions(pin: str) -> list[str]" + }, + "set_pin_function": { + "type": "func", + "name": "set_pin_function", + "doc": { + "brief": "Set function of a pin", + "param": { + "pin": "pin name, string type.", + "func": "which function should this pin use." + }, + "return": "if set ok, will return err.Err.ERR_NONE, else error occurs.", + "maixpy": "maix.peripheral.pinmap.set_pin_function", + "py_doc": "Set function of a pin\n\nArgs:\n - pin: pin name, string type.\n - func: which function should this pin use.\n\n\nReturns: if set ok, will return err.Err.ERR_NONE, else error occurs.\n" + }, + "args": [ + [ + "const std::string &", + "pin", + null + ], + [ + "const std::string &", + "func", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err set_pin_function(const std::string &pin, const std::string &func)", + "py_def": "def set_pin_function(pin: str, func: str) -> maix.err.Err" + } + }, + "auto_add": true + }, + "timer": { + "type": "module", + "doc": { + "brief": "maix.peripheral.timer module" + }, + "members": { + "TIMER": { + "type": "class", + "name": "TIMER", + "doc": { + "brief": "Peripheral timer class", + "maixpy": "maix.peripheral.timer.TIMER", + "py_doc": "Peripheral timer class" + }, + "members": { + "__init__": { + "type": "func", + "name": "TIMER", + "doc": { + "brief": "TIMER constructor", + "maixpy": "maix.peripheral.timer.TIMER.__init__", + "py_doc": "TIMER constructor" + }, + "args": [], + "ret_type": null, + "static": false, + "def": "TIMER()" + } + }, + "def": "class TIMER" + } + }, + "auto_add": true + }, + "pwm": { + "type": "module", + "doc": { + "brief": "maix.peripheral.pwm module" + }, + "members": { + "PWM": { + "type": "class", + "name": "PWM", + "doc": { + "brief": "Peripheral pwm class", + "maixpy": "maix.peripheral.pwm.PWM", + "py_doc": "Peripheral pwm class" + }, + "members": { + "__init__": { + "type": "func", + "name": "PWM", + "doc": { + "brief": "PWM constructor", + "param": { + "pin": "direction [in], pwm id, int type, like 0, 1, 2 etc.", + "freq": "direction [in], pwm frequency, unit: Hz. int type. default is 1000", + "duty": "direction [in], pwm duty. double type. range is [0, 100], default is 0.", + "enable": "direction [in], enable pwm output right now. bool type. default is true, if false, you need to call enable() to enable pwm output.", + "duty_val": "direction [in], pwm duty value, int type. default -1 means not set and auto calculate by freq and duty.\nThis arg directly set pwm duty value, if set, will ignore duty arg.\nduty_val = duty / 100 * T_ns, T_ns = 1 / freq * 1000000000." + }, + "throw": "If args error or init pwm failed, will throw err::Exception", + "maixpy": "maix.peripheral.pwm.PWM.__init__", + "py_doc": "PWM constructor\n\nArgs:\n - pin: direction [in], pwm id, int type, like 0, 1, 2 etc.\n - freq: direction [in], pwm frequency, unit: Hz. int type. default is 1000\n - duty: direction [in], pwm duty. double type. range is [0, 100], default is 0.\n - enable: direction [in], enable pwm output right now. bool type. default is true, if false, you need to call enable() to enable pwm output.\n - duty_val: direction [in], pwm duty value, int type. default -1 means not set and auto calculate by freq and duty.\nThis arg directly set pwm duty value, if set, will ignore duty arg.\nduty_val = duty / 100 * T_ns, T_ns = 1 / freq * 1000000000.\n" + }, + "args": [ + [ + "int", + "id", + null + ], + [ + "int", + "freq", + "1000" + ], + [ + "double", + "duty", + "0" + ], + [ + "bool", + "enable", + "true" + ], + [ + "int", + "duty_val", + "-1" + ] + ], + "ret_type": null, + "static": false, + "def": "PWM(int id, int freq = 1000, double duty = 0, bool enable = true, int duty_val = -1)" + }, + "duty": { + "type": "func", + "name": "duty", + "doc": { + "brief": "get or set pwm duty", + "param": { + "duty": "direction [in], pwm duty, double type, value in [0, 100], default -1 means only read." + }, + "return": "current duty, float type, if set and set failed will return -err::Err", + "maixpy": "maix.peripheral.pwm.PWM.duty", + "py_doc": "get or set pwm duty\n\nArgs:\n - duty: direction [in], pwm duty, double type, value in [0, 100], default -1 means only read.\n\n\nReturns: current duty, float type, if set and set failed will return -err::Err\n" + }, + "args": [ + [ + "double", + "duty", + "-1" + ] + ], + "ret_type": "double", + "static": false, + "def": "double duty(double duty = -1)" + }, + "duty_val": { + "type": "func", + "name": "duty_val", + "doc": { + "brief": "set pwm duty value", + "param": { + "duty_val": "direction [in], pwm duty value. int type. default is -1\nduty_val > 0 means set duty_val\nduty_val == -1 or not set, return current duty_val" + }, + "return": "int type\nwhen get duty_val, return current duty_val, else return -err::Err code.", + "maixpy": "maix.peripheral.pwm.PWM.duty_val", + "py_doc": "set pwm duty value\n\nArgs:\n - duty_val: direction [in], pwm duty value. int type. default is -1\nduty_val > 0 means set duty_val\nduty_val == -1 or not set, return current duty_val\n\n\nReturns: int type\nwhen get duty_val, return current duty_val, else return -err::Err code.\n" + }, + "args": [ + [ + "int", + "duty_val", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int duty_val(int duty_val = -1)" + }, + "freq": { + "type": "func", + "name": "freq", + "doc": { + "brief": "get or set pwm frequency", + "param": { + "freq": "direction [in], pwm frequency. int type. default is -1\nfreq >= 0, set freq\nfreq == -1 or not set, return current freq" + }, + "return": "int type, current freq, if set and set failed will return -err::Err", + "maixpy": "maix.peripheral.pwm.PWM.freq", + "py_doc": "get or set pwm frequency\n\nArgs:\n - freq: direction [in], pwm frequency. int type. default is -1\nfreq >= 0, set freq\nfreq == -1 or not set, return current freq\n\n\nReturns: int type, current freq, if set and set failed will return -err::Err\n" + }, + "args": [ + [ + "int", + "freq", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int freq(int freq = -1)" + }, + "enable": { + "type": "func", + "name": "enable", + "doc": { + "brief": "set pwm enable", + "return": "err::Err type, err.Err.ERR_NONE means success", + "maixpy": "maix.peripheral.pwm.PWM.enable", + "py_doc": "set pwm enable\n\nReturns: err::Err type, err.Err.ERR_NONE means success\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err enable()" + }, + "disable": { + "type": "func", + "name": "disable", + "doc": { + "brief": "set pwm disable", + "return": "err::Err type, err.Err.ERR_NONE means success", + "maixpy": "maix.peripheral.pwm.PWM.disable", + "py_doc": "set pwm disable\n\nReturns: err::Err type, err.Err.ERR_NONE means success\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err disable()" + }, + "is_enabled": { + "type": "func", + "name": "is_enabled", + "doc": { + "brief": "get pwm enable status", + "return": "bool type, true means enable, false means disable", + "maixpy": "maix.peripheral.pwm.PWM.is_enabled", + "py_doc": "get pwm enable status\n\nReturns: bool type, true means enable, false means disable\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool is_enabled()" + } + }, + "def": "class PWM" + } + }, + "auto_add": true + }, + "gpio": { + "type": "module", + "doc": { + "brief": "maix.peripheral.gpio module" + }, + "members": { + "Mode": { + "type": "enum", + "name": "Mode", + "doc": { + "brief": "GPIO mode", + "maixpy": "maix.peripheral.gpio.Mode", + "py_doc": "GPIO mode" + }, + "values": [ + [ + "IN", + "0x01", + "input mode" + ], + [ + "OUT", + "0x02", + "output mode" + ], + [ + "OUT_OD", + "0x03", + "output open drain mode" + ], + [ + "MODE_MAX", + "", + "" + ] + ], + "def": "enum Mode\n {\n IN = 0x01, // input mode\n OUT = 0x02, // output mode\n OUT_OD = 0x03, // output open drain mode\n MODE_MAX\n }" + }, + "Pull": { + "type": "enum", + "name": "Pull", + "doc": { + "brief": "GPIO pull mode", + "maixpy": "maix.peripheral.gpio.Pull", + "py_doc": "GPIO pull mode" + }, + "values": [ + [ + "PULL_NONE", + "0x00", + "pull none mode" + ], + [ + "PULL_UP", + "0x01", + "pull up mode" + ], + [ + "PULL_DOWN", + "0x02", + "pull down mode" + ], + [ + "PULL_MAX", + "", + "" + ] + ], + "def": "enum Pull\n {\n PULL_NONE = 0x00, // pull none mode\n PULL_UP = 0x01, // pull up mode\n PULL_DOWN = 0x02, // pull down mode\n PULL_MAX\n }" + }, + "GPIO": { + "type": "class", + "name": "GPIO", + "doc": { + "brief": "Peripheral gpio class", + "maixpy": "maix.peripheral.gpio.GPIO", + "py_doc": "Peripheral gpio class" + }, + "members": { + "__init__": { + "type": "func", + "name": "GPIO", + "doc": { + "brief": "GPIO constructor", + "param": { + "pin": "direction [in], gpio pin name, string type the same as board's pin name, e.g. \"B14\" or \"GPIOB14\", or number string like \"10\" if board no gpiochipe name.", + "mode": "direction [in], gpio mode. gpio.Mode type, default is gpio.Mode.IN (input) mode.", + "pull": "direction [in], gpio pull. gpio.Pull type, default is gpio.Pull.PULL_NONE (pull none) mode.\nFor input mode, this will set gpio default status(value), if set to gpio.Pull.PULL_NONE, gpio value will be floating.\nFor output mode, this will set gpio default status(value), if set to gpio.Pull.PULL_UP, gpio value will be 1, else 0." + }, + "throw": "err::Exception if open gpio device failed.", + "maixpy": "maix.peripheral.gpio.GPIO.__init__", + "py_doc": "GPIO constructor\n\nArgs:\n - pin: direction [in], gpio pin name, string type the same as board's pin name, e.g. \"B14\" or \"GPIOB14\", or number string like \"10\" if board no gpiochipe name.\n - mode: direction [in], gpio mode. gpio.Mode type, default is gpio.Mode.IN (input) mode.\n - pull: direction [in], gpio pull. gpio.Pull type, default is gpio.Pull.PULL_NONE (pull none) mode.\nFor input mode, this will set gpio default status(value), if set to gpio.Pull.PULL_NONE, gpio value will be floating.\nFor output mode, this will set gpio default status(value), if set to gpio.Pull.PULL_UP, gpio value will be 1, else 0.\n" + }, + "args": [ + [ + "std::string", + "pin", + null + ], + [ + "gpio::Mode", + "mode", + "gpio::Mode::IN" + ], + [ + "gpio::Pull", + "pull", + "gpio::Pull::PULL_NONE" + ] + ], + "ret_type": null, + "static": false, + "def": "GPIO(std::string pin, gpio::Mode mode = gpio::Mode::IN, gpio::Pull pull = gpio::Pull::PULL_NONE)", + "py_def": "def __init__(self, pin: str, mode: Mode = ..., pull: Pull = ...) -> None" + }, + "value": { + "type": "func", + "name": "value", + "doc": { + "brief": "set and get gpio value", + "param": { + "value": "direction [in], gpio value. int type.\n0, means write gpio to low level\n1, means write gpio to high level\n-1, means read gpio value, not set" + }, + "return": "int type, return gpio value, can be 0 or 1", + "maixpy": "maix.peripheral.gpio.GPIO.value", + "py_doc": "set and get gpio value\n\nArgs:\n - value: direction [in], gpio value. int type.\n0, means write gpio to low level\n1, means write gpio to high level\n-1, means read gpio value, not set\n\n\nReturns: int type, return gpio value, can be 0 or 1\n" + }, + "args": [ + [ + "int", + "value", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int value(int value = -1)", + "py_def": "def value(self, value: int = -1) -> int" + }, + "high": { + "type": "func", + "name": "high", + "doc": { + "brief": "set gpio high (value to 1)", + "maixpy": "maix.peripheral.gpio.GPIO.high", + "py_doc": "set gpio high (value to 1)" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void high()", + "py_def": "def high(self) -> None" + }, + "low": { + "type": "func", + "name": "low", + "doc": { + "brief": "set gpio low (value to 0)", + "maixpy": "maix.peripheral.gpio.GPIO.low", + "py_doc": "set gpio low (value to 0)" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void low()", + "py_def": "def low(self) -> None" + }, + "toggle": { + "type": "func", + "name": "toggle", + "doc": { + "brief": "gpio toggle", + "maixpy": "maix.peripheral.gpio.GPIO.toggle", + "py_doc": "gpio toggle" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void toggle()", + "py_def": "def toggle(self) -> None" + } + }, + "def": "class GPIO" + } + }, + "auto_add": true + }, + "wdt": { + "type": "module", + "doc": { + "brief": "maix.peripheral.wdt module" + }, + "members": { + "WDT": { + "type": "class", + "name": "WDT", + "doc": { + "brief": "Peripheral wdt class", + "maixpy": "maix.peripheral.wdt.WDT", + "py_doc": "Peripheral wdt class" + }, + "members": { + "__init__": { + "type": "func", + "name": "WDT", + "doc": { + "brief": "WDT constructor, after construct, the wdt will auto start.", + "param": { + "id": "direction [in], id of wdt, int type", + "feed_ms": "direction [in], feed interval, int type, unit is ms, you must feed wdt in this interval, or system will restart." + }, + "maixpy": "maix.peripheral.wdt.WDT.__init__", + "py_doc": "WDT constructor, after construct, the wdt will auto start.\n\nArgs:\n - id: direction [in], id of wdt, int type\n - feed_ms: direction [in], feed interval, int type, unit is ms, you must feed wdt in this interval, or system will restart.\n" + }, + "args": [ + [ + "int", + "id", + null + ], + [ + "int", + "feed_ms", + null + ] + ], + "ret_type": null, + "static": false, + "def": "WDT(int id, int feed_ms)" + }, + "feed": { + "type": "func", + "name": "feed", + "doc": { + "brief": "feed wdt", + "return": "error code, if feed success, return err::ERR_NONE", + "maixpy": "maix.peripheral.wdt.WDT.feed", + "py_doc": "feed wdt\n\nReturns: error code, if feed success, return err::ERR_NONE\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int feed()" + }, + "stop": { + "type": "func", + "name": "stop", + "doc": { + "brief": "stop wdt", + "maixpy": "maix.peripheral.wdt.WDT.stop", + "py_doc": "stop wdt" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int stop()" + }, + "restart": { + "type": "func", + "name": "restart", + "doc": { + "brief": "restart wdt, stop and start watchdog timer.", + "maixpy": "maix.peripheral.wdt.WDT.restart", + "py_doc": "restart wdt, stop and start watchdog timer." + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int restart()" + } + }, + "def": "class WDT" + } + }, + "auto_add": true + } + }, + "auto_add": true + }, + "util": { + "type": "module", + "doc": { + "brief": "maix.util module" + }, + "members": { + "disable_kernel_debug": { + "type": "func", + "name": "disable_kernel_debug", + "doc": { + "brief": "disable the kernel debug", + "maixpy": "maix.util.disable_kernel_debug", + "py_doc": "disable the kernel debug" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void disable_kernel_debug()", + "py_def": "def disable_kernel_debug() -> None" + }, + "enable_kernel_debug": { + "type": "func", + "name": "enable_kernel_debug", + "doc": { + "brief": "disable the kernel debug", + "maixpy": "maix.util.enable_kernel_debug", + "py_doc": "disable the kernel debug" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void enable_kernel_debug()", + "py_def": "def enable_kernel_debug() -> None" + } + }, + "auto_add": true + }, + "time": { + "type": "module", + "doc": { + "brief": "maix.time module" + }, + "members": { + "time": { + "type": "func", + "name": "time", + "doc": { + "brief": "Get current time in s", + "return": "current time in s, double type", + "maixpy": "maix.time.time", + "py_doc": "Get current time in s\n\nReturns: current time in s, double type\n" + }, + "args": [], + "ret_type": "double", + "static": false, + "def": "double time()", + "py_def": "def time() -> float" + }, + "time_ms": { + "type": "func", + "name": "time_ms", + "doc": { + "brief": "Get current time in ms", + "return": "current time in ms, uint64_t type", + "maixpy": "maix.time.time_ms", + "py_doc": "Get current time in ms\n\nReturns: current time in ms, uint64_t type\n" + }, + "args": [], + "ret_type": "uint64_t", + "static": false, + "def": "uint64_t time_ms()", + "py_def": "def time_ms() -> int" + }, + "time_s": { + "type": "func", + "name": "time_s", + "doc": { + "brief": "Get current time in s", + "return": "current time in s, uint64_t type", + "maixpy": "maix.time.time_s", + "py_doc": "Get current time in s\n\nReturns: current time in s, uint64_t type\n" + }, + "args": [], + "ret_type": "uint64_t", + "static": false, + "def": "uint64_t time_s()", + "py_def": "def time_s() -> int" + }, + "time_us": { + "type": "func", + "name": "time_us", + "doc": { + "brief": "Get current time in us", + "return": "current time in us, uint64_t type", + "maixpy": "maix.time.time_us", + "py_doc": "Get current time in us\n\nReturns: current time in us, uint64_t type\n" + }, + "args": [], + "ret_type": "uint64_t", + "static": false, + "def": "uint64_t time_us()", + "py_def": "def time_us() -> int" + }, + "time_diff": { + "type": "func", + "name": "time_diff", + "doc": { + "brief": "Calculate time difference", + "param": { + "last": "last time", + "now": "current time" + }, + "return": "time difference", + "maixpy": "maix.time.time_diff", + "py_doc": "Calculate time difference\n\nArgs:\n - last: last time\n - now: current time\n\n\nReturns: time difference\n" + }, + "args": [ + [ + "double", + "last", + null + ], + [ + "double", + "now", + "-1" + ] + ], + "ret_type": "double", + "static": false, + "def": "double time_diff(double last, double now = -1)", + "py_def": "def time_diff(last: float, now: float = -1) -> float" + }, + "sleep": { + "type": "func", + "name": "sleep", + "doc": { + "brief": "Sleep seconds", + "param": { + "s": "seconds, double type" + }, + "maixpy": "maix.time.sleep", + "py_doc": "Sleep seconds\n\nArgs:\n - s: seconds, double type\n" + }, + "args": [ + [ + "double", + "s", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void sleep(double s)", + "py_def": "def sleep(s: float) -> None" + }, + "sleep_ms": { + "type": "func", + "name": "sleep_ms", + "doc": { + "brief": "Sleep milliseconds", + "param": { + "ms": "milliseconds, uint64_t type" + }, + "maixpy": "maix.time.sleep_ms", + "py_doc": "Sleep milliseconds\n\nArgs:\n - ms: milliseconds, uint64_t type\n" + }, + "args": [ + [ + "uint64_t", + "ms", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void sleep_ms(uint64_t ms)", + "py_def": "def sleep_ms(ms: int) -> None" + }, + "sleep_us": { + "type": "func", + "name": "sleep_us", + "doc": { + "brief": "Sleep microseconds", + "param": { + "us": "microseconds, uint64_t type" + }, + "maixpy": "maix.time.sleep_us", + "py_doc": "Sleep microseconds\n\nArgs:\n - us: microseconds, uint64_t type\n" + }, + "args": [ + [ + "uint64_t", + "us", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void sleep_us(uint64_t us)", + "py_def": "def sleep_us(us: int) -> None" + }, + "DateTime": { + "type": "class", + "name": "DateTime", + "doc": { + "brief": "Date and time class", + "maixpy": "maix.time.DateTime", + "py_doc": "Date and time class" + }, + "members": { + "year": { + "type": "var", + "name": "year", + "doc": { + "brief": "Year", + "maixpy": "maix.time.DateTime.year", + "py_doc": "Year" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int year" + }, + "month": { + "type": "var", + "name": "month", + "doc": { + "brief": "Month, 1~12", + "maixpy": "maix.time.DateTime.month", + "py_doc": "Month, 1~12" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int month" + }, + "day": { + "type": "var", + "name": "day", + "doc": { + "brief": "Day", + "maixpy": "maix.time.DateTime.day", + "py_doc": "Day" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int day" + }, + "hour": { + "type": "var", + "name": "hour", + "doc": { + "brief": "Hour", + "maixpy": "maix.time.DateTime.hour", + "py_doc": "Hour" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int hour" + }, + "minute": { + "type": "var", + "name": "minute", + "doc": { + "brief": "Minute", + "maixpy": "maix.time.DateTime.minute", + "py_doc": "Minute" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int minute" + }, + "second": { + "type": "var", + "name": "second", + "doc": { + "brief": "Second", + "maixpy": "maix.time.DateTime.second", + "py_doc": "Second" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int second" + }, + "microsecond": { + "type": "var", + "name": "microsecond", + "doc": { + "brief": "Microsecond", + "maixpy": "maix.time.DateTime.microsecond", + "py_doc": "Microsecond" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int microsecond" + }, + "yearday": { + "type": "var", + "name": "yearday", + "doc": { + "brief": "Year day", + "maixpy": "maix.time.DateTime.yearday", + "py_doc": "Year day" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int yearday" + }, + "weekday": { + "type": "var", + "name": "weekday", + "doc": { + "brief": "Weekday, 0 is Monday, 6 is Sunday", + "maixpy": "maix.time.DateTime.weekday", + "py_doc": "Weekday, 0 is Monday, 6 is Sunday" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int weekday" + }, + "zone": { + "type": "var", + "name": "zone", + "doc": { + "brief": "Time zone", + "maixpy": "maix.time.DateTime.zone", + "py_doc": "Time zone" + }, + "value": null, + "static": false, + "readonly": false, + "def": "float zone" + }, + "zone_name": { + "type": "var", + "name": "zone_name", + "doc": { + "brief": "Time zone name", + "maixpy": "maix.time.DateTime.zone_name", + "py_doc": "Time zone name" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::string zone_name" + }, + "__init__": { + "type": "func", + "name": "DateTime", + "doc": { + "brief": "Constructor", + "param": { + "year": "year", + "month": "month", + "day": "day", + "hour": "hour", + "minute": "minute", + "second": "second", + "microsecond": "microsecond", + "yearday": "year day", + "weekday": "weekday", + "zone": "time zone" + }, + "maixcdk": "maix.time.DateTime.DateTime", + "maixpy": "maix.time.DateTime.__init__", + "py_doc": "Constructor\n\nArgs:\n - year: year\n - month: month\n - day: day\n - hour: hour\n - minute: minute\n - second: second\n - microsecond: microsecond\n - yearday: year day\n - weekday: weekday\n - zone: time zone\n" + }, + "args": [ + [ + "int", + "year", + "0" + ], + [ + "int", + "month", + "0" + ], + [ + "int", + "day", + "0" + ], + [ + "int", + "hour", + "0" + ], + [ + "int", + "minute", + "0" + ], + [ + "int", + "second", + "0" + ], + [ + "int", + "microsecond", + "0" + ], + [ + "int", + "yearday", + "0" + ], + [ + "int", + "weekday", + "0" + ], + [ + "int", + "zone", + "0" + ] + ], + "ret_type": null, + "static": false, + "def": "DateTime(int year = 0, int month = 0, int day = 0, int hour = 0, int minute = 0, int second = 0, int microsecond = 0, int yearday = 0, int weekday = 0, int zone = 0)", + "py_def": "def __init__(self, year: int = 0, month: int = 0, day: int = 0, hour: int = 0, minute: int = 0, second: int = 0, microsecond: int = 0, yearday: int = 0, weekday: int = 0, zone: int = 0) -> None" + }, + "strftime": { + "type": "func", + "name": "strftime", + "doc": { + "brief": "Convert to string", + "return": "date time string", + "maixpy": "maix.time.DateTime.strftime", + "py_doc": "Convert to string\n\nReturns: date time string\n" + }, + "args": [ + [ + "const std::string &", + "format", + null + ] + ], + "ret_type": "std::string", + "static": false, + "def": "std::string strftime(const std::string &format)", + "py_def": "def strftime(self, format: str) -> str" + }, + "timestamp": { + "type": "func", + "name": "timestamp", + "doc": { + "brief": "Convert to float timestamp", + "return": "float timestamp", + "maixpy": "maix.time.DateTime.timestamp", + "py_doc": "Convert to float timestamp\n\nReturns: float timestamp\n" + }, + "args": [], + "ret_type": "double", + "static": false, + "def": "double timestamp()", + "py_def": "def timestamp(self) -> float" + } + }, + "def": "class DateTime" + }, + "now": { + "type": "func", + "name": "now", + "doc": { + "brief": "Get current UTC date and time", + "return": "current date and time, DateTime type", + "maixpy": "maix.time.now", + "py_doc": "Get current UTC date and time\n\nReturns: current date and time, DateTime type\n" + }, + "args": [], + "ret_type": "time::DateTime*", + "static": false, + "def": "time::DateTime *now()", + "py_def": "def now() -> DateTime" + }, + "localtime": { + "type": "func", + "name": "localtime", + "doc": { + "brief": "Get local time", + "return": "local time, DateTime type", + "maixpy": "maix.time.localtime", + "py_doc": "Get local time\n\nReturns: local time, DateTime type\n" + }, + "args": [], + "ret_type": "time::DateTime*", + "static": false, + "def": "time::DateTime *localtime()", + "py_def": "def localtime() -> DateTime" + }, + "strptime": { + "type": "func", + "name": "strptime", + "doc": { + "brief": "DateTime from string", + "param": { + "str": "date time string", + "format": "date time format" + }, + "return": "DateTime", + "maixpy": "maix.time.strptime", + "py_doc": "DateTime from string\n\nArgs:\n - str: date time string\n - format: date time format\n\n\nReturns: DateTime\n" + }, + "args": [ + [ + "const std::string &", + "str", + null + ], + [ + "const std::string &", + "format", + null + ] + ], + "ret_type": "time::DateTime*", + "static": false, + "def": "time::DateTime *strptime(const std::string &str, const std::string &format)", + "py_def": "def strptime(str: str, format: str) -> DateTime" + }, + "gmtime": { + "type": "func", + "name": "gmtime", + "doc": { + "brief": "timestamp to DateTime(time zone is UTC (value 0))", + "param": { + "timestamp": "double timestamp" + }, + "return": "DateTime", + "maixpy": "maix.time.gmtime", + "py_doc": "timestamp to DateTime(time zone is UTC (value 0))\n\nArgs:\n - timestamp: double timestamp\n\n\nReturns: DateTime\n" + }, + "args": [ + [ + "double", + "timestamp", + null + ] + ], + "ret_type": "time::DateTime*", + "static": false, + "def": "time::DateTime *gmtime(double timestamp)" + } + }, + "auto_add": true + }, + "app": { + "type": "module", + "doc": { + "brief": "maix.app module" + }, + "members": { + "Version": { + "type": "class", + "name": "Version", + "doc": { + "brief": "APP version", + "maixpy": "maix.app.Version", + "py_doc": "APP version" + }, + "members": { + "__str__": { + "type": "func", + "name": "__str__", + "doc": { + "brief": "Convert to string, e.g. 1.0.0", + "maixpy": "maix.app.Version.__str__", + "py_doc": "Convert to string, e.g. 1.0.0" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string __str__()" + }, + "from_str": { + "type": "func", + "name": "from_str", + "doc": { + "brief": "Convert from string, e.g. \\\"1.0.0\\\"", + "maixpy": "maix.app.Version.from_str", + "py_doc": "Convert from string, e.g. \"1.0.0\"" + }, + "args": [ + [ + "const string &", + "version_str", + null + ] + ], + "ret_type": "app::Version", + "static": true, + "def": "static app::Version from_str(const string &version_str)" + } + }, + "def": "class Version" + }, + "APP_Info": { + "type": "class", + "name": "APP_Info", + "doc": { + "brief": "APP info", + "maixpy": "maix.app.APP_Info", + "py_doc": "APP info" + }, + "members": { + "id": { + "type": "var", + "name": "id", + "doc": { + "brief": "APP id", + "maixpy": "maix.app.APP_Info.id", + "py_doc": "APP id" + }, + "value": null, + "static": false, + "readonly": false, + "def": "string id" + }, + "name": { + "type": "var", + "name": "name", + "doc": { + "brief": "APP name", + "maixpy": "maix.app.APP_Info.name", + "py_doc": "APP name" + }, + "value": null, + "static": false, + "readonly": false, + "def": "string name" + }, + "icon": { + "type": "var", + "name": "icon", + "doc": { + "brief": "APP icon", + "maixpy": "maix.app.APP_Info.icon", + "py_doc": "APP icon" + }, + "value": null, + "static": false, + "readonly": false, + "def": "string icon" + }, + "version": { + "type": "var", + "name": "version", + "doc": { + "brief": "APP version", + "maixpy": "maix.app.APP_Info.version", + "py_doc": "APP version" + }, + "value": null, + "static": false, + "readonly": false, + "def": "Version version" + }, + "exec": { + "type": "var", + "name": "exec", + "doc": { + "brief": "APP exec", + "maixpy": "maix.app.APP_Info.exec", + "py_doc": "APP exec" + }, + "value": null, + "static": false, + "readonly": false, + "def": "string exec" + }, + "author": { + "type": "var", + "name": "author", + "doc": { + "brief": "APP author", + "maixpy": "maix.app.APP_Info.author", + "py_doc": "APP author" + }, + "value": null, + "static": false, + "readonly": false, + "def": "string author" + }, + "desc": { + "type": "var", + "name": "desc", + "doc": { + "brief": "APP desc", + "maixpy": "maix.app.APP_Info.desc", + "py_doc": "APP desc" + }, + "value": null, + "static": false, + "readonly": false, + "def": "string desc" + }, + "names": { + "type": "var", + "name": "names", + "doc": { + "brief": "APP names", + "maixpy": "maix.app.APP_Info.names", + "py_doc": "APP names" + }, + "value": null, + "static": false, + "readonly": false, + "def": "map names" + }, + "descs": { + "type": "var", + "name": "descs", + "doc": { + "brief": "APP descs", + "maixpy": "maix.app.APP_Info.descs", + "py_doc": "APP descs" + }, + "value": null, + "static": false, + "readonly": false, + "def": "map descs" + } + }, + "def": "class APP_Info" + }, + "app_id": { + "type": "func", + "name": "app_id", + "doc": { + "brief": "Get current APP ID.", + "return": "APP ID.", + "maixpy": "maix.app.app_id", + "py_doc": "Get current APP ID.\n\nReturns: APP ID.\n" + }, + "args": [], + "ret_type": "string", + "static": false, + "def": "string app_id()", + "py_def": "def app_id() -> str" + }, + "set_app_id": { + "type": "func", + "name": "set_app_id", + "doc": { + "brief": "Set current APP ID.", + "param": { + "app_id": "APP ID." + }, + "maixpy": "maix.app.set_app_id", + "py_doc": "Set current APP ID.\n\nArgs:\n - app_id: APP ID.\n" + }, + "args": [ + [ + "const string &", + "app_id", + null + ] + ], + "ret_type": "string", + "static": false, + "def": "string set_app_id(const string &app_id)", + "py_def": "def set_app_id(app_id: str) -> str" + }, + "get_apps_info_path": { + "type": "func", + "name": "get_apps_info_path", + "doc": { + "brief": "Get APP info file path.", + "maixpy": "maix.app.get_apps_info_path", + "py_doc": "Get APP info file path." + }, + "args": [], + "ret_type": "string", + "static": false, + "def": "string get_apps_info_path()", + "py_def": "def get_apps_info_path() -> str" + }, + "get_apps_info": { + "type": "func", + "name": "get_apps_info", + "doc": { + "brief": "Get APP info list.", + "param": { + "ignore_launcher": "if true, ignore launcher APP. default false.", + "ignore_app_store": "if true, ignore app store APP. default false." + }, + "return": "APP info list. APP_Info object list.", + "maixpy": "maix.app.get_apps_info", + "py_doc": "Get APP info list.\n\nArgs:\n - ignore_launcher: if true, ignore launcher APP. default false.\n - ignore_app_store: if true, ignore app store APP. default false.\n\n\nReturns: APP info list. APP_Info object list.\n" + }, + "args": [ + [ + "bool", + "ignore_launcher", + "false" + ], + [ + "bool", + "ignore_app_store", + "false" + ] + ], + "ret_type": "vector&", + "static": false, + "def": "vector &get_apps_info(bool ignore_launcher = false, bool ignore_app_store = false)", + "py_def": "def get_apps_info(ignore_launcher: bool = False, ignore_app_store: bool = False) -> list[APP_Info]" + }, + "get_app_data_path": { + "type": "func", + "name": "get_app_data_path", + "doc": { + "brief": "Get APP info, APP can store private data in this directory.", + "return": "APP data path \"./data\", just return the data folder in current path because APP executed in app install path or project path.\nSo, you must execute your program in you project path to use the project/data folder when you debug your APP.", + "maixpy": "maix.app.get_app_data_path", + "py_doc": "Get APP info, APP can store private data in this directory.\n\nReturns: APP data path \"./data\", just return the data folder in current path because APP executed in app install path or project path.\nSo, you must execute your program in you project path to use the project/data folder when you debug your APP.\n" + }, + "args": [], + "ret_type": "string", + "static": false, + "def": "string get_app_data_path()", + "py_def": "def get_app_data_path() -> str" + }, + "get_app_path": { + "type": "func", + "name": "get_app_path", + "doc": { + "brief": "Get APP path.", + "param": { + "app_id": "APP ID, if empty, return current APP path, else return the APP path by app_id." + }, + "return": "APP path, just return the current path because APP executed in app install path or project path.\nSo, you must execute your program in you project path to use the project/data folder when you debug your APP.", + "maixpy": "maix.app.get_app_path", + "py_doc": "Get APP path.\n\nArgs:\n - app_id: APP ID, if empty, return current APP path, else return the APP path by app_id.\n\n\nReturns: APP path, just return the current path because APP executed in app install path or project path.\nSo, you must execute your program in you project path to use the project/data folder when you debug your APP.\n" + }, + "args": [ + [ + "const string &", + "app_id", + "\"\"" + ] + ], + "ret_type": "string", + "static": false, + "def": "string get_app_path(const string &app_id = \"\")", + "py_def": "def get_app_path(app_id: str = '') -> str" + }, + "get_tmp_path": { + "type": "func", + "name": "get_tmp_path", + "doc": { + "brief": "Get global temporary data path, APPs can use this path as temporary data directory.", + "return": "temporary data path.", + "maixpy": "maix.app.get_tmp_path", + "py_doc": "Get global temporary data path, APPs can use this path as temporary data directory.\n\nReturns: temporary data path.\n" + }, + "args": [], + "ret_type": "string", + "static": false, + "def": "string get_tmp_path()", + "py_def": "def get_tmp_path() -> str" + }, + "get_share_path": { + "type": "func", + "name": "get_share_path", + "doc": { + "brief": "Get data path of share, shared data like picture and video will put in this directory", + "return": "share data path.", + "maixpy": "maix.app.get_share_path", + "py_doc": "Get data path of share, shared data like picture and video will put in this directory\n\nReturns: share data path.\n" + }, + "args": [], + "ret_type": "string", + "static": false, + "def": "string get_share_path()", + "py_def": "def get_share_path() -> str" + }, + "get_picture_path": { + "type": "func", + "name": "get_picture_path", + "doc": { + "brief": "Get picture path of share, shared picture will put in this directory", + "return": "share picture path.", + "maixpy": "maix.app.get_picture_path", + "py_doc": "Get picture path of share, shared picture will put in this directory\n\nReturns: share picture path.\n" + }, + "args": [], + "ret_type": "string", + "static": false, + "def": "string get_picture_path()", + "py_def": "def get_picture_path() -> str" + }, + "get_video_path": { + "type": "func", + "name": "get_video_path", + "doc": { + "brief": "Get video path of share, shared video will put in this directory", + "return": "share video path.", + "maixpy": "maix.app.get_video_path", + "py_doc": "Get video path of share, shared video will put in this directory\n\nReturns: share video path.\n" + }, + "args": [], + "ret_type": "string", + "static": false, + "def": "string get_video_path()", + "py_def": "def get_video_path() -> str" + }, + "get_font_path": { + "type": "func", + "name": "get_font_path", + "doc": { + "brief": "Get font path of share, shared font will put in this directory", + "return": "share font path.", + "maixpy": "maix.app.get_font_path", + "py_doc": "Get font path of share, shared font will put in this directory\n\nReturns: share font path.\n" + }, + "args": [], + "ret_type": "string", + "static": false, + "def": "string get_font_path()", + "py_def": "def get_font_path() -> str" + }, + "get_icon_path": { + "type": "func", + "name": "get_icon_path", + "doc": { + "brief": "Get icon path of share, shared icon will put in this directory", + "return": "share icon path.", + "maixpy": "maix.app.get_icon_path", + "py_doc": "Get icon path of share, shared icon will put in this directory\n\nReturns: share icon path.\n" + }, + "args": [], + "ret_type": "string", + "static": false, + "def": "string get_icon_path()", + "py_def": "def get_icon_path() -> str" + }, + "get_sys_config_kv": { + "type": "func", + "name": "get_sys_config_kv", + "doc": { + "brief": "Get system config item value.", + "param": { + "item": "name of setting item, e.g. wifi, language. more see settings APP.", + "key": "config key, e.g. for wifi, key can be ssid, for language, key can be locale.", + "value": "default value, if not found, return this value.", + "from_cache": "if true, read from cache, if false, read from file." + }, + "return": "config value, always string type, if not found, return empty string.", + "maixpy": "maix.app.get_sys_config_kv", + "py_doc": "Get system config item value.\n\nArgs:\n - item: name of setting item, e.g. wifi, language. more see settings APP.\n - key: config key, e.g. for wifi, key can be ssid, for language, key can be locale.\n - value: default value, if not found, return this value.\n - from_cache: if true, read from cache, if false, read from file.\n\n\nReturns: config value, always string type, if not found, return empty string.\n" + }, + "args": [ + [ + "const string &", + "item", + null + ], + [ + "const string &", + "key", + null + ], + [ + "const string &", + "value", + "\"\"" + ], + [ + "bool", + "from_cache", + "true" + ] + ], + "ret_type": "string", + "static": false, + "def": "string get_sys_config_kv(const string &item, const string &key, const string &value = \"\", bool from_cache = true)", + "py_def": "def get_sys_config_kv(item: str, key: str, value: str = '', from_cache: bool = True) -> str" + }, + "get_app_config_kv": { + "type": "func", + "name": "get_app_config_kv", + "doc": { + "brief": "Get APP config item value.", + "param": { + "item": "name of setting item, e.g. user_info", + "key": "config key, e.g. for user_info, key can be name, age etc.", + "value": "default value, if not found, return this value.", + "from_cache": "if true, read from cache, if false, read from file." + }, + "return": "config value, always string type, if not found, return empty string.", + "maixpy": "maix.app.get_app_config_kv", + "py_doc": "Get APP config item value.\n\nArgs:\n - item: name of setting item, e.g. user_info\n - key: config key, e.g. for user_info, key can be name, age etc.\n - value: default value, if not found, return this value.\n - from_cache: if true, read from cache, if false, read from file.\n\n\nReturns: config value, always string type, if not found, return empty string.\n" + }, + "args": [ + [ + "const string &", + "item", + null + ], + [ + "const string &", + "key", + null + ], + [ + "const string &", + "value", + "\"\"" + ], + [ + "bool", + "from_cache", + "true" + ] + ], + "ret_type": "string", + "static": false, + "def": "string get_app_config_kv(const string &item, const string &key, const string &value = \"\", bool from_cache = true)", + "py_def": "def get_app_config_kv(item: str, key: str, value: str = '', from_cache: bool = True) -> str" + }, + "set_app_config_kv": { + "type": "func", + "name": "set_app_config_kv", + "doc": { + "brief": "Set APP config item value.", + "param": { + "item": "name of setting item, e.g. user_info", + "key": "config key, e.g. for user_info, key can be name, age etc.", + "value": "config value, always string type.", + "write_file": "if true, write to file, if false, just write to cache." + }, + "return": "err::Err", + "maixpy": "maix.app.set_app_config_kv", + "py_doc": "Set APP config item value.\n\nArgs:\n - item: name of setting item, e.g. user_info\n - key: config key, e.g. for user_info, key can be name, age etc.\n - value: config value, always string type.\n - write_file: if true, write to file, if false, just write to cache.\n\n\nReturns: err::Err\n" + }, + "args": [ + [ + "const string &", + "item", + null + ], + [ + "const string &", + "key", + null + ], + [ + "const string &", + "value", + null + ], + [ + "bool", + "write_file", + "true" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err set_app_config_kv(const string &item, const string &key, const string &value, bool write_file = true)", + "py_def": "def set_app_config_kv(item: str, key: str, value: str, write_file: bool = True) -> maix.err.Err" + }, + "get_app_config_path": { + "type": "func", + "name": "get_app_config_path", + "doc": { + "brief": "Get APP config path, ini format, so you can use your own ini parser to parse it like `configparser` in Python.\\nAll APP config info is recommended to store in this file.", + "return": "APP config path(ini format).", + "maixpy": "maix.app.get_app_config_path", + "py_doc": "Get APP config path, ini format, so you can use your own ini parser to parse it like `configparser` in Python.\nAll APP config info is recommended to store in this file.\n\nReturns: APP config path(ini format).\n" + }, + "args": [], + "ret_type": "string", + "static": false, + "def": "string get_app_config_path()", + "py_def": "def get_app_config_path() -> str" + }, + "set_exit_msg": { + "type": "func", + "name": "set_exit_msg", + "doc": { + "brief": "Set APP exit code and exit message.\\nIf code != 0, the launcher will show a dialog to user, and display the msg.", + "param": { + "code": "exit code, 0 means success, other means error, if code is 0, do nothing.", + "msg": "exit message, if code is 0, msg is not used." + }, + "return": "exit code, the same as arg @code.", + "maixpy": "maix.app.set_exit_msg", + "py_doc": "Set APP exit code and exit message.\nIf code != 0, the launcher will show a dialog to user, and display the msg.\n\nArgs:\n - code: exit code, 0 means success, other means error, if code is 0, do nothing.\n - msg: exit message, if code is 0, msg is not used.\n\n\nReturns: exit code, the same as arg @code.\n" + }, + "args": [ + [ + "err::Err", + "code", + null + ], + [ + "const string &", + "msg", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err set_exit_msg(err::Err code, const string &msg)", + "py_def": "def set_exit_msg(code: maix.err.Err, msg: str) -> maix.err.Err" + }, + "get_exit_msg": { + "type": "func", + "name": "get_exit_msg", + "doc": { + "brief": "Get APP exit code and exit message.", + "param": { + "cache": "if true, read from cache, if false, read from file. default false." + }, + "return": "exit return app_id, exit code and exit message.", + "maixpy": "maix.app.get_exit_msg", + "py_doc": "Get APP exit code and exit message.\n\nArgs:\n - cache: if true, read from cache, if false, read from file. default false.\n\n\nReturns: exit return app_id, exit code and exit message.\n" + }, + "args": [ + [ + "bool", + "cache", + "false" + ] + ], + "ret_type": "tuple", + "static": false, + "def": "tuple get_exit_msg(bool cache = false)", + "py_def": "def get_exit_msg(cache: bool = False) -> tuple[str, maix.err.Err, str]" + }, + "have_exit_msg": { + "type": "func", + "name": "have_exit_msg", + "doc": { + "brief": "Check if have exit msg", + "param": { + "cache": "if true, just check from cache, if false, check from file. default false." + }, + "return": "true if have exit msg, false if not.", + "maixpy": "maix.app.have_exit_msg", + "py_doc": "Check if have exit msg\n\nArgs:\n - cache: if true, just check from cache, if false, check from file. default false.\n\n\nReturns: true if have exit msg, false if not.\n" + }, + "args": [ + [ + "bool", + "cache", + "false" + ] + ], + "ret_type": "bool", + "static": false, + "def": "bool have_exit_msg(bool cache = false)", + "py_def": "def have_exit_msg(cache: bool = False) -> bool" + }, + "switch_app": { + "type": "func", + "name": "switch_app", + "doc": { + "brief": "Exit this APP and start another APP(by launcher).\\nCall this API will call set_exit_flag(true), you should check app::need_exit() in your code.\\nAnd exit this APP if app::need_exit() return true.", + "param": { + "app_id": "APP ID which will be started. app_id and idx must have one is valid.", + "idx": "APP index. app_id and idx must have one is valid." + }, + "maixpy": "maix.app.switch_app", + "py_doc": "Exit this APP and start another APP(by launcher).\nCall this API will call set_exit_flag(true), you should check app::need_exit() in your code.\nAnd exit this APP if app::need_exit() return true.\n\nArgs:\n - app_id: APP ID which will be started. app_id and idx must have one is valid.\n - idx: APP index. app_id and idx must have one is valid.\n" + }, + "args": [ + [ + "const string &", + "app_id", + null + ], + [ + "int", + "idx", + "-1" + ] + ], + "ret_type": "void", + "static": false, + "def": "void switch_app(const string &app_id, int idx = -1)", + "py_def": "def switch_app(app_id: str, idx: int = -1) -> None" + }, + "need_exit": { + "type": "func", + "name": "need_exit", + "doc": { + "brief": "Shoule this APP exit?", + "return": "true if this APP should exit, false if not.", + "attention": "This API is a function, not a variable.", + "maixpy": "maix.app.need_exit", + "py_doc": "Shoule this APP exit?\n\nReturns: true if this APP should exit, false if not.\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool need_exit()", + "py_def": "def need_exit() -> bool" + }, + "running": { + "type": "func", + "name": "running", + "doc": { + "brief": "App should running? The same as !app::need_exit() (not app::need_exit() in MaixPy).", + "return": "true if this APP should running, false if not.", + "attention": "This API is a function, not a variable.", + "maixpy": "maix.app.running", + "py_doc": "App should running? The same as !app::need_exit() (not app::need_exit() in MaixPy).\n\nReturns: true if this APP should running, false if not.\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool running()", + "py_def": "def running() -> bool" + }, + "set_exit_flag": { + "type": "func", + "name": "set_exit_flag", + "doc": { + "brief": "Set exit flag. You can get exit flag by app.need_exit().", + "param": { + "exit": "true if this APP should exit, false if not." + }, + "maixpy": "maix.app.set_exit_flag", + "py_doc": "Set exit flag. You can get exit flag by app.need_exit().\n\nArgs:\n - exit: true if this APP should exit, false if not.\n" + }, + "args": [ + [ + "bool", + "exit", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_exit_flag(bool exit)", + "py_def": "def set_exit_flag(exit: bool) -> None" + } + }, + "auto_add": true + }, + "example": { + "type": "module", + "doc": { + "brief": "example module, this will be maix.example module in MaixPy, maix::example namespace in MaixCDK", + "maixpy": "maix.example", + "py_doc": "example module, this will be maix.example module in MaixPy, maix::example namespace in MaixCDK" + }, + "members": { + "Test": { + "type": "class", + "name": "Test", + "doc": { + "brief": "Test class", + "maixpy": "maix.example.Test", + "py_doc": "Test class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Test", + "doc": { + "brief": "Test constructor", + "maixpy": "maix.example.Test.__init__", + "maixcdk": "maix.example.Test.Test", + "py_doc": "Test constructor" + }, + "args": [], + "ret_type": null, + "static": false, + "def": "Test()", + "py_def": "def __init__(self) -> None" + } + }, + "def": "class Test" + }, + "Kind": { + "type": "enum", + "name": "Kind", + "doc": { + "brief": "Example enum", + "maixpy": "maix.example.Kind", + "py_doc": "Example enum" + }, + "values": [ + [ + "KIND_NONE", + "0", + "Kind none, value always 0, other enum value will auto increase" + ], + [ + "KIND_DOG", + "", + "Kind dog" + ], + [ + "KIND_CAT", + "", + "Kind cat, value is auto generated according to KING_DOG" + ], + [ + "KIND_BIRD", + "", + "" + ], + [ + "KIND_MAX", + "", + "Max Kind quantity\nYou can get max Kind value by KIND_MAX - 1" + ] + ], + "def": "enum Kind\n {\n KIND_NONE = 0, /** Kind none, value always 0, other enum value will auto increase */\n KIND_DOG, /** Kind dog*/\n KIND_CAT, // Kind cat, value is auto generated according to KING_DOG\n KIND_BIRD,\n KIND_MAX /* Max Kind quantity,\n You can get max Kind value by KIND_MAX - 1\n */\n }" + }, + "var1": { + "type": "var", + "name": "", + "doc": { + "brief": "Example module variable", + "attention": "It's a copy of this variable in MaixPy,\nso change it in C++ (e.g. update var in hello function) will not take effect the var inMaixPy.\nSo we add const for this var to avoid this mistake.", + "maixpy": "maix.example.var1", + "py_doc": "Example module variable" + }, + "value": "\"Sipeed\"", + "static": false, + "readonly": true, + "def": "const std::string var1 = \"Sipeed\"" + }, + "list_var": { + "type": "var", + "name": "", + "doc": { + "brief": "Tensor data type size in bytes", + "attention": [ + "DO NOT use C/C++ array directly for python API, the python wrapper not support it.\nUse std::vector instead.", + "It's a copy of this variable in MaixPy,\nso change it in C++ (e.g. update var in hello function) will not take effect the var inMaixPy.\nSo we add const for this var to avoid this mistake." + ], + "maixpy": "maix.example.list_var", + "py_doc": "Tensor data type size in bytes" + }, + "value": "{\n 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}", + "static": false, + "readonly": true, + "def": "const std::vector list_var = {\n 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}" + }, + "test_var": { + "type": "var", + "name": "", + "doc": { + "brief": "Example module variable test_var", + "attention": "It's a copy of this variable in MaixPy, so if you change it in C++, it will not take effect in MaixPy.\nAnd change it in MaixPy will not take effect in C++ as well !!!\nIf you want to use vars shared between C++ and MaixPy, you can create a class and use its member.", + "maixpy": "maix.example.test_var", + "py_doc": "Example module variable test_var" + }, + "value": "100", + "static": false, + "readonly": false, + "def": "int test_var = 100" + }, + "hello": { + "type": "func", + "name": "hello", + "doc": { + "brief": "say hello to someone", + "param": { + "name": "direction [in], name of someone, string type" + }, + "return": "string type, content is hello + name", + "maixpy": "maix.example.hello", + "py_doc": "say hello to someone\n\nArgs:\n - name: direction [in], name of someone, string type\n\n\nReturns: string type, content is hello + name\n" + }, + "args": [ + [ + "std::string", + "name", + null + ] + ], + "ret_type": "std::string", + "static": false, + "def": "std::string hello(std::string name)", + "py_def": "def hello(name: str) -> str" + }, + "Example": { + "type": "class", + "name": "Example", + "doc": { + "brief": "Example class\\nthis class will be export to MaixPy as maix.example.Example", + "maixpy": "maix.example.Example", + "py_doc": "Example class\nthis class will be export to MaixPy as maix.example.Example" + }, + "members": { + "__init__": { + "type": "func", + "name": "Example", + "doc": { + "brief": "Example constructor\\nthis constructor will be export to MaixPy as maix.example.Example.__init__", + "param": { + "name": "direction [in], name of Example, string type", + "age": "direction [in], age of Example, int type, default is 18, value range is [0, 100]" + }, + "attention": "to make auto generate code work, param Kind should with full namespace name `example::Kind` instead of `Kind`,\nnamespace `maix` can be ignored.", + "maixpy": "maix.example.Example.__init__", + "maixcdk": "maix.example.Example.Example", + "py_doc": "Example constructor\nthis constructor will be export to MaixPy as maix.example.Example.__init__\n\nArgs:\n - name: direction [in], name of Example, string type\n - age: direction [in], age of Example, int type, default is 18, value range is [0, 100]\n" + }, + "args": [ + [ + "std::string &", + "name", + null + ], + [ + "int", + "age", + "18" + ], + [ + "example::Kind", + "pet", + "example::KIND_NONE" + ] + ], + "ret_type": null, + "static": false, + "def": "Example(std::string &name, int age = 18, example::Kind pet = example::KIND_NONE)", + "py_def": "def __init__(self, name: str, age: int = 18, pet: Kind = ...) -> None" + }, + "get_name": { + "type": "func", + "name": "get_name", + "doc": { + "brief": "get name of Example\\nyou can also get name by property `name`.", + "return": "name of Example, string type", + "maixpy": "maix.example.Example.get_name", + "py_doc": "get name of Example\nyou can also get name by property `name`.\n\nReturns: name of Example, string type\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string get_name()", + "py_def": "def get_name(self) -> str" + }, + "get_age": { + "type": "func", + "name": "get_age", + "doc": { + "brief": "get age of Example", + "return": "age of Example, int type, value range is [0, 100]", + "maixpy": "maix.example.Example.get_age", + "py_doc": "get age of Example\n\nReturns: age of Example, int type, value range is [0, 100]\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int get_age()", + "py_def": "def get_age(self) -> int" + }, + "set_name": { + "type": "func", + "name": "set_name", + "doc": { + "brief": "set name of Example", + "param": { + "name": "name of Example, string type" + }, + "maixpy": "maix.example.Example.set_name", + "py_doc": "set name of Example\n\nArgs:\n - name: name of Example, string type\n" + }, + "args": [ + [ + "std::string", + "name", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_name(std::string name)", + "py_def": "def set_name(self, name: str) -> None" + }, + "set_age": { + "type": "func", + "name": "set_age", + "doc": { + "brief": "set age of Example", + "param": { + "age": "age of Example, int type, value range is [0, 100]" + }, + "maixpy": "maix.example.Example.set_age", + "py_doc": "set age of Example\n\nArgs:\n - age: age of Example, int type, value range is [0, 100]\n" + }, + "args": [ + [ + "int", + "age", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_age(int age)", + "py_def": "def set_age(self, age: int) -> None" + }, + "set_pet": { + "type": "func", + "name": "set_pet", + "doc": { + "brief": "Example enum member", + "attention": "", + "maixpy": "maix.example.Example.set_pet", + "py_doc": "Example enum member" + }, + "args": [ + [ + "example::Kind", + "pet", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_pet(example::Kind pet)", + "py_def": "def set_pet(self, pet: Kind) -> None" + }, + "get_pet": { + "type": "func", + "name": "get_pet", + "doc": { + "brief": "Example enum member", + "maixpy": "maix.example.Example.get_pet", + "py_doc": "Example enum member" + }, + "args": [], + "ret_type": "example::Kind", + "static": false, + "def": "example::Kind get_pet()", + "py_def": "def get_pet(self) -> Kind" + }, + "get_list": { + "type": "func", + "name": "get_list", + "doc": { + "brief": "get list example", + "param": { + "in": "direction [in], input list, items are int type.\nIn MaixPy, you can pass list or tuple to this API" + }, + "return": "list, items are int type, content is [1, 2, 3] + in. Alloc item, del in MaixPy will auto free memory.", + "maixpy": "maix.example.Example.get_list", + "py_doc": "get list example\n\nArgs:\n - in: direction [in], input list, items are int type.\nIn MaixPy, you can pass list or tuple to this API\n\n\nReturns: list, items are int type, content is [1, 2, 3] + in. Alloc item, del in MaixPy will auto free memory.\n" + }, + "args": [ + [ + "std::vector", + "in", + null + ] + ], + "ret_type": "std::vector*", + "static": false, + "def": "std::vector *get_list(std::vector in)", + "py_def": "def get_list(self, in: list[int]) -> list[int]" + }, + "get_dict": { + "type": "func", + "name": "get_dict", + "doc": { + "brief": "Example dict API", + "param": { + "in": "direction [in], input dict, key is string type, value is int type.\nIn MaixPy, you can pass `dict` to this API" + }, + "return": "dict, key is string type, value is int type, content is {\"a\": 1} + in\nIn MaixPy, return type is `dict` object", + "maixpy": "maix.example.Example.get_dict", + "py_doc": "Example dict API\n\nArgs:\n - in: direction [in], input dict, key is string type, value is int type.\nIn MaixPy, you can pass `dict` to this API\n\n\nReturns: dict, key is string type, value is int type, content is {\"a\": 1} + in\nIn MaixPy, return type is `dict` object\n" + }, + "args": [ + [ + "std::map &", + "in", + null + ] + ], + "ret_type": "std::map", + "static": false, + "def": "std::map get_dict(std::map &in)", + "py_def": "def get_dict(self, in: dict[str, int]) -> dict[str, int]" + }, + "hello": { + "type": "func", + "name": "hello", + "doc": { + "brief": "say hello to someone", + "param": { + "name": "name of someone, string type" + }, + "return": "string type, content is Example::hello_str + name", + "maixpy": "maix.example.Example.hello", + "py_doc": "say hello to someone\n\nArgs:\n - name: name of someone, string type\n\n\nReturns: string type, content is Example::hello_str + name\n" + }, + "args": [ + [ + "std::string", + "name", + null + ] + ], + "ret_type": "std::string", + "static": true, + "def": "static std::string hello(std::string name)", + "py_def": "def hello(name: str) -> str" + }, + "hello_bytes": { + "type": "func", + "name": "hello_bytes", + "doc": { + "brief": "param is bytes example", + "param": { + "bytes": "bytes type param" + }, + "return": "bytes type, return value is bytes changed value", + "maixpy": "maix.example.Example.hello_bytes", + "py_doc": "param is bytes example\n\nArgs:\n - bytes: bytes type param\n\n\nReturns: bytes type, return value is bytes changed value\n" + }, + "args": [ + [ + "Bytes &", + "bytes", + null + ] + ], + "ret_type": "Bytes*", + "static": true, + "def": "static Bytes *hello_bytes(Bytes &bytes)", + "py_def": "def hello_bytes(*args, **kwargs)" + }, + "callback": { + "type": "func", + "name": "callback", + "doc": { + "brief": "Callback example", + "param": { + "cb": "callback function, param is two int type, return is int type" + }, + "return": "int type, return value is cb(1, 2)", + "maixpy": "maix.example.Example.callback", + "py_doc": "Callback example\n\nArgs:\n - cb: callback function, param is two int type, return is int type\n\n\nReturns: int type, return value is cb(1, 2)\n" + }, + "args": [ + [ + "std::function", + "cb", + null + ] + ], + "ret_type": "int", + "static": true, + "def": "static int callback(std::function cb)", + "py_def": "def callback(cb: typing.Callable[[int, int], int]) -> int" + }, + "hello_dict": { + "type": "func", + "name": "hello_dict", + "doc": { + "brief": "Dict param example", + "param": { + "dict": "dict type param, key is string type, value is int type" + }, + "maixpy": "maix.example.Example.hello_dict", + "py_doc": "Dict param example\n\nArgs:\n - dict: dict type param, key is string type, value is int type\n" + }, + "args": [ + [ + "std::map *", + "dict", + null + ] + ], + "ret_type": "std::map*", + "static": true, + "def": "static std::map *hello_dict(std::map *dict)", + "py_def": "def hello_dict(dict: dict[str, int]) -> dict[str, int]" + }, + "name": { + "type": "var", + "name": "name", + "doc": { + "brief": "name member of Example", + "maixpy": "maix.example.Example.name", + "py_doc": "name member of Example" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::string name" + }, + "age": { + "type": "var", + "name": "age", + "doc": { + "brief": "age member of Example, value range should be [0, 100]", + "maixpy": "maix.example.Example.age", + "py_doc": "age member of Example, value range should be [0, 100]" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int age" + }, + "hello_str": { + "type": "var", + "name": "hello_str", + "doc": { + "brief": "hello_str member of Example, default value is \\\"hello \\\"", + "maixpy": "maix.example.Example.hello_str", + "py_doc": "hello_str member of Example, default value is \"hello \"" + }, + "value": null, + "static": true, + "readonly": false, + "def": "static std::string hello_str" + }, + "var1": { + "type": "var", + "name": "", + "doc": { + "brief": "Example module readonly variable", + "maixpy": "maix.example.Example.var1", + "py_doc": "Example module readonly variable" + }, + "value": "\"Example.var1\"", + "static": false, + "readonly": true, + "def": "const std::string var1 = \"Example.var1\"" + }, + "var2": { + "type": "var", + "name": "", + "doc": { + "brief": "Example module readonly variable", + "maixpy": "maix.example.Example.var2\n:readonly", + "py_doc": "Example module readonly variable" + }, + "value": "\"Example.var2\"", + "static": false, + "readonly": true, + "def": "std::string var2 = \"Example.var2\"" + }, + "dict_test": { + "type": "func", + "name": "dict_test", + "doc": { + "brief": "dict_test, return dict type, and element is pointer type(alloc in C++).\\nHere when the returned Tensor object will auto delete by Python GC.", + "maixpy": "maix.example.Example.dict_test", + "py_doc": "dict_test, return dict type, and element is pointer type(alloc in C++).\nHere when the returned Tensor object will auto delete by Python GC." + }, + "args": [], + "ret_type": "std::map*", + "static": true, + "def": "static std::map *dict_test()", + "py_def": "def dict_test() -> dict[str, Test]" + } + }, + "def": "class Example" + }, + "change_arg_name": { + "type": "func", + "name": "change_arg_name", + "doc": { + "brief": "Change arg name example", + "param": { + "e": "Example object" + }, + "return": "same as arg", + "maixpy": "maix.example.change_arg_name", + "py_doc": "Change arg name example\n\nArgs:\n - e: Example object\n\n\nReturns: same as arg\n" + }, + "args": [ + [ + "example::Example *", + "e", + null + ] + ], + "ret_type": "example::Example*", + "static": false, + "def": "example::Example *change_arg_name(example::Example *e)" + }, + "change_arg_name2": { + "type": "func", + "name": "change_arg_name2", + "doc": { + "brief": "Change arg name example", + "param": { + "e": "Example object" + }, + "maixpy": "maix.example.change_arg_name2", + "py_doc": "Change arg name example\n\nArgs:\n - e: Example object\n" + }, + "args": [ + [ + "example::Example &", + "e", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void change_arg_name2(example::Example &e)", + "py_def": "def change_arg_name2(e: Example) -> None" + } + }, + "auto_add": false + }, + "i18n": { + "type": "module", + "doc": { + "brief": "maix.i18n module" + }, + "members": { + "locales": { + "type": "var", + "name": "", + "doc": { + "brief": "i18n locales list", + "maixpy": "maix.i18n.locales", + "py_doc": "i18n locales list" + }, + "value": "{\n \"en\",\n \"zh\",\n \"zh-tw\",\n \"ja\"\n }", + "static": true, + "readonly": false, + "def": "static std::vector locales = {\n \"en\",\n \"zh\",\n \"zh-tw\",\n \"ja\"\n }" + }, + "names": { + "type": "var", + "name": "", + "doc": { + "brief": "i18n language names list", + "maixpy": "maix.i18n.names", + "py_doc": "i18n language names list" + }, + "value": "{\n \"English\",\n \"\u7b80\u4f53\u4e2d\u6587\",\n \"\u7e41\u9ad4\u4e2d\u6587\",\n \"\u65e5\u672c\u8a9e\"\n }", + "static": false, + "readonly": true, + "def": "const static std::vector names = {\n \"English\",\n \"\u7b80\u4f53\u4e2d\u6587\",\n \"\u7e41\u9ad4\u4e2d\u6587\",\n \"\u65e5\u672c\u8a9e\"\n }" + }, + "get_locale": { + "type": "func", + "name": "get_locale", + "doc": { + "brief": "Get system config of locale.", + "return": "language locale, e.g. en, zh, zh_CN, zh_TW, etc.", + "maixpy": "maix.i18n.get_locale", + "py_doc": "Get system config of locale.\n\nReturns: language locale, e.g. en, zh, zh_CN, zh_TW, etc.\n" + }, + "args": [], + "ret_type": "string", + "static": false, + "def": "string get_locale()", + "py_def": "def get_locale(self) -> str" + }, + "get_language_name": { + "type": "func", + "name": "get_language_name", + "doc": { + "brief": "Get system config of language name.", + "return": "language name, e.g. English, \u7b80\u4f53\u4e2d\u6587, \u7e41\u9ad4\u4e2d\u6587, etc.", + "maixpy": "maix.i18n.get_language_name", + "py_doc": "Get system config of language name.\n\nReturns: language name, e.g. English, \u7b80\u4f53\u4e2d\u6587, \u7e41\u9ad4\u4e2d\u6587, etc.\n" + }, + "args": [], + "ret_type": "string", + "static": false, + "def": "string get_language_name()" + }, + "Trans": { + "type": "class", + "name": "Trans", + "doc": { + "brief": "Translate helper class.", + "maixpy": "maix.i18n.Trans", + "py_doc": "Translate helper class." + }, + "members": { + "__init__": { + "type": "func", + "name": "Trans", + "doc": { + "brief": "Translate helper class constructor.\\nBy default locale is get by `i18n.get_locale()` function which set by system settings.\\nBut you can also manually set by `set_locale` function temporarily.", + "param": { + "locales_dict": "locales dict, e.g. {\"zh\": {\"Confirm\": \"\u786e\u8ba4\", \"OK\": \"\u597d\u7684\"}, \"en\": {\"Confirm\": \"Confirm\", \"OK\": \"OK\"}}" + }, + "maixpy": "maix.i18n.Trans.__init__", + "maixcdk": "maix.i18n.Trans.Trans", + "py_doc": "Translate helper class constructor.\nBy default locale is get by `i18n.get_locale()` function which set by system settings.\nBut you can also manually set by `set_locale` function temporarily.\n\nArgs:\n - locales_dict: locales dict, e.g. {\"zh\": {\"Confirm\": \"\u786e\u8ba4\", \"OK\": \"\u597d\u7684\"}, \"en\": {\"Confirm\": \"Confirm\", \"OK\": \"OK\"}}\n" + }, + "args": [ + [ + "const std::map> &", + "locales_dict", + null + ] + ], + "ret_type": null, + "static": false, + "def": "Trans(const std::map> &locales_dict)", + "py_def": "def __init__(self, locales_dict: dict[str, dict[str, str]]) -> None" + }, + "tr": { + "type": "func", + "name": "tr", + "doc": { + "brief": "Translate string by key.", + "param": { + "key": "string key, e.g. \"Confirm\"", + "locale": "locale name, if not assign, use default locale set by system settings or set_locale function." + }, + "return": "translated string, if find translation, return it, or return key, e.g. \"\u786e\u8ba4\", \"Confirm\", etc.", + "maixpy": "maix.i18n.Trans.tr", + "py_doc": "Translate string by key.\n\nArgs:\n - key: string key, e.g. \"Confirm\"\n - locale: locale name, if not assign, use default locale set by system settings or set_locale function.\n\n\nReturns: translated string, if find translation, return it, or return key, e.g. \"\u786e\u8ba4\", \"Confirm\", etc.\n" + }, + "args": [ + [ + "const string &", + "key", + null + ], + [ + "const string", + "locale", + "\"\"" + ] + ], + "ret_type": "string", + "static": false, + "def": "string tr(const string &key, const string locale = \"\")", + "py_def": "def tr(self, key: str, locale: str = '') -> str" + }, + "set_locale": { + "type": "func", + "name": "set_locale", + "doc": { + "brief": "Set locale temporarily, will not affect system settings.", + "param": { + "locale": "locale name, e.g. \"zh\", \"en\", etc. @see maix.i18n.locales" + }, + "maixpy": "maix.i18n.Trans.set_locale", + "py_doc": "Set locale temporarily, will not affect system settings.\n\nArgs:\n - locale: locale name, e.g. \"zh\", \"en\", etc. @see maix.i18n.locales\n" + }, + "args": [ + [ + "const string &", + "locale", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_locale(const string &locale)", + "py_def": "def set_locale(self, locale: str) -> None" + }, + "get_locale": { + "type": "func", + "name": "get_locale", + "doc": { + "brief": "Get current locale.", + "return": "locale name, e.g. \"zh\", \"en\", etc. @see maix.i18n.locales", + "maixpy": "maix.i18n.Trans.get_locale", + "py_doc": "Get current locale.\n\nReturns: locale name, e.g. \"zh\", \"en\", etc. @see maix.i18n.locales\n" + }, + "args": [], + "ret_type": "string", + "static": false, + "def": "string get_locale()", + "py_def": "def get_locale(self) -> str" + } + }, + "def": "class Trans" + } + }, + "auto_add": true + }, + "fs": { + "type": "module", + "doc": { + "brief": "maix.fs module" + }, + "members": { + "SEEK": { + "type": "enum", + "name": "SEEK", + "doc": { + "brief": "SEEK enums", + "maixpy": "maix.fs.SEEK", + "py_doc": "SEEK enums" + }, + "values": [ + [ + "SEEK_SET", + "0", + "Seek from beginning of file." + ], + [ + "SEEK_CUR", + "1", + "Seek from current position." + ], + [ + "SEEK_END", + "2", + "Seek from end of file." + ] + ], + "def": "enum SEEK\n {\n SEEK_SET = 0, // Seek from beginning of file.\n SEEK_CUR = 1, // Seek from current position.\n SEEK_END = 2, // Seek from end of file.\n }" + }, + "isabs": { + "type": "func", + "name": "isabs", + "doc": { + "brief": "Check if the path is absolute path", + "param": { + "path": "path to check" + }, + "return": "true if path is absolute path", + "maixpy": "maix.fs.isabs", + "py_doc": "Check if the path is absolute path\n\nArgs:\n - path: path to check\n\n\nReturns: true if path is absolute path\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ] + ], + "ret_type": "bool", + "static": false, + "def": "bool isabs(const std::string &path)", + "py_def": "def isabs(path: str) -> bool" + }, + "isdir": { + "type": "func", + "name": "isdir", + "doc": { + "brief": "Check if the path is a directory, if not exist, throw exception", + "param": { + "path": "path to check" + }, + "return": "true if path is a directory", + "maixpy": "maix.fs.isdir", + "py_doc": "Check if the path is a directory, if not exist, throw exception\n\nArgs:\n - path: path to check\n\n\nReturns: true if path is a directory\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ] + ], + "ret_type": "bool", + "static": false, + "def": "bool isdir(const std::string &path)", + "py_def": "def isdir(path: str) -> bool" + }, + "isfile": { + "type": "func", + "name": "isfile", + "doc": { + "brief": "Check if the path is a file, if not exist, throw exception", + "param": { + "path": "path to check" + }, + "return": "true if path is a file", + "maixpy": "maix.fs.isfile", + "py_doc": "Check if the path is a file, if not exist, throw exception\n\nArgs:\n - path: path to check\n\n\nReturns: true if path is a file\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ] + ], + "ret_type": "bool", + "static": false, + "def": "bool isfile(const std::string &path)", + "py_def": "def isfile(path: str) -> bool" + }, + "islink": { + "type": "func", + "name": "islink", + "doc": { + "brief": "Check if the path is a link, if not exist, throw exception", + "param": { + "path": "path to check" + }, + "return": "true if path is a link", + "maixpy": "maix.fs.islink", + "py_doc": "Check if the path is a link, if not exist, throw exception\n\nArgs:\n - path: path to check\n\n\nReturns: true if path is a link\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ] + ], + "ret_type": "bool", + "static": false, + "def": "bool islink(const std::string &path)", + "py_def": "def islink(path: str) -> bool" + }, + "symlink": { + "type": "func", + "name": "symlink", + "doc": { + "brief": "Create soft link", + "param": { + "src": "real file path", + "link": "link file path", + "force": "force link, if already have link file, will delet it first then create." + }, + "maixpy": "maix.fs.symlink", + "py_doc": "Create soft link\n\nArgs:\n - src: real file path\n - link: link file path\n - force: force link, if already have link file, will delet it first then create.\n" + }, + "args": [ + [ + "const std::string &", + "src", + null + ], + [ + "const std::string &", + "link", + null + ], + [ + "bool", + "force", + "false" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err symlink(const std::string &src, const std::string &link, bool force = false)", + "py_def": "def symlink(src: str, link: str, force: bool = False) -> maix.err.Err" + }, + "exists": { + "type": "func", + "name": "exists", + "doc": { + "brief": "Check if the path exists", + "param": { + "path": "path to check" + }, + "return": "true if path exists", + "maixpy": "maix.fs.exists", + "py_doc": "Check if the path exists\n\nArgs:\n - path: path to check\n\n\nReturns: true if path exists\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ] + ], + "ret_type": "bool", + "static": false, + "def": "bool exists(const std::string &path)", + "py_def": "def exists(path: str) -> bool" + }, + "mkdir": { + "type": "func", + "name": "mkdir", + "doc": { + "brief": "Create a directory recursively", + "param": { + "path": "path to create", + "exist_ok": "if true, also return true if directory already exists", + "recursive": "if true, create directory recursively, otherwise, only create one directory, default is true" + }, + "return": "err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed", + "maixpy": "maix.fs.mkdir", + "py_doc": "Create a directory recursively\n\nArgs:\n - path: path to create\n - exist_ok: if true, also return true if directory already exists\n - recursive: if true, create directory recursively, otherwise, only create one directory, default is true\n\n\nReturns: err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ], + [ + "bool", + "exist_ok", + "true" + ], + [ + "bool", + "recursive", + "true" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err mkdir(const std::string &path, bool exist_ok = true, bool recursive = true)", + "py_def": "def mkdir(path: str, exist_ok: bool = True, recursive: bool = True) -> maix.err.Err" + }, + "rmdir": { + "type": "func", + "name": "rmdir", + "doc": { + "brief": "Remove a directory", + "param": { + "path": "path to remove", + "recursive": "if true, remove directory recursively, otherwise, only remove empty directory, default is false" + }, + "return": "err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed", + "maixpy": "maix.fs.rmdir", + "py_doc": "Remove a directory\n\nArgs:\n - path: path to remove\n - recursive: if true, remove directory recursively, otherwise, only remove empty directory, default is false\n\n\nReturns: err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ], + [ + "bool", + "recursive", + "false" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err rmdir(const std::string &path, bool recursive = false)", + "py_def": "def rmdir(path: str, recursive: bool = False) -> maix.err.Err" + }, + "remove": { + "type": "func", + "name": "remove", + "doc": { + "brief": "Remove a file", + "param": { + "path": "path to remove" + }, + "return": "err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed", + "maixpy": "maix.fs.remove", + "py_doc": "Remove a file\n\nArgs:\n - path: path to remove\n\n\nReturns: err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err remove(const std::string &path)", + "py_def": "def remove(path: str) -> maix.err.Err" + }, + "rename": { + "type": "func", + "name": "rename", + "doc": { + "brief": "Rename a file or directory", + "param": { + "src": "source path", + "dst": "destination path, if destination dirs not exist, will auto create" + }, + "return": "err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed", + "maixpy": "maix.fs.rename", + "py_doc": "Rename a file or directory\n\nArgs:\n - src: source path\n - dst: destination path, if destination dirs not exist, will auto create\n\n\nReturns: err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed\n" + }, + "args": [ + [ + "const std::string &", + "src", + null + ], + [ + "const std::string &", + "dst", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err rename(const std::string &src, const std::string &dst)", + "py_def": "def rename(src: str, dst: str) -> maix.err.Err" + }, + "sync": { + "type": "func", + "name": "sync", + "doc": { + "brief": "Sync files, ensure they're wrriten to disk from RAM", + "maixpy": "maix.fs.sync", + "py_doc": "Sync files, ensure they're wrriten to disk from RAM" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void sync()", + "py_def": "def sync() -> None" + }, + "getsize": { + "type": "func", + "name": "getsize", + "doc": { + "brief": "Get file size", + "param": { + "path": "path to get size" + }, + "return": "file size if success, -err::Err code if failed", + "maixpy": "maix.fs.getsize", + "py_doc": "Get file size\n\nArgs:\n - path: path to get size\n\n\nReturns: file size if success, -err::Err code if failed\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ] + ], + "ret_type": "int", + "static": false, + "def": "int getsize(const std::string &path)", + "py_def": "def getsize(path: str) -> int" + }, + "dirname": { + "type": "func", + "name": "dirname", + "doc": { + "brief": "Get directory name of path", + "param": { + "path": "path to get dirname" + }, + "return": "dirname if success, empty string if failed", + "maixpy": "maix.fs.dirname", + "py_doc": "Get directory name of path\n\nArgs:\n - path: path to get dirname\n\n\nReturns: dirname if success, empty string if failed\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ] + ], + "ret_type": "std::string", + "static": false, + "def": "std::string dirname(const std::string &path)", + "py_def": "def dirname(path: str) -> str" + }, + "basename": { + "type": "func", + "name": "basename", + "doc": { + "brief": "Get base name of path", + "param": { + "path": "path to get basename" + }, + "return": "basename if success, empty string if failed", + "maixpy": "maix.fs.basename", + "py_doc": "Get base name of path\n\nArgs:\n - path: path to get basename\n\n\nReturns: basename if success, empty string if failed\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ] + ], + "ret_type": "std::string", + "static": false, + "def": "std::string basename(const std::string &path)", + "py_def": "def basename(path: str) -> str" + }, + "abspath": { + "type": "func", + "name": "abspath", + "doc": { + "brief": "Get absolute path", + "param": { + "path": "path to get absolute path" + }, + "return": "absolute path if success, empty string if failed", + "maixpy": "maix.fs.abspath", + "py_doc": "Get absolute path\n\nArgs:\n - path: path to get absolute path\n\n\nReturns: absolute path if success, empty string if failed\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ] + ], + "ret_type": "std::string", + "static": false, + "def": "std::string abspath(const std::string &path)", + "py_def": "def abspath(path: str) -> str" + }, + "getcwd": { + "type": "func", + "name": "getcwd", + "doc": { + "brief": "Get current working directory", + "return": "current working directory absolute path", + "maixpy": "maix.fs.getcwd", + "py_doc": "Get current working directory\n\nReturns: current working directory absolute path\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string getcwd()", + "py_def": "def getcwd() -> str" + }, + "realpath": { + "type": "func", + "name": "realpath", + "doc": { + "brief": "Get realpath of path", + "param": { + "path": "path to get realpath" + }, + "return": "realpath if success, empty string if failed", + "maixpy": "maix.fs.realpath", + "py_doc": "Get realpath of path\n\nArgs:\n - path: path to get realpath\n\n\nReturns: realpath if success, empty string if failed\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ] + ], + "ret_type": "std::string", + "static": false, + "def": "std::string realpath(const std::string &path)", + "py_def": "def realpath(path: str) -> str" + }, + "splitext": { + "type": "func", + "name": "splitext", + "doc": { + "brief": "Get file extension", + "param": { + "path": "path to get extension" + }, + "return": "extension if success, empty string if failed", + "maixpy": "maix.fs.splitext", + "py_doc": "Get file extension\n\nArgs:\n - path: path to get extension\n\n\nReturns: extension if success, empty string if failed\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ] + ], + "ret_type": "std::string", + "static": false, + "def": "std::string splitext(const std::string &path)", + "py_def": "def splitext(path: str) -> str" + }, + "listdir": { + "type": "func", + "name": "listdir", + "doc": { + "brief": "List files in directory", + "param": { + "path": "path to list", + "recursive": "if true, list recursively, otherwise, only list current directory, default is false", + "full_path": "if true, return full path, otherwise, only return basename, default is false" + }, + "return": "files list if success, nullptr if failed, you should manually delete it in C++.", + "maixpy": "maix.fs.listdir", + "py_doc": "List files in directory\n\nArgs:\n - path: path to list\n - recursive: if true, list recursively, otherwise, only list current directory, default is false\n - full_path: if true, return full path, otherwise, only return basename, default is false\n\n\nReturns: files list if success, nullptr if failed, you should manually delete it in C++.\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ], + [ + "bool", + "recursive", + "false" + ], + [ + "bool", + "full_path", + "false" + ] + ], + "ret_type": "std::vector*", + "static": false, + "def": "std::vector *listdir(const std::string &path, bool recursive = false, bool full_path = false)", + "py_def": "def listdir(path: str, recursive: bool = False, full_path: bool = False) -> list[str]" + }, + "File": { + "type": "class", + "name": "File", + "doc": { + "brief": "File read write ops", + "maixpy": "maix.fs.File", + "py_doc": "File read write ops" + }, + "members": { + "__init__": { + "type": "func", + "name": "File", + "doc": { + "brief": "Construct File object", + "maixpy": "maix.fs.File.__init__", + "maixcdk": "maix.fs.File.File", + "py_doc": "Construct File object" + }, + "args": [], + "ret_type": null, + "static": false, + "def": "File()", + "py_def": "def __init__(self) -> None" + }, + "open": { + "type": "func", + "name": "open", + "doc": { + "brief": "Open a file", + "param": { + "path": "path to open", + "mode": "open mode, support \"r\", \"w\", \"a\", \"r+\", \"w+\", \"a+\", \"rb\", \"wb\", \"ab\", \"rb+\", \"wb+\", \"ab+\"" + }, + "return": "err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed", + "maixpy": "maix.fs.File.open", + "py_doc": "Open a file\n\nArgs:\n - path: path to open\n - mode: open mode, support \"r\", \"w\", \"a\", \"r+\", \"w+\", \"a+\", \"rb\", \"wb\", \"ab\", \"rb+\", \"wb+\", \"ab+\"\n\n\nReturns: err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ], + [ + "const std::string &", + "mode", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err open(const std::string &path, const std::string &mode)", + "py_def": "def open(self, path: str, mode: str) -> maix.err.Err" + }, + "close": { + "type": "func", + "name": "close", + "doc": { + "brief": "Close a file", + "maixpy": "maix.fs.File.close", + "py_doc": "Close a file" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void close()", + "py_def": "def close(self) -> None" + }, + "read": { + "type": "func", + "name": "read", + "doc": { + "brief": "Read data from file API2", + "param": { + "size": "max read size" + }, + "return": "bytes data if success(need delete manually in C/C++), nullptr if failed", + "maixpy": "maix.fs.File.read", + "py_doc": "Read data from file API2\n\nArgs:\n - size: max read size\n\n\nReturns: bytes data if success(need delete manually in C/C++), nullptr if failed\n" + }, + "args": [ + [ + "int", + "size", + null + ] + ], + "ret_type": "std::vector*", + "static": false, + "def": "std::vector *read(int size)", + "py_def": "def read(self, size: int) -> list[int]" + }, + "readline": { + "type": "func", + "name": "readline", + "doc": { + "brief": "Read line from file", + "return": "line if success, empty string if failed. You need to delete the returned object manually in C/C++.", + "maixpy": "maix.fs.File.readline", + "py_doc": "Read line from file\n\nReturns: line if success, empty string if failed. You need to delete the returned object manually in C/C++.\n" + }, + "args": [], + "ret_type": "std::string*", + "static": false, + "def": "std::string *readline()", + "py_def": "def readline(self) -> str" + }, + "write": { + "type": "func", + "name": "write", + "doc": { + "brief": "Write data to file API2", + "param": { + "buf": "buffer to write" + }, + "return": "write size if success, -err::Err code if failed", + "maixpy": "maix.fs.File.write", + "py_doc": "Write data to file API2\n\nArgs:\n - buf: buffer to write\n\n\nReturns: write size if success, -err::Err code if failed\n" + }, + "args": [ + [ + "const std::vector &", + "buf", + null + ] + ], + "ret_type": "int", + "static": false, + "def": "int write(const std::vector &buf)", + "py_def": "def write(self, buf: list[int]) -> int" + }, + "seek": { + "type": "func", + "name": "seek", + "doc": { + "brief": "Seek file position", + "param": { + "offset": "offset to seek", + "whence": "@see maix.fs.SEEK" + }, + "return": "new position if success, -err::Err code if failed", + "maixpy": "maix.fs.File.seek", + "py_doc": "Seek file position\n\nArgs:\n - offset: offset to seek\n - whence: @see maix.fs.SEEK\n\n\nReturns: new position if success, -err::Err code if failed\n" + }, + "args": [ + [ + "int", + "offset", + null + ], + [ + "int", + "whence", + null + ] + ], + "ret_type": "int", + "static": false, + "def": "int seek(int offset, int whence)", + "py_def": "def seek(self, offset: int, whence: int) -> int" + }, + "tell": { + "type": "func", + "name": "tell", + "doc": { + "brief": "Get file position", + "return": "file position if success, -err::Err code if failed", + "maixpy": "maix.fs.File.tell", + "py_doc": "Get file position\n\nReturns: file position if success, -err::Err code if failed\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int tell()", + "py_def": "def tell(self) -> int" + }, + "flush": { + "type": "func", + "name": "flush", + "doc": { + "brief": "Flush file", + "return": "err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed", + "maixpy": "maix.fs.File.flush", + "py_doc": "Flush file\n\nReturns: err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err flush()", + "py_def": "def flush(self) -> maix.err.Err" + } + }, + "def": "class File" + }, + "open": { + "type": "func", + "name": "open", + "doc": { + "brief": "Open a file, and return a File object", + "param": { + "path": "path to open", + "mode": "open mode, support \"r\", \"w\", \"a\", \"r+\", \"w+\", \"a+\", \"rb\", \"wb\", \"ab\", \"rb+\", \"wb+\", \"ab+\"" + }, + "return": "File object if success(need to delete object manually in C/C++), nullptr if failed", + "maixpy": "maix.fs.open", + "py_doc": "Open a file, and return a File object\n\nArgs:\n - path: path to open\n - mode: open mode, support \"r\", \"w\", \"a\", \"r+\", \"w+\", \"a+\", \"rb\", \"wb\", \"ab\", \"rb+\", \"wb+\", \"ab+\"\n\n\nReturns: File object if success(need to delete object manually in C/C++), nullptr if failed\n" + }, + "args": [ + [ + "const std::string &", + "path", + null + ], + [ + "const std::string &", + "mode", + null + ] + ], + "ret_type": "fs::File*", + "static": false, + "def": "fs::File *open(const std::string &path, const std::string &mode)", + "py_def": "def open(self, path: str, mode: str) -> maix.err.Err" + }, + "tempdir": { + "type": "func", + "name": "tempdir", + "doc": { + "brief": "Get temp files directory", + "return": "temp files directory", + "maixpy": "maix.fs.tempdir", + "py_doc": "Get temp files directory\n\nReturns: temp files directory\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string tempdir()", + "py_def": "def tempdir() -> str" + } + }, + "auto_add": true + }, + "protocol": { + "type": "module", + "doc": { + "brief": "maix.protocol module" + }, + "members": { + "VERSION": { + "type": "var", + "name": "", + "doc": { + "brief": "protocol version", + "maixpy": "maix.protocol.VERSION", + "py_doc": "protocol version" + }, + "value": "1", + "static": false, + "readonly": true, + "def": "const uint8_t VERSION = 1" + }, + "HEADER": { + "type": "var", + "name": "", + "doc": { + "brief": "protocol header", + "maixpy": "maix.protocol.HEADER", + "py_doc": "protocol header" + }, + "value": "0xBBACCAAA", + "static": false, + "readonly": true, + "def": "const uint32_t HEADER = 0xBBACCAAA" + }, + "CMD": { + "type": "enum", + "name": "CMD", + "doc": { + "brief": "protocol cmd, more doc see MaixCDK document's convention doc", + "note": "max app custom CMD value should < CMD_APP_MAX", + "maixpy": "maix.protocol.CMD", + "py_doc": "protocol cmd, more doc see MaixCDK document's convention doc" + }, + "values": [ + [ + "CMD_APP_MAX", + "0xC8", + "200, max app custom CMD value should < CMD_APP_MAX" + ], + [ + "CMD_SET_UPLOAD", + "0xF8", + "set auto upload data mode" + ], + [ + "CMD_APP_LIST", + "0xF9", + "" + ], + [ + "CMD_START_APP", + "0xFA", + "" + ], + [ + "CMD_EXIT_APP", + "0xFB", + "" + ], + [ + "CMD_CUR_APP_INFO", + "0xFC", + "" + ], + [ + "CMD_APP_INFO", + "0xFD", + "" + ], + [ + "CMD_KEY", + "0xFE", + "" + ], + [ + "CMD_TOUCH", + "0xFF", + "" + ] + ], + "def": "enum CMD\n {\n CMD_APP_MAX = 0xC8, // 200, max app custom CMD value should < CMD_APP_MAX\n\n CMD_SET_UPLOAD = 0xF8, // set auto upload data mode\n CMD_APP_LIST = 0xF9,\n CMD_START_APP = 0xFA,\n CMD_EXIT_APP = 0xFB,\n CMD_CUR_APP_INFO = 0xFC,\n CMD_APP_INFO = 0xFD,\n CMD_KEY = 0xFE,\n CMD_TOUCH = 0xFF,\n }" + }, + "FLAGS": { + "type": "enum", + "name": "FLAGS", + "doc": { + "brief": "protocol flags, more doc see MaixCDK document's convention doc", + "maixpy": "maix.protocol.FLAGS", + "py_doc": "protocol flags, more doc see MaixCDK document's convention doc" + }, + "values": [ + [ + "FLAG_REQ", + "0x00", + "" + ], + [ + "FLAG_RESP", + "0x80", + "" + ], + [ + "FLAG_IS_RESP_MASK", + "0x80", + "" + ], + [ + "FLAG_RESP_OK", + "0x40", + "" + ], + [ + "FLAG_RESP_ERR", + "0x00", + "" + ], + [ + "FLAG_RESP_OK_MASK", + "0x40", + "" + ], + [ + "FLAG_REPORT", + "0x20", + "" + ], + [ + "FLAG_REPORT_MASK", + "0x20", + "" + ], + [ + "FLAG_VERSION_MASK", + "0x03", + "" + ] + ], + "def": "enum FLAGS\n {\n FLAG_REQ = 0x00,\n FLAG_RESP = 0x80,\n FLAG_IS_RESP_MASK = 0x80,\n\n FLAG_RESP_OK = 0x40,\n FLAG_RESP_ERR = 0x00,\n FLAG_RESP_OK_MASK = 0x40,\n\n FLAG_REPORT = 0x20,\n FLAG_REPORT_MASK = 0x20,\n\n FLAG_VERSION_MASK = 0x03\n }" + }, + "MSG": { + "type": "class", + "name": "MSG", + "doc": { + "brief": "protocol msg", + "maixpy": "maix.protocol.MSG", + "py_doc": "protocol msg" + }, + "members": { + "version": { + "type": "var", + "name": "version", + "doc": { + "brief": "protocol version", + "maixpy": "maix.protocol.MSG.version", + "py_doc": "protocol version" + }, + "value": null, + "static": false, + "readonly": false, + "def": "uint8_t version" + }, + "resp_ok": { + "type": "var", + "name": "resp_ok", + "doc": { + "brief": "Is success response or not, (only for response msg)", + "maixpy": "maix.protocol.MSG.resp_ok", + "py_doc": "Is success response or not, (only for response msg)" + }, + "value": null, + "static": false, + "readonly": false, + "def": "uint8_t resp_ok" + }, + "cmd": { + "type": "var", + "name": "cmd", + "doc": { + "brief": "CMD value", + "maixpy": "maix.protocol.MSG.cmd", + "py_doc": "CMD value" + }, + "value": null, + "static": false, + "readonly": false, + "def": "uint8_t cmd" + }, + "is_resp": { + "type": "var", + "name": "is_resp", + "doc": { + "brief": "message is response or not, contrast with is_req", + "maixpy": "maix.protocol.MSG.is_resp", + "py_doc": "message is response or not, contrast with is_req" + }, + "value": null, + "static": false, + "readonly": false, + "def": "bool is_resp" + }, + "body_len": { + "type": "var", + "name": "body_len", + "doc": { + "brief": "Message body length, read only, use set_body() to update", + "attention": "DO NOT manually change this value", + "maixpy": "maix.protocol.MSG.body_len", + "py_doc": "Message body length, read only, use set_body() to update" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int body_len" + }, + "encode_resp_ok": { + "type": "func", + "name": "encode_resp_ok", + "doc": { + "brief": "Encode response ok(success) message", + "param": { + "body": "response body, can be null" + }, + "return": "encoded data, if nullptr, means error, and the error code is -err.Err", + "maixpy": "maix.protocol.MSG.encode_resp_ok", + "py_doc": "Encode response ok(success) message\n\nArgs:\n - body: response body, can be null\n\n\nReturns: encoded data, if nullptr, means error, and the error code is -err.Err\n" + }, + "args": [ + [ + "Bytes *", + "body", + "nullptr" + ] + ], + "ret_type": "Bytes*", + "static": false, + "def": "Bytes *encode_resp_ok(Bytes *body = nullptr)", + "py_def": "def encode_resp_ok(*args, **kwargs)" + }, + "encode_report": { + "type": "func", + "name": "encode_report", + "doc": { + "brief": "Encode proactively report message", + "param": { + "body": "report body, can be null" + }, + "return": "encoded data, if nullptr, means error, and the error code is -err.Err", + "maixpy": "maix.protocol.MSG.encode_report", + "py_doc": "Encode proactively report message\n\nArgs:\n - body: report body, can be null\n\n\nReturns: encoded data, if nullptr, means error, and the error code is -err.Err\n" + }, + "args": [ + [ + "Bytes *", + "body", + "nullptr" + ] + ], + "ret_type": "Bytes*", + "static": false, + "def": "Bytes *encode_report(Bytes *body = nullptr)", + "py_def": "def encode_report(*args, **kwargs)" + }, + "encode_resp_err": { + "type": "func", + "name": "encode_resp_err", + "doc": { + "brief": "Encode response error message", + "param": { + "code": "error code", + "msg": "error message" + }, + "return": "encoded data, if nullptr, means error, and the error code is -err.Err", + "maixpy": "maix.protocol.MSG.encode_resp_err", + "py_doc": "Encode response error message\n\nArgs:\n - code: error code\n - msg: error message\n\n\nReturns: encoded data, if nullptr, means error, and the error code is -err.Err\n" + }, + "args": [ + [ + "err::Err", + "code", + null + ], + [ + "const std::string &", + "msg", + null + ] + ], + "ret_type": "Bytes*", + "static": false, + "def": "Bytes *encode_resp_err(err::Err code, const std::string &msg)", + "py_def": "def encode_resp_err(*args, **kwargs)" + }, + "set_body": { + "type": "func", + "name": "set_body", + "doc": { + "brief": "Update message body", + "param": { + "body_new": "new body data" + }, + "maixpy": "maix.protocol.MSG.set_body", + "py_doc": "Update message body\n\nArgs:\n - body_new: new body data\n" + }, + "args": [ + [ + "Bytes *", + "body_new", + null + ] + ], + "ret_type": "void", + "static": false, + "def": "void set_body(Bytes *body_new)", + "py_def": "def set_body(self, body_new: maix.Bytes(bytes)) -> None" + }, + "get_body": { + "type": "func", + "name": "get_body", + "doc": { + "brief": "Get message body", + "return": "message body, bytes type", + "maixpy": "maix.protocol.MSG.get_body", + "py_doc": "Get message body\n\nReturns: message body, bytes type\n" + }, + "args": [], + "ret_type": "Bytes*", + "static": false, + "def": "Bytes *get_body()", + "py_def": "def get_body(*args, **kwargs)" + } + }, + "def": "class MSG" + }, + "Protocol": { + "type": "class", + "name": "Protocol", + "doc": { + "brief": "Communicate protocol", + "maixpy": "maix.protocol.Protocol", + "py_doc": "Communicate protocol" + }, + "members": { + "__init__": { + "type": "func", + "name": "Protocol", + "doc": { + "brief": "Construct a new Protocol object", + "param": { + "buff_size": "Data queue buffer size" + }, + "maixpy": "maix.protocol.Protocol.__init__", + "maixcdk": "maix.protocol.Protocol.Protocol", + "py_doc": "Construct a new Protocol object\n\nArgs:\n - buff_size: Data queue buffer size\n" + }, + "args": [ + [ + "int", + "buff_size", + "1024" + ] + ], + "ret_type": null, + "static": false, + "def": "Protocol(int buff_size = 1024)" + }, + "buff_size": { + "type": "func", + "name": "buff_size", + "doc": { + "brief": "Data queue buffer size", + "maixpy": "maix.protocol.Protocol.buff_size", + "py_doc": "Data queue buffer size" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int buff_size()" + }, + "push_data": { + "type": "func", + "name": "push_data", + "doc": { + "brief": "Add data to data queue", + "param": { + "new_data": "new data" + }, + "return": "error code, maybe err.Err.ERR_BUFF_FULL", + "maixpy": "maix.protocol.Protocol.push_data", + "py_doc": "Add data to data queue\n\nArgs:\n - new_data: new data\n\n\nReturns: error code, maybe err.Err.ERR_BUFF_FULL\n" + }, + "args": [ + [ + "const Bytes *", + "new_data", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err push_data(const Bytes *new_data)" + }, + "decode": { + "type": "func", + "name": "decode", + "doc": { + "brief": "Decode data in data queue and return a message", + "param": { + "new_data": "new data add to data queue, if null, only decode." + }, + "return": "decoded message, if nullptr, means no message decoded.", + "maixpy": "maix.protocol.Protocol.decode", + "py_doc": "Decode data in data queue and return a message\n\nArgs:\n - new_data: new data add to data queue, if null, only decode.\n\n\nReturns: decoded message, if nullptr, means no message decoded.\n" + }, + "args": [ + [ + "const Bytes *", + "new_data", + "nullptr" + ] + ], + "ret_type": "protocol::MSG*", + "static": false, + "def": "protocol::MSG *decode(const Bytes *new_data = nullptr)" + }, + "encode_resp_ok": { + "type": "func", + "name": "encode_resp_ok", + "doc": { + "brief": "Encode response ok(success) message to buffer", + "param": { + "cmd": "CMD value", + "body": "response body, can be null" + }, + "return": "encoded data, if nullptr, means error, and the error code is -err.Err", + "maixpy": "maix.protocol.Protocol.encode_resp_ok", + "py_doc": "Encode response ok(success) message to buffer\n\nArgs:\n - cmd: CMD value\n - body: response body, can be null\n\n\nReturns: encoded data, if nullptr, means error, and the error code is -err.Err\n" + }, + "args": [ + [ + "uint8_t", + "cmd", + null + ], + [ + "Bytes *", + "body", + "nullptr" + ] + ], + "ret_type": "Bytes*", + "static": false, + "def": "Bytes *encode_resp_ok(uint8_t cmd, Bytes *body = nullptr)" + }, + "encode_report": { + "type": "func", + "name": "encode_report", + "doc": { + "brief": "Encode proactively report message to buffer", + "param": { + "cmd": "CMD value", + "body": "report body, can be null" + }, + "return": "encoded data, if nullptr, means error, and the error code is -err.Err", + "maixpy": "maix.protocol.Protocol.encode_report", + "py_doc": "Encode proactively report message to buffer\n\nArgs:\n - cmd: CMD value\n - body: report body, can be null\n\n\nReturns: encoded data, if nullptr, means error, and the error code is -err.Err\n" + }, + "args": [ + [ + "uint8_t", + "cmd", + null + ], + [ + "Bytes *", + "body", + "nullptr" + ] + ], + "ret_type": "Bytes*", + "static": false, + "def": "Bytes *encode_report(uint8_t cmd, Bytes *body = nullptr)" + }, + "encode_resp_err": { + "type": "func", + "name": "encode_resp_err", + "doc": { + "brief": "Encode response error message to buffer", + "param": { + "cmd": "CMD value", + "code": "error code", + "msg": "error message" + }, + "return": "encoded data, if nullptr, means error, and the error code is -err.Err", + "maixpy": "maix.protocol.Protocol.encode_resp_err", + "py_doc": "Encode response error message to buffer\n\nArgs:\n - cmd: CMD value\n - code: error code\n - msg: error message\n\n\nReturns: encoded data, if nullptr, means error, and the error code is -err.Err\n" + }, + "args": [ + [ + "uint8_t", + "cmd", + null + ], + [ + "err::Err", + "code", + null + ], + [ + "const std::string &", + "msg", + null + ] + ], + "ret_type": "Bytes*", + "static": false, + "def": "Bytes *encode_resp_err(uint8_t cmd, err::Err code, const std::string &msg)" + } + }, + "def": "class Protocol" + }, + "crc16_IBM": { + "type": "func", + "name": "crc16_IBM", + "doc": { + "brief": "CRC16-IBM", + "param": { + "data": "data, bytes type." + }, + "return": "CRC16-IBM value, uint16_t type.", + "maixpy": "maix.protocol.crc16_IBM", + "py_doc": "CRC16-IBM\n\nArgs:\n - data: data, bytes type.\n\n\nReturns: CRC16-IBM value, uint16_t type.\n" + }, + "args": [ + [ + "const Bytes *", + "data", + null + ] + ], + "ret_type": "uint16_t", + "static": false, + "def": "uint16_t crc16_IBM(const Bytes *data)", + "py_def": "def crc16_IBM(data: maix.Bytes(bytes)) -> int" + } + }, + "auto_add": true + }, + "sys": { + "type": "module", + "doc": { + "brief": "maix.sys module" + }, + "members": { + "os_version": { + "type": "func", + "name": "os_version", + "doc": { + "brief": "Get system version", + "return": "version string, e.g. \"2024.4.1-13af4b\"", + "maixpy": "maix.sys.os_version", + "py_doc": "Get system version\n\nReturns: version string, e.g. \"2024.4.1-13af4b\"\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string os_version()", + "py_def": "def os_version() -> str" + }, + "device_name": { + "type": "func", + "name": "device_name", + "doc": { + "brief": "Get device name", + "return": "device name, e.g. \"MaixCAM\"", + "maixpy": "maix.sys.device_name", + "py_doc": "Get device name\n\nReturns: device name, e.g. \"MaixCAM\"\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string device_name()", + "py_def": "def device_name() -> str" + }, + "host_name": { + "type": "func", + "name": "host_name", + "doc": { + "brief": "Get host name", + "return": "host name, e.g. \"maixcam-2f9f\"", + "maixpy": "maix.sys.host_name", + "py_doc": "Get host name\n\nReturns: host name, e.g. \"maixcam-2f9f\"\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string host_name()", + "py_def": "def host_name() -> str" + }, + "host_domain": { + "type": "func", + "name": "host_domain", + "doc": { + "brief": "Get host domain", + "return": "host domain, e.g. \"maixcam-2f9f.local\"", + "maixpy": "maix.sys.host_domain", + "py_doc": "Get host domain\n\nReturns: host domain, e.g. \"maixcam-2f9f.local\"\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string host_domain()", + "py_def": "def host_domain() -> str" + }, + "ip_address": { + "type": "func", + "name": "ip_address", + "doc": { + "brief": "Get ip address", + "return": "ip address, dict type, e.g. {\"eth0\": \"192.168.0.195\", \"wlan0\": \"192.168.0.123\", \"usb0\": \"10.47.159.1\"}", + "maixpy": "maix.sys.ip_address", + "py_doc": "Get ip address\n\nReturns: ip address, dict type, e.g. {\"eth0\": \"192.168.0.195\", \"wlan0\": \"192.168.0.123\", \"usb0\": \"10.47.159.1\"}\n" + }, + "args": [], + "ret_type": "std::map", + "static": false, + "def": "std::map ip_address()", + "py_def": "def ip_address() -> dict[str, str]" + }, + "mac_address": { + "type": "func", + "name": "mac_address", + "doc": { + "brief": "Get mac address", + "return": "mac address, dict type, e.g. {\"eth0\": \"00:0c:29:2f:9f:00\", \"wlan0\": \"00:0c:29:2f:9f:01\", \"usb0\": \"00:0c:29:2f:9f:02\"}", + "maixpy": "maix.sys.mac_address", + "py_doc": "Get mac address\n\nReturns: mac address, dict type, e.g. {\"eth0\": \"00:0c:29:2f:9f:00\", \"wlan0\": \"00:0c:29:2f:9f:01\", \"usb0\": \"00:0c:29:2f:9f:02\"}\n" + }, + "args": [], + "ret_type": "std::map", + "static": false, + "def": "std::map mac_address()", + "py_def": "def mac_address() -> dict[str, str]" + }, + "device_key": { + "type": "func", + "name": "device_key", + "doc": { + "brief": "Get device key, can be unique id of device", + "return": "device key, 32 bytes hex string, e.g. \"1234567890abcdef1234567890abcdef\"", + "maixpy": "maix.sys.device_key", + "py_doc": "Get device key, can be unique id of device\n\nReturns: device key, 32 bytes hex string, e.g. \"1234567890abcdef1234567890abcdef\"\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string device_key()", + "py_def": "def device_key() -> str" + }, + "memory_info": { + "type": "func", + "name": "memory_info", + "doc": { + "brief": "Get memory info", + "return": "memory info, dict type, e.g. {\"total\": 1024, \"used\": 512, \"hw_total\": 256*1024*1024}\ntotal: total memory size in Byte.\nused: used memory size in Byte.\nhw_total: total memory size in Byte of hardware, the total <= hw_total\uff0c\nOS kernel may reserve some memory for some hardware like camera, npu, display etc.", + "maixpy": "maix.sys.memory_info", + "py_doc": "Get memory info\n\nReturns: memory info, dict type, e.g. {\"total\": 1024, \"used\": 512, \"hw_total\": 256*1024*1024}\ntotal: total memory size in Byte.\nused: used memory size in Byte.\nhw_total: total memory size in Byte of hardware, the total <= hw_total\uff0c\nOS kernel may reserve some memory for some hardware like camera, npu, display etc.\n" + }, + "args": [], + "ret_type": "std::map", + "static": false, + "def": "std::map memory_info()", + "py_def": "def memory_info() -> dict[str, int]" + }, + "bytes_to_human": { + "type": "func", + "name": "bytes_to_human", + "doc": { + "brief": "Bytes to human readable string", + "param": { + "bytes:": "bytes size\uff0ce.g. 1234B = 1234/1024 = 1.205 KB", + "precision:": "decimal precision, default 2", + "base:": "base number, default 1024", + "unit:": "unit string, e.g. \"B\"", + "sep:": "separator string, e.g. \" \"" + }, + "return": "human readable string, e.g. \"1.21 KB\"", + "maixpy": "maix.sys.bytes_to_human", + "py_doc": "Bytes to human readable string\n\nArgs:\n - bytes:: bytes size\uff0ce.g. 1234B = 1234/1024 = 1.205 KB\n - precision:: decimal precision, default 2\n - base:: base number, default 1024\n - unit:: unit string, e.g. \"B\"\n - sep:: separator string, e.g. \" \"\n\n\nReturns: human readable string, e.g. \"1.21 KB\"\n" + }, + "args": [ + [ + "unsigned long long", + "bytes", + null + ], + [ + "int", + "precision", + "2" + ], + [ + "int", + "base", + "1024" + ], + [ + "const std::string &", + "unit", + "\"B\"" + ], + [ + "const std::string &", + "sep", + "\" \"" + ] + ], + "ret_type": "std::string", + "static": false, + "def": "std::string bytes_to_human(unsigned long long bytes, int precision = 2, int base = 1024, const std::string &unit = \"B\", const std::string &sep = \" \")", + "py_def": "def bytes_to_human(bytes: int, precision: int = 2, base: int = 1024, unit: str = 'B', sep: str = ' ') -> str" + }, + "cpu_freq": { + "type": "func", + "name": "cpu_freq", + "doc": { + "brief": "Get CPU frequency", + "return": "CPU frequency, dict type, e.g. {\"cpu0\": 1000000000, \"cpu1\": 1000000000}", + "maixpy": "maix.sys.cpu_freq", + "py_doc": "Get CPU frequency\n\nReturns: CPU frequency, dict type, e.g. {\"cpu0\": 1000000000, \"cpu1\": 1000000000}\n" + }, + "args": [], + "ret_type": "std::map", + "static": false, + "def": "std::map cpu_freq()", + "py_def": "def cpu_freq() -> dict[str, int]" + }, + "cpu_temp": { + "type": "func", + "name": "cpu_temp", + "doc": { + "brief": "Get CPU temperature", + "return": "CPU temperature, unit dgree, dict type, e.g. {\"cpu\": 50.0, \"cpu0\": 50, \"cpu1\": 50}", + "maixpy": "maix.sys.cpu_temp", + "py_doc": "Get CPU temperature\n\nReturns: CPU temperature, unit dgree, dict type, e.g. {\"cpu\": 50.0, \"cpu0\": 50, \"cpu1\": 50}\n" + }, + "args": [], + "ret_type": "std::map", + "static": false, + "def": "std::map cpu_temp()", + "py_def": "def cpu_temp() -> dict[str, float]" + }, + "cpu_usage": { + "type": "func", + "name": "cpu_usage", + "doc": { + "brief": "Get CPU usage", + "return": "CPU usage, dict type, e.g. {\"cpu\": 50.0, \"cpu0\": 50, \"cpu1\": 50}", + "maixpy": "maix.sys.cpu_usage", + "py_doc": "Get CPU usage\n\nReturns: CPU usage, dict type, e.g. {\"cpu\": 50.0, \"cpu0\": 50, \"cpu1\": 50}\n" + }, + "args": [], + "ret_type": "std::map", + "static": false, + "def": "std::map cpu_usage()", + "py_def": "def cpu_usage() -> dict[str, float]" + }, + "npu_freq": { + "type": "func", + "name": "npu_freq", + "doc": { + "brief": "Get NPU frequency", + "return": "NPU frequency, dict type, e.g. {\"npu0\": 500000000}", + "maixpy": "maix.sys.npu_freq", + "py_doc": "Get NPU frequency\n\nReturns: NPU frequency, dict type, e.g. {\"npu0\": 500000000}\n" + }, + "args": [], + "ret_type": "std::map", + "static": false, + "def": "std::map npu_freq()", + "py_def": "def npu_freq() -> dict[str, int]" + }, + "disk_usage": { + "type": "func", + "name": "disk_usage", + "doc": { + "brief": "Get disk usage", + "param": { + "path:": "disk path, default \"/\"" + }, + "return": "disk usage, dict type, e.g. {\"total\": 1024, \"used\": 512}", + "maixpy": "maix.sys.disk_usage", + "py_doc": "Get disk usage\n\nArgs:\n - path:: disk path, default \"/\"\n\n\nReturns: disk usage, dict type, e.g. {\"total\": 1024, \"used\": 512}\n" + }, + "args": [ + [ + "const std::string &", + "path", + "\"/\"" + ] + ], + "ret_type": "std::map", + "static": false, + "def": "std::map disk_usage(const std::string &path = \"/\")", + "py_def": "def disk_usage(path: str = '/') -> dict[str, int]" + }, + "disk_partitions": { + "type": "func", + "name": "disk_partitions", + "doc": { + "brief": "Get disk partition and mount point info", + "param": { + "only_disk": "only return real disk, tempfs sysfs etc. not return, default true." + }, + "return": "disk partition and mount point info, list type, e.g. [{\"device\": \"/dev/mmcblk0p1\", \"mountpoint\": \"/mnt/sdcard\", \"fstype\": \"vfat\"}]", + "maixpy": "maix.sys.disk_partitions", + "py_doc": "Get disk partition and mount point info\n\nArgs:\n - only_disk: only return real disk, tempfs sysfs etc. not return, default true.\n\n\nReturns: disk partition and mount point info, list type, e.g. [{\"device\": \"/dev/mmcblk0p1\", \"mountpoint\": \"/mnt/sdcard\", \"fstype\": \"vfat\"}]\n" + }, + "args": [ + [ + "bool", + "only_disk", + "true" + ] + ], + "ret_type": "std::vector>", + "static": false, + "def": "std::vector> disk_partitions(bool only_disk = true)", + "py_def": "def disk_partitions(only_disk: bool = True) -> list[dict[str, str]]" + }, + "poweroff": { + "type": "func", + "name": "poweroff", + "doc": { + "brief": "Power off device", + "maixpy": "maix.sys.poweroff", + "py_doc": "Power off device" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void poweroff()", + "py_def": "def poweroff() -> None" + }, + "reboot": { + "type": "func", + "name": "reboot", + "doc": { + "brief": "Power off device and power on", + "maixpy": "maix.sys.reboot", + "py_doc": "Power off device and power on" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void reboot()", + "py_def": "def reboot() -> None" + } + }, + "auto_add": true + }, + "thread": { + "type": "module", + "doc": { + "brief": "maix.thread module" + }, + "members": { + "Thread": { + "type": "class", + "name": "Thread", + "doc": { + "brief": "thread class", + "maixpy": "maix.thread.Thread", + "py_doc": "thread class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Thread", + "doc": { + "brief": "create thread", + "param": { + "func": "direction [in], thread function, one `args` parameter, void* type, no return value", + "args": "direction [in], thread function parameter" + }, + "maixpy": "maix.thread.Thread.__init__", + "maixcdk": "maix.thread.Thread.Thread", + "py_doc": "create thread\n\nArgs:\n - func: direction [in], thread function, one `args` parameter, void* type, no return value\n - args: direction [in], thread function parameter\n" + }, + "args": [ + [ + "std::function", + "func", + null + ], + [ + "void *", + "args", + "nullptr" + ] + ], + "ret_type": null, + "static": false, + "def": "Thread(std::function func, void *args = nullptr)" + }, + "join": { + "type": "func", + "name": "join", + "doc": { + "brief": "wait thread exit", + "maixpy": "maix.thread.Thread.join", + "py_doc": "wait thread exit" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void join()" + }, + "detach": { + "type": "func", + "name": "detach", + "doc": { + "brief": "detach thread", + "maixpy": "maix.thread.Thread.detach", + "py_doc": "detach thread" + }, + "args": [], + "ret_type": "void", + "static": false, + "def": "void detach()" + }, + "joinable": { + "type": "func", + "name": "joinable", + "doc": { + "brief": "Check if thread is joinable", + "return": "true if thread is joinable", + "maixpy": "maix.thread.Thread.joinable", + "py_doc": "Check if thread is joinable\n\nReturns: true if thread is joinable\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool joinable()" + } + }, + "def": "class Thread" + } + }, + "auto_add": true + }, + "nn": { + "type": "module", + "doc": { + "brief": "maix.nn module" + }, + "members": { + "Object": { + "type": "class", + "name": "Object", + "doc": { + "brief": "Object for detect result", + "maixpy": "maix.nn.Object", + "py_doc": "Object for detect result" + }, + "members": { + "__init__": { + "type": "func", + "name": "Object", + "doc": { + "brief": "Constructor of Object for detect result", + "param": { + "x": "left top x", + "y": "left top y", + "w": "width", + "h": "height", + "class_id": "class id", + "score": "score" + }, + "maixpy": "maix.nn.Object.__init__", + "maixcdk": "maix.nn.Object.Object", + "py_doc": "Constructor of Object for detect result\n\nArgs:\n - x: left top x\n - y: left top y\n - w: width\n - h: height\n - class_id: class id\n - score: score\n" + }, + "args": [ + [ + "int", + "x", + "0" + ], + [ + "int", + "y", + "0" + ], + [ + "int", + "w", + "0" + ], + [ + "int", + "h", + "0" + ], + [ + "int", + "class_id", + "0" + ], + [ + "float", + "score", + "0" + ] + ], + "ret_type": null, + "static": false, + "def": "Object(int x = 0, int y = 0, int w = 0, int h = 0, int class_id = 0, float score = 0)" + }, + "__str__": { + "type": "func", + "name": "to_str", + "doc": { + "brief": "Object info to string", + "return": "Object info string", + "maixpy": "maix.nn.Object.__str__", + "maixcdk": "maix.nn.Object.to_str", + "py_doc": "Object info to string\n\nReturns: Object info string\n" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string to_str()" + }, + "x": { + "type": "var", + "name": "x", + "doc": { + "brief": "Object left top coordinate x", + "maixpy": "maix.nn.Object.x", + "py_doc": "Object left top coordinate x" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int x" + }, + "y": { + "type": "var", + "name": "y", + "doc": { + "brief": "Object left top coordinate y", + "maixpy": "maix.nn.Object.y", + "py_doc": "Object left top coordinate y" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int y" + }, + "w": { + "type": "var", + "name": "w", + "doc": { + "brief": "Object width", + "maixpy": "maix.nn.Object.w", + "py_doc": "Object width" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int w" + }, + "h": { + "type": "var", + "name": "h", + "doc": { + "brief": "Object height", + "maixpy": "maix.nn.Object.h", + "py_doc": "Object height" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int h" + }, + "class_id": { + "type": "var", + "name": "class_id", + "doc": { + "brief": "Object class id", + "maixpy": "maix.nn.Object.class_id", + "py_doc": "Object class id" + }, + "value": null, + "static": false, + "readonly": false, + "def": "int class_id" + }, + "score": { + "type": "var", + "name": "score", + "doc": { + "brief": "Object score", + "maixpy": "maix.nn.Object.score", + "py_doc": "Object score" + }, + "value": null, + "static": false, + "readonly": false, + "def": "float score" + } + }, + "def": "class Object" + }, + "YOLOv5": { + "type": "class", + "name": "YOLOv5", + "doc": { + "brief": "YOLOv5 class", + "maixpy": "maix.nn.YOLOv5", + "py_doc": "YOLOv5 class" + }, + "members": { + "__init__": { + "type": "func", + "name": "YOLOv5", + "doc": { + "brief": "Constructor of YOLOv5 class", + "param": { + "model": "model path, default empty, you can load model later by load function." + }, + "throw": "If model arg is not empty and load failed, will throw err::Exception.", + "maixpy": "maix.nn.YOLOv5.__init__", + "maixcdk": "maix.nn.YOLOv5.YOLOv5", + "py_doc": "Constructor of YOLOv5 class\n\nArgs:\n - model: model path, default empty, you can load model later by load function.\n" + }, + "args": [ + [ + "const string &", + "model", + "\"\"" + ] + ], + "ret_type": null, + "static": false, + "def": "YOLOv5(const string &model = \"\")" + }, + "load": { + "type": "func", + "name": "load", + "doc": { + "brief": "Load model from file", + "param": { + "model": "Model path want to load" + }, + "return": "err::Err", + "maixpy": "maix.nn.YOLOv5.load", + "py_doc": "Load model from file\n\nArgs:\n - model: Model path want to load\n\n\nReturns: err::Err\n" + }, + "args": [ + [ + "const string &", + "model", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err load(const string &model)", + "py_def": "def load(self, model: str) -> maix.err.Err" + }, + "detect": { + "type": "func", + "name": "detect", + "doc": { + "brief": "Detect objects from image", + "param": { + "img": "Image want to detect, if image's size not match model input's, will auto resize with fit method.", + "conf_th": "Confidence threshold, default 0.5.", + "iou_th": "IoU threshold, default 0.45.", + "fit": "Resize method, default image.Fit.FIT_CONTAIN." + }, + "throw": "If image format not match model input format, will throw err::Exception.", + "return": "Object list. In C++, you should delete it after use.", + "maixpy": "maix.nn.YOLOv5.detect", + "py_doc": "Detect objects from image\n\nArgs:\n - img: Image want to detect, if image's size not match model input's, will auto resize with fit method.\n - conf_th: Confidence threshold, default 0.5.\n - iou_th: IoU threshold, default 0.45.\n - fit: Resize method, default image.Fit.FIT_CONTAIN.\n\n\nReturns: Object list. In C++, you should delete it after use.\n" + }, + "args": [ + [ + "image::Image &", + "img", + null + ], + [ + "float", + "conf_th", + "0.5" + ], + [ + "float", + "iou_th", + "0.45" + ], + [ + "maix::image::Fit", + "fit", + "maix::image::FIT_CONTAIN" + ] + ], + "ret_type": "std::vector*", + "static": false, + "def": "std::vector *detect(image::Image &img, float conf_th = 0.5, float iou_th = 0.45, maix::image::Fit fit = maix::image::FIT_CONTAIN)" + }, + "input_size": { + "type": "func", + "name": "input_size", + "doc": { + "brief": "Get model input size", + "return": "model input size", + "maixpy": "maix.nn.YOLOv5.input_size", + "py_doc": "Get model input size\n\nReturns: model input size\n" + }, + "args": [], + "ret_type": "image::Size", + "static": false, + "def": "image::Size input_size()", + "py_def": "def input_size(self) -> maix.image.Size" + }, + "input_width": { + "type": "func", + "name": "input_width", + "doc": { + "brief": "Get model input width", + "return": "model input size of width", + "maixpy": "maix.nn.YOLOv5.input_width", + "py_doc": "Get model input width\n\nReturns: model input size of width\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int input_width()", + "py_def": "def input_width(self) -> int" + }, + "input_height": { + "type": "func", + "name": "input_height", + "doc": { + "brief": "Get model input height", + "return": "model input size of height", + "maixpy": "maix.nn.YOLOv5.input_height", + "py_doc": "Get model input height\n\nReturns: model input size of height\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int input_height()", + "py_def": "def input_height(self) -> int" + }, + "input_format": { + "type": "func", + "name": "input_format", + "doc": { + "brief": "Get input image format", + "return": "input image format, image::Format type.", + "maixpy": "maix.nn.YOLOv5.input_format", + "py_doc": "Get input image format\n\nReturns: input image format, image::Format type.\n" + }, + "args": [], + "ret_type": "image::Format", + "static": false, + "def": "image::Format input_format()", + "py_def": "def input_format(self) -> maix.image.Format" + }, + "labels": { + "type": "var", + "name": "labels", + "doc": { + "brief": "Labels list", + "maixpy": "maix.nn.YOLOv5.labels", + "py_doc": "Labels list" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector labels" + }, + "label_path": { + "type": "var", + "name": "label_path", + "doc": { + "brief": "Label file path", + "maixpy": "maix.nn.YOLOv5.label_path", + "py_doc": "Label file path" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::string label_path" + }, + "mean": { + "type": "var", + "name": "mean", + "doc": { + "brief": "Get mean value, list type", + "maixpy": "maix.nn.YOLOv5.mean", + "py_doc": "Get mean value, list type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector mean" + }, + "scale": { + "type": "var", + "name": "scale", + "doc": { + "brief": "Get scale value, list type", + "maixpy": "maix.nn.YOLOv5.scale", + "py_doc": "Get scale value, list type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector scale" + }, + "anchors": { + "type": "var", + "name": "anchors", + "doc": { + "brief": "Get anchors", + "maixpy": "maix.nn.YOLOv5.anchors", + "py_doc": "Get anchors" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector anchors" + } + }, + "def": "class YOLOv5" + }, + "F": { + "type": "module", + "doc": { + "brief": "maix.nn.F module" + }, + "members": { + "softmax": { + "type": "func", + "name": "softmax", + "doc": { + "brief": "Softmax, only support 1D tensor, multi-dimension tensor will be treated as 1D tensor", + "param": { + "tensor": "input tensor", + "replace": "change input tensor data directly, if not, will create a new tensor" + }, + "throw": "If arg error, will raise err.Exception error", + "return": "output tensor, if arg replace is true, return the arg tensor's address.\nIf not replace, return a new object, so In C++, you should delete it manually in this case!", + "maixpy": "maix.nn.F.softmax", + "py_doc": "Softmax, only support 1D tensor, multi-dimension tensor will be treated as 1D tensor\n\nArgs:\n - tensor: input tensor\n - replace: change input tensor data directly, if not, will create a new tensor\n\n\nReturns: output tensor, if arg replace is true, return the arg tensor's address.\nIf not replace, return a new object, so In C++, you should delete it manually in this case!\n" + }, + "args": [ + [ + "tensor::Tensor *", + "tensor", + null + ], + [ + "bool", + "replace", + null + ] + ], + "ret_type": "tensor::Tensor*", + "static": false, + "def": "tensor::Tensor *softmax(tensor::Tensor *tensor, bool replace)", + "py_def": "def softmax(tensor: maix.tensor.Tensor, replace: bool) -> maix.tensor.Tensor" + } + }, + "auto_add": true + }, + "Classifier": { + "type": "class", + "name": "Classifier", + "doc": { + "brief": "Classifier", + "maixpy": "maix.nn.Classifier", + "py_doc": "Classifier" + }, + "members": { + "__init__": { + "type": "func", + "name": "Classifier", + "doc": { + "brief": "Construct a new Classifier object", + "param": { + "model": "MUD model path, if empty, will not load model, you can call load() later.\nif not empty, will load model and will raise err::Exception if load failed." + }, + "maixpy": "maix.nn.Classifier.__init__", + "maixcdk": "maix.nn.Classifier.Classifier", + "py_doc": "Construct a new Classifier object\n\nArgs:\n - model: MUD model path, if empty, will not load model, you can call load() later.\nif not empty, will load model and will raise err::Exception if load failed.\n" + }, + "args": [ + [ + "const string &", + "model", + "\"\"" + ] + ], + "ret_type": null, + "static": false, + "def": "Classifier(const string &model = \"\")", + "py_def": "def __init__(self, model: str = '') -> None" + }, + "load": { + "type": "func", + "name": "load", + "doc": { + "brief": "Load model from file, model format is .mud,\\nMUD file should contain [extra] section, have key-values:\\n- model_type: classifier\\n- input_type: rgb or bgr\\n- mean: 123.675, 116.28, 103.53\\n- scale: 0.017124753831663668, 0.01750700280112045, 0.017429193899782137\\n- labels: imagenet_classes.txt", + "param": { + "model": "MUD model path" + }, + "return": "error code, if load failed, return error code", + "maixpy": "maix.nn.Classifier.load", + "py_doc": "Load model from file, model format is .mud,\nMUD file should contain [extra] section, have key-values:\n- model_type: classifier\n- input_type: rgb or bgr\n- mean: 123.675, 116.28, 103.53\n- scale: 0.017124753831663668, 0.01750700280112045, 0.017429193899782137\n- labels: imagenet_classes.txt\n\nArgs:\n - model: MUD model path\n\n\nReturns: error code, if load failed, return error code\n" + }, + "args": [ + [ + "const string &", + "model", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err load(const string &model)", + "py_def": "def load(self, model: str) -> maix.err.Err" + }, + "classify": { + "type": "func", + "name": "classify", + "doc": { + "brief": "Forward image to model, get result. Only for image input, use classify_raw for tensor input.", + "param": { + "img": "image, format should match model input_type\uff0c or will raise err.Exception", + "softmax": "if true, will do softmax to result, or will return raw value" + }, + "throw": "If error occurred, will raise err::Exception, you can find reason in log, mostly caused by args error or hardware error.", + "return": "result, a list of (label, score). In C++, you need to delete it after use.", + "maixpy": "maix.nn.Classifier.classify", + "py_doc": "Forward image to model, get result. Only for image input, use classify_raw for tensor input.\n\nArgs:\n - img: image, format should match model input_type\uff0c or will raise err.Exception\n - softmax: if true, will do softmax to result, or will return raw value\n\n\nReturns: result, a list of (label, score). In C++, you need to delete it after use.\n" + }, + "args": [ + [ + "image::Image &", + "img", + null + ], + [ + "bool", + "softmax", + "true" + ] + ], + "ret_type": "std::vector>*", + "static": false, + "def": "std::vector> *classify(image::Image &img, bool softmax = true)", + "py_def": "def classify(self, img: maix.image.Image, softmax: bool = True) -> list[tuple[int, float]]" + }, + "classify_raw": { + "type": "func", + "name": "classify_raw", + "doc": { + "brief": "Forward tensor data to model, get result", + "param": { + "data": "tensor data, format should match model input_type\uff0c or will raise err.Excetion", + "softmax": "if true, will do softmax to result, or will return raw value" + }, + "throw": "If error occurred, will raise err::Exception, you can find reason in log, mostly caused by args error or hardware error.", + "return": "result, a list of (label, score). In C++, you need to delete it after use.", + "maixpy": "maix.nn.Classifier.classify_raw", + "py_doc": "Forward tensor data to model, get result\n\nArgs:\n - data: tensor data, format should match model input_type\uff0c or will raise err.Excetion\n - softmax: if true, will do softmax to result, or will return raw value\n\n\nReturns: result, a list of (label, score). In C++, you need to delete it after use.\n" + }, + "args": [ + [ + "tensor::Tensor &", + "data", + null + ], + [ + "bool", + "softmax", + "true" + ] + ], + "ret_type": "std::vector>*", + "static": false, + "def": "std::vector> *classify_raw(tensor::Tensor &data, bool softmax = true)", + "py_def": "def classify_raw(self, data: maix.tensor.Tensor, softmax: bool = True) -> list[tuple[int, float]]" + }, + "input_size": { + "type": "func", + "name": "input_size", + "doc": { + "brief": "Get model input size, only for image input", + "return": "model input size", + "maixpy": "maix.nn.Classifier.input_size", + "py_doc": "Get model input size, only for image input\n\nReturns: model input size\n" + }, + "args": [], + "ret_type": "image::Size", + "static": false, + "def": "image::Size input_size()", + "py_def": "def input_size(self) -> maix.image.Size" + }, + "input_width": { + "type": "func", + "name": "input_width", + "doc": { + "brief": "Get model input width, only for image input", + "return": "model input size of width", + "maixpy": "maix.nn.Classifier.input_width", + "py_doc": "Get model input width, only for image input\n\nReturns: model input size of width\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int input_width()", + "py_def": "def input_width(self) -> int" + }, + "input_height": { + "type": "func", + "name": "input_height", + "doc": { + "brief": "Get model input height, only for image input", + "return": "model input size of height", + "maixpy": "maix.nn.Classifier.input_height", + "py_doc": "Get model input height, only for image input\n\nReturns: model input size of height\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int input_height()", + "py_def": "def input_height(self) -> int" + }, + "input_format": { + "type": "func", + "name": "input_format", + "doc": { + "brief": "Get input image format, only for image input", + "return": "input image format, image::Format type.", + "maixpy": "maix.nn.Classifier.input_format", + "py_doc": "Get input image format, only for image input\n\nReturns: input image format, image::Format type.\n" + }, + "args": [], + "ret_type": "image::Format", + "static": false, + "def": "image::Format input_format()", + "py_def": "def input_format(self) -> maix.image.Format" + }, + "input_shape": { + "type": "func", + "name": "input_shape", + "doc": { + "brief": "Get input shape, if have multiple input, only return first input shape", + "return": "input shape, list type", + "maixpy": "maix.nn.Classifier.input_shape", + "py_doc": "Get input shape, if have multiple input, only return first input shape\n\nReturns: input shape, list type\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector input_shape()", + "py_def": "def input_shape(self) -> list[int]" + }, + "labels": { + "type": "var", + "name": "labels", + "doc": { + "brief": "Labels list", + "maixpy": "maix.nn.Classifier.labels", + "py_doc": "Labels list" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector labels" + }, + "label_path": { + "type": "var", + "name": "label_path", + "doc": { + "brief": "Label file path", + "maixpy": "maix.nn.Classifier.label_path", + "py_doc": "Label file path" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::string label_path" + }, + "mean": { + "type": "var", + "name": "mean", + "doc": { + "brief": "Get mean value, list type", + "maixpy": "maix.nn.Classifier.mean", + "py_doc": "Get mean value, list type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector mean" + }, + "scale": { + "type": "var", + "name": "scale", + "doc": { + "brief": "Get scale value, list type", + "maixpy": "maix.nn.Classifier.scale", + "py_doc": "Get scale value, list type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector scale" + } + }, + "def": "class Classifier" + }, + "MUD": { + "type": "class", + "name": "MUD", + "doc": { + "brief": "MUD(model universal describe file) class", + "maixpy": "maix.nn.MUD", + "py_doc": "MUD(model universal describe file) class" + }, + "members": { + "__init__": { + "type": "func", + "name": "MUD", + "doc": { + "brief": "MUD constructor", + "param": { + "model_path": "direction [in], model file path, model format can be MUD(model universal describe file) file.\nIf model_path set, will load model from file, load failed will raise err.Exception.\nIf model_path not set, you can load model later by load function." + }, + "maixpy": "maix.nn.MUD.__init__", + "maixcdk": "maix.nn.MUD.MUD", + "py_doc": "MUD constructor\n\nArgs:\n - model_path: direction [in], model file path, model format can be MUD(model universal describe file) file.\nIf model_path set, will load model from file, load failed will raise err.Exception.\nIf model_path not set, you can load model later by load function.\n" + }, + "args": [ + [ + "const char *", + "model_path", + "nullptr" + ] + ], + "ret_type": null, + "static": false, + "def": "MUD(const char *model_path = nullptr)", + "py_def": "def __init__(self, model_path: str = None) -> None" + }, + "load": { + "type": "func", + "name": "load", + "doc": { + "brief": "Load model from file", + "param": { + "model_path": "direction [in], model file path, model format can be MUD(model universal describe file) file." + }, + "return": "error code, if load success, return err::ERR_NONE", + "maixpy": "maix.nn.MUD.load", + "py_doc": "Load model from file\n\nArgs:\n - model_path: direction [in], model file path, model format can be MUD(model universal describe file) file.\n\n\nReturns: error code, if load success, return err::ERR_NONE\n" + }, + "args": [ + [ + "const std::string &", + "model_path", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err load(const std::string &model_path)", + "py_def": "def load(self, model: str) -> maix.err.Err" + }, + "type": { + "type": "var", + "name": "type", + "doc": { + "brief": "Model type, string type", + "maixpy": "maix.nn.MUD.type", + "py_doc": "Model type, string type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::string type" + }, + "items": { + "type": "var", + "name": "items", + "doc": { + "brief": "Model config items, different model type has different config items", + "maixpy": "maix.nn.MUD.items", + "py_doc": "Model config items, different model type has different config items" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::map> items" + } + }, + "def": "class MUD" + }, + "LayerInfo": { + "type": "class", + "name": "LayerInfo", + "doc": { + "brief": "NN model layer info", + "maixpy": "maix.nn.LayerInfo", + "py_doc": "NN model layer info" + }, + "members": { + "__init__": { + "type": "func", + "name": "LayerInfo", + "doc": { + "brief": "LayerInfo constructor", + "param": { + "name": "direction [in], layer name", + "dtype": "direction [in], layer data type", + "shape": "direction [in], layer shape" + }, + "maixpy": "maix.nn.LayerInfo.__init__", + "maixcdk": "maix.nn.LayerInfo.LayerInfo", + "py_doc": "LayerInfo constructor\n\nArgs:\n - name: direction [in], layer name\n - dtype: direction [in], layer data type\n - shape: direction [in], layer shape\n" + }, + "args": [ + [ + "const std::string &", + "name", + "\"\"" + ], + [ + "tensor::DType", + "dtype", + "tensor::DType::FLOAT32" + ], + [ + "std::vector", + "shape", + "std::vector()" + ] + ], + "ret_type": null, + "static": false, + "def": "LayerInfo(const std::string &name = \"\", tensor::DType dtype = tensor::DType::FLOAT32, std::vector shape = std::vector())" + }, + "name": { + "type": "var", + "name": "name", + "doc": { + "brief": "Layer name", + "maixpy": "maix.nn.LayerInfo.name", + "py_doc": "Layer name" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::string name" + }, + "dtype": { + "type": "var", + "name": "dtype", + "doc": { + "brief": "Layer data type", + "attention": "If model is quantized, this is the real quantized data type like int8 float16,\nin most scene, inputs and outputs we actually use float32 in API like forward.", + "maixpy": "maix.nn.LayerInfo.dtype", + "py_doc": "Layer data type" + }, + "value": null, + "static": false, + "readonly": false, + "def": "tensor::DType dtype" + }, + "shape": { + "type": "var", + "name": "shape", + "doc": { + "brief": "Layer shape", + "maixpy": "maix.nn.LayerInfo.shape", + "py_doc": "Layer shape" + }, + "value": null, + "static": false, + "readonly": false, + "def": "std::vector shape" + }, + "to_str": { + "type": "func", + "name": "to_str", + "doc": { + "brief": "To string", + "maixpy": "maix.nn.LayerInfo.to_str", + "py_doc": "To string" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string to_str()" + }, + "__str__": { + "type": "func", + "name": "__str__", + "doc": { + "brief": "To string", + "maixpy": "maix.nn.LayerInfo.__str__", + "py_doc": "To string" + }, + "args": [], + "ret_type": "std::string", + "static": false, + "def": "std::string __str__()", + "py_def": "def __str__(self) -> str" + } + }, + "def": "class LayerInfo" + }, + "NN": { + "type": "class", + "name": "NN", + "doc": { + "brief": "Neural network class", + "maixpy": "maix.nn.NN", + "py_doc": "Neural network class" + }, + "members": { + "__init__": { + "type": "func", + "name": "NN", + "doc": { + "brief": "Neural network constructor", + "param": { + "model": "direction [in], model file path, model format can be MUD(model universal describe file) file.\nIf model_path set, will load model from file, load failed will raise err.Exception.\nIf model_path not set, you can load model later by load function." + }, + "maixpy": "maix.nn.NN.__init__", + "py_doc": "Neural network constructor\n\nArgs:\n - model: direction [in], model file path, model format can be MUD(model universal describe file) file.\nIf model_path set, will load model from file, load failed will raise err.Exception.\nIf model_path not set, you can load model later by load function.\n" + }, + "args": [ + [ + "const std::string &", + "model", + "\"\"" + ] + ], + "ret_type": null, + "static": false, + "def": "NN(const std::string &model = \"\")" + }, + "load": { + "type": "func", + "name": "load", + "doc": { + "brief": "Load model from file", + "param": { + "model": "direction [in], model file path, model format can be MUD(model universal describe file) file." + }, + "return": "error code, if load success, return err::ERR_NONE", + "maixpy": "maix.nn.NN.load", + "py_doc": "Load model from file\n\nArgs:\n - model: direction [in], model file path, model format can be MUD(model universal describe file) file.\n\n\nReturns: error code, if load success, return err::ERR_NONE\n" + }, + "args": [ + [ + "const std::string &", + "model", + null + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err load(const std::string &model)", + "py_def": "def load(self, model: str) -> maix.err.Err" + }, + "loaded": { + "type": "func", + "name": "loaded", + "doc": { + "brief": "Is model loaded", + "return": "true if model loaded, else false", + "maixpy": "maix.nn.NN.loaded", + "py_doc": "Is model loaded\n\nReturns: true if model loaded, else false\n" + }, + "args": [], + "ret_type": "bool", + "static": false, + "def": "bool loaded()" + }, + "inputs_info": { + "type": "func", + "name": "inputs_info", + "doc": { + "brief": "Get model input layer info", + "return": "input layer info", + "maixpy": "maix.nn.NN.inputs_info", + "py_doc": "Get model input layer info\n\nReturns: input layer info\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector inputs_info()" + }, + "outputs_info": { + "type": "func", + "name": "outputs_info", + "doc": { + "brief": "Get model output layer info", + "return": "output layer info", + "maixpy": "maix.nn.NN.outputs_info", + "py_doc": "Get model output layer info\n\nReturns: output layer info\n" + }, + "args": [], + "ret_type": "std::vector", + "static": false, + "def": "std::vector outputs_info()" + }, + "extra_info": { + "type": "func", + "name": "extra_info", + "doc": { + "brief": "Get model extra info define in MUD file", + "return": "extra info, dict type, key-value object, attention: key and value are all string type.", + "maixpy": "maix.nn.NN.extra_info", + "py_doc": "Get model extra info define in MUD file\n\nReturns: extra info, dict type, key-value object, attention: key and value are all string type.\n" + }, + "args": [], + "ret_type": "std::map", + "static": false, + "def": "std::map extra_info()" + }, + "forward": { + "type": "func", + "name": "forward", + "doc": { + "brief": "forward run model, get output of model,\\nthis is specially for MaixPy, not efficient, but easy to use in MaixPy", + "param": { + "input": "direction [in], input tensor" + }, + "return": "output tensor. In C++, you should manually delete tensors in return value and return value.", + "maixpy": "maix.nn.NN.forward", + "py_doc": "forward run model, get output of model,\nthis is specially for MaixPy, not efficient, but easy to use in MaixPy\n\nArgs:\n - input: direction [in], input tensor\n\n\nReturns: output tensor. In C++, you should manually delete tensors in return value and return value.\n" + }, + "args": [ + [ + "tensor::Tensors &", + "inputs", + null + ] + ], + "ret_type": "tensor::Tensors*", + "static": false, + "def": "tensor::Tensors *forward(tensor::Tensors &inputs)" + }, + "forward_image": { + "type": "func", + "name": "forward_image", + "doc": { + "brief": "forward model, param is image", + "param": { + "img": "input image", + "mean": "mean value, a list type, e.g. [0.485, 0.456, 0.406], default is empty list means not normalize.", + "scale": "scale value, a list type, e.g. [1/0.229, 1/0.224, 1/0.225], default is empty list means not normalize.", + "fit": "fit mode, if the image size of input not equal to model's input, it will auto resize use this fit method,\ndefault is image.Fit.FIT_FILL for easy coordinate calculation, but for more accurate result, use image.Fit.FIT_CONTAIN is better.", + "copy_result": "If set true, will copy result to a new variable; else will use a internal memory, you can only use it until to the next forward.\nDefault true to avoid problems, you can set it to false manually to make speed faster." + }, + "return": "output tensor. In C++, you should manually delete tensors in return value and return value.", + "maixpy": "maix.nn.NN.forward_image", + "py_doc": "forward model, param is image\n\nArgs:\n - img: input image\n - mean: mean value, a list type, e.g. [0.485, 0.456, 0.406], default is empty list means not normalize.\n - scale: scale value, a list type, e.g. [1/0.229, 1/0.224, 1/0.225], default is empty list means not normalize.\n - fit: fit mode, if the image size of input not equal to model's input, it will auto resize use this fit method,\ndefault is image.Fit.FIT_FILL for easy coordinate calculation, but for more accurate result, use image.Fit.FIT_CONTAIN is better.\n - copy_result: If set true, will copy result to a new variable; else will use a internal memory, you can only use it until to the next forward.\nDefault true to avoid problems, you can set it to false manually to make speed faster.\n\n\nReturns: output tensor. In C++, you should manually delete tensors in return value and return value.\n" + }, + "args": [ + [ + "image::Image &", + "img", + null + ], + [ + "std::vector", + "mean", + "std::vector()" + ], + [ + "std::vector", + "scale", + "std::vector()" + ], + [ + "image::Fit", + "fit", + "image::Fit::FIT_FILL" + ], + [ + "bool", + "copy_result", + "true" + ] + ], + "ret_type": "tensor::Tensors*", + "static": false, + "def": "tensor::Tensors *forward_image(image::Image &img, std::vector mean = std::vector(), std::vector scale = std::vector(), image::Fit fit = image::Fit::FIT_FILL, bool copy_result = true)" + } + }, + "def": "class NN" + } + }, + "auto_add": true + }, + "audio": { + "type": "module", + "doc": { + "brief": "maix.audio module", + "maixpy": "maix.audio", + "py_doc": "maix.audio module" + }, + "members": { + "Format": { + "type": "enum", + "name": "Format", + "doc": { + "brief": "Audio type", + "maixpy": "maix.audio.Format", + "py_doc": "Audio type" + }, + "values": [ + [ + "FMT_NONE", + "0", + "format invalid" + ], + [ + "FMT_S8", + "", + "unsigned 8 bits" + ], + [ + "FMT_S16_LE", + "", + "signed 16 bits, little endian" + ], + [ + "FMT_S32_LE", + "", + "signed 32 bits, little endian" + ], + [ + "FMT_S16_BE", + "", + "signed 16 bits, big endian" + ], + [ + "FMT_S32_BE", + "", + "signed 32 bits, big endian" + ], + [ + "FMT_U8", + "", + "unsigned 8 bits" + ], + [ + "FMT_U16_LE", + "", + "unsigned 16 bits, little endian" + ], + [ + "FMT_U32_LE", + "", + "unsigned 32 bits, little endian" + ], + [ + "FMT_U16_BE", + "", + "unsigned 16 bits, big endian" + ], + [ + "FMT_U32_BE", + "", + "unsigned 32 bits, big endian" + ] + ], + "def": "enum Format\n {\n FMT_NONE = 0, // format invalid\n FMT_S8, // unsigned 8 bits\n FMT_S16_LE, // signed 16 bits, little endian\n FMT_S32_LE, // signed 32 bits, little endian\n FMT_S16_BE, // signed 16 bits, big endian\n FMT_S32_BE, // signed 32 bits, big endian\n FMT_U8, // unsigned 8 bits\n FMT_U16_LE, // unsigned 16 bits, little endian\n FMT_U32_LE, // unsigned 32 bits, little endian\n FMT_U16_BE, // unsigned 16 bits, big endian\n FMT_U32_BE, // unsigned 32 bits, big endian\n }" + }, + "Recorder": { + "type": "class", + "name": "Recorder", + "doc": { + "brief": "Recorder class", + "maixpy": "maix.audio.Recorder", + "py_doc": "Recorder class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Recorder", + "doc": { + "brief": "Construct a new Recorder object", + "param": { + "path": "record path. the path determines the location where you save the file, if path is none, the audio module will not save file.", + "sample_rate": "record sample rate, default is 48000(48KHz), means 48000 samples per second.", + "format": "record sample format, default is audio::Format::FMT_S16_LE, means sampling 16 bits at a time and save as signed 16 bits, little endian. see @audio::Format", + "channel": "record sample channel, default is 1, means 1 channel sampling at the same time" + }, + "maixpy": "maix.audio.Recorder.__init__", + "maixcdk": "maix.audio.Recorder.Recorder", + "py_doc": "Construct a new Recorder object\n\nArgs:\n - path: record path. the path determines the location where you save the file, if path is none, the audio module will not save file.\n - sample_rate: record sample rate, default is 48000(48KHz), means 48000 samples per second.\n - format: record sample format, default is audio::Format::FMT_S16_LE, means sampling 16 bits at a time and save as signed 16 bits, little endian. see @audio::Format\n - channel: record sample channel, default is 1, means 1 channel sampling at the same time\n" + }, + "args": [ + [ + "std::string", + "path", + "std::string()" + ], + [ + "int", + "sample_rate", + "48000" + ], + [ + "audio::Format", + "format", + "audio::Format::FMT_S16_LE" + ], + [ + "int", + "channel", + "1" + ] + ], + "ret_type": null, + "static": false, + "def": "Recorder(std::string path = std::string(), int sample_rate = 48000, audio::Format format = audio::Format::FMT_S16_LE, int channel = 1)" + }, + "volume": { + "type": "func", + "name": "volume", + "doc": { + "brief": "Set/Get record volume", + "param": { + "value": "volume value, If you use this parameter, audio will set the value to volume,\nif you don't, it will return the current volume." + }, + "return": "the current volume", + "maixpy": "maix.audio.Recorder.volume", + "py_doc": "Set/Get record volume\n\nArgs:\n - value: volume value, If you use this parameter, audio will set the value to volume,\nif you don't, it will return the current volume.\n\n\nReturns: the current volume\n" + }, + "args": [ + [ + "int", + "value", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int volume(int value = -1)" + }, + "record": { + "type": "func", + "name": "record", + "doc": { + "brief": "Record, Read all cached data in buffer and return.", + "param": { + "record_ms": "record time. unit: ms", + "sample_rate": "audio sample rate", + "format": "audio sample format", + "channel": "audio sample channel" + }, + "return": "pcm data. datatype @see Bytes. If you pass in record_ms parameter, the return value is an empty Bytes object.", + "maixpy": "maix.audio.Recorder.record", + "py_doc": "Record, Read all cached data in buffer and return.\n\nArgs:\n - record_ms: record time. unit: ms\n - sample_rate: audio sample rate\n - format: audio sample format\n - channel: audio sample channel\n\n\nReturns: pcm data. datatype @see Bytes. If you pass in record_ms parameter, the return value is an empty Bytes object.\n" + }, + "args": [ + [ + "int", + "record_ms", + "-1" + ] + ], + "ret_type": "maix::Bytes*", + "static": false, + "def": "maix::Bytes *record(int record_ms = -1)" + }, + "finish": { + "type": "func", + "name": "finish", + "doc": { + "brief": "Finish the record, if you have passed in the path, this api will save the audio data to file.", + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.audio.Recorder.finish", + "py_doc": "Finish the record, if you have passed in the path, this api will save the audio data to file.\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [], + "ret_type": "err::Err", + "static": false, + "def": "err::Err finish()" + }, + "sample_rate": { + "type": "func", + "name": "sample_rate", + "doc": { + "brief": "Get sample rate", + "return": "returns sample rate", + "maixpy": "maix.audio.Recorder.sample_rate", + "py_doc": "Get sample rate\n\nReturns: returns sample rate\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int sample_rate()" + }, + "format": { + "type": "func", + "name": "format", + "doc": { + "brief": "Get sample format", + "return": "returns sample format", + "maixpy": "maix.audio.Recorder.format", + "py_doc": "Get sample format\n\nReturns: returns sample format\n" + }, + "args": [], + "ret_type": "audio::Format", + "static": false, + "def": "audio::Format format()" + }, + "channel": { + "type": "func", + "name": "channel", + "doc": { + "brief": "Get sample channel", + "return": "returns sample channel", + "maixpy": "maix.audio.Recorder.channel", + "py_doc": "Get sample channel\n\nReturns: returns sample channel\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int channel()" + } + }, + "def": "class Recorder" + }, + "Player": { + "type": "class", + "name": "Player", + "doc": { + "brief": "Player class", + "maixpy": "maix.audio.Player", + "py_doc": "Player class" + }, + "members": { + "__init__": { + "type": "func", + "name": "Player", + "doc": { + "brief": "Construct a new Player object", + "param": { + "path": "player path. the path determines the location where you save the file, if path is none, the audio module will not save file.", + "sample_rate": "player sample rate, default is 48000(48KHz), means 48000 samples per second.", + "format": "player sample format, default is audio::Format::FMT_S16_LE, means sampling 16 bits at a time and save as signed 16 bits, little endian. see @audio::Format", + "channel": "player sample channel, default is 1, means 1 channel sampling at the same time" + }, + "maixpy": "maix.audio.Player.__init__", + "maixcdk": "maix.audio.Player.Player", + "py_doc": "Construct a new Player object\n\nArgs:\n - path: player path. the path determines the location where you save the file, if path is none, the audio module will not save file.\n - sample_rate: player sample rate, default is 48000(48KHz), means 48000 samples per second.\n - format: player sample format, default is audio::Format::FMT_S16_LE, means sampling 16 bits at a time and save as signed 16 bits, little endian. see @audio::Format\n - channel: player sample channel, default is 1, means 1 channel sampling at the same time\n" + }, + "args": [ + [ + "std::string", + "path", + "std::string()" + ], + [ + "int", + "sample_rate", + "48000" + ], + [ + "audio::Format", + "format", + "audio::Format::FMT_S16_LE" + ], + [ + "int", + "channel", + "1" + ] + ], + "ret_type": null, + "static": false, + "def": "Player(std::string path = std::string(), int sample_rate = 48000, audio::Format format = audio::Format::FMT_S16_LE, int channel = 1)" + }, + "volume": { + "type": "func", + "name": "volume", + "doc": { + "brief": "Set/Get player volume(Not support now)", + "param": { + "value": "volume value, If you use this parameter, audio will set the value to volume,\nif you don't, it will return the current volume." + }, + "return": "the current volume", + "maixpy": "maix.audio.Player.volume", + "py_doc": "Set/Get player volume(Not support now)\n\nArgs:\n - value: volume value, If you use this parameter, audio will set the value to volume,\nif you don't, it will return the current volume.\n\n\nReturns: the current volume\n" + }, + "args": [ + [ + "int", + "value", + "-1" + ] + ], + "ret_type": "int", + "static": false, + "def": "int volume(int value = -1)" + }, + "play": { + "type": "func", + "name": "play", + "doc": { + "brief": "Play", + "param": { + "data": "audio data, must be raw data" + }, + "return": "error code, err::ERR_NONE means success, others means failed", + "maixpy": "maix.audio.Player.play", + "py_doc": "Play\n\nArgs:\n - data: audio data, must be raw data\n\n\nReturns: error code, err::ERR_NONE means success, others means failed\n" + }, + "args": [ + [ + "maix::Bytes *", + "data", + "maix::audio::Player::NoneBytes" + ] + ], + "ret_type": "err::Err", + "static": false, + "def": "err::Err play(maix::Bytes *data = maix::audio::Player::NoneBytes)" + }, + "sample_rate": { + "type": "func", + "name": "sample_rate", + "doc": { + "brief": "Get sample rate", + "return": "returns sample rate", + "maixpy": "maix.audio.Player.sample_rate", + "py_doc": "Get sample rate\n\nReturns: returns sample rate\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int sample_rate()" + }, + "format": { + "type": "func", + "name": "format", + "doc": { + "brief": "Get sample format", + "return": "returns sample format", + "maixpy": "maix.audio.Player.format", + "py_doc": "Get sample format\n\nReturns: returns sample format\n" + }, + "args": [], + "ret_type": "audio::Format", + "static": false, + "def": "audio::Format format()" + }, + "channel": { + "type": "func", + "name": "channel", + "doc": { + "brief": "Get sample channel", + "return": "returns sample channel", + "maixpy": "maix.audio.Player.channel", + "py_doc": "Get sample channel\n\nReturns: returns sample channel\n" + }, + "args": [], + "ret_type": "int", + "static": false, + "def": "int channel()" + } + }, + "def": "class Player" + } + }, + "auto_add": false + } + } + } + } +} \ No newline at end of file diff --git a/maixpy/api/config.json b/maixpy/api/config.json new file mode 100644 index 00000000..ff4f116e --- /dev/null +++ b/maixpy/api/config.json @@ -0,0 +1,4 @@ +{ + "import": "config_en", + "name": "MaixPy API Reference" +} diff --git a/maixpy/api/index.html b/maixpy/api/index.html new file mode 100644 index 00000000..753e2fd8 --- /dev/null +++ b/maixpy/api/index.html @@ -0,0 +1,391 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy API -- Maix AI machine vision platform Python API - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy API -- Maix AI machine vision platform Python API

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

You can read API doc at MaixPy API on Sipeed Wiki

+

If you want to preview API doc offline, build MaixPy, and API doc will be generated in MaixPy/docs/api/ directory.

+
+

For MaixPy developer: This API documentation is generated from the source code, DO NOT edit this file manually!

+
+

MaixPy API documentation, modules:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
modulebrief
maix.errmaix.err module
maix.tensormaix.tensor module
maix.imagemaix.image module, image related definition and functions
maix.cameramaix.camera module, access camera device and get image from it
maix.displaymaix.display module, control display device and show image on it
maix.videomaix.video module
maix.touchscreenmaix.touchscreen module
maix.rtspmaix.rtsp module
maix.networkmaix.network module
maix.commmaix.comm module
maix.peripheralChip's peripheral driver
maix.utilmaix.util module
maix.timemaix.time module
maix.appmaix.app module
maix.exampleexample module, this will be maix.example module in MaixPy, maix::example namespace in MaixCDK
maix.i18nmaix.i18n module
maix.fsmaix.fs module
maix.protocolmaix.protocol module
maix.sysmaix.sys module
maix.threadmaix.thread module
maix.nnmaix.nn module
maix.audiomaix.audio module
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/maix/app.html b/maixpy/api/maix/app.html new file mode 100644 index 00000000..deb88002 --- /dev/null +++ b/maixpy/api/maix/app.html @@ -0,0 +1,1308 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix.app - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix.app

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.app module

+
+

You can use maix.app to access this module with MaixPy
+This module is generated from MaixCDK

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

app_id

+ +
def app_id() -> str
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet current APP ID.
returnAPP ID.
+

C++ defination code:

+ +
string app_id()
+
+

set_app_id

+ +
def set_app_id(app_id: str) -> str
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefSet current APP ID.
paramapp_id: APP ID.
+

C++ defination code:

+ +
string set_app_id(const string &app_id)
+
+

get_apps_info_path

+ +
def get_apps_info_path() -> str
+
+ + + + + + + + + + + + + +
itemdoc
briefGet APP info file path.
+

C++ defination code:

+ +
string get_apps_info_path()
+
+

get_apps_info

+ +
def get_apps_info(ignore_launcher: bool = False, ignore_app_store: bool = False) -> list[APP_Info]
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefGet APP info list.
paramignore_launcher: if true, ignore launcher APP. default false.
ignore_app_store: if true, ignore app store APP. default false.
returnAPP info list. APP_Info object list.
+

C++ defination code:

+ +
vector<app::APP_Info> &get_apps_info(bool ignore_launcher = false, bool ignore_app_store = false)
+
+

get_app_data_path

+ +
def get_app_data_path() -> str
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet APP info, APP can store private data in this directory.
returnAPP data path "./data", just return the data folder in current path because APP executed in app install path or project path.
So, you must execute your program in you project path to use the project/data folder when you debug your APP.
+

C++ defination code:

+ +
string get_app_data_path()
+
+

get_app_path

+ +
def get_app_path(app_id: str = '') -> str
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefGet APP path.
paramapp_id: APP ID, if empty, return current APP path, else return the APP path by app_id.
returnAPP path, just return the current path because APP executed in app install path or project path.
So, you must execute your program in you project path to use the project/data folder when you debug your APP.
+

C++ defination code:

+ +
string get_app_path(const string &app_id = "")
+
+

get_tmp_path

+ +
def get_tmp_path() -> str
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet global temporary data path, APPs can use this path as temporary data directory.
returntemporary data path.
+

C++ defination code:

+ +
string get_tmp_path()
+
+

get_share_path

+ +
def get_share_path() -> str
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet data path of share, shared data like picture and video will put in this directory
returnshare data path.
+

C++ defination code:

+ +
string get_share_path()
+
+

get_picture_path

+ +
def get_picture_path() -> str
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet picture path of share, shared picture will put in this directory
returnshare picture path.
+

C++ defination code:

+ +
string get_picture_path()
+
+

get_video_path

+ +
def get_video_path() -> str
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet video path of share, shared video will put in this directory
returnshare video path.
+

C++ defination code:

+ +
string get_video_path()
+
+

get_font_path

+ +
def get_font_path() -> str
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet font path of share, shared font will put in this directory
returnshare font path.
+

C++ defination code:

+ +
string get_font_path()
+
+

get_icon_path

+ +
def get_icon_path() -> str
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet icon path of share, shared icon will put in this directory
returnshare icon path.
+

C++ defination code:

+ +
string get_icon_path()
+
+

get_sys_config_kv

+ +
def get_sys_config_kv(item: str, key: str, value: str = '', from_cache: bool = True) -> str
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefGet system config item value.
paramitem: name of setting item, e.g. wifi, language. more see settings APP.
key: config key, e.g. for wifi, key can be ssid, for language, key can be locale.
value: default value, if not found, return this value.
from_cache: if true, read from cache, if false, read from file.
returnconfig value, always string type, if not found, return empty string.
+

C++ defination code:

+ +
string get_sys_config_kv(const string &item, const string &key, const string &value = "", bool from_cache = true)
+
+

get_app_config_kv

+ +
def get_app_config_kv(item: str, key: str, value: str = '', from_cache: bool = True) -> str
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefGet APP config item value.
paramitem: name of setting item, e.g. user_info
key: config key, e.g. for user_info, key can be name, age etc.
value: default value, if not found, return this value.
from_cache: if true, read from cache, if false, read from file.
returnconfig value, always string type, if not found, return empty string.
+

C++ defination code:

+ +
string get_app_config_kv(const string &item, const string &key, const string &value = "", bool from_cache = true)
+
+

set_app_config_kv

+ +
def set_app_config_kv(item: str, key: str, value: str, write_file: bool = True) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefSet APP config item value.
paramitem: name of setting item, e.g. user_info
key: config key, e.g. for user_info, key can be name, age etc.
value: config value, always string type.
write_file: if true, write to file, if false, just write to cache.
returnerr::Err
+

C++ defination code:

+ +
err::Err set_app_config_kv(const string &item, const string &key, const string &value, bool write_file = true)
+
+

get_app_config_path

+ +
def get_app_config_path() -> str
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet APP config path, ini format, so you can use your own ini parser to parse it like configparser in Python.\nAll APP config info is recommended to store in this file.
returnAPP config path(ini format).
+

C++ defination code:

+ +
string get_app_config_path()
+
+

set_exit_msg

+ +
def set_exit_msg(code: maix.err.Err, msg: str) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefSet APP exit code and exit message.\nIf code != 0, the launcher will show a dialog to user, and display the msg.
paramcode: exit code, 0 means success, other means error, if code is 0, do nothing.
msg: exit message, if code is 0, msg is not used.
returnexit code, the same as arg @code.
+

C++ defination code:

+ +
err::Err set_exit_msg(err::Err code, const string &msg)
+
+

get_exit_msg

+ +
def get_exit_msg(cache: bool = False) -> tuple[str, maix.err.Err, str]
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefGet APP exit code and exit message.
paramcache: if true, read from cache, if false, read from file. default false.
returnexit return app_id, exit code and exit message.
+

C++ defination code:

+ +
tuple<string, err::Err, string> get_exit_msg(bool cache = false)
+
+

have_exit_msg

+ +
def have_exit_msg(cache: bool = False) -> bool
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefCheck if have exit msg
paramcache: if true, just check from cache, if false, check from file. default false.
returntrue if have exit msg, false if not.
+

C++ defination code:

+ +
bool have_exit_msg(bool cache = false)
+
+

switch_app

+ +
def switch_app(app_id: str, idx: int = -1) -> None
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefExit this APP and start another APP(by launcher).\nCall this API will call set_exit_flag(true), you should check app::need_exit() in your code.\nAnd exit this APP if app::need_exit() return true.
paramapp_id: APP ID which will be started. app_id and idx must have one is valid.
idx: APP index. app_id and idx must have one is valid.
+

C++ defination code:

+ +
void switch_app(const string &app_id, int idx = -1)
+
+

need_exit

+ +
def need_exit() -> bool
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefShoule this APP exit?
returntrue if this APP should exit, false if not.
attentionThis API is a function, not a variable.
+

C++ defination code:

+ +
bool need_exit()
+
+

running

+ +
def running() -> bool
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefApp should running? The same as !app::need_exit() (not app::need_exit() in MaixPy).
returntrue if this APP should running, false if not.
attentionThis API is a function, not a variable.
+

C++ defination code:

+ +
bool running()
+
+

set_exit_flag

+ +
def set_exit_flag(exit: bool) -> None
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefSet exit flag. You can get exit flag by app.need_exit().
paramexit: true if this APP should exit, false if not.
+

C++ defination code:

+ +
void set_exit_flag(bool exit)
+
+

Class

+

Version

+ + + + + + + + + + + + + +
itemdoc
briefAPP version
+

C++ defination code:

+ +
class Version
+
+

__str__

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefConvert to string, e.g. 1.0.0
staticFalse
+

C++ defination code:

+ +
std::string __str__()
+
+

from_str

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefConvert from string, e.g. "1.0.0"
staticTrue
+

C++ defination code:

+ +
static app::Version from_str(const string &version_str)
+
+

APP_Info

+ + + + + + + + + + + + + +
itemdoc
briefAPP info
+

C++ defination code:

+ +
class APP_Info
+
+

id

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefAPP id
staticFalse
readonlyFalse
+

C++ defination code:

+ +
string id
+
+

name

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefAPP name
staticFalse
readonlyFalse
+

C++ defination code:

+ +
string name
+
+

icon

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefAPP icon
staticFalse
readonlyFalse
+

C++ defination code:

+ +
string icon
+
+

version

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefAPP version
staticFalse
readonlyFalse
+

C++ defination code:

+ +
Version version
+
+

exec

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefAPP exec
staticFalse
readonlyFalse
+

C++ defination code:

+ +
string exec
+
+

author

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefAPP author
staticFalse
readonlyFalse
+

C++ defination code:

+ +
string author
+
+

desc

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefAPP desc
staticFalse
readonlyFalse
+

C++ defination code:

+ +
string desc
+
+

names

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefAPP names
staticFalse
readonlyFalse
+

C++ defination code:

+ +
map<string, string> names
+
+

descs

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefAPP descs
staticFalse
readonlyFalse
+

C++ defination code:

+ +
map<string, string> descs
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/maix/audio.html b/maixpy/api/maix/audio.html new file mode 100644 index 00000000..7a9d5a94 --- /dev/null +++ b/maixpy/api/maix/audio.html @@ -0,0 +1,791 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix.audio - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix.audio

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.audio module

+
+

You can use maix.audio to access this module with MaixPy
+This module is generated from MaixCDK

+
+

Module

+

No module

+

Enum

+

Format

+ + + + + + + + + + + + + + + + + +
itemdoc
briefAudio type
valuesFMT_NONE: format invalid
FMT_S8: unsigned 8 bits
FMT_S16_LE: signed 16 bits, little endian
FMT_S32_LE: signed 32 bits, little endian
FMT_S16_BE: signed 16 bits, big endian
FMT_S32_BE: signed 32 bits, big endian
FMT_U8: unsigned 8 bits
FMT_U16_LE: unsigned 16 bits, little endian
FMT_U32_LE: unsigned 32 bits, little endian
FMT_U16_BE: unsigned 16 bits, big endian
FMT_U32_BE: unsigned 32 bits, big endian
+

C++ defination code:

+ +
enum Format
+    {
+        FMT_NONE = 0,       // format invalid
+        FMT_S8,             // unsigned 8 bits
+        FMT_S16_LE,         // signed 16 bits, little endian
+        FMT_S32_LE,         // signed 32 bits, little endian
+        FMT_S16_BE,         // signed 16 bits, big endian
+        FMT_S32_BE,         // signed 32 bits, big endian
+        FMT_U8,             // unsigned 8 bits
+        FMT_U16_LE,         // unsigned 16 bits, little endian
+        FMT_U32_LE,         // unsigned 32 bits, little endian
+        FMT_U16_BE,         // unsigned 16 bits, big endian
+        FMT_U32_BE,         // unsigned 32 bits, big endian
+    }
+
+

Variable

+

Function

+

Class

+

Recorder

+ + + + + + + + + + + + + +
itemdoc
briefRecorder class
+

C++ defination code:

+ +
class Recorder
+
+

__init__

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefConstruct a new Recorder object
parampath: record path. the path determines the location where you save the file, if path is none, the audio module will not save file.
sample_rate: record sample rate, default is 48000(48KHz), means 48000 samples per second.
format: record sample format, default is audio::Format::FMT_S16_LE, means sampling 16 bits at a time and save as signed 16 bits, little endian. see @audio::Format
channel: record sample channel, default is 1, means 1 channel sampling at the same time
staticFalse
+

C++ defination code:

+ +
Recorder(std::string path = std::string(), int sample_rate = 48000, audio::Format format = audio::Format::FMT_S16_LE, int channel = 1)
+
+

volume

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSet/Get record volume
paramvalue: volume value, If you use this parameter, audio will set the value to volume,
if you don't, it will return the current volume.
returnthe current volume
staticFalse
+

C++ defination code:

+ +
int volume(int value = -1)
+
+

record

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefRecord, Read all cached data in buffer and return.
paramrecord_ms: record time. unit: ms
sample_rate: audio sample rate
format: audio sample format
channel: audio sample channel
returnpcm data. datatype @see Bytes. If you pass in record_ms parameter, the return value is an empty Bytes object.
staticFalse
+

C++ defination code:

+ +
maix::Bytes *record(int record_ms = -1)
+
+

finish

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefFinish the record, if you have passed in the path, this api will save the audio data to file.
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+

C++ defination code:

+ +
err::Err finish()
+
+

sample_rate

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet sample rate
returnreturns sample rate
staticFalse
+

C++ defination code:

+ +
int sample_rate()
+
+

format

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet sample format
returnreturns sample format
staticFalse
+

C++ defination code:

+ +
audio::Format format()
+
+

channel

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet sample channel
returnreturns sample channel
staticFalse
+

C++ defination code:

+ +
int channel()
+
+

Player

+ + + + + + + + + + + + + +
itemdoc
briefPlayer class
+

C++ defination code:

+ +
class Player
+
+

__init__

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefConstruct a new Player object
parampath: player path. the path determines the location where you save the file, if path is none, the audio module will not save file.
sample_rate: player sample rate, default is 48000(48KHz), means 48000 samples per second.
format: player sample format, default is audio::Format::FMT_S16_LE, means sampling 16 bits at a time and save as signed 16 bits, little endian. see @audio::Format
channel: player sample channel, default is 1, means 1 channel sampling at the same time
staticFalse
+

C++ defination code:

+ +
Player(std::string path = std::string(), int sample_rate = 48000, audio::Format format = audio::Format::FMT_S16_LE, int channel = 1)
+
+

volume

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSet/Get player volume(Not support now)
paramvalue: volume value, If you use this parameter, audio will set the value to volume,
if you don't, it will return the current volume.
returnthe current volume
staticFalse
+

C++ defination code:

+ +
int volume(int value = -1)
+
+

play

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefPlay
paramdata: audio data, must be raw data
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+

C++ defination code:

+ +
err::Err play(maix::Bytes *data = maix::audio::Player::NoneBytes)
+
+

sample_rate

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet sample rate
returnreturns sample rate
staticFalse
+

C++ defination code:

+ +
int sample_rate()
+
+

format

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet sample format
returnreturns sample format
staticFalse
+

C++ defination code:

+ +
audio::Format format()
+
+

channel

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet sample channel
returnreturns sample channel
staticFalse
+

C++ defination code:

+ +
int channel()
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/maix/camera.html b/maixpy/api/maix/camera.html new file mode 100644 index 00000000..0361aac0 --- /dev/null +++ b/maixpy/api/maix/camera.html @@ -0,0 +1,1383 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix.camera - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix.camera

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.camera module, access camera device and get image from it

+
+

You can use maix.camera to access this module with MaixPy
+This module is generated from MaixCDK

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

list_devices

+ + + + + + + + + + + + + + + + + +
itemdoc
briefList all supported camera devices.
returnReturns the path to the camera device.
+

C++ defination code:

+ +
std::vector<std::string> list_devices()
+
+

set_regs_enable

+ +
def set_regs_enable(enable: bool = True) -> None
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefEnable set camera registers, default is false, if set to true, will not set camera registers, you can manually set registers by write_reg API.
paramenable: enable/disable set camera registers
+

C++ defination code:

+ +
void set_regs_enable(bool enable = true)
+
+

Class

+

Camera

+ + + + + + + + + + + + + +
itemdoc
briefCamera class
+

C++ defination code:

+ +
class Camera
+
+

__init__

+ +
def __init__(self, width: int = -1, height: int = -1, format: maix.image.Format = ..., device: str = None, fps: int = -1, buff_num: int = 3, open: bool = True) -> None
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefConstruct a new Camera object
paramwidth: camera width, default is -1, means auto, mostly means max width of camera support
height: camera height, default is -1, means auto, mostly means max height of camera support
format: camera output format, default is image.Format.FMT_RGB888
device: camera device path, you can get devices by list_devices method, by default(value is NULL(None in MaixPy)) means the first device
fps: camera fps, default is -1, means auto, mostly means max fps of camera support
buff_num: camera buffer number, default is 3, means 3 buffer, one used by user, one used for cache the next frame,
more than one buffer will accelerate image read speed, but will cost more memory.
open: If true, camera will automatically call open() after creation. default is true.
staticFalse
+

C++ defination code:

+ +
Camera(int width = -1, int height = -1, image::Format format = image::FMT_RGB888, const char *device = nullptr, int fps = -1, int buff_num = 3, bool open = true)
+
+

get_ch_nums

+ +
def get_ch_nums(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet the number of channels supported by the camera.
returnReturns the maximum number of channels.
staticFalse
+

C++ defination code:

+ +
int get_ch_nums()
+
+

open

+ +
def open(self, width: int = -1, height: int = -1, format: maix.image.Format = ..., fps: int = -1, buff_num: int = -1) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefOpen camera and run
paramwidth: camera width, default is -1, means auto, mostly means max width of camera support
height: camera height, default is -1, means auto, mostly means max height of camera support
format: camera output format, default same as the constructor's format argument
fps: camera fps, default is -1, means auto, mostly means max fps of camera support
buff_num: camera buffer number, default is 3, means 3 buffer, one used by user, one used for cache the next frame,
more than one buffer will accelerate image read speed, but will cost more memory.
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+

C++ defination code:

+ +
err::Err open(int width = -1, int height = -1, image::Format format = image::FMT_INVALID, int fps = -1, int buff_num = -1)
+
+

read

+ +
def read(self, buff: capsule = None, buff_size: int = 0, block: bool = True) -> maix.image.Image
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet one frame image from camera buffer, must call open method before read.\nIf open method not called, will call it automatically, if open failed, will throw exception!\nSo call open method before read is recommended.
parambuff: buffer to store image data, if buff is nullptr, will alloc memory automatically.
In MaixPy, default to None, you can create a image.Image object, then pass img.data() to buff.
block: block read, default is true, means block util read image successfully,
if set to false, will return nullptr if no image in buffer
returnimage::Image object, if failed, return nullptr, you should delete if manually in C++
staticFalse
+

C++ defination code:

+ +
image::Image *read(void *buff = nullptr, size_t buff_size = 0, bool block = true)
+
+

clear_buff

+ +
def clear_buff(self) -> None
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefClear buff to ensure the next read image is the latest image
staticFalse
+

C++ defination code:

+ +
void clear_buff()
+
+

skip_frames

+ +
def skip_frames(self, num: int) -> None
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefRead some frames and drop, this is usually used avoid read not stable image when camera just opened.
paramnum: number of frames to read and drop
staticFalse
+

C++ defination code:

+ +
void skip_frames(int num)
+
+

close

+ +
def close(self) -> None
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefClose camera
staticFalse
+

C++ defination code:

+ +
void close()
+
+

add_channel

+ +
def add_channel(self, width: int = -1, height: int = -1, format: maix.image.Format = ..., fps: int = -1, buff_num: int = 3, open: bool = True) -> Camera
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefAdd a new channel and return a new Camera object, you can use close() to close this channel.
paramwidth: camera width, default is -1, means auto, mostly means max width of camera support
height: camera height, default is -1, means auto, mostly means max height of camera support
format: camera output format, default is RGB888
fps: camera fps, default is -1, means auto, mostly means max fps of camera support
buff_num: camera buffer number, default is 3, means 3 buffer, one used by user, one used for cache the next frame,
more than one buffer will accelerate image read speed, but will cost more memory.
open: If true, camera will automatically call open() after creation. default is true.
returnnew Camera object
staticFalse
+

C++ defination code:

+ +
camera::Camera *add_channel(int width = -1, int height = -1, image::Format format = image::FMT_RGB888, int fps = -1, int buff_num = 3, bool open = true)
+
+

is_opened

+ +
def is_opened(self) -> bool
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefCheck if camera is opened
returntrue if camera is opened, false if not
staticFalse
+

C++ defination code:

+ +
bool is_opened()
+
+

is_closed

+ +
def is_closed(self) -> bool
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefcheck camera device is closed or not
returnclosed or not, bool type
staticFalse
+

C++ defination code:

+ +
bool is_closed()
+
+

width

+ +
def width(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet camera width
returncamera width
staticFalse
+

C++ defination code:

+ +
int width()
+
+

height

+ +
def height(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet camera height
returncamera height
staticFalse
+

C++ defination code:

+ +
int height()
+
+

fps

+ +
def fps(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet camera fps
returncamera fps
staticFalse
+

C++ defination code:

+ +
int fps()
+
+

format

+ +
def format(self) -> maix.image.Format
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet camera output format
returncamera output format, image::Format object
staticFalse
+

C++ defination code:

+ +
image::Format format()
+
+

buff_num

+ +
def buff_num(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet camera buffer number
returncamera buffer number
staticFalse
+

C++ defination code:

+ +
int buff_num()
+
+

hmirror

+ +
def hmirror(self, value: int = -1) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSet/Get camera horizontal mirror
returncamera horizontal mirror
staticFalse
+

C++ defination code:

+ +
int hmirror(int value = -1)
+
+

vflip

+ +
def vflip(self, value: int = -1) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSet/Get camera vertical flip
returncamera vertical flip
staticFalse
+

C++ defination code:

+ +
int vflip(int value = -1)
+
+

device

+ +
def device(self) -> str
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet camera device path
returncamera device path
staticFalse
+

C++ defination code:

+ +
std::string device()
+
+

write_reg

+ +
def write_reg(self, addr: int, data: int, bit_width: int = 8) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefWrite camera register
paramaddr: register address
data: register data
bit_width: register data bit width, default is 8
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+

C++ defination code:

+ +
err::Err write_reg(int addr, int data, int bit_width = 8)
+
+

read_reg

+ +
def read_reg(self, addr: int, bit_width: int = 8) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefRead camera register
paramaddr: register address
bit_width: register data bit width, default is 8
returnregister data, -1 means failed
staticFalse
+

C++ defination code:

+ +
int read_reg(int addr, int bit_width = 8)
+
+

show_colorbar

+ +
def show_colorbar(self, enable: bool) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefCamera output color bar image for test
paramenable: enable/disable color bar
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+

C++ defination code:

+ +
err::Err show_colorbar(bool enable)
+
+

get_channel

+ +
def get_channel(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet channel of camera
returnchannel number
staticFalse
+

C++ defination code:

+ +
int get_channel()
+
+

set_resolution

+ +
def set_resolution(self, width: int, height: int) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSet camera resolution
paramwidth: new width
height: new height
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+

C++ defination code:

+ +
err::Err set_resolution(int width, int height)
+
+

exposure

+ +
def exposure(self, value: int = -1) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSet/Get camera exposure
attentionThis method will affect the isp and thus the image, so please be careful with it.
paramvalue: exposure time. unit: us
If value == -1, return exposure time.
If value != 0, set and return exposure time.
returncamera exposure time
staticFalse
+

C++ defination code:

+ +
uint64_t exposure(uint64_t value = -1)
+
+

gain

+ +
def gain(self, value: int = -1) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSet/Get camera gain
attentionThis method will affect the isp and thus the image, so please be careful with it.
paramvalue: camera gain.
If value == -1, returns camera gain.
If value != 0, set and return camera gain.
returncamera gain
staticFalse
+

C++ defination code:

+ +
uint32_t gain(uint32_t value = -1)
+
+

luma

+ +
def luma(self, value: int = -1) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSet/Get camera luma
attentionThis method will affect the isp and thus the image, so please be careful with it.
paramvalue: luma value, range is [0, 100]
If value == -1, returns luma value.
If value != 0, set and return luma value.
returnreturns luma value
staticFalse
+

C++ defination code:

+ +
uint32_t luma(uint32_t value = -1)
+
+

constrast

+ +
def constrast(self, value: int = -1) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSet/Get camera constrast
attentionThis method will affect the isp and thus the image, so please be careful with it.
paramvalue: constrast value, range is [0, 100]
If value == -1, returns constrast value.
If value != 0, set and return constrast value.
returnreturns constrast value
staticFalse
+

C++ defination code:

+ +
uint32_t constrast(uint32_t value = -1)
+
+

saturation

+ +
def saturation(self, value: int = -1) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSet/Get camera saturation
attentionThis method will affect the isp and thus the image, so please be careful with it.
paramvalue: saturation value, range is [0, 100]
If value == -1, returns saturation value.
If value != 0, set and return saturation value.
returnreturns saturation value
staticFalse
+

C++ defination code:

+ +
uint32_t saturation(uint32_t value = -1)
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/maix/comm.html b/maixpy/api/maix/comm.html new file mode 100644 index 00000000..286bb48e --- /dev/null +++ b/maixpy/api/maix/comm.html @@ -0,0 +1,489 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix.comm - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix.comm

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.comm module

+
+

You can use maix.comm to access this module with MaixPy
+This module is generated from MaixCDK

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

Class

+

CommProtocol

+ + + + + + + + + + + + + +
itemdoc
briefClass for communication protocol
+

C++ defination code:

+ +
class CommProtocol
+
+

__init__

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefConstruct a new CommProtocol object
parambuff_size: buffer size, default to 1024 bytes
staticFalse
+

C++ defination code:

+ +
CommProtocol(int buff_size = 1024)
+
+

get_msg

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefRead data to buffer, and try to decode it as maix.protocol.MSG object
returndecoded data, if nullptr, means no valid frame found.
Attentioin, delete it after use in C++.
staticFalse
+

C++ defination code:

+ +
protocol::MSG *get_msg()
+
+

resp_ok

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSend response ok(success) message
paramcmd: CMD value
body: response body, can be null
returnencoded data, if nullptr, means error, and the error code is -err.Err.
Attentioin, delete it after use in C++.
staticFalse
+

C++ defination code:

+ +
err::Err resp_ok(uint8_t cmd, Bytes *body = nullptr)
+
+

report

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSend report message
paramcmd: CMD value
body: report body, can be null
returnencoded data, if nullptr, means error, and the error code is -err.Err.
Attentioin, delete it after use in C++.
staticFalse
+

C++ defination code:

+ +
err::Err report(uint8_t cmd, Bytes *body = nullptr)
+
+

resp_err

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefEncode response error message to buffer
paramcmd: CMD value
code: error code
msg: error message
returnencoded data, if nullptr, means error, and the error code is -err.Err.
Attentioin, delete it after use in C++.
staticFalse
+

C++ defination code:

+ +
err::Err resp_err(uint8_t cmd, err::Err code, const std::string &msg)
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/maix/display.html b/maixpy/api/maix/display.html new file mode 100644 index 00000000..e88758b0 --- /dev/null +++ b/maixpy/api/maix/display.html @@ -0,0 +1,909 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix.display - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix.display

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.display module, control display device and show image on it

+
+

You can use maix.display to access this module with MaixPy
+This module is generated from MaixCDK

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

send_to_maixvision

+ + + + + + + + + + + + + + + + + +
itemdoc
briefSend image to MaixVision work station if connected.\nIf you want to debug your program an don't want to initialize display, use this method.
paramimg: image to send, image.Image object
+

C++ defination code:

+ +
void send_to_maixvision(image::Image &img)
+
+

Class

+

Display

+ + + + + + + + + + + + + +
itemdoc
briefDisplay class
+

C++ defination code:

+ +
class Display
+
+

__init__

+ +
def __init__(self, width: int = -1, height: int = -1, format: maix.image.Format = ..., device: str = None, open: bool = True) -> None
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefConstruct a new Display object
paramwidth: display width, by default(value is -1) means auto detect,
if width > max device supported width, will auto set to max device supported width
height: display height, by default(value is -1) means auto detect,
if height > max device supported height, will auto set to max device supported height
device: display device name, you can get devices by list_devices method, by default(value is NULL(None in MaixPy)) means the first device
open: If true, display will automatically call open() after creation. default is true.
staticFalse
+

C++ defination code:

+ +
Display(int width = -1, int height = -1, image::Format format = image::FMT_RGB888, const char *device = nullptr, bool open = true)
+
+

width

+ +
def width(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet display width
returnwidth
staticFalse
+

C++ defination code:

+ +
int width()
+
+

height

+ +
def height(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet display height
paramch: channel to get, by default(value is 0) means the first channel
returnheight
staticFalse
+

C++ defination code:

+ +
int height()
+
+

size

+ +
def size(self) -> list[int]
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet display size
paramch: channel to get, by default(value is 0) means the first channel
returnsize A list type in MaixPy, [width, height]
staticFalse
+

C++ defination code:

+ +
std::vector<int> size()
+
+

format

+ +
def format(self) -> maix.image.Format
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet display format
returnformat
staticFalse
+

C++ defination code:

+ +
image::Format format()
+
+

open

+ +
def open(self, width: int = -1, height: int = -1, format: maix.image.Format = ...) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefopen display device, if already opened, will return err.ERR_NONE.
paramwidth: display width, default is -1, means auto, mostly means max width of display support
height: display height, default is -1, means auto, mostly means max height of display support
format: display output format, default is RGB888
returnerror code
staticFalse
+

C++ defination code:

+ +
err::Err open(int width = -1, int height = -1, image::Format format = image::FMT_INVALID)
+
+

close

+ +
def close(self) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefclose display device
returnerror code
staticFalse
+

C++ defination code:

+ +
err::Err close()
+
+

add_channel

+ +
def add_channel(self, width: int = -1, height: int = -1, format: maix.image.Format = ..., open: bool = True) -> Display
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefAdd a new channel and return a new Display object, you can use close() to close this channel.
paramwidth: display width, default is -1, means auto, mostly means max width of display support
height: display height, default is -1, means auto, mostly means max height of display support
format: display output format, default is RGB888
open: If true, display will automatically call open() after creation. default is true.
returnnew Display object
staticFalse
+

C++ defination code:

+ +
display::Display *add_channel(int width = -1, int height = -1, image::Format format = image::FMT_RGB888, bool open = true)
+
+

is_opened

+ +
def is_opened(self) -> bool
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefcheck display device is opened or not
returnopened or not, bool type
staticFalse
+

C++ defination code:

+ +
bool is_opened()
+
+

is_closed

+ +
def is_closed(self) -> bool
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefcheck display device is closed or not
returnclosed or not, bool type
staticFalse
+

C++ defination code:

+ +
bool is_closed()
+
+

show

+ +
def show(self, img: maix.image.Image, fit: maix.image.Fit = ...) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefshow image on display device, and will also send to MaixVision work station if connected.
paramimg: image to show, image.Image object,
if the size of image smaller than display size, will show in the center of display;
if the size of image bigger than display size, will auto resize to display size and keep ratio, fill blank with black color.
fit: image in screen fit mode, by default(value is image.FIT_CONTAIN), @see image.Fit for more details
e.g. image.FIT_CONTAIN means resize image to fit display size and keep ratio, fill blank with black color.
returnerror code
staticFalse
+

C++ defination code:

+ +
err::Err show(image::Image &img, image::Fit fit = image::FIT_CONTAIN)
+
+

device

+ +
def device(self) -> str
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet display device path
returndisplay device path
staticFalse
+

C++ defination code:

+ +
std::string device()
+
+

set_backlight

+ +
def set_backlight(self, value: float) -> None
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSet display backlight
paramvalue: backlight value, float type, range is [0, 100]
staticFalse
+

C++ defination code:

+ +
void set_backlight(float value)
+
+

get_backlight

+ +
def get_backlight(self) -> float
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet display backlight
returnvalue backlight value, float type, range is [0, 100]
staticFalse
+

C++ defination code:

+ +
float get_backlight()
+
+

set_hmirror

+ +
def set_hmirror(self, en: bool) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSet display mirror
paramen: enable/disable mirror
staticFalse
+

C++ defination code:

+ +
err::Err set_hmirror(bool en)
+
+

set_vflip

+ +
def set_vflip(self, en: bool) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSet display flip
paramen: enable/disable flip
staticFalse
+

C++ defination code:

+ +
err::Err set_vflip(bool en)
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/maix/err.html b/maixpy/api/maix/err.html new file mode 100644 index 00000000..4eeb42f9 --- /dev/null +++ b/maixpy/api/maix/err.html @@ -0,0 +1,530 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix.err - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix.err

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.err module

+
+

You can use maix.err to access this module with MaixPy
+This module is generated from MaixCDK

+
+

Module

+

No module

+

Enum

+

Err

+ + + + + + + + + + + + + + + + + +
itemdoc
briefMaix Error code
valuesERR_NONE: No error
ERR_ARGS: Invalid arguments
ERR_NO_MEM: No memory
ERR_NOT_IMPL: Not implemented
ERR_NOT_READY: Not ready
ERR_NOT_INIT: Not initialized
ERR_NOT_OPEN: Not opened
ERR_NOT_PERMIT: Not permitted
ERR_REOPEN: Re-open
ERR_BUSY: Busy
ERR_READ: Read error
ERR_WRITE: Write error
ERR_TIMEOUT: Timeout
ERR_RUNTIME: Runtime error
ERR_IO: IO error
ERR_NOT_FOUND: Not found
ERR_ALREAY_EXIST: Already exist
ERR_BUFF_FULL: Buffer full
ERR_BUFF_EMPTY: Buffer empty
ERR_CANCEL: Cancel
ERR_OVERFLOW: Overflow
ERR_MAX:
+

C++ defination code:

+ +
enum Err
+    {
+        // !!! fixed error code, DO NOT change number already defined, only append new error code
+        ERR_NONE        = 0,   // No error
+        ERR_ARGS           ,   // Invalid arguments
+        ERR_NO_MEM         ,   // No memory
+        ERR_NOT_IMPL       ,   // Not implemented
+        ERR_NOT_READY      ,   // Not ready
+        ERR_NOT_INIT       ,   // Not initialized
+        ERR_NOT_OPEN       ,   // Not opened
+        ERR_NOT_PERMIT     ,   // Not permitted
+        ERR_REOPEN         ,   // Re-open
+        ERR_BUSY           ,   // Busy
+        ERR_READ           ,   // Read error
+        ERR_WRITE          ,   // Write error
+        ERR_TIMEOUT        ,   // Timeout
+        ERR_RUNTIME        ,   // Runtime error
+        ERR_IO             ,   // IO error
+        ERR_NOT_FOUND      ,   // Not found
+        ERR_ALREAY_EXIST   ,   // Already exist
+        ERR_BUFF_FULL      ,   // Buffer full
+        ERR_BUFF_EMPTY     ,   // Buffer empty
+        ERR_CANCEL         ,   // Cancel
+        ERR_OVERFLOW       ,   // Overflow
+        ERR_MAX,
+    }
+
+

Variable

+

Function

+

to_str

+ +
def to_str(e: Err) -> str
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefError code to string
parame: direction [in], error code, err::Err type
returnerror string
+

C++ defination code:

+ +
std::string to_str(err::Err e)
+
+

get_error

+ +
def get_error() -> str
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefget last error string
returnerror string
+

C++ defination code:

+ +
std::string& get_error()
+
+

set_error

+ +
def set_error(str: str) -> None
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefset last error string
paramstr: direction [in], error string
+

C++ defination code:

+ +
void set_error(const std::string &str)
+
+

check_raise

+ +
def check_raise(e: Err, msg: str = '') -> None
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefCheck error code, if not ERR_NONE, raise err.Exception
parame: direction [in], error code, err::Err type
msg: direction [in], error message
+

C++ defination code:

+ +
void check_raise(err::Err e, const std::string &msg = "")
+
+

check_bool_raise

+ +
def check_bool_raise(ok: bool, msg: str = '') -> None
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefCheck condition, if false, raise err.Exception
paramok: direction [in], condition, if true, do nothing, if false, raise err.Exception
msg: direction [in], error message
+

C++ defination code:

+ +
void check_bool_raise(bool ok, const std::string &msg = "")
+
+

check_null_raise

+ +
def check_null_raise(ptr: capsule, msg: str = '') -> None
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefCheck NULL pointer, if NULL, raise exception
paramptr: direction [in], pointer
msg: direction [in], error message
+

C++ defination code:

+ +
void check_null_raise(void *ptr, const std::string &msg = "")
+
+

Class

+

Exception

+ + + + + + + + + + + + + +
itemdoc
briefMaix Exception
+

C++ defination code:

+ +
class Exception : public std::exception
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/maix/example.html b/maixpy/api/maix/example.html new file mode 100644 index 00000000..89d4c208 --- /dev/null +++ b/maixpy/api/maix/example.html @@ -0,0 +1,1227 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix.example - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix.example

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

example module, this will be maix.example module in MaixPy, maix::example namespace in MaixCDK

+
+

You can use maix.example to access this module with MaixPy
+This module is generated from MaixCDK

+
+

Module

+

No module

+

Enum

+

Kind

+ + + + + + + + + + + + + + + + + +
itemdoc
briefExample enum
valuesKIND_NONE: Kind none, value always 0, other enum value will auto increase
KIND_DOG: Kind dog
KIND_CAT: Kind cat, value is auto generated according to KING_DOG
KIND_BIRD:
KIND_MAX: Max Kind quantity
You can get max Kind value by KIND_MAX - 1
+

C++ defination code:

+ +
enum Kind
+        {
+            KIND_NONE = 0, /** Kind none, value always 0, other enum value will auto increase */
+            KIND_DOG,      /** Kind dog*/
+            KIND_CAT,      // Kind cat, value is auto generated according to KING_DOG
+            KIND_BIRD,
+            KIND_MAX /* Max Kind quantity,
+                        You can get max Kind value by KIND_MAX - 1
+                     */
+        }
+
+

Variable

+

var1

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefExample module variable
attentionIt's a copy of this variable in MaixPy,
so change it in C++ (e.g. update var in hello function) will not take effect the var inMaixPy.
So we add const for this var to avoid this mistake.
value"Sipeed"
readonlyTrue
+

C++ defination code:

+ +
const std::string var1 = "Sipeed"
+
+

list_var

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefTensor data type size in bytes
attention1. DO NOT use C/C++ array directly for python API, the python wrapper not support it.
Use std::vector instead.
2. It's a copy of this variable in MaixPy,
so change it in C++ (e.g. update var in hello function) will not take effect the var inMaixPy.
So we add const for this var to avoid this mistake.
value{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
readonlyTrue
+

C++ defination code:

+ +
const std::vector<int> list_var = {
+            0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
+
+

test_var

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefExample module variable test_var
attentionIt's a copy of this variable in MaixPy, so if you change it in C++, it will not take effect in MaixPy.
And change it in MaixPy will not take effect in C++ as well !!!
If you want to use vars shared between C++ and MaixPy, you can create a class and use its member.
value100
readonlyFalse
+

C++ defination code:

+ +
int test_var = 100
+
+

Function

+

hello

+ +
def hello(name: str) -> str
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefsay hello to someone
paramname: direction [in], name of someone, string type
returnstring type, content is hello + name
+

C++ defination code:

+ +
std::string hello(std::string name)
+
+

change_arg_name

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefChange arg name example
parame: Example object
returnsame as arg
+

C++ defination code:

+ +
example::Example *change_arg_name(example::Example *e)
+
+

change_arg_name2

+ +
def change_arg_name2(e: Example) -> None
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefChange arg name example
parame: Example object
+

C++ defination code:

+ +
void change_arg_name2(example::Example &e)
+
+

Class

+

Test

+ + + + + + + + + + + + + +
itemdoc
briefTest class
+

C++ defination code:

+ +
class Test
+
+

__init__

+ +
def __init__(self) -> None
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefTest constructor
staticFalse
+

C++ defination code:

+ +
Test()
+
+

Example

+ + + + + + + + + + + + + +
itemdoc
briefExample class\nthis class will be export to MaixPy as maix.example.Example
+

C++ defination code:

+ +
class Example
+
+

__init__

+ +
def __init__(self, name: str, age: int = 18, pet: Kind = ...) -> None
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefExample constructor\nthis constructor will be export to MaixPy as maix.example.Example.init
paramname: direction [in], name of Example, string type
age: direction [in], age of Example, int type, default is 18, value range is [0, 100]
attentionto make auto generate code work, param Kind should with full namespace name example::Kind instead of Kind,
namespace maix can be ignored.
staticFalse
+

C++ defination code:

+ +
Example(std::string &name, int age = 18, example::Kind pet = example::KIND_NONE)
+
+

get_name

+ +
def get_name(self) -> str
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget name of Example\nyou can also get name by property name.
returnname of Example, string type
staticFalse
+

C++ defination code:

+ +
std::string get_name()
+
+

get_age

+ +
def get_age(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget age of Example
returnage of Example, int type, value range is [0, 100]
staticFalse
+

C++ defination code:

+ +
int get_age()
+
+

set_name

+ +
def set_name(self, name: str) -> None
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefset name of Example
paramname: name of Example, string type
staticFalse
+

C++ defination code:

+ +
void set_name(std::string name)
+
+

set_age

+ +
def set_age(self, age: int) -> None
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefset age of Example
paramage: age of Example, int type, value range is [0, 100]
staticFalse
+

C++ defination code:

+ +
void set_age(int age)
+
+

set_pet

+ +
def set_pet(self, pet: Kind) -> None
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefExample enum member
attention
staticFalse
+

C++ defination code:

+ +
void set_pet(example::Kind pet)
+
+

get_pet

+ +
def get_pet(self) -> Kind
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefExample enum member
staticFalse
+

C++ defination code:

+ +
example::Kind get_pet()
+
+

get_list

+ +
def get_list(self, in: list[int]) -> list[int]
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget list example
paramin: direction [in], input list, items are int type.
In MaixPy, you can pass list or tuple to this API
returnlist, items are int type, content is [1, 2, 3] + in. Alloc item, del in MaixPy will auto free memory.
staticFalse
+

C++ defination code:

+ +
std::vector<int> *get_list(std::vector<int> in)
+
+

get_dict

+ +
def get_dict(self, in: dict[str, int]) -> dict[str, int]
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefExample dict API
paramin: direction [in], input dict, key is string type, value is int type.
In MaixPy, you can pass dict to this API
returndict, key is string type, value is int type, content is {"a": 1} + in
In MaixPy, return type is dict object
staticFalse
+

C++ defination code:

+ +
std::map<std::string, int> get_dict(std::map<std::string, int> &in)
+
+

hello

+ +
def hello(name: str) -> str
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefsay hello to someone
paramname: name of someone, string type
returnstring type, content is Example::hello_str + name
staticTrue
+

C++ defination code:

+ +
static std::string hello(std::string name)
+
+

hello_bytes

+ +
def hello_bytes(*args, **kwargs)
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefparam is bytes example
parambytes: bytes type param
returnbytes type, return value is bytes changed value
staticTrue
+

C++ defination code:

+ +
static Bytes *hello_bytes(Bytes &bytes)
+
+

callback

+ +
def callback(cb: typing.Callable[[int, int], int]) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefCallback example
paramcb: callback function, param is two int type, return is int type
returnint type, return value is cb(1, 2)
staticTrue
+

C++ defination code:

+ +
static int callback(std::function<int(int, int)> cb)
+
+

hello_dict

+ +
def hello_dict(dict: dict[str, int]) -> dict[str, int]
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefDict param example
paramdict: dict type param, key is string type, value is int type
staticTrue
+

C++ defination code:

+ +
static std::map<std::string, int> *hello_dict(std::map<std::string, int> *dict)
+
+

name

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefname member of Example
staticFalse
readonlyFalse
+

C++ defination code:

+ +
std::string name
+
+

age

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefage member of Example, value range should be [0, 100]
staticFalse
readonlyFalse
+

C++ defination code:

+ +
int age
+
+

hello_str

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefhello_str member of Example, default value is "hello "
staticTrue
readonlyFalse
+

C++ defination code:

+ +
static std::string hello_str
+
+

var1

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefExample module readonly variable
staticFalse
readonlyTrue
+

C++ defination code:

+ +
const std::string var1 = "Example.var1"
+
+

var2

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefExample module readonly variable
staticFalse
readonlyTrue
+

C++ defination code:

+ +
std::string var2 = "Example.var2"
+
+

dict_test

+ +
def dict_test() -> dict[str, Test]
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefdict_test, return dict type, and element is pointer type(alloc in C++).\nHere when the returned Tensor object will auto delete by Python GC.
staticTrue
+

C++ defination code:

+ +
static std::map<std::string, example::Test *> *dict_test()
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/maix/fs.html b/maixpy/api/maix/fs.html new file mode 100644 index 00000000..2902cad5 --- /dev/null +++ b/maixpy/api/maix/fs.html @@ -0,0 +1,1274 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix.fs - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix.fs

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.fs module

+
+

You can use maix.fs to access this module with MaixPy
+This module is generated from MaixCDK

+
+

Module

+

No module

+

Enum

+

SEEK

+ + + + + + + + + + + + + + + + + +
itemdoc
briefSEEK enums
valuesSEEK_SET: Seek from beginning of file.
SEEK_CUR: Seek from current position.
SEEK_END: Seek from end of file.
+

C++ defination code:

+ +
enum SEEK
+    {
+        SEEK_SET = 0,  // Seek from beginning of file.
+        SEEK_CUR = 1,  // Seek from current position.
+        SEEK_END = 2,  // Seek from end of file.
+    }
+
+

Variable

+

Function

+

isabs

+ +
def isabs(path: str) -> bool
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefCheck if the path is absolute path
parampath: path to check
returntrue if path is absolute path
+

C++ defination code:

+ +
bool isabs(const std::string &path)
+
+

isdir

+ +
def isdir(path: str) -> bool
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefCheck if the path is a directory, if not exist, throw exception
parampath: path to check
returntrue if path is a directory
+

C++ defination code:

+ +
bool isdir(const std::string &path)
+
+

isfile

+ +
def isfile(path: str) -> bool
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefCheck if the path is a file, if not exist, throw exception
parampath: path to check
returntrue if path is a file
+

C++ defination code:

+ +
bool isfile(const std::string &path)
+
+ + +
def islink(path: str) -> bool
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefCheck if the path is a link, if not exist, throw exception
parampath: path to check
returntrue if path is a link
+

C++ defination code:

+ +
bool islink(const std::string &path)
+
+ + +
def symlink(src: str, link: str, force: bool = False) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefCreate soft link
paramsrc: real file path
link: link file path
force: force link, if already have link file, will delet it first then create.
+

C++ defination code:

+ +
err::Err symlink(const std::string &src, const std::string &link, bool force = false)
+
+

exists

+ +
def exists(path: str) -> bool
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefCheck if the path exists
parampath: path to check
returntrue if path exists
+

C++ defination code:

+ +
bool exists(const std::string &path)
+
+

mkdir

+ +
def mkdir(path: str, exist_ok: bool = True, recursive: bool = True) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefCreate a directory recursively
parampath: path to create
exist_ok: if true, also return true if directory already exists
recursive: if true, create directory recursively, otherwise, only create one directory, default is true
returnerr::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed
+

C++ defination code:

+ +
err::Err mkdir(const std::string &path, bool exist_ok = true, bool recursive = true)
+
+

rmdir

+ +
def rmdir(path: str, recursive: bool = False) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefRemove a directory
parampath: path to remove
recursive: if true, remove directory recursively, otherwise, only remove empty directory, default is false
returnerr::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed
+

C++ defination code:

+ +
err::Err rmdir(const std::string &path, bool recursive = false)
+
+

remove

+ +
def remove(path: str) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefRemove a file
parampath: path to remove
returnerr::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed
+

C++ defination code:

+ +
err::Err remove(const std::string &path)
+
+

rename

+ +
def rename(src: str, dst: str) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefRename a file or directory
paramsrc: source path
dst: destination path, if destination dirs not exist, will auto create
returnerr::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed
+

C++ defination code:

+ +
err::Err rename(const std::string &src, const std::string &dst)
+
+

sync

+ +
def sync() -> None
+
+ + + + + + + + + + + + + +
itemdoc
briefSync files, ensure they're wrriten to disk from RAM
+

C++ defination code:

+ +
void sync()
+
+

getsize

+ +
def getsize(path: str) -> int
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefGet file size
parampath: path to get size
returnfile size if success, -err::Err code if failed
+

C++ defination code:

+ +
int getsize(const std::string &path)
+
+

dirname

+ +
def dirname(path: str) -> str
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefGet directory name of path
parampath: path to get dirname
returndirname if success, empty string if failed
+

C++ defination code:

+ +
std::string dirname(const std::string &path)
+
+

basename

+ +
def basename(path: str) -> str
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefGet base name of path
parampath: path to get basename
returnbasename if success, empty string if failed
+

C++ defination code:

+ +
std::string basename(const std::string &path)
+
+

abspath

+ +
def abspath(path: str) -> str
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefGet absolute path
parampath: path to get absolute path
returnabsolute path if success, empty string if failed
+

C++ defination code:

+ +
std::string abspath(const std::string &path)
+
+

getcwd

+ +
def getcwd() -> str
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet current working directory
returncurrent working directory absolute path
+

C++ defination code:

+ +
std::string getcwd()
+
+

realpath

+ +
def realpath(path: str) -> str
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefGet realpath of path
parampath: path to get realpath
returnrealpath if success, empty string if failed
+

C++ defination code:

+ +
std::string realpath(const std::string &path)
+
+

splitext

+ +
def splitext(path: str) -> str
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefGet file extension
parampath: path to get extension
returnextension if success, empty string if failed
+

C++ defination code:

+ +
std::string splitext(const std::string &path)
+
+

listdir

+ +
def listdir(path: str, recursive: bool = False, full_path: bool = False) -> list[str]
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefList files in directory
parampath: path to list
recursive: if true, list recursively, otherwise, only list current directory, default is false
full_path: if true, return full path, otherwise, only return basename, default is false
returnfiles list if success, nullptr if failed, you should manually delete it in C++.
+

C++ defination code:

+ +
std::vector<std::string> *listdir(const std::string &path, bool recursive = false, bool full_path = false)
+
+

open

+ +
def open(self, path: str, mode: str) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefOpen a file, and return a File object
parampath: path to open
mode: open mode, support "r", "w", "a", "r+", "w+", "a+", "rb", "wb", "ab", "rb+", "wb+", "ab+"
returnFile object if success(need to delete object manually in C/C++), nullptr if failed
+

C++ defination code:

+ +
fs::File *open(const std::string &path, const std::string &mode)
+
+

tempdir

+ +
def tempdir() -> str
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet temp files directory
returntemp files directory
+

C++ defination code:

+ +
std::string tempdir()
+
+

Class

+

File

+ + + + + + + + + + + + + +
itemdoc
briefFile read write ops
+

C++ defination code:

+ +
class File
+
+

__init__

+ +
def __init__(self) -> None
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefConstruct File object
staticFalse
+

C++ defination code:

+ +
File()
+
+

open

+ +
def open(self, path: str, mode: str) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefOpen a file
parampath: path to open
mode: open mode, support "r", "w", "a", "r+", "w+", "a+", "rb", "wb", "ab", "rb+", "wb+", "ab+"
returnerr::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed
staticFalse
+

C++ defination code:

+ +
err::Err open(const std::string &path, const std::string &mode)
+
+

close

+ +
def close(self) -> None
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefClose a file
staticFalse
+

C++ defination code:

+ +
void close()
+
+

read

+ +
def read(self, size: int) -> list[int]
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefRead data from file API2
paramsize: max read size
returnbytes data if success(need delete manually in C/C++), nullptr if failed
staticFalse
+

C++ defination code:

+ +
std::vector<uint8_t> *read(int size)
+
+

readline

+ +
def readline(self) -> str
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefRead line from file
returnline if success, empty string if failed. You need to delete the returned object manually in C/C++.
staticFalse
+

C++ defination code:

+ +
std::string *readline()
+
+

write

+ +
def write(self, buf: list[int]) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefWrite data to file API2
parambuf: buffer to write
returnwrite size if success, -err::Err code if failed
staticFalse
+

C++ defination code:

+ +
int write(const std::vector<uint8_t> &buf)
+
+

seek

+ +
def seek(self, offset: int, whence: int) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSeek file position
paramoffset: offset to seek
whence: @see maix.fs.SEEK
returnnew position if success, -err::Err code if failed
staticFalse
+

C++ defination code:

+ +
int seek(int offset, int whence)
+
+

tell

+ +
def tell(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet file position
returnfile position if success, -err::Err code if failed
staticFalse
+

C++ defination code:

+ +
int tell()
+
+

flush

+ +
def flush(self) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefFlush file
returnerr::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed
staticFalse
+

C++ defination code:

+ +
err::Err flush()
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/maix/i18n.html b/maixpy/api/maix/i18n.html new file mode 100644 index 00000000..8cf8be12 --- /dev/null +++ b/maixpy/api/maix/i18n.html @@ -0,0 +1,575 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix.i18n - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix.i18n

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.i18n module

+
+

You can use maix.i18n to access this module with MaixPy
+This module is generated from MaixCDK

+
+

Module

+

No module

+

Enum

+

Variable

+

locales

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefi18n locales list
value{
"en",
"zh",
"zh-tw",
"ja"
}
readonlyFalse
+

C++ defination code:

+ +
static std::vector<std::string> locales = {
+        "en",
+        "zh",
+        "zh-tw",
+        "ja"
+    }
+
+

names

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefi18n language names list
value{
"English",
"简体中文",
"繁體中文",
"日本語"
}
readonlyTrue
+

C++ defination code:

+ +
const static std::vector<std::string> names = {
+        "English",
+        "简体中文",
+        "繁體中文",
+        "日本語"
+    }
+
+

Function

+

get_locale

+ +
def get_locale(self) -> str
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet system config of locale.
returnlanguage locale, e.g. en, zh, zh_CN, zh_TW, etc.
+

C++ defination code:

+ +
string get_locale()
+
+

get_language_name

+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet system config of language name.
returnlanguage name, e.g. English, 简体中文, 繁體中文, etc.
+

C++ defination code:

+ +
string get_language_name()
+
+

Class

+

Trans

+ + + + + + + + + + + + + +
itemdoc
briefTranslate helper class.
+

C++ defination code:

+ +
class Trans
+
+

__init__

+ +
def __init__(self, locales_dict: dict[str, dict[str, str]]) -> None
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefTranslate helper class constructor.\nBy default locale is get by i18n.get_locale() function which set by system settings.\nBut you can also manually set by set_locale function temporarily.
paramlocales_dict: locales dict, e.g. {"zh": {"Confirm": "确认", "OK": "好的"}, "en": {"Confirm": "Confirm", "OK": "OK"}}
staticFalse
+

C++ defination code:

+ +
Trans(const std::map<string, const std::map<string, string>> &locales_dict)
+
+

tr

+ +
def tr(self, key: str, locale: str = '') -> str
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefTranslate string by key.
paramkey: string key, e.g. "Confirm"
locale: locale name, if not assign, use default locale set by system settings or set_locale function.
returntranslated string, if find translation, return it, or return key, e.g. "确认", "Confirm", etc.
staticFalse
+

C++ defination code:

+ +
string tr(const string &key, const string locale = "")
+
+

set_locale

+ +
def set_locale(self, locale: str) -> None
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSet locale temporarily, will not affect system settings.
paramlocale: locale name, e.g. "zh", "en", etc. @see maix.i18n.locales
staticFalse
+

C++ defination code:

+ +
void set_locale(const string &locale)
+
+

get_locale

+ +
def get_locale(self) -> str
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet current locale.
returnlocale name, e.g. "zh", "en", etc. @see maix.i18n.locales
staticFalse
+

C++ defination code:

+ +
string get_locale()
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/maix/image.html b/maixpy/api/maix/image.html new file mode 100644 index 00000000..61944439 --- /dev/null +++ b/maixpy/api/maix/image.html @@ -0,0 +1,10979 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix.image - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix.image

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.image module, image related definition and functions

+
+

You can use maix.image to access this module with MaixPy
+This module is generated from MaixCDK

+
+

Module

+

No module

+

Enum

+

Format

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefImage formats
attentionfor developers, update this enum will also need to update the fmt_size in maix_image.cpp
valuesFMT_RGB888: RGBRGB...RGB, R at the lowest address
FMT_BGR888: BGRBGR...BGR, B at the lowest address
FMT_RGBA8888: RGBARGBA...RGBA, R at the lowest address
FMT_BGRA8888: BGRABGRA...BGRA, B at the lowest address
FMT_RGB565:
FMT_BGR565:
FMT_YUV422SP: YYY...UVUVUV...UVUV
FMT_YUV422P: YYY...UUU...VVV
FMT_YVU420SP: YYY...VUVUVU...VUVU, NV21
FMT_YUV420SP: YYY...UVUVUV...UVUV, NV12
FMT_YVU420P: YYY...VVV...UUU
FMT_YUV420P: YYY...UUU...VVV
FMT_GRAYSCALE:
FMT_UNCOMPRESSED_MAX:
FMT_COMPRESSED_MIN:
FMT_JPEG:
FMT_PNG:
FMT_COMPRESSED_MAX:
FMT_INVALID: format not valid
+

C++ defination code:

+ +
enum Format
+    {
+        FMT_RGB888 = 0, // RGBRGB...RGB, R at the lowest address
+        FMT_BGR888,     // BGRBGR...BGR, B at the lowest address
+        FMT_RGBA8888,   // RGBARGBA...RGBA, R at the lowest address
+        FMT_BGRA8888,   // BGRABGRA...BGRA, B at the lowest address
+        FMT_RGB565,
+        FMT_BGR565,
+        FMT_YUV422SP, // YYY...UVUVUV...UVUV
+        FMT_YUV422P,  // YYY...UUU...VVV
+        FMT_YVU420SP, // YYY...VUVUVU...VUVU, NV21
+        FMT_YUV420SP, // YYY...UVUVUV...UVUV, NV12
+        FMT_YVU420P,  // YYY...VVV...UUU
+        FMT_YUV420P,  // YYY...UUU...VVV
+        FMT_GRAYSCALE,
+        FMT_UNCOMPRESSED_MAX,
+
+        // compressed format below, not compressed should define upper
+        FMT_COMPRESSED_MIN,
+        FMT_JPEG,
+        FMT_PNG,
+        FMT_COMPRESSED_MAX,
+
+        FMT_INVALID = 0xFF  // format not valid
+    }
+
+

Fit

+ + + + + + + + + + + + + + + + + +
itemdoc
briefObject fit method
valuesFIT_NONE: no object fit, keep original
FIT_FILL: width to new width, height to new height, may be stretch
FIT_CONTAIN: keep aspect ratio, fill blank area with black color
FIT_COVER: keep aspect ratio, crop image to fit new size
FIT_MAX:
+

C++ defination code:

+ +
enum Fit
+    {
+        FIT_NONE = -1, // no object fit, keep original
+        FIT_FILL = 0,  // width to new width, height to new height, may be stretch
+        FIT_CONTAIN,   // keep aspect ratio, fill blank area with black color
+        FIT_COVER,     // keep aspect ratio, crop image to fit new size
+        FIT_MAX
+    }
+
+

ResizeMethod

+ + + + + + + + + + + + + + + + + +
itemdoc
briefResize method
valuesNEAREST:
BILINEAR:
BICUBIC:
AREA:
LANCZOS:
HAMMING:
RESIZE_METHOD_MAX:
+

C++ defination code:

+ +
enum ResizeMethod
+    {
+        NEAREST = 0,
+        BILINEAR,
+        BICUBIC,
+        AREA,
+        LANCZOS,
+        HAMMING,
+        RESIZE_METHOD_MAX
+    }
+
+

ApriltagFamilies

+ + + + + + + + + + + + + + + + + +
itemdoc
briefFamily of apriltag
valuesTAG16H5:
TAG25H7:
TAG25H9:
TAG36H10:
TAG36H11:
ARTOOLKIT:
+

C++ defination code:

+ +
enum ApriltagFamilies
+    {
+        TAG16H5   = 1,
+        TAG25H7   = 2,
+        TAG25H9   = 4,
+        TAG36H10  = 8,
+        TAG36H11  = 16,
+        ARTOOLKIT = 32
+    }
+
+

TemplateMatch

+ + + + + + + + + + + + + + + + + +
itemdoc
briefTemplate match method
valuesSEARCH_EX: Exhaustive search
SEARCH_DS: Diamond search
+

C++ defination code:

+ +
enum TemplateMatch
+    {
+        SEARCH_EX,  // Exhaustive search
+        SEARCH_DS,  // Diamond search
+    }
+
+

CornerDetector

+ + + + + + + + + + + + + + + + + +
itemdoc
briefCornerDetector class
valuesCORNER_FAST:
CORNER_AGAST:
+

C++ defination code:

+ +
enum CornerDetector
+    {
+        CORNER_FAST,
+        CORNER_AGAST
+    }
+
+

EdgeDetector

+ + + + + + + + + + + + + + + + + +
itemdoc
briefEdgeDetector class
valuesEDGE_CANNY:
EDGE_SIMPLE:
+

C++ defination code:

+ +
enum EdgeDetector
+    {
+        EDGE_CANNY,
+        EDGE_SIMPLE,
+    }
+
+

Variable

+

fmt_size

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefImage format size in bytes
attentionIt's a copy of this variable in MaixPy,
so change it in C++ (e.g. update var in hello function) will not take effect the var inMaixPy.
So we add const for this var to avoid this mistake.
value{
3,
3,
4,
4,
2,
2,
2,
2,
1.5,
1.5,
1.5,
1.5,
1,
0,
0,
0,
0,
0
}
readonlyTrue
+

C++ defination code:

+ +
const std::vector<float> fmt_size = {
+        3,
+        3,
+        4,
+        4,
+        2,
+        2,
+        2,
+        2,
+        1.5,
+        1.5,
+        1.5,
+        1.5,
+        1,
+        0,
+        0,
+        0,
+        0,
+        0
+        }
+
+

fmt_names

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefImage format string
value{
"RGB888",
"BGR888",
"RGBA8888",
"BGRA8888",
"RGB565",
"BGR565",
"YUV422SP",
"YUV422P",
"YVU420SP",
"YUV420SP",
"YVU420P"
"YUV420P",
"GRAYSCALE",
"MAX"}
readonlyTrue
+

C++ defination code:

+ +
const std::vector<std::string> fmt_names = {
+        "RGB888",
+        "BGR888",
+        "RGBA8888",
+        "BGRA8888",
+        "RGB565",
+        "BGR565",
+        "YUV422SP",
+        "YUV422P",
+        "YVU420SP",
+        "YUV420SP",
+        "YVU420P"
+        "YUV420P",
+        "GRAYSCALE",
+        "MAX"}
+
+

COLOR_WHITE

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefPredefined color white
valueimage::Color::from_rgb(255, 255, 255)
readonlyTrue
+

C++ defination code:

+ +
const image::Color COLOR_WHITE = image::Color::from_rgb(255, 255, 255)
+
+

COLOR_BLACK

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefPredefined color black
valueimage::Color::from_rgb(0, 0, 0)
readonlyTrue
+

C++ defination code:

+ +
const image::Color COLOR_BLACK = image::Color::from_rgb(0, 0, 0)
+
+

COLOR_RED

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefPredefined color red
valueimage::Color::from_rgb(255, 0, 0)
readonlyTrue
+

C++ defination code:

+ +
const image::Color COLOR_RED = image::Color::from_rgb(255, 0, 0)
+
+

COLOR_GREEN

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefPredefined color green
valueimage::Color::from_rgb(0, 255, 0)
readonlyTrue
+

C++ defination code:

+ +
const image::Color COLOR_GREEN = image::Color::from_rgb(0, 255, 0)
+
+

COLOR_BLUE

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefPredefined color blue
valueimage::Color::from_rgb(0, 0, 255)
readonlyTrue
+

C++ defination code:

+ +
const image::Color COLOR_BLUE = image::Color::from_rgb(0, 0, 255)
+
+

COLOR_YELLOW

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefPredefined color yellow
valueimage::Color::from_rgb(255, 255, 0)
readonlyTrue
+

C++ defination code:

+ +
const image::Color COLOR_YELLOW = image::Color::from_rgb(255, 255, 0)
+
+

COLOR_PURPLE

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefPredefined color purple
valueimage::Color::from_rgb(143, 0, 255)
readonlyTrue
+

C++ defination code:

+ +
const image::Color COLOR_PURPLE = image::Color::from_rgb(143, 0, 255)
+
+

COLOR_ORANGE

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefPredefined color orange
valueimage::Color::from_rgb(255, 127, 0)
readonlyTrue
+

C++ defination code:

+ +
const image::Color COLOR_ORANGE = image::Color::from_rgb(255, 127, 0)
+
+

COLOR_GRAY

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefPredefined color gray
valueimage::Color::from_rgb(127, 127, 127)
readonlyTrue
+

C++ defination code:

+ +
const image::Color COLOR_GRAY = image::Color::from_rgb(127, 127, 127)
+
+

Function

+

load

+ +
def load(path: str, format: Format = ...) -> Image
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefLoad image from file, and convert to Image object
parampath: image file path
format: read as this format, if not match, will convert to this format, by default is RGB888
returnImage object
+

C++ defination code:

+ +
image::Image *load(const char *path, image::Format format = image::Format::FMT_RGB888)
+
+

from_bytes

+ +
def from_bytes(width: int, height: int, format: Format, data: maix.Bytes(bytes), copy: bool = True) -> Image
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefCreate image from bytes
paramwidth: image width
height: image height
format: image format
data: image data, if data is None, will malloc memory for image data
If the image is in jpeg format, data must be filled in.
copy: if true and data is not None, will copy data to new buffer, else will use data directly. default is true to avoid memory leak.
Use it carefully!!!
returnImage object
+

C++ defination code:

+ +
image::Image *from_bytes(int width, int height, image::Format format, Bytes *data, bool copy = true)
+
+

load_font

+ +
def load_font(name: str, path: str, size: int = 16) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefLoad font from file
paramname: font name, used to identify font
path: font file path, support ttf, ttc, otf
size: font size, font height, by default is 16
returnerror code, err::ERR_NONE is ok, other is error
+

C++ defination code:

+ +
err::Err load_font(const std::string &name, const char *path, int size = 16)
+
+

set_default_font

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefSet default font, if not call this method, default is hershey_plain
paramname: font name, supported names can be get by fonts()
returnerror code, err::ERR_NONE is ok, other is error
+

C++ defination code:

+ +
err::Err set_default_font(const std::string &name)
+
+

fonts

+ +
def fonts() -> list[str]
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet all loaded fonts
returnall loaded fonts, string list type
+

C++ defination code:

+ +
std::vector<std::string> *fonts()
+
+

string_size

+ +
def string_size(string: str, scale: float = 1, thickness: int = 1, font: str = '') -> Size
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefGet text rendered width and height
paramstring: text content
scale: font scale, by default(value is 1)
thickness: text thickness(line width), by default(value is 1)
returntext rendered width and height, [width, height]
+

C++ defination code:

+ +
image::Size string_size(std::string string, float scale = 1, int thickness = 1, const std::string &font = "")
+
+

cv2image

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefOpenCV Mat(numpy array object) to Image object
paramarray: numpy array object, must be a 3-dim or 2-dim continuous array with shape hwc or hw
returnImage object
+

C++ defination code:

+ +
image::Image *cv2image(py::array_t<uint8_t, py::array::c_style> array, bool bgr = true, bool copy = true)
+
+

image2cv

+ +
def image2cv(img: Image, bgr: bool = True, copy: bool = True) -> numpy.ndarray[numpy.uint8]
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefImage object to OpenCV Mat(numpy array object)
paramimg: Image object
returnnumpy array object
+

C++ defination code:

+ +
py::array_t<uint8_t, py::array::c_style> image2cv(image::Image *img, bool bgr = true, bool copy = true)
+
+

Class

+

Size

+ + + + + + + + + + + + + +
itemdoc
briefImage size type
+

C++ defination code:

+ +
class Size
+
+

__init__

+ +
def __init__(self, width: int = 0, height: int = 0) -> None
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefConstruct a new Size object
paramwidth: image width
height: image height
staticFalse
+

C++ defination code:

+ +
Size(int width = 0, int height = 0)
+
+

width

+ +
def width(self, width: int = -1) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefwidth of size
paramwidth: set new width, if not set, only return current width
staticFalse
+

C++ defination code:

+ +
int width(int width = -1)
+
+

height

+ +
def height(self, height: int = -1) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefheight of size
paramheight: set new height, if not set, only return current height
staticFalse
+

C++ defination code:

+ +
int height(int height = -1)
+
+

__getitem__

+ +
def __getitem__(self, index: int) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSubscript operator
paramindex: 0 for width, 1 for height
returnint& width or height
staticFalse
+

C++ defination code:

+ +
int &operator[](int index)
+
+

__str__

+ +
def __str__(self) -> str
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefto string
staticFalse
+

C++ defination code:

+ +
std::string __str__()
+
+

Line

+ + + + + + + + + + + + + +
itemdoc
briefLine class
+

C++ defination code:

+ +
class Line
+
+

__init__

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefLine constructor
paramx1: coordinate x1 of the straight line
y1: coordinate y1 of the straight line
x2: coordinate x2 of the straight line
y2: coordinate y2 of the straight line
magnitude: magnitude of the straight line after Hough transformation
theta: angle of the straight line after Hough transformation
rho: p-value of the straight line after Hough transformation
staticFalse
+

C++ defination code:

+ +
Line(int x1, int y1, int x2, int y2, int magnitude = 0, int theta = 0, int rho = 0)
+
+

__getitem__

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSubscript operator
param**index
+

[0]: get x1 of line
[1] get y1 of line
[2] get x2 of line
[3] get y2 of line
[4] get length of line
[5] get magnitude of the straight line after Hough transformation
[6] get angle of the straight line after Hough transformation (0-179 degrees)
[7] get p-value of the straight line after Hough transformation
|
+|
return** | int& |
+| static | False |

+

C++ defination code:

+ +
int &__getitem__(int index)
+
+

x1

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget x1 of line
returnreturn x1 of the line, type is int
staticFalse
+

C++ defination code:

+ +
int x1()
+
+

y1

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget y1 of line
returnreturn y1 of the line, type is int
staticFalse
+

C++ defination code:

+ +
int y1()
+
+

x2

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget x2 of line
returnreturn x2 of the line, type is int
staticFalse
+

C++ defination code:

+ +
int x2()
+
+

y2

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget y2 of line
returnreturn y2 of the line, type is int
staticFalse
+

C++ defination code:

+ +
int y2()
+
+

length

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget length of line
returnreturn length of the line, type is int
staticFalse
+

C++ defination code:

+ +
int length()
+
+

magnitude

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget magnitude of the straight line after Hough transformation
returnreturn magnitude, type is int
staticFalse
+

C++ defination code:

+ +
int magnitude()
+
+

theta

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget angle of the straight line after Hough transformation (0-179 degrees)
returnreturn angle, type is int
staticFalse
+

C++ defination code:

+ +
int theta()
+
+

rho

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget p-value of the straight line after Hough transformation
returnreturn p-value, type is int
staticFalse
+

C++ defination code:

+ +
int rho()
+
+

Rect

+ + + + + + + + + + + + + +
itemdoc
briefRect class
+

C++ defination code:

+ +
class Rect
+
+

__init__

+ +
def __init__(self, corners: list[list[int]], x: int, y: int, w: int, h: int, magnitude: int = 0) -> None
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefRect constructor
paramcorners: corners of rect
x: coordinate x of the straight line
y: coordinate y of the straight line
w: coordinate w of the straight line
h: coordinate h of the straight line
magnitude: magnitude of the straight line after Hough transformation
staticFalse
+

C++ defination code:

+ +
Rect(std::vector<std::vector<int>> &corners, int x, int y, int w, int h, int magnitude = 0)
+
+

__getitem__

+ +
def __getitem__(self, index: int) -> int
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSubscript operator
param**index
+

[0]: get x of rect
[1] get y of rect
[2] get w of rect
[3] get h of rect
[4] get magnitude of the straight line after Hough transformation
|
+|
return** | int& |
+| static | False |

+

C++ defination code:

+ +
int &__getitem__(int index)
+
+

corners

+ +
def corners(self) -> list[list[int]]
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget corners of rect
returnreturn the coordinate of the rect.
staticFalse
+

C++ defination code:

+ +
std::vector<std::vector<int>> corners()
+
+

rect

+ +
def rect(self) -> list[int]
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget rectangle of rect
returnreturn the rectangle of the rect. format is {x, y, w, h}, type is std::vector
staticFalse
+

C++ defination code:

+ +
std::vector<int> rect()
+
+

x

+ +
def x(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget x of rect
returnreturn x of the rect, type is int
staticFalse
+

C++ defination code:

+ +
int x()
+
+

y

+ +
def y(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget y of rect
returnreturn y of the rect, type is int
staticFalse
+

C++ defination code:

+ +
int y()
+
+

w

+ +
def w(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget w of rect
returnreturn w of the rect, type is int
staticFalse
+

C++ defination code:

+ +
int w()
+
+

h

+ +
def h(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget h of rect
returnreturn h of the rect, type is int
staticFalse
+

C++ defination code:

+ +
int h()
+
+

magnitude

+ +
def magnitude(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget magnitude of the straight line after Hough transformation
returnreturn magnitude, type is int
staticFalse
+

C++ defination code:

+ +
int magnitude()
+
+

Circle

+ + + + + + + + + + + + + +
itemdoc
briefcircle class
+

C++ defination code:

+ +
class Circle
+
+

__init__

+ +
def __init__(self, x: int, y: int, r: int, magnitude: int) -> None
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefCircle constructor
paramx: coordinate x of the circle
y: coordinate y of the circle
r: coordinate r of the circle
magnitude: coordinate y2 of the straight line
staticFalse
+

C++ defination code:

+ +
Circle(int x, int y, int r, int magnitude)
+
+

__getitem__

+ +
def __getitem__(self, index: int) -> int
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSubscript operator
param**index
+

[0]: get x of circle
[1] get y of circle
[2] get r of circle
[3] get magnitude of the circle after Hough transformation
|
+|
return** | int& |
+| static | False |

+

C++ defination code:

+ +
int &__getitem__(int index)
+
+

x

+ +
def x(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget x of circle
returnreturn x of the circle, type is int
staticFalse
+

C++ defination code:

+ +
int x()
+
+

y

+ +
def y(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget y of circle
returnreturn y of the circle, type is int
staticFalse
+

C++ defination code:

+ +
int y()
+
+

r

+ +
def r(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget r of circle
returnreturn r of the circle, type is int
staticFalse
+

C++ defination code:

+ +
int r()
+
+

magnitude

+ +
def magnitude(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget magnitude of the circle after Hough transformation
returnreturn magnitude, type is int
staticFalse
+

C++ defination code:

+ +
int magnitude()
+
+

Blob

+ + + + + + + + + + + + + +
itemdoc
briefBlob class
+

C++ defination code:

+ +
class Blob
+
+

__init__

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefBlob constructor
paramrect: blob rect, type is std::vector
corners: blob corners, type is std::vector<std::vector>
mini_corners: blob mini_corners, type is std::vector<std::vector>
cx: blob center x, type is float
cy: blob center y, type is float
pixels: blob pixels, type is int
rotation: blob rotation, type is float
code: blob code, type is int
count: blob count, type is int
perimeter: blob perimeter, type is int
roundness: blob roundness, type is float
x_hist_bins: blob x_hist_bins, type is std::vector
y_hist_bins: blob y_hist_bins, type is std::vector
staticFalse
+

C++ defination code:

+ +
Blob(std::vector<int> &rect, std::vector<std::vector<int>> &corners, std::vector<std::vector<int>> &mini_corners,float cx, float cy, int pixels, float rotation, int code, int count, int perimeter, float roundness, std::vector<int> &x_hist_bins, std::vector<int> &y_hist_bins)
+
+

__getitem__

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSubscript operator
param**index
+

[0]: Returns the blob’s bounding box x coordinate
[1] Returns the blob’s bounding box y coordinate
[2] Returns the blob’s bounding box w coordinate
[3] Returns the blob’s bounding box h coordinate
[4] Returns the number of pixels that are part of this blob
[5] Returns the centroid x position of the blob
[6] Returns the centroid y position of the blob
|
+|
return** | int& width or height |
+| static | False |

+

C++ defination code:

+ +
int &__getitem__(int index)
+
+

corners

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget blob corners
returnReturns a list of 4 (x,y) tuples of the 4 corners of the object.
(x0, y0)___________(x1, y1)



___________
(x3, y3) (x2, y2)
note: the order of corners may change
staticFalse
+

C++ defination code:

+ +
std::vector<std::vector<int>> corners()
+
+

mini_corners

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget blob mini corners
returnReturns a list of 4 (x,y) tuples of the 4 corners than bound the min area rectangle of the blob.
(x0, y0)___________(x1, y1)



___________
(x3, y3) (x2, y2)
note: the order of corners may change
staticFalse
+

C++ defination code:

+ +
std::vector<std::vector<int>> mini_corners()
+
+

rect

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget blob rect
returnReturns the center coordinates and width and height of the rectangle. format is (x, y, w, h)
w
(x, y) ___________

h

___________
staticFalse
+

C++ defination code:

+ +
std::vector<int> rect()
+
+

x

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget blob x of the upper left coordinate
returnReturns the x coordinate of the upper left corner of the rectangle.
staticFalse
+

C++ defination code:

+ +
int x()
+
+

y

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget blob y of the upper left coordinate
returnReturns the y coordinate of the upper left corner of the rectangle.
staticFalse
+

C++ defination code:

+ +
int y()
+
+

w

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget blob width
returnReturns the blob’s bounding box w coordinate
staticFalse
+

C++ defination code:

+ +
int w()
+
+

h

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget blob height
returnReturns the blob’s bounding box h coordinate
staticFalse
+

C++ defination code:

+ +
int h()
+
+

pixels

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget blob pixels
returnReturns the number of pixels that are part of this blob.
staticFalse
+

C++ defination code:

+ +
int pixels()
+
+

cx

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget blob center x
returnReturns the centroid x position of the blob
staticFalse
+

C++ defination code:

+ +
int cx()
+
+

cy

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget blob center y
returnReturns the centroid y position of the blob
staticFalse
+

C++ defination code:

+ +
int cy()
+
+

cxf

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget blob center x
returnReturns the centroid x position of the blob
staticFalse
+

C++ defination code:

+ +
float cxf()
+
+

cyf

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget blob center y
returnReturns the centroid y position of the blob
staticFalse
+

C++ defination code:

+ +
float cyf()
+
+

rotation

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget blob rotation
returnReturns the rotation of the blob in radians (float). If the blob is like a pencil or pen this value will be unique for 0-180 degrees.
staticFalse
+

C++ defination code:

+ +
float rotation()
+
+

rotation_rad

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget blob rotation_rad
returnReturns the rotation of the blob in radians
staticFalse
+

C++ defination code:

+ +
float rotation_rad()
+
+

rotation_deg

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget blob rotation_deg
returnReturns the rotation of the blob in degrees.
staticFalse
+

C++ defination code:

+ +
int rotation_deg()
+
+

code

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget blob code
returnReturns a 32-bit binary number with a bit set in it for each color threshold that’s part of this blob
staticFalse
+

C++ defination code:

+ +
int code()
+
+

count

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget blob count
returnReturns the number of blobs merged into this blob.
staticFalse
+

C++ defination code:

+ +
int count()
+
+

perimeter

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget blob merge_cnt
returnReturns the number of pixels on this blob’s perimeter.
staticFalse
+

C++ defination code:

+ +
int perimeter()
+
+

roundness

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget blob roundness
returnReturns a value between 0 and 1 representing how round the object is
staticFalse
+

C++ defination code:

+ +
float roundness()
+
+

elongation

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget blob elongation
returnReturnsa value between 0 and 1 representing how long (not round) the object is
staticFalse
+

C++ defination code:

+ +
float elongation()
+
+

area

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget blob area
returnReturns the area of the bounding box around the blob
staticFalse
+

C++ defination code:

+ +
int area()
+
+

density

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget blob density
returnReturns the density ratio of the blob
staticFalse
+

C++ defination code:

+ +
float density()
+
+

extent

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefAlias for blob.density()
returnReturns the density ratio of the blob
staticFalse
+

C++ defination code:

+ +
float extent()
+
+

compactness

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget blob compactness
returnReturns the compactness ratio of the blob
staticFalse
+

C++ defination code:

+ +
float compactness()
+
+

solidity

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget blob solidity
returnReturns the solidity ratio of the blob
staticFalse
+

C++ defination code:

+ +
float solidity()
+
+

convexity

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget blob convexity
returnReturns a value between 0 and 1 representing how convex the object is
staticFalse
+

C++ defination code:

+ +
float convexity()
+
+

x_hist_bins

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget blob x_hist_bins
returnReturns the x_hist_bins of the blob
staticFalse
+

C++ defination code:

+ +
std::vector<int> x_hist_bins()
+
+

y_hist_bins

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget blob y_hist_bins
returnReturns the y_hist_bins of the blob
staticFalse
+

C++ defination code:

+ +
std::vector<int> y_hist_bins()
+
+

major_axis_line

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget blob major_axis_line
returnReturns a line tuple (x1, y1, x2, y2) of the minor axis of the blob.
staticFalse
+

C++ defination code:

+ +
std::vector<int> major_axis_line()
+
+

minor_axis_line

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget blob minor_axis_line
returnReturns a line tuple (x1, y1, x2, y2) of the minor axis of the blob.
staticFalse
+

C++ defination code:

+ +
std::vector<int> minor_axis_line()
+
+

enclosing_circle

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget blob enclosing_circle
returnReturns a circle tuple (x, y, r) of the circle that encloses the min area rectangle of a blob.
staticFalse
+

C++ defination code:

+ +
std::vector<int> enclosing_circle()
+
+

enclosed_ellipse

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget blob enclosed_ellipse
returnReturns an ellipse tuple (x, y, rx, ry, rotation) of the ellipse that fits inside of the min area rectangle of a blob.
staticFalse
+

C++ defination code:

+ +
std::vector<int> enclosed_ellipse()
+
+

QRCode

+ + + + + + + + + + + + + +
itemdoc
briefQRCode class
+

C++ defination code:

+ +
class QRCode
+
+

__init__

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefQRCode constructor
paramrect: rect of corners, type is std::vector
corners: corners of QRCode
payload: payload of the QRCode
version: version of the QRCode
ecc_level: ecc_level of the QRCode
mask: mask of the QRCode
data_type: data_type of the QRCode
eci: eci of the QRCode
staticFalse
+

C++ defination code:

+ +
QRCode(std::vector<int> &rect, std::vector<std::vector<int>> &corners, std::string &payload, int version, int ecc_level, int mask, int data_type, int eci)
+
+

__getitem__

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSubscript operator
param**index
+

[0]: Returns the qrcode’s bounding box x coordinate
[1] Returns the qrcode’s bounding box y coordinate
[2] Returns the qrcode’s bounding box w coordinate
[3] Returns the qrcode’s bounding box h coordinate
[4] Not support this index, try to use payload() method
[5] Returns the version of qrcode
[6] Returns the error correction level of qrcode
[7] Returns the mask of qrcode
[8] Returns the datatype of qrcode
[9] Returns the eci of qrcode
|
+|
return** | int& |
+| static | False |

+

C++ defination code:

+ +
int &__getitem__(int index)
+
+

corners

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget coordinate of QRCode
returnreturn the coordinate of the QRCode.
staticFalse
+

C++ defination code:

+ +
std::vector<std::vector<int>> corners()
+
+

rect

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget rectangle of QRCode
returnreturn the rectangle of the QRCode. format is {x, y, w, h}, type is std::vector
staticFalse
+

C++ defination code:

+ +
std::vector<int> rect()
+
+

x

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget x of QRCode
returnreturn x of the QRCode, type is int
staticFalse
+

C++ defination code:

+ +
int x()
+
+

y

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget y of QRCode
returnreturn y of the QRCode, type is int
staticFalse
+

C++ defination code:

+ +
int y()
+
+

w

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget w of QRCode
returnreturn w of the QRCode, type is int
staticFalse
+

C++ defination code:

+ +
int w()
+
+

h

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget h of QRCode
returnreturn h of the QRCode, type is int
staticFalse
+

C++ defination code:

+ +
int h()
+
+

payload

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget QRCode payload
returnreturn area of the QRCode
staticFalse
+

C++ defination code:

+ +
std::string payload()
+
+

version

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget QRCode version
returnreturn version of the QRCode
staticFalse
+

C++ defination code:

+ +
int version()
+
+

ecc_level

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget QRCode error correction level
returnreturn error correction level of the QRCode
staticFalse
+

C++ defination code:

+ +
int ecc_level()
+
+

mask

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget QRCode mask
returnreturn mask of the QRCode
staticFalse
+

C++ defination code:

+ +
int mask()
+
+

data_type

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget QRCode dataType
returnreturn mask of the QRCode
staticFalse
+

C++ defination code:

+ +
int data_type()
+
+

eci

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget QRCode eci
returnreturn data of the QRCode
staticFalse
+

C++ defination code:

+ +
int eci()
+
+

is_numeric

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefcheck QRCode is numeric
returnreturn true if the result type of the QRCode is numeric
staticFalse
+

C++ defination code:

+ +
bool is_numeric()
+
+

is_alphanumeric

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefcheck QRCode is alphanumeric
returnreturn true if the result type of the QRCode is alphanumeric
staticFalse
+

C++ defination code:

+ +
bool is_alphanumeric()
+
+

is_binary

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefcheck QRCode is binary
returnreturn true if the result type of the QRCode is binary
staticFalse
+

C++ defination code:

+ +
bool is_binary()
+
+

is_kanji

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefcheck QRCode is kanji
returnreturn true if the result type of the QRCode is kanji
staticFalse
+

C++ defination code:

+ +
bool is_kanji()
+
+

AprilTag

+ + + + + + + + + + + + + +
itemdoc
briefAprilTag class
+

C++ defination code:

+ +
class AprilTag
+
+

__init__

+ +
def __init__(self, rect: list[int], corners: list[list[int]], id: int, famliy: int, centroid_x: float, centroid_y: float, rotation: float, decision_margin: float, hamming: int, goodness: float, x_translation: float, y_translation: float, z_translation: float, x_rotation: float, y_rotation: float, z_rotation: float) -> None
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefAprilTag constructor
paramrect: Inlucdes the top-left corner and the width and height of the rectangle. format is {x, y, w, h}, type is std::vector
corners: Includes the four corners of the rectangle. format is {{x0, y0}, {x1, y1}, {x2, y2}, {x3, y3}}, type is std::vector<std::vector>
id: The id of the AprilTag
famliy: The family of the AprilTag
centroid_x: The x coordinate of the center of the AprilTag
centroid_y: The y coordinate of the center of the AprilTag
rotation: The rotation of the AprilTag
decision_margin: The decision_margin of the AprilTag
hamming: The hamming of the AprilTag
goodness: The goodness of the AprilTag
x_translation: The x_translation of the AprilTag
y_translation: The y_translation of the AprilTag
z_translation: The z_translation of the AprilTag
x_rotation: The x_rotation of the AprilTag
y_rotation: The y_rotation of the AprilTag
z_rotation: The z_rotation of the AprilTag
staticFalse
+

C++ defination code:

+ +
AprilTag(std::vector<int> &rect, std::vector<std::vector<int>> &corners, int id, int famliy, float centroid_x, float centroid_y, float rotation, float decision_margin, int hamming, float goodness, float x_translation, float y_translation, float z_translation, float x_rotation, float y_rotation, float z_rotation)
+
+

__getitem__

+ +
def __getitem__(self, index: int) -> int
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSubscript operator
param**index
+

[0]: Returns the apriltag’s bounding box x coordinate
[1] Returns the apriltag’s bounding box y coordinate
[2] Returns the apriltag’s bounding box w coordinate
[3] Returns the apriltag’s bounding box h coordinate
[4] Returns the apriltag’s id
[5] Returns the apriltag’s family
[6] Not support
[7] Not support
[8] Not support
[9] Not support
[10] Returns the apriltag’s hamming
[11] Not support
[12] Not support
[13] Not support
[14] Not support
[15] Not support
[16] Not support
[17] Not support
|
+|
return** | int& |
+| static | False |

+

C++ defination code:

+ +
int &__getitem__(int index)
+
+

corners

+ +
def corners(self) -> list[list[int]]
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget coordinate of AprilTag
returnreturn the coordinate of the AprilTag.
staticFalse
+

C++ defination code:

+ +
std::vector<std::vector<int>> corners()
+
+

rect

+ +
def rect(self) -> list[int]
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget rectangle of AprilTag
returnreturn the rectangle of the AprilTag. format is {x, y, w, h}, type is std::vector
staticFalse
+

C++ defination code:

+ +
std::vector<int> rect()
+
+

x

+ +
def x(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget x of AprilTag
returnreturn x of the AprilTag, type is int
staticFalse
+

C++ defination code:

+ +
int x()
+
+

y

+ +
def y(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget y of AprilTag
returnreturn y of the AprilTag, type is int
staticFalse
+

C++ defination code:

+ +
int y()
+
+

w

+ +
def w(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget w of AprilTag
returnreturn w of the AprilTag, type is int
staticFalse
+

C++ defination code:

+ +
int w()
+
+

h

+ +
def h(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget h of AprilTag
returnreturn h of the AprilTag, type is int
staticFalse
+

C++ defination code:

+ +
int h()
+
+

id

+ +
def id(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget id of AprilTag
returnreturn id of the AprilTag, type is int
staticFalse
+

C++ defination code:

+ +
int id()
+
+

family

+ +
def family(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget family of AprilTag
returnreturn family of the AprilTag, type is int
staticFalse
+

C++ defination code:

+ +
int family()
+
+

cx

+ +
def cx(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget cx of AprilTag
returnreturn cx of the AprilTag, type is int
staticFalse
+

C++ defination code:

+ +
int cx()
+
+

cxf

+ +
def cxf(self) -> float
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget cxf of AprilTag
returnreturn cxf of the AprilTag, type is float
staticFalse
+

C++ defination code:

+ +
float cxf()
+
+

cy

+ +
def cy(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget cy of AprilTag
returnreturn cy of the AprilTag, type is int
staticFalse
+

C++ defination code:

+ +
int cy()
+
+

cyf

+ +
def cyf(self) -> float
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget cyf of AprilTag
returnreturn cyf of the AprilTag, type is float
staticFalse
+

C++ defination code:

+ +
float cyf()
+
+

rotation

+ +
def rotation(self) -> float
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget rotation of AprilTag
returnreturn rotation of the AprilTag, type is float
staticFalse
+

C++ defination code:

+ +
float rotation()
+
+

decision_margin

+ +
def decision_margin(self) -> float
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet decision_margin of AprilTag
returnReturns the quality of the apriltag match (0.0 - 1.0) where 1.0 is the best.
staticFalse
+

C++ defination code:

+ +
float decision_margin()
+
+

hamming

+ +
def hamming(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget hamming of AprilTag
returnReturns the number of accepted bit errors for this tag.
return 0, means 0 bit errors will be accepted.
1 is TAG25H7, means up to 1 bit error may be accepted
2 is TAG25H9, means up to 3 bit errors may be accepted
3 is TAG36H10, means up to 3 bit errors may be accepted
4 is TAG36H11, means up to 4 bit errors may be accepted
5 is ARTOOLKIT, means 0 bit errors will be accepted
staticFalse
+

C++ defination code:

+ +
int hamming()
+
+

goodness

+ +
def goodness(self) -> float
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget goodness of AprilTag
returnreturn goodness of the AprilTag, type is float
Note: This value is always 0.0 for now.
staticFalse
+

C++ defination code:

+ +
float goodness()
+
+

x_translation

+ +
def x_translation(self) -> float
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget x_translation of AprilTag
returnreturn x_translation of the AprilTag, type is float
staticFalse
+

C++ defination code:

+ +
float x_translation()
+
+

y_translation

+ +
def y_translation(self) -> float
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget y_translation of AprilTag
returnreturn y_translation of the AprilTag, type is float
staticFalse
+

C++ defination code:

+ +
float y_translation()
+
+

z_translation

+ +
def z_translation(self) -> float
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget z_translation of AprilTag
returnreturn z_translation of the AprilTag, type is float
staticFalse
+

C++ defination code:

+ +
float z_translation()
+
+

x_rotation

+ +
def x_rotation(self) -> float
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget x_rotation of AprilTag
returnreturn x_rotation of the AprilTag, type is float
staticFalse
+

C++ defination code:

+ +
float x_rotation()
+
+

y_rotation

+ +
def y_rotation(self) -> float
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget y_rotation of AprilTag
returnreturn y_rotation of the AprilTag, type is float
staticFalse
+

C++ defination code:

+ +
float y_rotation()
+
+

z_rotation

+ +
def z_rotation(self) -> float
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget z_rotation of AprilTag
returnreturn z_rotation of the AprilTag, type is float
staticFalse
+

C++ defination code:

+ +
float z_rotation()
+
+

DataMatrix

+ + + + + + + + + + + + + +
itemdoc
briefDataMatrix class
+

C++ defination code:

+ +
class DataMatrix
+
+

__init__

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefDataMatrix constructor
paramrect: Inlucdes the top-left corner and the width and height of the rectangle. format is {x, y, w, h}, type is std::vector
corners: Includes the four corners of the rectangle. format is {{x0, y0}, {x1, y1}, {x2, y2}, {x3, y3}}, type is std::vector<std::vector>
payload: The payload of the DataMatrix
rotation: The rotation of the DataMatrix
rows: The rows of the DataMatrix
columns: The columns of the DataMatrix
capacity: The capacity of the DataMatrix
padding: The padding of the DataMatrix
staticFalse
+

C++ defination code:

+ +
DataMatrix(std::vector<int> &rect, std::vector<std::vector<int>> &corners, std::string &payload, float rotation, int rows, int columns, int capacity, int padding)
+
+

__getitem__

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSubscript operator
param**index
+

[0]: get x of DataMatrix
[1] get y of DataMatrix
[2] get w of DataMatrix
[3] get h of DataMatrix
[4] Not support this index, try to use payload() method
[5] Not support this index, try to use rotation() method
[6] get rows of DataMatrix
[7] get columns of DataMatrix
[8] get capacity of DataMatrix
[9] get padding of DataMatrix
|
+|
return** | int& |
+| static | False |

+

C++ defination code:

+ +
int &__getitem__(int index)
+
+

corners

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget coordinate of DataMatrix
returnreturn the coordinate of the DataMatrix.
staticFalse
+

C++ defination code:

+ +
std::vector<std::vector<int>> corners()
+
+

rect

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget rectangle of DataMatrix
returnreturn the rectangle of the DataMatrix. format is {x, y, w, h}, type is std::vector
staticFalse
+

C++ defination code:

+ +
std::vector<int> rect()
+
+

x

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget x of DataMatrix
returnreturn x of the DataMatrix, type is int
staticFalse
+

C++ defination code:

+ +
int x()
+
+

y

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget y of DataMatrix
returnreturn y of the DataMatrix, type is int
staticFalse
+

C++ defination code:

+ +
int y()
+
+

w

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget w of DataMatrix
returnreturn w of the DataMatrix, type is int
staticFalse
+

C++ defination code:

+ +
int w()
+
+

h

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget h of DataMatrix
returnreturn h of the DataMatrix, type is int
staticFalse
+

C++ defination code:

+ +
int h()
+
+

payload

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget payload of DataMatrix
returnreturn payload of the DataMatrix, type is std::string
staticFalse
+

C++ defination code:

+ +
std::string payload()
+
+

rotation

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget rotation of DataMatrix
returnreturn rotation of the DataMatrix, type is float
staticFalse
+

C++ defination code:

+ +
float rotation()
+
+

rows

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget rows of DataMatrix
returnreturn rows of the DataMatrix, type is int
staticFalse
+

C++ defination code:

+ +
int rows()
+
+

columns

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget columns of DataMatrix
returnreturn columns of the DataMatrix, type is int
staticFalse
+

C++ defination code:

+ +
int columns()
+
+

capacity

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget capacity of DataMatrix
returnreturns how many characters could fit in this data matrix, type is int
staticFalse
+

C++ defination code:

+ +
int capacity()
+
+

padding

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget padding of DataMatrix
returnreturns how many unused characters are in this data matrix, type is int
staticFalse
+

C++ defination code:

+ +
int padding()
+
+

BarCode

+ + + + + + + + + + + + + +
itemdoc
briefBarCode class
+

C++ defination code:

+ +
class BarCode
+
+

__init__

+ +
def __init__(self, rect: list[int], corners: list[list[int]], payload: str, type: int, rotation: float, quality: int) -> None
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefBarCode constructor
paramrect: Inlucdes the top-left corner and the width and height of the rectangle. format is {x, y, w, h}, type is std::vector
corners: Includes the four corners of the rectangle. format is {{x0, y0}, {x1, y1}, {x2, y2}, {x3, y3}}, type is std::vector<std::vector>
payload: The payload of the BarCode
type: The type of the BarCode
rotation: The rotation of the BarCode
quality: The quality of the BarCode
staticFalse
+

C++ defination code:

+ +
BarCode(std::vector<int> &rect, std::vector<std::vector<int>> &corners, std::string &payload, int type, float rotation, int quality)
+
+

__getitem__

+ +
def __getitem__(self, index: int) -> int
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSubscript operator
param**index
+

[0]: get x of BarCode
[1] get y of BarCode
[2] get w of BarCode
[3] get h of BarCode
[4] Not support this index, try to use payload() method
[5] get type of BarCode
[6] Not support this index, try to use rotation() method
[7] get quality of BarCode
|
+|
return** | int& |
+| static | False |

+

C++ defination code:

+ +
int &__getitem__(int index)
+
+

corners

+ +
def corners(self) -> list[list[int]]
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget coordinate of BarCode
returnreturn the coordinate of the BarCode.
staticFalse
+

C++ defination code:

+ +
std::vector<std::vector<int>> corners()
+
+

rect

+ +
def rect(self) -> list[int]
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget rectangle of BarCode
returnreturn the rectangle of the BarCode. format is {x, y, w, h}, type is std::vector
staticFalse
+

C++ defination code:

+ +
std::vector<int> rect()
+
+

x

+ +
def x(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget x of BarCode
returnreturn x of the BarCode, type is int
staticFalse
+

C++ defination code:

+ +
int x()
+
+

y

+ +
def y(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget y of BarCode
returnreturn y of the BarCode, type is int
staticFalse
+

C++ defination code:

+ +
int y()
+
+

w

+ +
def w(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget w of BarCode
returnreturn w of the BarCode, type is int
staticFalse
+

C++ defination code:

+ +
int w()
+
+

h

+ +
def h(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget h of BarCode
returnreturn h of the BarCode, type is int
staticFalse
+

C++ defination code:

+ +
int h()
+
+

payload

+ +
def payload(self) -> str
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget payload of BarCode
returnreturn payload of the BarCode, type is std::string
staticFalse
+

C++ defination code:

+ +
std::string payload()
+
+

type

+ +
def type(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget type of BarCode
returnreturn type of the BarCode, type is int
staticFalse
+

C++ defination code:

+ +
int type()
+
+

rotation

+ +
def rotation(self) -> float
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget rotation of BarCode
returnreturn rotation of the BarCode, type is float. FIXME: always return 0.0
staticFalse
+

C++ defination code:

+ +
float rotation()
+
+

quality

+ +
def quality(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget quality of BarCode
returnreturn quality of the BarCode, type is int
staticFalse
+

C++ defination code:

+ +
int quality()
+
+

Statistics

+ + + + + + + + + + + + + +
itemdoc
briefStatistics class
+

C++ defination code:

+ +
class Statistics
+
+

__init__

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefStatistics constructor
paramformat: The statistics source image format
l_statistics: The statistics of the L channel. format is {mean, median, mode, std_dev, min, max, lq, uq}, type is std::vector
a_statistics: The statistics of the A channel. format is {mean, median, mode, std_dev, min, max, lq, uq}, type is std::vector
b_statistics: The statistics of the B channel. format is {mean, median, mode, std_dev, min, max, lq, uq}, type is std::vector
staticFalse
+

C++ defination code:

+ +
Statistics(image::Format format, std::vector<int> &l_statistics, std::vector<int> &a_statistics, std::vector<int> &b_statistics)
+
+

__getitem__

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSubscript operator
paramindex: array index
returnint&
staticFalse
+

C++ defination code:

+ +
int &__getitem__(int index)
+
+

format

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget format of Statistics source image
returnreturn format of the Statistics source image, type is image::Format
staticFalse
+

C++ defination code:

+ +
image::Format format()
+
+

l_mean

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget L channel mean
returnreturn L channel mean, type is int
staticFalse
+

C++ defination code:

+ +
int l_mean()
+
+

l_median

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget L channel median
returnreturn L channel median, type is int
staticFalse
+

C++ defination code:

+ +
int l_median()
+
+

l_mode

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget L channel mode
returnreturn L channel mode, type is int
staticFalse
+

C++ defination code:

+ +
int l_mode()
+
+

l_std_dev

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget L channel std_dev
returnreturn L channel std_dev, type is int
staticFalse
+

C++ defination code:

+ +
int l_std_dev()
+
+

l_min

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget L channel min
returnreturn L channel min, type is int
staticFalse
+

C++ defination code:

+ +
int l_min()
+
+

l_max

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget L channel max
returnreturn L channel max, type is int
staticFalse
+

C++ defination code:

+ +
int l_max()
+
+

l_lq

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget L channel lq
returnreturn L channel lq, type is int
staticFalse
+

C++ defination code:

+ +
int l_lq()
+
+

l_uq

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget L channel uq
returnreturn L channel uq, type is int
staticFalse
+

C++ defination code:

+ +
int l_uq()
+
+

a_mean

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget A channel mean
returnreturn A channel mean, type is int
staticFalse
+

C++ defination code:

+ +
int a_mean()
+
+

a_median

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget A channea median
returnreturn A channel median, type is int
staticFalse
+

C++ defination code:

+ +
int a_median()
+
+

a_mode

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget A channel mode
returnreturn A channel mode, type is int
staticFalse
+

C++ defination code:

+ +
int a_mode()
+
+

a_std_dev

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget A channel std_dev
returnreturn A channel std_dev, type is int
staticFalse
+

C++ defination code:

+ +
int a_std_dev()
+
+

a_min

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget A channel min
returnreturn A channel min, type is int
staticFalse
+

C++ defination code:

+ +
int a_min()
+
+

a_max

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget A channel max
returnreturn A channel max, type is int
staticFalse
+

C++ defination code:

+ +
int a_max()
+
+

a_lq

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget A channel lq
returnreturn A channel lq, type is int
staticFalse
+

C++ defination code:

+ +
int a_lq()
+
+

a_uq

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget A channel uq
returnreturn A channel uq, type is int
staticFalse
+

C++ defination code:

+ +
int a_uq()
+
+

b_mean

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget B channel mean
returnreturn B channel mean, type is int
staticFalse
+

C++ defination code:

+ +
int b_mean()
+
+

b_median

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget B channea median
returnreturn B channel median, type is int
staticFalse
+

C++ defination code:

+ +
int b_median()
+
+

b_mode

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget B channel mode
returnreturn B channel mode, type is int
staticFalse
+

C++ defination code:

+ +
int b_mode()
+
+

b_std_dev

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget B channel std_dev
returnreturn B channel std_dev, type is int
staticFalse
+

C++ defination code:

+ +
int b_std_dev()
+
+

b_min

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget B channel min
returnreturn B channel min, type is int
staticFalse
+

C++ defination code:

+ +
int b_min()
+
+

b_max

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget B channel max
returnreturn B channel max, type is int
staticFalse
+

C++ defination code:

+ +
int b_max()
+
+

b_lq

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget B channel lq
returnreturn B channel lq, type is int
staticFalse
+

C++ defination code:

+ +
int b_lq()
+
+

b_uq

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget B channel uq
returnreturn B channel uq, type is int
staticFalse
+

C++ defination code:

+ +
int b_uq()
+
+

Displacement

+ + + + + + + + + + + + + +
itemdoc
briefDisplacement class
+

C++ defination code:

+ +
class Displacement
+
+

__init__

+ +
def __init__(self, x_translation: float, y_translation: float, rotation: float, scale: float, response: float) -> None
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefDisplacement constructor
paramx_translation: The x_translation of the Displacement
y_translation: The y_translation of the Displacement
rotation: The rotation of the Displacement
scale: The scale of the Displacement
response: The response of the Displacement
staticFalse
+

C++ defination code:

+ +
Displacement(float x_translation, float y_translation, float rotation, float scale, float response)
+
+

__getitem__

+ +
def __getitem__(self, index: int) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSubscript operator
paramindex: array index
returnint&
staticFalse
+

C++ defination code:

+ +
int &__getitem__(int index)
+
+

x_translation

+ +
def x_translation(self) -> float
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget x_translation of Displacement
returnreturn x_translation of the Displacement, type is float
staticFalse
+

C++ defination code:

+ +
float x_translation()
+
+

y_translation

+ +
def y_translation(self) -> float
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget y_translation of Displacement
returnreturn y_translation of the Displacement, type is float
staticFalse
+

C++ defination code:

+ +
float y_translation()
+
+

rotation

+ +
def rotation(self) -> float
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget rotation of Displacement
returnreturn rotation of the Displacement, type is float
staticFalse
+

C++ defination code:

+ +
float rotation()
+
+

scale

+ +
def scale(self) -> float
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget scale of Displacement
returnreturn scale of the Displacement, type is float
staticFalse
+

C++ defination code:

+ +
float scale()
+
+

response

+ +
def response(self) -> float
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget response of Displacement
returnreturn response of the Displacement, type is float
staticFalse
+

C++ defination code:

+ +
float response()
+
+

LBPKeyPoint

+ + + + + + + + + + + + + +
itemdoc
briefLBPKeyPoint class
+

C++ defination code:

+ +
class LBPKeyPoint
+
+

__init__

+ +
def __init__(self, data: list[int]) -> None
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefLBPKeyPoint constructor
paramdata: The data of the LBPKeyPoint
staticFalse
+

C++ defination code:

+ +
LBPKeyPoint(std::valarray<uint8_t> &data)
+
+

KeyPoint

+ + + + + + + + + + + + + +
itemdoc
briefKeyPoint class
+

C++ defination code:

+ +
class KeyPoint
+
+

__init__

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefKeyPoint constructor
paramx: The x of the KeyPoint
y: The y of the KeyPoint
score: The score of the KeyPoint
octave: The octave of the KeyPoint
angle: The angle of the KeyPoint
matched: The matched of the KeyPoint
desc: The desc of the KeyPoint
staticFalse
+

C++ defination code:

+ +
KeyPoint(uint16_t x, uint16_t y, uint16_t score, uint16_t octave, uint16_t angle, uint16_t matched, std::vector<uint8_t> &desc)
+
+

KPTMatch

+ + + + + + + + + + + + + +
itemdoc
briefKPTMatch class
+

C++ defination code:

+ +
class KPTMatch
+
+

__init__

+ +
def __init__(self, cx: int, cy: int, x: int, y: int, w: int, h: int, score: int, theta: int, match: int) -> None
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefKPTMatch constructor
paramcx: The cx of the KPTMatch
cy: The cy of the KPTMatch
x: The x of the KPTMatch
y: The y of the KPTMatch
w: The w of the KPTMatch
h: The h of the KPTMatch
score: The score of the KPTMatch
theta: The theta of the KPTMatch
match: The match of the KPTMatch
staticFalse
+

C++ defination code:

+ +
KPTMatch(int cx, int cy, int x, int y, int w, int h, int score, int theta, int match)
+
+

ORBKeyPoint

+ + + + + + + + + + + + + +
itemdoc
briefORBKeyPoint class
+

C++ defination code:

+ +
class ORBKeyPoint
+
+

__init__

+ +
def __init__(self, data: list[KeyPoint], threshold: int, normalized: bool) -> None
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefORBKeyPoint constructor
paramdata: The data of the ORBKeyPoint
threshold: The threshold of the ORBKeyPoint
normalized: The normalized of the ORBKeyPoint
staticFalse
+

C++ defination code:

+ +
ORBKeyPoint(std::vector<image::KeyPoint> &data, int threshold, bool normalized)
+
+

get_data

+ +
def get_data(self) -> list[KeyPoint]
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget data of ORBKeyPoint
returnreturn data of the ORBKeyPoint, type is std::vector
staticFalse
+

C++ defination code:

+ +
std::vector<image::KeyPoint> get_data()
+
+

HaarCascade

+ + + + + + + + + + + + + +
itemdoc
briefHaarCascade class
+

C++ defination code:

+ +
class HaarCascade
+
+

__init__

+ +
def __init__(self) -> None
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefHaarCascade constructor
paramdata: The data of the HaarCascade
threshold: The threshold of the HaarCascade
normalized: The normalized of the HaarCascade
staticFalse
+

C++ defination code:

+ +
HaarCascade()
+
+

Color

+ + + + + + + + + + + + + +
itemdoc
briefColor class
+

C++ defination code:

+ +
class Color
+
+

__init__

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefColor constructor
paramalpha: alpha channel, value range: 0 ~ 1
staticFalse
+

C++ defination code:

+ +
Color(uint8_t ch1, uint8_t ch2 = 0, uint8_t ch3 = 0, float alpha = 0, image::Format format = image::FMT_GRAYSCALE)
+
+

r

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefColor red channel
staticFalse
readonlyFalse
+

C++ defination code:

+ +
uint8_t r
+
+

g

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefColor green channel
staticFalse
readonlyFalse
+

C++ defination code:

+ +
uint8_t g
+
+

b

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefColor blue channel
staticFalse
readonlyFalse
+

C++ defination code:

+ +
uint8_t b
+
+

alpha

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefColor alpha channel, value from 0.0 to 1.0, float value
staticFalse
readonlyFalse
+

C++ defination code:

+ +
float alpha
+
+

gray

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefColor gray channel
staticFalse
readonlyFalse
+

C++ defination code:

+ +
uint8_t gray
+
+

format

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefColor format
staticFalse
readonlyFalse
+

C++ defination code:

+ +
image::Format format
+
+

hex

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet color's hex value
staticFalse
+

C++ defination code:

+ +
uint32_t hex()
+
+

from_rgb

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefCreate Color object from RGB channels
staticTrue
+

C++ defination code:

+ +
static image::Color from_rgb(uint8_t r, uint8_t g, uint8_t b)
+
+

from_bgr

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefCreate Color object from BGR channels
staticTrue
+

C++ defination code:

+ +
static image::Color from_bgr(uint8_t b, uint8_t g, uint8_t r)
+
+

from_gray

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefCreate Color object from gray channel
staticTrue
+

C++ defination code:

+ +
static image::Color from_gray(uint8_t gray)
+
+

from_rgba

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefCreate Color object from RGBA channels
paramalpha: alpha channel, float value, value range: 0 ~ 1
staticTrue
+

C++ defination code:

+ +
static image::Color from_rgba(uint8_t r, uint8_t g, uint8_t b, float alpha)
+
+

from_bgra

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefCreate Color object from BGRA channels
paramalpha: alpha channel, float value, value range: 0 ~ 1
staticTrue
+

C++ defination code:

+ +
static image::Color from_bgra(uint8_t b, uint8_t g, uint8_t r, float alpha)
+
+

from_hex

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefCreate Color object from hex value
paramhex: hex value, e.g. 0x0000FF00, lower address if first channel
format: color format, @see image::Format
staticTrue
+

C++ defination code:

+ +
static image::Color from_hex(uint32_t hex, image::Format &format)
+
+

to_format

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefConvert Color format
paramformat: format want to convert to, @see image::Format, only support RGB888, BGR888, RGBA8888, BGRA8888, GRAYSCALE.
staticFalse
+

C++ defination code:

+ +
void to_format(const image::Format &format)
+
+

to_format2

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefConvert color format and return a new Color object
paramformat: format want to convert to, @see image::Format, only support RGB888, BGR888, RGBA8888, BGRA8888, GRAYSCALE.
returnnew Color object, you need to delete it manually in C++.
staticFalse
+

C++ defination code:

+ +
image::Color *to_format2(const image::Format &format)
+
+

Image

+ + + + + + + + + + + + + +
itemdoc
briefImage class
+

C++ defination code:

+ +
class Image
+
+

__init__

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefImage constructor
paramwidth: image width, should > 0
height: image height, should > 0
format: image format @see image::Format
staticFalse
+

C++ defination code:

+ +
Image(int width, int height, image::Format format = image::Format::FMT_RGB888)
+
+

format

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet image's format
seeimage.Format
staticFalse
+

C++ defination code:

+ +
image::Format format()
+
+

size

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet image's size, [width, height]
staticFalse
+

C++ defination code:

+ +
image::Size size()
+
+

data_size

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet image's data size
staticFalse
+

C++ defination code:

+ +
int data_size()
+
+

width

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet image's width
staticFalse
+

C++ defination code:

+ +
int width()
+
+

height

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet image's height
staticFalse
+

C++ defination code:

+ +
int height()
+
+

data

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet image's data pointer.\nIn MaixPy is capsule object.
staticFalse
+

C++ defination code:

+ +
void *data()
+
+

__str__

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefTo string method
staticFalse
+

C++ defination code:

+ +
std::string __str__()
+
+

to_str

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefTo string method
staticFalse
+

C++ defination code:

+ +
std::string to_str()
+
+

get_pixel

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet pixel of image
paramx: pixel's coordinate x. x must less than image's width
y: pixel's coordinate y. y must less than image's height
rgbtuple: switch return value method. rgbtuple decides whether to split the return or not. default is false.
returnpixel value,
According to image format and rgbtuple, return different value:
format is FMT_RGB888, rgbtuple is true, return [R, G, B]; rgbtuple is false, return [RGB]
foramt is FMT_BGR888, rgbtuple is true, return [B, G, R]; rgbtuple is false, return [BGR]
format is FMT_GRAYSCALE, return [GRAY];
staticFalse
+

C++ defination code:

+ +
std::vector<int> get_pixel(int x, int y, bool rgbtuple = false)
+
+

set_pixel

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSet pixel of image
paramx: pixel's coordinate x. x must less than image's width
y: pixel's coordinate y. y must less than image's height
pixel: pixel value, according to image format and size of pixel, has different operation:
format is FMT_RGB888, pixel size must be 1 or 3, if size is 1, will split pixel[0] to [R, G, B]; if size is 3, will use pixel directly
format is FMT_BGR888, pixel size must be 1 or 3, if size is 1, will split pixel[0] to [B, G, R]; if size is 3, will use pixel directly
format is FMT_GRAYSCALE, pixel size must be 1, will use pixel directly
returnerror code, Err::ERR_NONE is ok, other is error
staticFalse
+

C++ defination code:

+ +
err::Err set_pixel(int x, int y, std::vector<int> pixel)
+
+

to_tensor

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefConvert Image object to tensor::Tensor object
paramchw: if true, the shape of tensor is [C, H, W], else [H, W, C]
copy: if true, will alloc memory for tensor data, else will use the memory of Image object
returntensor::Tensor object pointer, an allocated tensor object
staticFalse
+

C++ defination code:

+ +
tensor::Tensor *to_tensor(bool chw = false, bool copy = true)
+
+

to_bytes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet image's data and convert to array bytes
paramcopy: if true, will alloc memory and copy data to new buffer,
else will use the memory of Image object, delete bytes object will not affect Image object,
but delete Image object will make bytes object invalid, it may cause program crash !!!!
So use this param carefully.
returnimage's data bytes, need be delete by caller in C++.
staticFalse
+

C++ defination code:

+ +
Bytes *to_bytes(bool copy = true)
+
+

to_format

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefConvert image to specific format
paramformat: format want to convert to, @see image::Format, only support RGB888, BGR888, RGBA8888, BGRA8888, GRAYSCALE, JPEG.
returnnew image object. Need be delete by caller in C++.
throwerr.Exception, if two images' format not support, or already the format, will raise exception
staticFalse
+

C++ defination code:

+ +
image::Image *to_format(const image::Format &format)
+
+

to_jpeg

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefConvert image to jpeg
paramquality: the quality of jpg, default is 95. range is (50, 100].
returnnew image object. Need be delete by caller in C++.
throwerr.Exception, if two images' format not support, or already the format, will raise exception
staticFalse
+

C++ defination code:

+ +
image::Image *to_jpeg(int quality = 95)
+
+

draw_image

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefDraw image on this image
paramx: left top corner of image point's coordinate x
y: left top corner of image point's coordinate y
img: image object to draw, the caller's channel must <= the args' channel,
e.g. caller is RGB888, args is RGBA8888, will throw exception, but caller is RGBA8888, args is RGB888 or RGBA8888 is ok
returnthis image object self
staticFalse
+

C++ defination code:

+ +
image::Image *draw_image(int x, int y, image::Image &img)
+
+

draw_rect

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefFill rectangle color to image
paramx: left top corner of rectangle point's coordinate x
y: left top corner of rectangle point's coordinate y
w: rectangle width
h: rectangle height
color: rectangle color
thickness: rectangle thickness(line width), by default(value is 1), -1 means fill rectangle
returnthis image object self
staticFalse
+

C++ defination code:

+ +
image::Image *draw_rect(int x, int y, int w, int h, const image::Color &color, int thickness = 1)
+
+

draw_line

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefDraw line on image
paramx1: start point's coordinate x
y1: start point's coordinate y
x2: end point's coordinate x
y2: end point's coordinate y
color: line color @see image::Color
thickness: line thickness(line width), by default(value is 1)
returnthis image object self
staticFalse
+

C++ defination code:

+ +
image::Image *draw_line(int x1, int y1, int x2, int y2, const image::Color &color, int thickness = 1)
+
+

draw_circle

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefDraw circle on image
paramx: circle center point's coordinate x
y: circle center point's coordinate y
radius: circle radius
color: circle color @see image::Color
thickness: circle thickness(line width), by default(value is 1), -1 means fill circle
returnthis image object self
staticFalse
+

C++ defination code:

+ +
image::Image *draw_circle(int x, int y, int radius, const image::Color &color, int thickness = 1)
+
+

draw_ellipse

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefDraw ellipse on image
paramx: ellipse center point's coordinate x
y: ellipse center point's coordinate y
a: ellipse major axis length
b: ellipse minor axis length
angle: ellipse rotation angle
start_angle: ellipse start angle
end_angle: ellipse end angle
color: ellipse color @see image::Color
thickness: ellipse thickness(line width), by default(value is 1), -1 means fill ellipse
returnthis image object self
staticFalse
+

C++ defination code:

+ +
image::Image *draw_ellipse(int x, int y, int a, int b, float angle, float start_angle, float end_angle, const image::Color &color, int thickness = 1)
+
+

draw_string

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefDraw text on image
paramx: text left top point's coordinate x
y: text left top point's coordinate y
string: text content
color: text color @see image::Color, default is white
scale: font scale, by default(value is 1)
thickness: text thickness(line width), if negative, the glyph is filled, by default(value is -1)
wrap: if true, will auto wrap text to next line if text width > image width, by default(value is true)
returnthis image object self
staticFalse
+

C++ defination code:

+ +
image::Image *draw_string(int x, int y, const std::string &textstring, const image::Color &color = image::COLOR_WHITE, float scale = 1, int thickness = -1,
+                                bool wrap = true, int wrap_space = 4, const std::string &font = "")
+
+

draw_cross

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefDraw cross on image
paramx: cross center point's coordinate x
y: cross center point's coordinate y
color: cross color @see image::Color
size: how long the lines of the cross extend, by default(value is 5). So the line length is 2 * size + thickness
thickness: cross thickness(line width), by default(value is 1)
staticFalse
+

C++ defination code:

+ +
image::Image *draw_cross(int x, int y, const image::Color &color, int size = 5, int thickness = 1)
+
+

draw_arrow

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefDraw arrow on image
paramx0: start coordinate of the arrow x0
y0: start coordinate of the arrow y0
x1: end coordinate of the arrow x1
y1: end coordinate of the arrow y1
color: cross color @see image::Color
thickness: cross thickness(line width), by default(value is 1)
returnthis image object self
staticFalse
+

C++ defination code:

+ +
image::Image *draw_arrow(int x0, int y0, int x1, int y1, const image::Color &color, int thickness = 1)
+
+

draw_edges

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefDraw edges on image
paramcorners: edges, [[x0, y0], [x1, y1], [x2, y2], [x3, y3]]
color: edges color @see image::Color
size: the circle of radius size. TODO: support in the feature
thickness: edges thickness(line width), by default(value is 1)
fill: if true, will fill edges, by default(value is false)
returnthis image object self
staticFalse
+

C++ defination code:

+ +
image::Image *draw_edges(std::vector<std::vector<int>> corners, const image::Color &color, int size = 0, int thickness = 1, bool fill = false)
+
+

draw_keypoints

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefDraw keypoints on image
paramkeypoints: keypoints, [x, y, rotation_andle_in_degrees], TODO: rotation_andle_in_degrees support in the feature
color: keypoints color @see image::Color
size: size of keypoints
thickness: keypoints thickness(line width), by default(value is 1)
fill: if true, will fill keypoints, by default(value is false)
returnthis image object self
staticFalse
+

C++ defination code:

+ +
image::Image *draw_keypoints(std::vector<int> keypoints, const image::Color &color, int size = 10, int thickness = 1, bool fill = false)
+
+

resize

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefResize image, will create a new resized image object
paramwidth: new width, if value is -1, will use height to calculate aspect ratio
height: new height, if value is -1, will use width to calculate aspect ratio
object_fit: fill, contain, cover, by default is fill
method: resize method, by default is bilinear
returnAlways return a new resized image object even size not change, So in C++ you should take care of the return value to avoid memory leak.
And it's better to judge whether the size has changed before calling this function to make the program more efficient.
e.g.
if img->width() != width
img->height() != height:
img = img->resize(width, height);
staticFalse
+

C++ defination code:

+ +
image::Image *resize(int width, int height, image::Fit object_fit = image::Fit::FIT_FILL, image::ResizeMethod method = image::ResizeMethod::NEAREST)
+
+

affine

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefAffine transform image, will create a new transformed image object
paramsrc_points: three source points, [x1, y1, x2, y2, x3, y3]
dst_points: three destination points, [x1, y1, x2, y2, x3, y3]
width: new width, if value is -1, will use height to calculate aspect ratio
height: new height, if value is -1, will use width to calculate aspect ratio
method: resize method, by default is bilinear
returnnew transformed image object
staticFalse
+

C++ defination code:

+ +
image::Image *affine(std::vector<int> src_points, std::vector<int> dst_points, int width = -1, int height = -1, image::ResizeMethod method = image::ResizeMethod::BILINEAR)
+
+

copy

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefCopy image, will create a new copied image object
returnnew copied image object
staticFalse
+

C++ defination code:

+ +
image::Image *copy()
+
+

crop

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefCrop image, will create a new cropped image object
paramx: left top corner of crop rectangle point's coordinate x
y: left top corner of crop rectangle point's coordinate y
w: crop rectangle width
h: crop rectangle height
returnnew cropped image object
staticFalse
+

C++ defination code:

+ +
image::Image *crop(int x, int y, int w, int h)
+
+

rotate

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefRotate image, will create a new rotated image object
paramangle: anti-clock wise rotate angle, if angle is 90 or 270, and width or height is -1, will swap width and height, or will throw exception
width: new width, if value is -1, will use height to calculate aspect ratio
height: new height, if value is -1, will use width to calculate aspect ratio
method: resize method, by default is bilinear
returnnew rotated image object
staticFalse
+

C++ defination code:

+ +
image::Image *rotate(float angle, int width = -1, int height = -1, image::ResizeMethod method = image::ResizeMethod::BILINEAR)
+
+

mean_pool

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefFinds the mean of x_div * y_div squares in the image and returns the modified image composed of the mean of each square.
paramx_div: The width of the squares.
y_div: The height of the squares.
copy: Select whether to return a new image or modify the original image. default is false.
If true, returns a new image composed of the mean of each square; If false, returns the modified image composed of the mean of each square.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *mean_pool(int x_div, int y_div, bool copy = false)
+
+

midpoint_pool

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefFinds the midpoint of x_div * y_div squares in the image and returns the modified image composed of the mean of each square.
paramx_div: The width of the squares.
y_div: The height of the squares.
bias: The bias of the midpoint. default is 0.5.
midpoint value is equal to (max * bias + min * (1 - bias))
copy: Select whether to return a new image or modify the original image. default is false.
If true, returns a new image composed of the midpoint of each square; If false, returns the modified image composed of the midpoint of each square.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *midpoint_pool(int x_div, int y_div, double bias = 0.5, bool copy = false)
+
+

compress

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefJPEG compresses the image in place, the same as to_jpeg functioin, it's recommend to use to_jpeg instead.
paramquality: The quality of the compressed image. default is 95.
returnReturns the compressed JPEG image
staticFalse
+

C++ defination code:

+ +
image::Image *compress(int quality = 95)
+
+

clear

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSets all pixels in the image to zero
parammask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *clear(image::Image *mask = nullptr)
+
+

mask_rectange

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefZeros a rectangular part of the image. If no arguments are supplied this method zeros the center of the image.
paramx: The x coordinate of the top left corner of the rectangle.
y: The y coordinate of the top left corner of the rectangle.
w: The width of the rectangle.
h: The height of the rectangle.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *mask_rectange(int x = -1, int y = -1, int w = -1, int h = -1)
+
+

mask_circle

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefZeros a circular part of the image. If no arguments are supplied this method zeros the center of the image.
paramx: The x coordinate of the center of the circle.
y: The y coordinate of the center of the circle.
radius: The radius of the circle.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *mask_circle(int x = -1, int y = -1, int radius = -1)
+
+

mask_ellipse

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefZeros a ellipse part of the image. If no arguments are supplied this method zeros the center of the image.
paramx: The x coordinate of the center of the ellipse.
y: The y coordinate of the center of the ellipse.
radius_x: The radius of the ellipse in the x direction.
radius_y: The radius of the ellipse in the y direction.
rotation_angle_in_degrees: The rotation angle of the ellipse in degrees.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *mask_ellipse(int x = -1, int y = -1, int radius_x = -1, int radius_y = -1, float rotation_angle_in_degrees = 0)
+
+

binary

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSets all pixels in the image to black or white depending on if the pixel is inside of a threshold in the threshold list thresholds or not.
paramthresholds: You can define multiple thresholds.
For GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.
For RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.
Where the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.
invert: If true, the thresholds will be inverted before the operation. default is false.
zero: If zero is true, the image will be set the pixels within the threshold to 0, other pixels remain unchanged. If zero is false, the image will be set to black or white. default is false.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
to_bitmap: If true, the image will be converted to a bitmap image before thresholding. default is false. TODO: support in the feature
copy: Select whether to return a new image or modify the original image. default is false.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *binary(std::vector<std::vector<int>> thresholds = std::vector<std::vector<int>>(), bool invert = false, bool zero = false, image::Image *mask = nullptr, bool to_bitmap = false, bool copy = false)
+
+

invert

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefInverts the image in place.
returnReturns the image after the operation is completed
staticFalse
+

C++ defination code:

+ +
image::Image *invert()
+
+

b_and

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefPerforms a bitwise and operation between the image and the other image.
paramother: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *b_and(image::Image *other, image::Image *mask = nullptr)
+
+

b_nand

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefPerforms a bitwise nand operation between the image and the other image.
paramother: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *b_nand(image::Image *other, image::Image *mask = nullptr)
+
+

b_or

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefPerforms a bitwise or operation between the image and the other image.
paramother: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *b_or(image::Image *other, image::Image *mask = nullptr)
+
+

b_nor

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefPerforms a bitwise nor operation between the image and the other image.
paramother: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *b_nor(image::Image *other, image::Image *mask = nullptr)
+
+

b_xor

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefPerforms a bitwise xor operation between the image and the other image.
paramother: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *b_xor(image::Image *other, image::Image *mask = nullptr)
+
+

b_xnor

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefPerforms a bitwise xnor operation between the image and the other image.
paramother: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *b_xnor(image::Image *other, image::Image *mask = nullptr)
+
+

awb

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefPerforms an auto white balance operation on the image. TODO: support in the feature
parammax: if True uses the white-patch algorithm instead. default is false.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *awb(bool max = false)
+
+

ccm

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefMultiples the passed (3x3) or (4x3) floating-point color-correction-matrix with the image.\nnote: Grayscale format is not support.
parammatrix: The color correction matrix to use. 3x3 or 4x3 matrix.
Weights may either be positive or negative, and the sum of each column in the 3x3 matrix should generally be 1.
example:
{
1, 0, 0,
0, 1, 0,
0, 0, 1,
}
Where the last row of the 4x3 matrix is an offset per color channel. If you add an offset you may wish to make the
weights sum to less than 1 to account for the offset.
example:
{
1, 0, 0,
0, 1, 0,
0, 0, 1,
0, 0, 0,
}
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *ccm(std::vector<float> &matrix)
+
+

gamma

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefQuickly changes the image gamma, contrast, and brightness. Create a array whose size is usually 255,\nand use the parameters gamma, contrast, and brightness to calculate the value of the array, and then map the\nimage pixel value through the value of the array.\nThe calculation method for array is: array[array_idx] = (powf((array_idx / 255.0), (1 / gamma)) * contrast + brightness) * scale,\npowf is a function used to calculate floating point power.\narray is the array used for mapping.\narray_idx is the index of the array, the maximum value is determined according to the image format, usually 255.\nscale is a constant, the value is determined by the image format, usually 255.\nMapping method:\nAssume that a pixel value in the image is 128, then map the pixel value to the value of array[128]\nUsers can adjust the value of the array through the gamma, contrast, and brightness parameters.
paramgamma: The contrast gamma greater than 1.0 makes the image darker in a non-linear manner while less than 1.0 makes the image brighter. default is 1.0.
contrast: The contrast value greater than 1.0 makes the image brighter in a linear manner while less than 1.0 makes the image darker. default is 1.0.
brightness: The brightness value greater than 0.0 makes the image brighter in a constant manner while less than 0.0 makes the image darker. default is 0.0.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *gamma(double gamma = 1.0, double contrast = 1.0, double brightness = 0.0)
+
+

gamma_corr

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefAlias for Image.gamma.
paramgamma: The contrast gamma greater than 1.0 makes the image darker in a non-linear manner while less than 1.0 makes the image brighter. default is 1.0.
contrast: The contrast value greater than 1.0 makes the image brighter in a linear manner while less than 1.0 makes the image darker. default is 1.0.
brightness: The brightness value greater than 0.0 makes the image brighter in a constant manner while less than 0.0 makes the image darker. default is 0.0.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *gamma_corr(double gamma, double contrast = 1.0, double brightness = 0.0)
+
+

negate

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefFlips (numerically inverts) all pixels values in an image
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *negate()
+
+

replace

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefReplaces all pixels in the image with the corresponding pixels in the other image.
paramother: The other image should be an image and should be the same size as the image being operated on.
hmirror: If true, the image will be horizontally mirrored before the operation. default is false.
vflip: If true, the image will be vertically flipped before the operation. default is false.
transpose: If true, the image can be used to rotate 90 degrees or 270 degrees.
hmirror = false, vflip = false, transpose = false, the image will not be rotated.
hmirror = false, vflip = true, transpose = true, the image will be rotated 90 degrees.
hmirror = true, vflip = true, transpose = false, the image will be rotated 180 degrees.
hmirror = true, vflip = false, transpose = true, the image will be rotated 270 degrees.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *replace(image::Image *other = nullptr, bool hmirror = false, bool vflip = false, bool transpose = false, image::Image *mask = nullptr)
+
+

set

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefAlias for Image::replace.
paramother: The other image should be an image and should be the same size as the image being operated on.
hmirror: If true, the image will be horizontally mirrored before the operation. default is false.
vflip: If true, the image will be vertically flipped before the operation. default is false.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *set(image::Image *other, bool hmirror = false, bool vflip = false, bool transpose = false, image::Image *mask = nullptr)
+
+

add

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefAdds the other image to the image.
paramother: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *add(image::Image *other, image::Image *mask = nullptr)
+
+

sub

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSubtracts the other image from the image.
paramother: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
reverse: If true, the image will be reversed before the operation. default is false.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *sub(image::Image *other, bool reverse = false, image::Image *mask = nullptr)
+
+

mul

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefMultiplies the image by the other image.\nNote: This method is meant for image blending and cannot multiply the pixels in the image by a scalar like 2.
paramother: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
invert: If true, the image will be change the multiplication operation from ab to 1/((1/a)(1/b)).
In particular, this lightens the image instead of darkening it (e.g. multiply versus burn operations). default is false.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *mul(image::Image *other, bool invert = false, image::Image *mask = nullptr)
+
+

div

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefDivides the image by the other image.\nThis method is meant for image blending and cannot divide the pixels in the image by a scalar like 2.
paramother: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
invert: If true, the image will be change the division direction from a/b to b/a. default is false.
mod: If true, the image will be change the division operation to the modulus operation. default is false.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *div(image::Image *other, bool invert = false, bool mod = false, image::Image *mask = nullptr)
+
+

min

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefCaculate the minimum of each pixel in the image and the other image.
paramother: The other image should be an image and should be the same size as the image being operated on.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *min(image::Image *other, image::Image *mask = nullptr)
+
+

max

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefCaculate the maximum of each pixel in the image and the other image.
paramother: The other image should be an image and should be the same size as the image being operated on.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *max(image::Image *other, image::Image *mask = nullptr)
+
+

difference

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefCaculate the absolute value of the difference between each pixel in the image and the other image.
paramother: The other image should be an image and should be the same size as the image being operated on.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *difference(image::Image *other, image::Image *mask = nullptr)
+
+

blend

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefBlends the image with the other image.\nres = alpha * this_img / 256 + (256 - alpha) * other_img / 256
paramother: The other image should be an image and should be the same size as the image being operated on.
alpha: The alpha value of the blend, the value range is [0, 256],default is 128.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *blend(image::Image *other, int alpha = 128, image::Image *mask = nullptr)
+
+

histeq

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefRuns the histogram equalization algorithm on the image.
paramadaptive: If true, an adaptive histogram equalization method will be run on the image instead which as generally better results than non-adaptive histogram qualization but a longer run time. default is false.
clip_limit: Provides a way to limit the contrast of the adaptive histogram qualization. Use a small value for this, like 10, to produce good histogram equalized contrast limited images. default is -1.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *histeq(bool adaptive = false, int clip_limit = -1, image::Image *mask = nullptr)
+
+

mean

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefStandard mean blurring filter using a box filter.\nThe parameters offset and invert are valid when threshold is True.
paramsize: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
threshold: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel’s brightness in relation to the brightness of the kernel of pixels around them.
default is false.
offset: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.
invert: If true, the image will be inverted before the operation. default is false.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *mean(int size, bool threshold = false, int offset = 0, bool invert = false, image::Image *mask = nullptr)
+
+

median

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefRuns the median filter on the image. The median filter is the best filter for smoothing surfaces while preserving edges but it is very slow.
paramsize: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
percentile: This parameter controls the percentile of the value used in the kernel. You can set this to 0 for a min filter, 0.25 for a lower quartile filter, 0.75 for an upper quartile filter, and 1.0 for a max filter. default is 0.5.
threshold: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel’s brightness in relation to the brightness of the kernel of pixels around them.
default is false.
offset: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.
invert: If true, the image will be inverted before the operation. default is false.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *median(int size, double percentile = 0.5, bool threshold = false, int offset = 0, bool invert = false, image::Image *mask = nullptr)
+
+

mode

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefRuns the mode filter on the image by replacing each pixel with the mode of their neighbors.
paramsize: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
threshold: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel’s brightness in relation to the brightness of the kernel of pixels around them.
default is false.
offset: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.
invert: If true, the image will be inverted before the operation. default is false.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *mode(int size, bool threshold = false, int offset = 0, bool invert = false, image::Image *mask = nullptr)
+
+

midpoint

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefRuns the midpoint filter on the image.This filter finds the midpoint (max * bias + min * (1 - bias)) of each pixel neighborhood in the image.
paramsize: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
bias: The bias of the midpoint. default is 0.5.
threshold: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel’s brightness in relation to the brightness of the kernel of pixels around them.
default is false.
offset: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.
invert: If true, the image will be inverted before the operation. default is false.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *midpoint(int size, double bias = 0.5, bool threshold = false, int offset = 0, bool invert = false, image::Image *mask = nullptr)
+
+

morph

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefConvolves the image by a filter kernel. This allows you to do general purpose convolutions on an image.
paramsize: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
kernel: The kernel used for convolution. The kernel should be a list of lists of numbers. The kernel should be the same size as the actual kernel size.
mul: This parameter is used to multiply the convolved pixel results. default is auto.
add: This parameter is the value to be added to each convolution pixel result. default is 0.0.
threshold: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel’s brightness in relation to the brightness of the kernel of pixels around them.
default is false.
offset: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.
invert: If true, the image will be inverted before the operation. default is false.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *morph(int size, std::vector<int> kernel, float mul = -1, float add = 0.0, bool threshold = false, int offset = 0, bool invert = false, image::Image *mask = nullptr)
+
+

gaussian

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefConvolves the image by a smoothing guassian kernel.
paramsize: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
unsharp: If true, this method will perform an unsharp mask operation instead of gaussian filtering operation, this improves the clarity of image edges. default is false.
mul: This parameter is used to multiply the convolved pixel results. default is auto.
add: This parameter is the value to be added to each convolution pixel result. default is 0.0.
threshold: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel’s brightness in relation to the brightness of the kernel of pixels around them.
default is false.
offset: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.
invert: If true, the image will be inverted before the operation. default is false.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *gaussian(int size, bool unsharp = false, float mul = -1, float add = 0.0, bool threshold = false, int offset = 0, bool invert = false, image::Image *mask = nullptr)
+
+

laplacian

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefConvolves the image by a edge detecting laplacian kernel.
paramsize: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
sharpen: If True, this method will sharpen the image instead of an unthresholded edge detection image. Then increase the kernel size to improve image clarity. default is false.
mul: This parameter is used to multiply the convolved pixel results. default is auto.
add: This parameter is the value to be added to each convolution pixel result. default is 0.0.
threshold: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel’s brightness in relation to the brightness of the kernel of pixels around them.
default is false.
offset: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.
invert: If true, the image will be inverted before the operation. default is false.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *laplacian(int size, bool sharpen = false, float mul = -1, float add = 0.0, bool threshold = false, int offset = 0, bool invert = false, image::Image *mask = nullptr)
+
+

bilateral

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefConvolves the image by a bilateral filter.
paramsize: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
color_sigma: Controls how closely colors are matched using the bilateral filter. default is 0.1.
space_sigma: Controls how closely pixels space-wise are blurred with each other. default is 1.
threshold: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel’s brightness in relation to the brightness of the kernel of pixels around them.
default is false.
offset: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.
invert: If true, the image will be inverted before the operation. default is false.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *bilateral(int size, double color_sigma = 0.1, double space_sigma = 1, bool threshold = false, int offset = 0, bool invert = false, image::Image *mask = nullptr)
+
+

linpolar

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefRe-project’s and image from cartessian coordinates to linear polar coordinates.
paramreverse: If true, the image will be reverse polar transformed. default is false.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *linpolar(bool reverse = false)
+
+

logpolar

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefRe-project’s and image from cartessian coordinates to log polar coordinates.
paramreverse: If true, the image will be reverse polar transformed. default is false.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *logpolar(bool reverse = false)
+
+

lens_corr

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefPerforms a lens correction operation on the image. TODO: support in the feature
paramstrength: The strength of the lens correction. default is 1.8.
zoom: The zoom of the lens correction. default is 1.0.
x_corr: The x correction of the lens correction. default is 0.5.
y_corr: The y correction of the lens correction. default is 0.5.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *lens_corr(double strength = 1.8, double zoom = 1.0, double x_corr = 0.5, double y_corr = 0.5)
+
+

rotation_corr

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefPerforms a rotation correction operation on the image. TODO: support in the feature
paramx_rotation: The x rotation of the rotation correction. default is 0.0.
y_rotation: The y rotation of the rotation correction. default is 0.0.
z_rotation: The z rotation of the rotation correction. default is 0.0.
x_translation: The x translation of the rotation correction. default is 0.0.
y_translation: The y translation of the rotation correction. default is 0.0.
zoom: The zoom of the rotation correction. default is 1.0.
fov: The fov of the rotation correction. default is 60.0.
corners: The corners of the rotation correction. default is None.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *rotation_corr(double x_rotation = 0.0, double y_rotation = 0.0, double z_rotation = 0.0, double x_translation = 0.0, double y_translation = 0.0, double zoom = 1.0, double fov = 60.0, std::vector<float> corners = std::vector<float>())
+
+

get_histogram

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGets the histogram of the image.
paramthresholds: You can define multiple thresholds.
For GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.
For RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.
Where the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.
invert: If true, the thresholds will be inverted before the operation. default is false.
roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
bins: The number of bins to use for the histogram.
In GRAYSCALE format, setting range is [2, 256], default is 100.
In rgb888 format, setting range is [2, 100], default is 100.
l_bins: The number of bins to use for the l channel of the histogram. Only valid in RGB888 format.
If an invalid value is set, bins will be used instead. The setting range is [2, 100], default is 100.
a_bins: The number of bins to use for the a channel of the histogram.
Only valid in RGB888 format.The setting range is [2, 256], default is 256.
b_bins: The number of bins to use for the b channel of the histogram.
Only valid in RGB888 format. The setting range is [2, 256], default is 256.
difference: difference may be set to an image object to cause this method to operate on the difference image between the current image and the difference image object.
default is None.
returnReturns the histogram of the image
staticFalse
+

C++ defination code:

+ +
std::map<std::string, std::vector<float>> get_histogram(std::vector<std::vector<int>> thresholds = std::vector<std::vector<int>>(), bool invert = false, std::vector<int> roi = std::vector<int>(), int bins = -1, int l_bins = 100, int a_bins = 256, int b_bins = 256, image::Image *difference = nullptr)
+
+

get_statistics

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGets the statistics of the image. TODO: support in the feature
paramthresholds: You can define multiple thresholds.
For GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.
For RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.
Where the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.
invert: If true, the image will be inverted before the operation. default is false.
roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
bins: The number of bins to use for the statistics. default is -1.
l_bins: The number of bins to use for the l channel of the statistics. default is -1.
a_bins: The number of bins to use for the a channel of the statistics. default is -1.
b_bins: The number of bins to use for the b channel of the statistics. default is -1.
difference: The difference image to use for the statistics. default is None.
returnReturns the statistics of the image
staticFalse
+

C++ defination code:

+ +
image::Statistics get_statistics(std::vector<std::vector<int>> thresholds = std::vector<std::vector<int>>(), bool invert = false, std::vector<int> roi = std::vector<int>(), int bins = -1, int l_bins = -1, int a_bins = -1, int b_bins = -1, image::Image *difference = nullptr)
+
+

get_regression

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGets the regression of the image.
paramthresholds: You can define multiple thresholds.
For GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.
For RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.
Where the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.
invert: If true, the image will be inverted before the operation. default is false.
roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
x_stride: The x stride to use for the regression. default is 2.
y_stride: The y stride to use for the regression. default is 1.
area_threshold: The area threshold to use for the regression. default is 10.
pixels_threshold: The pixels threshold to use for the regression. default is 10.
robust: If true, the regression will be robust. default is false.
returnReturns the regression of the image
staticFalse
+

C++ defination code:

+ +
std::vector<image::Line> get_regression(std::vector<std::vector<int>> thresholds = std::vector<std::vector<int>>(), bool invert = false, std::vector<int> roi = std::vector<int>(), int x_stride = 2, int y_stride = 1, int area_threshold = 10, int pixels_threshold = 10, bool robust = false)
+
+

save

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSave image to file
parampath: file path
quality: image quality, by default(value is 95), support jpeg and png format
returnerror code, err::ERR_NONE is ok, other is error
staticFalse
+

C++ defination code:

+ +
err::Err save(const char *path, int quality = 95)
+
+

flood_fill

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefFlood fills a region of the image starting from location x, y.
paramx: The x coordinate of the seed point.
y: The y coordinate of the seed point.
seed_threshold: The seed_threshold value controls how different any pixel in the fill area may be from the original starting pixel. default is 0.05.
floating_threshold: The floating_threshold value controls how different any pixel in the fill area may be from any neighbor pixels. default is 0.05.
color: The color to fill the region with. default is white.
invert: If true, the image will be inverted before the operation. default is false.
clear_background: If true, the background will be cleared before the operation. default is false.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None. FIXME: the mask image works abnormally
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *flood_fill(int x, int y, float seed_threshold = 0.05, float floating_threshold = 0.05, image::Color color = image::COLOR_WHITE, bool invert = false, bool clear_background = false, image::Image *mask = nullptr)
+
+

erode

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefErodes the image in place.
paramsize: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
threshold: The number of pixels in the kernel that are not 0. If it is less than or equal to the threshold, set the center pixel to black. default is (kernel_size - 1).
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *erode(int size, int threshold = -1, image::Image *mask = nullptr)
+
+

dilate

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefDilates the image in place.
paramsize: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
threshold: The number of pixels in the kernel that are not 0. If it is greater than or equal to the threshold, set the center pixel to white. default is 0.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *dilate(int size, int threshold = 0, image::Image *mask = nullptr)
+
+

open

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefPerforms erosion and dilation on an image in order.
paramsize: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
threshold: As the threshold for erosion and dilation, the actual threshold for erosion is (kernel_size - 1 - threshold), the actual threshold for dialation is threshold. default is 0.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *open(int size, int threshold = 0, image::Image *mask = nullptr)
+
+

close

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefPerforms dilation and erosion on an image in order.
paramsize: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
threshold: As the threshold for erosion and dilation, the actual threshold for erosion is (kernel_size - 1 - threshold), the actual threshold for dialation is threshold. default is 0.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *close(int size, int threshold = 0, image::Image *mask = nullptr)
+
+

top_hat

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefReturns the image difference of the image and Image.open()’ed image.
paramsize: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
threshold: As the threshold for open method. default is 0.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *top_hat(int size, int threshold = 0, image::Image *mask = nullptr)
+
+

black_hat

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefReturns the image difference of the image and Image.close()’ed image.
paramsize: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
threshold: As the threshold for close method. default is 0.
mask: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
Only pixels set in the mask are modified. default is None.
returnReturns the image after the operation is completed.
staticFalse
+

C++ defination code:

+ +
image::Image *black_hat(int size, int threshold = 0, image::Image *mask = nullptr)
+
+

find_blobs

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefFinds all blobs in the image and returns a list of image.Blob class which describe each Blob.\nPlease see the image.Blob object more more information.
paramthresholds: You can define multiple thresholds.
For GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.
For RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.
Where the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.
invert: if true, will invert thresholds before find blobs, default is false
roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
x_stride: x stride is the number of x pixels to skip when doing the hough transform. default is 2
y_stride: y_stride is the number of y pixels to skip when doing the hough transform. default is 1
area_threshold: area threshold, if the blob area is smaller than area_threshold, the blob is not returned, default is 10
pixels_threshold: pixels threshold, if the blob pixels is smaller than area_threshold, the blob is not returned,, default is 10.
when x_stride and y_stride is equal to 1, pixels_threshold is equivalent to area_threshold
merge: if True merges all not filtered out blobs whos bounding rectangles intersect each other. default is false
margin: margin can be used to increase or decrease the size of the bounding rectangles for blobs during the intersection test.
For example, with a margin of 1 blobs whos bounding rectangles are 1 pixel away from each other will be merged. default is 0
x_hist_bins_max: if set to non-zero populates a histogram buffer in each blob object with an x_histogram projection of all columns in the object. This value then sets the number of bins for that projection.
y_hist_bins_max: if set to non-zero populates a histogram buffer in each blob object with an y_histogram projection of all rows in the object. This value then sets the number of bins for that projection.
returnReturn the blob when found blobs, format is (blob1, blob2, ...), you can use blob class methods to do more operations.
staticFalse
+

C++ defination code:

+ +
std::vector<image::Blob> find_blobs(std::vector<std::vector<int>> thresholds = std::vector<std::vector<int>>(), bool invert = false, std::vector<int> roi = std::vector<int>(), int x_stride = 2, int y_stride = 1, int area_threshold = 10, int pixels_threshold = 10, bool merge = false, int margin = 0, int x_hist_bins_max = 0, int y_hist_bins_max = 0)
+
+

find_lines

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefFind lines in image
paramroi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
x_stride: x stride is the number of x pixels to skip when doing the hough transform. default is 2
y_stride: y_stride is the number of y pixels to skip when doing the hough transform. default is 1
threshold: threshold threshold controls what lines are detected from the hough transform. Only lines with a magnitude greater than or equal to threshold are returned.
The right value of threshold for your application is image dependent. default is 1000.
theta_margin: theta_margin controls the merging of detected lines. default is 25.
rho_margin: rho_margin controls the merging of detected lines. default is 25.
returnReturn the line when found lines, format is (line1, line2, ...), you can use line class methods to do more operations
staticFalse
+

C++ defination code:

+ +
std::vector<image::Line> find_lines(std::vector<int> roi = std::vector<int>(), int x_stride = 2, int y_stride = 1, double threshold = 1000, double theta_margin = 25, double rho_margin = 25)
+
+

find_line_segments

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefFinds all line segments in the image.
paramroi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
merge_distance: The maximum distance between two lines to merge them. default is 0.
max_theta_difference: The maximum difference between two lines to merge them. default is 15.
returnReturn the line when found lines, format is (line1, line2, ...), you can use line class methods to do more operations
staticFalse
+

C++ defination code:

+ +
std::vector<image::Line> find_line_segments(std::vector<int> roi = std::vector<int>(), int merge_distance = 0, int max_theta_difference = 15)
+
+

find_circles

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefFind circles in image
paramroi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
x_stride: x stride is the number of x pixels to skip when doing the hough transform. default is 2
y_stride: y_stride is the number of y pixels to skip when doing the hough transform. default is 1
threshold: threshold controls what circles are detected from the hough transform. Only circles with a magnitude greater than or equal to threshold are returned.
The right value of threshold for your application is image dependent.
x_margin: x_margin controls the merging of detected circles. Circles which are x_margin, y_margin, and r_margin pixels apart are merged. default is 10
y_margin: y_margin controls the merging of detected circles. Circles which are x_margin, y_margin, and r_margin pixels apart are merged. default is 10
r_margin: r_margin controls the merging of detected circles. Circles which are x_margin, y_margin, and r_margin pixels apart are merged. default is 10
r_min: r_min controls the minimum circle radius detected. Increase this to speed up the algorithm. default is 2
r_max: r_max controls the maximum circle radius detected. Decrease this to speed up the algorithm. default is min(roi.w / 2, roi.h / 2)
r_step: r_step controls how to step the radius detection by. default is 2.
returnReturn the circle when found circles, format is (circle1, circle2, ...), you can use circle class methods to do more operations
staticFalse
+

C++ defination code:

+ +
std::vector<image::Circle> find_circles(std::vector<int> roi = std::vector<int>(), int x_stride = 2, int y_stride = 1, int threshold = 2000, int x_margin = 10, int y_margin = 10, int r_margin = 10, int r_min = 2, int r_max = -1, int r_step = 2)
+
+

find_rects

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefFinds all rects in the image.
paramroi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
threshold: The threshold to use for the rects. default is 10000.
returnReturns the rects of the image
staticFalse
+

C++ defination code:

+ +
std::vector<image::Rect> find_rects(std::vector<int> roi = std::vector<int>(), int threshold = 10000)
+
+

find_qrcodes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefFinds all qrcodes in the image.
paramroi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
returnReturns the qrcodes of the image
staticFalse
+

C++ defination code:

+ +
std::vector<image::QRCode> find_qrcodes(std::vector<int> roi = std::vector<int>())
+
+

find_apriltags

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefFinds all apriltags in the image.
paramroi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
families: The families to use for the apriltags. default is TAG36H11.
fx: The camera X focal length in pixels, default is -1.
fy: The camera Y focal length in pixels, default is -1.
cx: The camera X center in pixels, default is image.width / 2.
cy: The camera Y center in pixels, default is image.height / 2.
returnReturns the apriltags of the image
staticFalse
+

C++ defination code:

+ +
std::vector<image::AprilTag> find_apriltags(std::vector<int> roi = std::vector<int>(), image::ApriltagFamilies families = image::ApriltagFamilies::TAG36H11, float fx = -1, float fy = -1, int cx = -1, int cy = -1)
+
+

find_datamatrices

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefFinds all datamatrices in the image.
paramroi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
effort: Controls how much time to spend trying to find data matrix matches. default is 200.
returnReturns the datamatrices of the image
staticFalse
+

C++ defination code:

+ +
std::vector<image::DataMatrix> find_datamatrices(std::vector<int> roi = std::vector<int>(), int effort = 200)
+
+

find_barcodes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefFinds all barcodes in the image.
paramroi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
returnReturns the barcodes of the image
staticFalse
+

C++ defination code:

+ +
std::vector<image::BarCode> find_barcodes(std::vector<int> roi = std::vector<int>())
+
+

find_displacement

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefFinds the displacement between the image and the template. TODO: support in the feature\nnote: this method must be used on power-of-2 image sizes
paramtemplate_image: The template image.
roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
template_roi: The region-of-interest rectangle (x, y, w, h) to work in. If not specified, it is equal to the image rectangle.
logpolar: If true, it will instead find rotation and scale changes between the two images. default is false.
returnReturns the displacement of the image
staticFalse
+

C++ defination code:

+ +
image::Displacement find_displacement(image::Image &template_image, std::vector<int> roi = std::vector<int>(), std::vector<int> template_roi = std::vector<int>(), bool logpolar = false)
+
+

find_template

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefFinds the template in the image.
paramtemplate_image: The template image.
threshold: Threshold is floating point number (0.0-1.0) where a higher threshold prevents false positives while lowering the detection rate while a lower threshold does the opposite.
roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image. Only valid in SEARCH_EX mode.
step: The step size to use for the template. default is 2. Only valid in SEARCH_EX mode
search: The search method to use for the template. default is SEARCH_EX.
returnReturns a bounding box tuple (x, y, w, h) for the matching location otherwise None.
staticFalse
+

C++ defination code:

+ +
std::vector<int> find_template(image::Image &template_image, float threshold, std::vector<int> roi = std::vector<int>(), int step = 2, image::TemplateMatch search = image::TemplateMatch::SEARCH_EX)
+
+

find_features

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefFinds the features in the image. TODO: support in the feature
paramcascade: The cascade to use for the features. default is CASCADE_FRONTALFACE_ALT.
threshold: The threshold to use for the features. default is 0.5.
scale: The scale to use for the features. default is 1.5.
roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
returnReturns the features of the image
staticFalse
+

C++ defination code:

+ +
std::vector<int> find_features(int cascade, float threshold = 0.5, float scale = 1.5, std::vector<int> roi = std::vector<int>())
+
+

find_lbp

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefFinds the lbp in the image. TODO: support in the feature.
paramroi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
returnReturns the lbp of the image
staticFalse
+

C++ defination code:

+ +
image::LBPKeyPoint find_lbp(std::vector<int> roi = std::vector<int>())
+
+

find_keypoints

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefFinds the keypoints in the image. TODO: support in the feature.
paramroi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
threshold: The threshold to use for the keypoints. default is 20.
normalized: If true, the image will be normalized before the operation. default is false.
scale_factor: The scale factor to use for the keypoints. default is 1.5.
max_keypoints: The maximum number of keypoints to use for the keypoints. default is 100.
corner_detector: The corner detector to use for the keypoints. default is CORNER_AGAST.
returnReturns the keypoints of the image
staticFalse
+

C++ defination code:

+ +
image::ORBKeyPoint find_keypoints(std::vector<int> roi = std::vector<int>(), int threshold = 20, bool normalized = false, float scale_factor = 1.5, int max_keypoints = 100, image::CornerDetector corner_detector = image::CornerDetector::CORNER_AGAST)
+
+

find_edges

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefFinds the edges in the image.
paramedge_type: The edge type to use for the edges. default is EDGE_CANNY.
roi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
threshold: The threshold to use for the edges. default is 20.
returnReturns the edges of the image
staticFalse
+

C++ defination code:

+ +
image::Image* find_edges(image::EdgeDetector edge_type, std::vector<int> roi = std::vector<int>(), std::vector<int> threshold = std::vector<int>({100, 200}))
+
+

find_hog

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefFinds the hog in the image. TODO: support in the feature
paramroi: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
default is None, means whole image.
size: The size to use for the hog. default is 8.
returnReturns the hog of the image
staticFalse
+

C++ defination code:

+ +
image::Image* find_hog(std::vector<int> roi = std::vector<int>(), int size = 8)
+
+

match_lbp_descriptor

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefMatches the lbp descriptor of the image. TODO: support in the feature
paramdesc1: The descriptor to use for the match.
desc2: The descriptor to use for the match.
returnReturns the match of the image
staticFalse
+

C++ defination code:

+ +
int match_lbp_descriptor(image::LBPKeyPoint &desc1, image::LBPKeyPoint &desc2)
+
+

match_orb_descriptor

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefMatches the orb descriptor of the image. TODO: support in the feature
paramdesc1: The descriptor to use for the match.
desc2: The descriptor to use for the match.
threshold: The threshold to use for the match. default is 95.
filter_outliers: If true, the image will be filter_outliers before the operation. default is false.
returnReturns the match of the image
staticFalse
+

C++ defination code:

+ +
image::KPTMatch match_orb_descriptor(image::ORBKeyPoint &desc1, image::ORBKeyPoint &desc2, int threshold = 95, bool filter_outliers = false)
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/maix/network.html b/maixpy/api/maix/network.html new file mode 100644 index 00000000..0baae3de --- /dev/null +++ b/maixpy/api/maix/network.html @@ -0,0 +1,342 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix.network - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix.network

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.network module

+
+

You can use maix.network to access this module with MaixPy
+This module is generated from MaixCDK

+
+

Module

+ + + + + + + + + + + + + +
modulebrief
wifimaix.network.wifi module
+

Enum

+

Variable

+

Function

+

have_network

+ +
def have_network() -> bool
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefReturn if device have network(WiFi/Eth etc.)
returnTrue if have network, else False.
+

C++ defination code:

+ +
bool have_network()
+
+

Class

+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/maix/network/wifi.html b/maixpy/api/maix/network/wifi.html new file mode 100644 index 00000000..f602dba9 --- /dev/null +++ b/maixpy/api/maix/network/wifi.html @@ -0,0 +1,893 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix.network.wifi - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix.network.wifi

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.network.wifi module

+
+

You can use maix.network.wifi to access this module with MaixPy
+This module is generated from MaixCDK

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

list_devices

+ +
def list_devices() -> list[str]
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefList WiFi interfaces
returnWiFi interface list, string type
+

C++ defination code:

+ +
std::vector<std::string> list_devices()
+
+

Class

+

AP_Info

+ + + + + + + + + + + + + +
itemdoc
briefWiFi AP info
+

C++ defination code:

+ +
class AP_Info
+
+

ssid

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefWiFi AP info SSID
staticFalse
readonlyFalse
+

C++ defination code:

+ +
std::vector<uint8_t> ssid
+
+

bssid

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefWiFi AP info BSSID
staticFalse
readonlyFalse
+

C++ defination code:

+ +
std::string bssid
+
+

security

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefWiFi AP info security
staticFalse
readonlyFalse
+

C++ defination code:

+ +
std::string security
+
+

channel

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefWiFi AP info channel
staticFalse
readonlyFalse
+

C++ defination code:

+ +
int channel
+
+

frequency

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefWiFi AP info frequency
staticFalse
readonlyFalse
+

C++ defination code:

+ +
int frequency
+
+

rssi

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefWiFi AP info rssi
staticFalse
readonlyFalse
+

C++ defination code:

+ +
int rssi
+
+

ssid_str

+ +
def ssid_str(self) -> str
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefWiFi AP info ssid_str
staticFalse
+

C++ defination code:

+ +
std::string ssid_str()
+
+

Wifi

+ + + + + + + + + + + + + +
itemdoc
briefWifi class
+

C++ defination code:

+ +
class Wifi
+
+

__init__

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefWifi class
paramiface: wifi interface name, default is wlan0
staticFalse
+

C++ defination code:

+ +
Wifi(std::string iface = "wlan0")
+
+

get_ip

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet current WiFi ip
returnip, string type, if network not connected, will return empty string.
staticFalse
+

C++ defination code:

+ +
std::string get_ip()
+
+

get_mac

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet current WiFi MAC address
returnip, string type.
staticFalse
+

C++ defination code:

+ +
std::string get_mac()
+
+

get_gateway

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet current WiFi ip
returnip, string type, if network not connected, will return empty string.
staticFalse
+

C++ defination code:

+ +
std::string get_gateway()
+
+

start_scan

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefWiFi start scan AP info around in background.
returnIf success, return err.Err.ERR_NONE, else means failed.
staticFalse
+

C++ defination code:

+ +
err::Err start_scan()
+
+

get_scan_result

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet WiFi scan AP info.
returnwifi.AP_Info list.
staticFalse
+

C++ defination code:

+ +
std::vector<network::wifi::AP_Info> get_scan_result()
+
+

stop_scan

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefStop WiFi scan AP info.
staticFalse
+

C++ defination code:

+ +
void stop_scan()
+
+

connect

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefConnect to WiFi AP.
paramssid: SSID of AP
password: password of AP, if no password, leave it empty.
wait: wait for got IP or failed or timeout.
timeout: connect timeout internal, unit second.
returnIf success, return err.Err.ERR_NONE, else means failed.
staticFalse
+

C++ defination code:

+ +
err::Err connect(const std::string &ssid, const std::string &password, bool wait = true, int timeout = 60)
+
+

disconnect

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefDisconnect from WiFi AP.
returnIf success, return err.Err.ERR_NONE, else means failed.
staticFalse
+

C++ defination code:

+ +
err::Err disconnect()
+
+

is_connected

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSee if WiFi is connected to AP.
returnIf connected return true, else false.
staticFalse
+

C++ defination code:

+ +
bool is_connected()
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/maix/nn.html b/maixpy/api/maix/nn.html new file mode 100644 index 00000000..c9bb7e37 --- /dev/null +++ b/maixpy/api/maix/nn.html @@ -0,0 +1,2113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix.nn - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix.nn

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.nn module

+
+

You can use maix.nn to access this module with MaixPy
+This module is generated from MaixCDK

+
+

Module

+ + + + + + + + + + + + + +
modulebrief
Fmaix.nn.F module
+

Enum

+

Variable

+

Function

+

Class

+

Object

+ + + + + + + + + + + + + +
itemdoc
briefObject for detect result
+

C++ defination code:

+ +
class Object
+
+

__init__

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefConstructor of Object for detect result
paramx: left top x
y: left top y
w: width
h: height
class_id: class id
score: score
staticFalse
+

C++ defination code:

+ +
Object(int x = 0, int y = 0, int w = 0, int h = 0, int class_id = 0, float score = 0)
+
+

__str__

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefObject info to string
returnObject info string
staticFalse
+

C++ defination code:

+ +
std::string to_str()
+
+

x

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefObject left top coordinate x
staticFalse
readonlyFalse
+

C++ defination code:

+ +
int x
+
+

y

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefObject left top coordinate y
staticFalse
readonlyFalse
+

C++ defination code:

+ +
int y
+
+

w

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefObject width
staticFalse
readonlyFalse
+

C++ defination code:

+ +
int w
+
+

h

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefObject height
staticFalse
readonlyFalse
+

C++ defination code:

+ +
int h
+
+

class_id

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefObject class id
staticFalse
readonlyFalse
+

C++ defination code:

+ +
int class_id
+
+

score

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefObject score
staticFalse
readonlyFalse
+

C++ defination code:

+ +
float score
+
+

YOLOv5

+ + + + + + + + + + + + + +
itemdoc
briefYOLOv5 class
+

C++ defination code:

+ +
class YOLOv5
+
+

__init__

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefConstructor of YOLOv5 class
parammodel: model path, default empty, you can load model later by load function.
throwIf model arg is not empty and load failed, will throw err::Exception.
staticFalse
+

C++ defination code:

+ +
YOLOv5(const string &model = "")
+
+

load

+ +
def load(self, model: str) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefLoad model from file
parammodel: Model path want to load
returnerr::Err
staticFalse
+

C++ defination code:

+ +
err::Err load(const string &model)
+
+

detect

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefDetect objects from image
paramimg: Image want to detect, if image's size not match model input's, will auto resize with fit method.
conf_th: Confidence threshold, default 0.5.
iou_th: IoU threshold, default 0.45.
fit: Resize method, default image.Fit.FIT_CONTAIN.
throwIf image format not match model input format, will throw err::Exception.
returnObject list. In C++, you should delete it after use.
staticFalse
+

C++ defination code:

+ +
std::vector<nn::Object> *detect(image::Image &img, float conf_th = 0.5, float iou_th = 0.45, maix::image::Fit fit = maix::image::FIT_CONTAIN)
+
+

input_size

+ +
def input_size(self) -> maix.image.Size
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet model input size
returnmodel input size
staticFalse
+

C++ defination code:

+ +
image::Size input_size()
+
+

input_width

+ +
def input_width(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet model input width
returnmodel input size of width
staticFalse
+

C++ defination code:

+ +
int input_width()
+
+

input_height

+ +
def input_height(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet model input height
returnmodel input size of height
staticFalse
+

C++ defination code:

+ +
int input_height()
+
+

input_format

+ +
def input_format(self) -> maix.image.Format
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet input image format
returninput image format, image::Format type.
staticFalse
+

C++ defination code:

+ +
image::Format input_format()
+
+

labels

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefLabels list
staticFalse
readonlyFalse
+

C++ defination code:

+ +
std::vector<string> labels
+
+

label_path

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefLabel file path
staticFalse
readonlyFalse
+

C++ defination code:

+ +
std::string label_path
+
+

mean

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefGet mean value, list type
staticFalse
readonlyFalse
+

C++ defination code:

+ +
std::vector<float> mean
+
+

scale

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefGet scale value, list type
staticFalse
readonlyFalse
+

C++ defination code:

+ +
std::vector<float> scale
+
+

anchors

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefGet anchors
staticFalse
readonlyFalse
+

C++ defination code:

+ +
std::vector<float> anchors
+
+

Classifier

+ + + + + + + + + + + + + +
itemdoc
briefClassifier
+

C++ defination code:

+ +
class Classifier
+
+

__init__

+ +
def __init__(self, model: str = '') -> None
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefConstruct a new Classifier object
parammodel: MUD model path, if empty, will not load model, you can call load() later.
if not empty, will load model and will raise err::Exception if load failed.
staticFalse
+

C++ defination code:

+ +
Classifier(const string &model = "")
+
+

load

+ +
def load(self, model: str) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefLoad model from file, model format is .mud,\nMUD file should contain [extra] section, have key-values:\n- model_type: classifier\n- input_type: rgb or bgr\n- mean: 123.675, 116.28, 103.53\n- scale: 0.017124753831663668, 0.01750700280112045, 0.017429193899782137\n- labels: imagenet_classes.txt
parammodel: MUD model path
returnerror code, if load failed, return error code
staticFalse
+

C++ defination code:

+ +
err::Err load(const string &model)
+
+

classify

+ +
def classify(self, img: maix.image.Image, softmax: bool = True) -> list[tuple[int, float]]
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefForward image to model, get result. Only for image input, use classify_raw for tensor input.
paramimg: image, format should match model input_type, or will raise err.Exception
softmax: if true, will do softmax to result, or will return raw value
throwIf error occurred, will raise err::Exception, you can find reason in log, mostly caused by args error or hardware error.
returnresult, a list of (label, score). In C++, you need to delete it after use.
staticFalse
+

C++ defination code:

+ +
std::vector<std::pair<int, float>> *classify(image::Image &img, bool softmax = true)
+
+

classify_raw

+ +
def classify_raw(self, data: maix.tensor.Tensor, softmax: bool = True) -> list[tuple[int, float]]
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefForward tensor data to model, get result
paramdata: tensor data, format should match model input_type, or will raise err.Excetion
softmax: if true, will do softmax to result, or will return raw value
throwIf error occurred, will raise err::Exception, you can find reason in log, mostly caused by args error or hardware error.
returnresult, a list of (label, score). In C++, you need to delete it after use.
staticFalse
+

C++ defination code:

+ +
std::vector<std::pair<int, float>> *classify_raw(tensor::Tensor &data, bool softmax = true)
+
+

input_size

+ +
def input_size(self) -> maix.image.Size
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet model input size, only for image input
returnmodel input size
staticFalse
+

C++ defination code:

+ +
image::Size input_size()
+
+

input_width

+ +
def input_width(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet model input width, only for image input
returnmodel input size of width
staticFalse
+

C++ defination code:

+ +
int input_width()
+
+

input_height

+ +
def input_height(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet model input height, only for image input
returnmodel input size of height
staticFalse
+

C++ defination code:

+ +
int input_height()
+
+

input_format

+ +
def input_format(self) -> maix.image.Format
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet input image format, only for image input
returninput image format, image::Format type.
staticFalse
+

C++ defination code:

+ +
image::Format input_format()
+
+

input_shape

+ +
def input_shape(self) -> list[int]
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet input shape, if have multiple input, only return first input shape
returninput shape, list type
staticFalse
+

C++ defination code:

+ +
std::vector<int> input_shape()
+
+

labels

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefLabels list
staticFalse
readonlyFalse
+

C++ defination code:

+ +
std::vector<string> labels
+
+

label_path

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefLabel file path
staticFalse
readonlyFalse
+

C++ defination code:

+ +
std::string label_path
+
+

mean

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefGet mean value, list type
staticFalse
readonlyFalse
+

C++ defination code:

+ +
std::vector<float> mean
+
+

scale

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefGet scale value, list type
staticFalse
readonlyFalse
+

C++ defination code:

+ +
std::vector<float> scale
+
+

MUD

+ + + + + + + + + + + + + +
itemdoc
briefMUD(model universal describe file) class
+

C++ defination code:

+ +
class MUD
+
+

__init__

+ +
def __init__(self, model_path: str = None) -> None
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefMUD constructor
parammodel_path: direction [in], model file path, model format can be MUD(model universal describe file) file.
If model_path set, will load model from file, load failed will raise err.Exception.
If model_path not set, you can load model later by load function.
staticFalse
+

C++ defination code:

+ +
MUD(const char *model_path = nullptr)
+
+

load

+ +
def load(self, model: str) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefLoad model from file
parammodel_path: direction [in], model file path, model format can be MUD(model universal describe file) file.
returnerror code, if load success, return err::ERR_NONE
staticFalse
+

C++ defination code:

+ +
err::Err load(const std::string &model_path)
+
+

type

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefModel type, string type
staticFalse
readonlyFalse
+

C++ defination code:

+ +
std::string type
+
+

items

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefModel config items, different model type has different config items
staticFalse
readonlyFalse
+

C++ defination code:

+ +
std::map<std::string, std::map<std::string, std::string>> items
+
+

LayerInfo

+ + + + + + + + + + + + + +
itemdoc
briefNN model layer info
+

C++ defination code:

+ +
class LayerInfo
+
+

__init__

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefLayerInfo constructor
paramname: direction [in], layer name
dtype: direction [in], layer data type
shape: direction [in], layer shape
staticFalse
+

C++ defination code:

+ +
LayerInfo(const std::string &name =  "", tensor::DType dtype = tensor::DType::FLOAT32, std::vector<int> shape = std::vector<int>())
+
+

name

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefLayer name
staticFalse
readonlyFalse
+

C++ defination code:

+ +
std::string   name
+
+

dtype

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefLayer data type
attentionIf model is quantized, this is the real quantized data type like int8 float16,
in most scene, inputs and outputs we actually use float32 in API like forward.
staticFalse
readonlyFalse
+

C++ defination code:

+ +
tensor::DType dtype
+
+

shape

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefLayer shape
staticFalse
readonlyFalse
+

C++ defination code:

+ +
std::vector<int> shape
+
+

to_str

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefTo string
staticFalse
+

C++ defination code:

+ +
std::string to_str()
+
+

__str__

+ +
def __str__(self) -> str
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefTo string
staticFalse
+

C++ defination code:

+ +
std::string __str__()
+
+

NN

+ + + + + + + + + + + + + +
itemdoc
briefNeural network class
+

C++ defination code:

+ +
class NN
+
+

__init__

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefNeural network constructor
parammodel: direction [in], model file path, model format can be MUD(model universal describe file) file.
If model_path set, will load model from file, load failed will raise err.Exception.
If model_path not set, you can load model later by load function.
staticFalse
+

C++ defination code:

+ +
NN(const std::string &model = "")
+
+

load

+ +
def load(self, model: str) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefLoad model from file
parammodel: direction [in], model file path, model format can be MUD(model universal describe file) file.
returnerror code, if load success, return err::ERR_NONE
staticFalse
+

C++ defination code:

+ +
err::Err load(const std::string &model)
+
+

loaded

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefIs model loaded
returntrue if model loaded, else false
staticFalse
+

C++ defination code:

+ +
bool loaded()
+
+

inputs_info

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet model input layer info
returninput layer info
staticFalse
+

C++ defination code:

+ +
std::vector<nn::LayerInfo> inputs_info()
+
+

outputs_info

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet model output layer info
returnoutput layer info
staticFalse
+

C++ defination code:

+ +
std::vector<nn::LayerInfo> outputs_info()
+
+

extra_info

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet model extra info define in MUD file
returnextra info, dict type, key-value object, attention: key and value are all string type.
staticFalse
+

C++ defination code:

+ +
std::map<std::string, std::string> extra_info()
+
+

forward

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefforward run model, get output of model,\nthis is specially for MaixPy, not efficient, but easy to use in MaixPy
paraminput: direction [in], input tensor
returnoutput tensor. In C++, you should manually delete tensors in return value and return value.
staticFalse
+

C++ defination code:

+ +
tensor::Tensors *forward(tensor::Tensors &inputs)
+
+

forward_image

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefforward model, param is image
paramimg: input image
mean: mean value, a list type, e.g. [0.485, 0.456, 0.406], default is empty list means not normalize.
scale: scale value, a list type, e.g. [1/0.229, 1/0.224, 1/0.225], default is empty list means not normalize.
fit: fit mode, if the image size of input not equal to model's input, it will auto resize use this fit method,
default is image.Fit.FIT_FILL for easy coordinate calculation, but for more accurate result, use image.Fit.FIT_CONTAIN is better.
copy_result: If set true, will copy result to a new variable; else will use a internal memory, you can only use it until to the next forward.
Default true to avoid problems, you can set it to false manually to make speed faster.
returnoutput tensor. In C++, you should manually delete tensors in return value and return value.
staticFalse
+

C++ defination code:

+ +
tensor::Tensors *forward_image(image::Image &img, std::vector<float> mean = std::vector<float>(), std::vector<float> scale = std::vector<float>(), image::Fit fit = image::Fit::FIT_FILL, bool copy_result = true)
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/maix/nn/F.html b/maixpy/api/maix/nn/F.html new file mode 100644 index 00000000..7754c333 --- /dev/null +++ b/maixpy/api/maix/nn/F.html @@ -0,0 +1,337 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix.nn.F - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix.nn.F

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.nn.F module

+
+

You can use maix.nn.F to access this module with MaixPy
+This module is generated from MaixCDK

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

softmax

+ +
def softmax(tensor: maix.tensor.Tensor, replace: bool) -> maix.tensor.Tensor
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefSoftmax, only support 1D tensor, multi-dimension tensor will be treated as 1D tensor
paramtensor: input tensor
replace: change input tensor data directly, if not, will create a new tensor
throwIf arg error, will raise err.Exception error
returnoutput tensor, if arg replace is true, return the arg tensor's address.
If not replace, return a new object, so In C++, you should delete it manually in this case!
+

C++ defination code:

+ +
tensor::Tensor *softmax(tensor::Tensor *tensor, bool replace)
+
+

Class

+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/maix/peripheral.html b/maixpy/api/maix/peripheral.html new file mode 100644 index 00000000..27d926cb --- /dev/null +++ b/maixpy/api/maix/peripheral.html @@ -0,0 +1,352 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix.peripheral - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix.peripheral

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

Chip's peripheral driver

+
+

You can use maix.peripheral to access this module with MaixPy
+This module is generated from MaixCDK

+
+

Module

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
modulebrief
adcmaix.peripheral.adc module
spimaix.peripheral.spi module
uartmaix uart peripheral driver
keymaix.peripheral.key module
i2cmaix.peripheral.i2c module
pinmapmaix.peripheral.pinmap module
timermaix.peripheral.timer module
pwmmaix.peripheral.pwm module
gpiomaix.peripheral.gpio module
wdtmaix.peripheral.wdt module
+

Enum

+

Variable

+

Function

+

Class

+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/maix/peripheral/adc.html b/maixpy/api/maix/peripheral/adc.html new file mode 100644 index 00000000..4bced554 --- /dev/null +++ b/maixpy/api/maix/peripheral/adc.html @@ -0,0 +1,532 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix.peripheral.adc - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix.peripheral.adc

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.peripheral.adc module

+
+

You can use maix.peripheral.adc to access this module with MaixPy
+This module is generated from MaixCDK

+
+

Module

+

No module

+

Enum

+

Variable

+

RES_BIT_8

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
brief8-bit resolution, supported by the actual hardware
value8
readonlyTrue
+

C++ defination code:

+ +
const int RES_BIT_8 = 8
+
+

RES_BIT_10

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
brief10-bit resolution, supported by the actual hardware
value10
readonlyTrue
+

C++ defination code:

+ +
const int RES_BIT_10 = 10
+
+

RES_BIT_12

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
brief12-bit resolution, supported by the actual hardware
value12
readonlyTrue
+

C++ defination code:

+ +
const int RES_BIT_12 = 12
+
+

RES_BIT_16

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
brief16-bit resolution, supported by the actual hardware
value16
readonlyTrue
+

C++ defination code:

+ +
const int RES_BIT_16 = 16
+
+

Function

+

Class

+

ADC

+ + + + + + + + + + + + + +
itemdoc
briefPeripheral adc class
+

C++ defination code:

+ +
class ADC
+
+

__init__

+ +
def __init__(self, pin: int, resolution: int, vref: float = -1) -> None
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefADC constructor
parampin: direction [in], adc pin, int type
resolution: direction [in], adc resolution. default is -1, means use default resolution
option:
resolution = adc.RES_BIT_8, means 8-bit resolution
resolution = adc.RES_BIT_10, means 10-bit resolution
resolution = adc.RES_BIT_12, means 12-bit resolution
resolution = adc.RES_BIT_16, means 16-bit resolution
the default resolution is determined by actual hardware.
vref: direction [in], adc refer voltage. default is -1, means use default refer voltage.
the default vref is determined by actual hardware. range: [0.0, 10.0]
staticFalse
+

C++ defination code:

+ +
ADC(int pin, int resolution, float vref = -1)
+
+

read

+ +
def read(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefread adc value
returnadc data, int type
if resolution is 8-bit, return value range is [0, 255]
if resolution is 10-bit, return value range is [0, 1023]
if resolution is 12-bit, return value range is [0, 4095]
if resolution is 16-bit, return value range is [0, 65535]
staticFalse
+

C++ defination code:

+ +
int read()
+
+

read_vol

+ +
def read_vol(self) -> float
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefread adc voltage
returnadc voltage, float type。the range is [0.0, vref]
staticFalse
+

C++ defination code:

+ +
float read_vol()
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/maix/peripheral/gpio.html b/maixpy/api/maix/peripheral/gpio.html new file mode 100644 index 00000000..d1de87e0 --- /dev/null +++ b/maixpy/api/maix/peripheral/gpio.html @@ -0,0 +1,546 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix.peripheral.gpio - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix.peripheral.gpio

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.peripheral.gpio module

+
+

You can use maix.peripheral.gpio to access this module with MaixPy
+This module is generated from MaixCDK

+
+

Module

+

No module

+

Enum

+

Mode

+ + + + + + + + + + + + + + + + + +
itemdoc
briefGPIO mode
valuesIN: input mode
OUT: output mode
OUT_OD: output open drain mode
MODE_MAX:
+

C++ defination code:

+ +
enum Mode
+    {
+        IN     = 0x01,     // input mode
+        OUT    = 0x02,     // output mode
+        OUT_OD = 0x03,     // output open drain mode
+        MODE_MAX
+    }
+
+

Pull

+ + + + + + + + + + + + + + + + + +
itemdoc
briefGPIO pull mode
valuesPULL_NONE: pull none mode
PULL_UP: pull up mode
PULL_DOWN: pull down mode
PULL_MAX:
+

C++ defination code:

+ +
enum Pull
+    {
+        PULL_NONE = 0x00,  // pull none mode
+        PULL_UP   = 0x01,  // pull up mode
+        PULL_DOWN = 0x02,  // pull down mode
+        PULL_MAX
+    }
+
+

Variable

+

Function

+

Class

+

GPIO

+ + + + + + + + + + + + + +
itemdoc
briefPeripheral gpio class
+

C++ defination code:

+ +
class GPIO
+
+

__init__

+ +
def __init__(self, pin: str, mode: Mode = ..., pull: Pull = ...) -> None
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGPIO constructor
parampin: direction [in], gpio pin name, string type the same as board's pin name, e.g. "B14" or "GPIOB14", or number string like "10" if board no gpiochipe name.
mode: direction [in], gpio mode. gpio.Mode type, default is gpio.Mode.IN (input) mode.
pull: direction [in], gpio pull. gpio.Pull type, default is gpio.Pull.PULL_NONE (pull none) mode.
For input mode, this will set gpio default status(value), if set to gpio.Pull.PULL_NONE, gpio value will be floating.
For output mode, this will set gpio default status(value), if set to gpio.Pull.PULL_UP, gpio value will be 1, else 0.
throwerr::Exception if open gpio device failed.
staticFalse
+

C++ defination code:

+ +
GPIO(std::string pin, gpio::Mode mode = gpio::Mode::IN, gpio::Pull pull = gpio::Pull::PULL_NONE)
+
+

value

+ +
def value(self, value: int = -1) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefset and get gpio value
paramvalue: direction [in], gpio value. int type.
0, means write gpio to low level
1, means write gpio to high level
-1, means read gpio value, not set
returnint type, return gpio value, can be 0 or 1
staticFalse
+

C++ defination code:

+ +
int value(int value = -1)
+
+

high

+ +
def high(self) -> None
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefset gpio high (value to 1)
staticFalse
+

C++ defination code:

+ +
void high()
+
+

low

+ +
def low(self) -> None
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefset gpio low (value to 0)
staticFalse
+

C++ defination code:

+ +
void low()
+
+

toggle

+ +
def toggle(self) -> None
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefgpio toggle
staticFalse
+

C++ defination code:

+ +
void toggle()
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/maix/peripheral/i2c.html b/maixpy/api/maix/peripheral/i2c.html new file mode 100644 index 00000000..8ff2891d --- /dev/null +++ b/maixpy/api/maix/peripheral/i2c.html @@ -0,0 +1,605 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix.peripheral.i2c - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix.peripheral.i2c

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.peripheral.i2c module

+
+

You can use maix.peripheral.i2c to access this module with MaixPy
+This module is generated from MaixCDK

+
+

Module

+

No module

+

Enum

+

AddrSize

+ + + + + + + + + + + + + + + + + +
itemdoc
briefAddress size enum
valuesSEVEN_BIT: 7-bit address mode
TEN_BIT: 10-bit address mode
+

C++ defination code:

+ +
enum AddrSize
+    {
+        SEVEN_BIT = 7,   // 7-bit address mode
+        TEN_BIT   = 10   // 10-bit address mode
+    }
+
+

Mode

+ + + + + + + + + + + + + + + + + +
itemdoc
briefI2C mode enum
valuesMASTER: master mode
SLAVE: slave mode
+

C++ defination code:

+ +
enum Mode
+    {
+        MASTER = 0x00, // master mode
+        SLAVE = 0x01   // slave mode
+    }
+
+

Variable

+

Function

+

list_devices

+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet supported i2c bus devices.
returni2c bus devices list, int type, is the i2c bus id.
+

C++ defination code:

+ +
std::vector<int> list_devices()
+
+

Class

+

I2C

+ + + + + + + + + + + + + +
itemdoc
briefPeripheral i2c class
+

C++ defination code:

+ +
class I2C
+
+

__init__

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefI2C Device constructor\nthis constructor will be export to MaixPy as _maix.example.Example.init
paramid: direction [in], i2c bus id, int type, e.g. 0, 1, 2
freq: direction [in], i2c clock, int type, default is 100000(100kbit/s), will auto set fast mode if freq > 100000.
mode: direction [in], mode of i2c, i2c.Mode.SLAVE or i2c.Mode.MASTER.
addr_size: direction [in], address length of i2c, i2c.AddrSize.SEVEN_BIT or i2c.AddrSize.TEN_BIT.
throwerr::Exception if open i2c device failed.
staticFalse
+

C++ defination code:

+ +
I2C(int id, i2c::Mode mode, int freq = 100000, i2c::AddrSize addr_size = i2c::AddrSize::SEVEN_BIT)
+
+

scan

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefscan all i2c salve address on the bus
returnthe list of i2c slave address, int list type.
staticFalse
+

C++ defination code:

+ +
std::vector<int> scan()
+
+

writeto

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefwrite data to i2c slave
paramaddr: direction [in], i2c slave address, int type
data: direction [in], data to write, bytes type.
Note: The range of value should be in [0,255].
returnif success, return the length of written data, error occurred will return -err::Err.
staticFalse
+

C++ defination code:

+ +
int writeto(int addr, const Bytes &data)
+
+

readfrom

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefread data from i2c slave
paramaddr: direction [in], i2c slave address, int type
len: direction [in], data length to read, int type
returnthe list of data read from i2c slave, bytes type, you should delete it after use in C++.
If read failed, return nullptr in C++, None in MaixPy.
staticFalse
+

C++ defination code:

+ +
Bytes* readfrom(int addr, int len)
+
+

writeto_mem

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefwrite data to i2c slave's memory address
paramaddr: direction [in], i2c slave address, int type
mem_addr: direction [in], memory address want to write, int type.
data: direction [in], data to write, bytes type.
mem_addr_size: direction [in], memory address size, default is 8.
mem_addr_le: direction [in], memory address little endian, default is false, that is send high byte first.
returndata length written if success, error occurred will return -err::Err.
staticFalse
+

C++ defination code:

+ +
int writeto_mem(int addr, int mem_addr, const Bytes &data, int mem_addr_size = 8, bool mem_addr_le = false)
+
+

readfrom_mem

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefread data from i2c slave
paramaddr: direction [in], i2c slave address, int type
mem_addr: direction [in], memory address want to read, int type.
len: direction [in], data length to read, int type
mem_addr_size: direction [in], memory address size, default is 8.
mem_addr_le: direction [in], memory address little endian, default is false, that is send high byte first.
returnthe list of data read from i2c slave, bytes type, you should delete it after use in C++.
If read failed, return nullptr in C++, None in MaixPy.
staticFalse
+

C++ defination code:

+ +
Bytes* readfrom_mem(int addr, int mem_addr, int len, int mem_addr_size = 8, bool mem_addr_le = false)
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/maix/peripheral/key.html b/maixpy/api/maix/peripheral/key.html new file mode 100644 index 00000000..ba959b95 --- /dev/null +++ b/maixpy/api/maix/peripheral/key.html @@ -0,0 +1,590 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix.peripheral.key - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix.peripheral.key

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.peripheral.key module

+
+

You can use maix.peripheral.key to access this module with MaixPy
+This module is generated from MaixCDK

+
+

Module

+

No module

+

Enum

+

Keys

+ + + + + + + + + + + + + + + + + +
itemdoc
briefKeys enum, id the same as linux input.h(input-event-codes.h)
valuesKEY_NONE:
KEY_ESC:
KEY_OK:
KEY_OPTION:
KEY_NEXT:
KEY_PREV:
+

C++ defination code:

+ +
enum Keys{
+        KEY_NONE   = 0x000,
+        KEY_ESC    = 0x001,
+        KEY_OK     = 0x160,
+        KEY_OPTION = 0x165,
+        KEY_NEXT   = 0x197,
+        KEY_PREV   = 0x19c
+    }
+
+

State

+ + + + + + + + + + + + + + + + + +
itemdoc
briefKey state enum
valuesKEY_RELEASED:
KEY_PRESSED:
+

C++ defination code:

+ +
enum State{
+        KEY_RELEASED  = 0,
+        KEY_PRESSED   = 1,
+    }
+
+

Variable

+

Function

+

add_default_listener

+ + + + + + + + + + + + + +
itemdoc
briefAdd default listener, if you want to exit app when press ok button, you can just call this function.\nThis function is auto called in MaixPy' startup code, so you don't need to call it in MaixPy.\nCreate Key object will auto call rm_default_listener() to cancel the default ok button function.\nWhen ok button pressed, a SIGINT signal will be raise and call app.set_exit_flag(True).
+

C++ defination code:

+ +
void add_default_listener()
+
+

rm_default_listener

+ + + + + + + + + + + + + +
itemdoc
briefRemove default listener, if you want to cancel the default ok button function(exit app), you can just call this function.
+

C++ defination code:

+ +
void rm_default_listener()
+
+

Class

+

Key

+ + + + + + + + + + + + + +
itemdoc
briefKey input class
+

C++ defination code:

+ +
class Key
+
+

__init__

+ +
def __init__(self, callback: typing.Callable[[int, int], None] = None, open: bool = True) -> None
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefKey Device constructor
paramcallback: When key triggered and callback is not empty(empty In MaixPy is None, in C++ is nullptr),
callback will be called with args key(key.Keys) and value(key.State).
If set to null, you can get key value by read() function.
This callback called in a standalone thread, so you can block a while in callback, and you should be carefully when operate shared data.
open: auto open device in constructor, if false, you need call open() to open device
staticFalse
+

C++ defination code:

+ +
Key(std::function<void(int, int)> callback = nullptr, bool open = true)
+
+

open

+ +
def open(self) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefOpen(Initialize) key device, if already opened, will close first and then open.
returnerr::Err type, err.Err.ERR_NONE means success
staticFalse
+

C++ defination code:

+ +
err::Err open()
+
+

close

+ +
def close(self) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefClose key device
returnerr::Err type, err.Err.ERR_NONE means success
staticFalse
+

C++ defination code:

+ +
err::Err close()
+
+

is_opened

+ +
def is_opened(self) -> bool
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefCheck key device is opened
returnbool type, true means opened, false means closed
staticFalse
+

C++ defination code:

+ +
bool is_opened()
+
+

read

+ +
def read(self) -> tuple[int, int]
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefRead key input, and return key and value, if callback is set, DO NOT call this function manually.
returnlist type, first is key(maix.key.Keys), second is value(maix.key.State), if no key input, return [0, 0]
throwIf read failed, will throw maix.err.Exception.
staticFalse
+

C++ defination code:

+ +
std::pair<int, int> read()
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/maix/peripheral/pinmap.html b/maixpy/api/maix/peripheral/pinmap.html new file mode 100644 index 00000000..c6c4cc6e --- /dev/null +++ b/maixpy/api/maix/peripheral/pinmap.html @@ -0,0 +1,393 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix.peripheral.pinmap - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix.peripheral.pinmap

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.peripheral.pinmap module

+
+

You can use maix.peripheral.pinmap to access this module with MaixPy
+This module is generated from MaixCDK

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

get_pins

+ +
def get_pins() -> list[str]
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet all pins of devices
returnpin name list, string type.
+

C++ defination code:

+ +
std::vector<std::string> get_pins()
+
+

get_pin_functions

+ +
def get_pin_functions(pin: str) -> list[str]
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefGet all function of a pin
parampin: pin name, string type.
returnfunction list, function name is string type.
throwIf pin name error will throwout err.Err.ERR_ARGS error.
+

C++ defination code:

+ +
std::vector<std::string> get_pin_functions(const std::string &pin)
+
+

set_pin_function

+ +
def set_pin_function(pin: str, func: str) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefSet function of a pin
parampin: pin name, string type.
func: which function should this pin use.
returnif set ok, will return err.Err.ERR_NONE, else error occurs.
+

C++ defination code:

+ +
err::Err set_pin_function(const std::string &pin, const std::string &func)
+
+

Class

+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/maix/peripheral/pwm.html b/maixpy/api/maix/peripheral/pwm.html new file mode 100644 index 00000000..79071ea8 --- /dev/null +++ b/maixpy/api/maix/peripheral/pwm.html @@ -0,0 +1,555 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix.peripheral.pwm - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix.peripheral.pwm

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.peripheral.pwm module

+
+

You can use maix.peripheral.pwm to access this module with MaixPy
+This module is generated from MaixCDK

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

Class

+

PWM

+ + + + + + + + + + + + + +
itemdoc
briefPeripheral pwm class
+

C++ defination code:

+ +
class PWM
+
+

__init__

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefPWM constructor
parampin: direction [in], pwm id, int type, like 0, 1, 2 etc.
freq: direction [in], pwm frequency, unit: Hz. int type. default is 1000
duty: direction [in], pwm duty. double type. range is [0, 100], default is 0.
enable: direction [in], enable pwm output right now. bool type. default is true, if false, you need to call enable() to enable pwm output.
duty_val: direction [in], pwm duty value, int type. default -1 means not set and auto calculate by freq and duty.
This arg directly set pwm duty value, if set, will ignore duty arg.
duty_val = duty / 100 * T_ns, T_ns = 1 / freq * 1000000000.
throwIf args error or init pwm failed, will throw err::Exception
staticFalse
+

C++ defination code:

+ +
PWM(int id, int freq = 1000, double duty = 0, bool enable = true, int duty_val = -1)
+
+

duty

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget or set pwm duty
paramduty: direction [in], pwm duty, double type, value in [0, 100], default -1 means only read.
returncurrent duty, float type, if set and set failed will return -err::Err
staticFalse
+

C++ defination code:

+ +
double duty(double duty = -1)
+
+

duty_val

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefset pwm duty value
paramduty_val: direction [in], pwm duty value. int type. default is -1
duty_val > 0 means set duty_val
duty_val == -1 or not set, return current duty_val
returnint type
when get duty_val, return current duty_val, else return -err::Err code.
staticFalse
+

C++ defination code:

+ +
int duty_val(int duty_val = -1)
+
+

freq

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget or set pwm frequency
paramfreq: direction [in], pwm frequency. int type. default is -1
freq >= 0, set freq
freq == -1 or not set, return current freq
returnint type, current freq, if set and set failed will return -err::Err
staticFalse
+

C++ defination code:

+ +
int freq(int freq = -1)
+
+

enable

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefset pwm enable
returnerr::Err type, err.Err.ERR_NONE means success
staticFalse
+

C++ defination code:

+ +
err::Err enable()
+
+

disable

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefset pwm disable
returnerr::Err type, err.Err.ERR_NONE means success
staticFalse
+

C++ defination code:

+ +
err::Err disable()
+
+

is_enabled

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget pwm enable status
returnbool type, true means enable, false means disable
staticFalse
+

C++ defination code:

+ +
bool is_enabled()
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/maix/peripheral/spi.html b/maixpy/api/maix/peripheral/spi.html new file mode 100644 index 00000000..da4e8d33 --- /dev/null +++ b/maixpy/api/maix/peripheral/spi.html @@ -0,0 +1,481 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix.peripheral.spi - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix.peripheral.spi

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.peripheral.spi module

+
+

You can use maix.peripheral.spi to access this module with MaixPy
+This module is generated from MaixCDK

+
+

Module

+

No module

+

Enum

+

Mode

+ + + + + + + + + + + + + + + + + +
itemdoc
briefSPI mode enum
valuesMASTER: spi master mode
SLAVE: spi slave mode
+

C++ defination code:

+ +
enum Mode
+    {
+        MASTER = 0x0, // spi master mode
+        SLAVE = 0x1,  // spi slave mode
+    }
+
+

Variable

+

Function

+

Class

+

SPI

+ + + + + + + + + + + + + +
itemdoc
briefPeripheral spi class
+

C++ defination code:

+ +
class SPI
+
+

__init__

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSPI constructor
paramid: direction [in], spi bus id, int type
freq: direction [in], freq of spi, int type
soft_cs: direction [in], not use hardware cs, bool type, if set true, you can operate cs pin use gpio manually.
mode: direction [in], mode of spi, spi.Mode type, spi.Mode.MASTER or spi.Mode.SLAVE.
polarity: direction [in], polarity of spi, 0 means idle level of clock is low, 1 means high, int type, default is 0.
phase: direction [in], phase of spi, 0 means data is captured on the first edge of the SPI clock cycle, 1 means second, int type, default is 0.
bits: direction [in], bits of spi, int type, default is 8.
cs: direction [in], cs pin number, int type, default is 0, if SPI support multi hardware cs, you can set it to other value.
staticFalse
+

C++ defination code:

+ +
SPI(int id, spi::Mode mode, int freq, bool soft_cs = false, int polarity = 0, int phase = 0, int bits = 8, int cs = 0)
+
+

read

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefread data from spi
paramlength: direction [in], read length, int type
returnbytes data, Bytes type in C++, bytes type in MaixPy. You need to delete it manually after use in C++.
staticFalse
+

C++ defination code:

+ +
Bytes *read(int length)
+
+

write_read

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefwrite data to spi and read data from spi at the same time.
paramdata: direction [in], data to write, Bytes type in C++, bytes type in MaixPy
read_len: direction [in], read length, int type, should > 0.
returnread data, Bytes type in C++, bytes type in MaixPy. You need to delete it manually after use in C++.
staticFalse
+

C++ defination code:

+ +
Bytes *write_read(Bytes *data, int read_len)
+
+

is_busy

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget busy status of spi
returnbusy status, bool type
staticFalse
+

C++ defination code:

+ +
bool is_busy()
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/maix/peripheral/timer.html b/maixpy/api/maix/peripheral/timer.html new file mode 100644 index 00000000..e7688a8f --- /dev/null +++ b/maixpy/api/maix/peripheral/timer.html @@ -0,0 +1,349 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix.peripheral.timer - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix.peripheral.timer

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.peripheral.timer module

+
+

You can use maix.peripheral.timer to access this module with MaixPy
+This module is generated from MaixCDK

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

Class

+

TIMER

+ + + + + + + + + + + + + +
itemdoc
briefPeripheral timer class
+

C++ defination code:

+ +
class TIMER
+
+

__init__

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefTIMER constructor
staticFalse
+

C++ defination code:

+ +
TIMER()
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/maix/peripheral/uart.html b/maixpy/api/maix/peripheral/uart.html new file mode 100644 index 00000000..b67c4884 --- /dev/null +++ b/maixpy/api/maix/peripheral/uart.html @@ -0,0 +1,937 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix.peripheral.uart - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix.peripheral.uart

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix uart peripheral driver

+
+

You can use maix.peripheral.uart to access this module with MaixPy
+This module is generated from MaixCDK

+
+

Module

+

No module

+

Enum

+

PARITY

+ + + + + + + + + + + + + + + + + +
itemdoc
briefuart parity enum
valuesPARITY_NONE: no parity
PARITY_ODD: odd parity
PARITY_EVEN: even parity
PARITY_MAX:
+

C++ defination code:

+ +
enum PARITY
+    {
+        PARITY_NONE = 0x00,  // no parity
+        PARITY_ODD  = 0x01,  // odd parity
+        PARITY_EVEN = 0x02,  // even parity
+        PARITY_MAX
+    }
+
+

STOP

+ + + + + + + + + + + + + + + + + +
itemdoc
briefuart stop bits
valuesSTOP_1: 1 stop bit
STOP_2: 2 stop bits
STOP_1_5: 1.5 stop bits
STOP_MAX:
+

C++ defination code:

+ +
enum STOP
+    {
+        STOP_1   = 0x01,  // 1 stop bit
+        STOP_2   = 0x02,  // 2 stop bits
+        STOP_1_5 = 0x03,  // 1.5 stop bits
+        STOP_MAX
+    }
+
+

BITS

+ + + + + + + + + + + + + + + + + +
itemdoc
briefuart stop bits
valuesBITS_5: 5 data bits
BITS_6: 6 data bits
BITS_7: 7 data bits
BITS_8: 8 data bits
BITS_MAX:
+

C++ defination code:

+ +
enum BITS
+    {
+        BITS_5 = 5,  // 5 data bits
+        BITS_6 = 6,  // 6 data bits
+        BITS_7 = 7,  // 7 data bits
+        BITS_8 = 8,  // 8 data bits
+        BITS_MAX
+    }
+
+

FLOW_CTRL

+ + + + + + + + + + + + + + + + + +
itemdoc
briefuart flow control
valuesFLOW_CTRL_NONE: no flow control
FLOW_CTRL_HW: hardware flow control
FLOW_CTRL_MAX:
+

C++ defination code:

+ +
enum FLOW_CTRL
+    {
+        FLOW_CTRL_NONE = 0,  // no flow control
+        FLOW_CTRL_HW   = 1,  // hardware flow control
+        FLOW_CTRL_MAX
+    }
+
+

Variable

+

Function

+

list_devices

+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet supported uart ports.
returnuart ports list, string type.
+

C++ defination code:

+ +
std::vector<std::string> list_devices()
+
+

Class

+

UART

+ + + + + + + + + + + + + +
itemdoc
briefmaix uart peripheral driver
+

C++ defination code:

+ +
class UART : public comm::CommBase
+
+

__init__

+ +
def __init__(self, port: str = '', baudrate: int = 115200, databits: BITS = ..., parity: PARITY = ..., stopbits: STOP = ..., flow_ctrl: FLOW_CTRL = ...) -> None
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefUART constructor. You need to call open() to open the device.
paramport: uart port. string type, can get it by uart.list_devices().
If empty, will not open device in constructor, default empty.
if not empty, will auto open device in constructor, open fail will throw err.Exception.
baudrate: baudrate of uart. int type, default 115200.
databits: databits, values @see uart.DATA_BITS
parity: parity, values @see uart.PARITY
stopbits: stopbits, values @see uart.STOP_BITS
flow_control: flow_control, values @see uart.FLOW_CTRL
staticFalse
+

C++ defination code:

+ +
UART(const std::string &port = "", int baudrate = 115200, uart::BITS databits = uart::BITS_8,
+            uart::PARITY parity = uart::PARITY_NONE, uart::STOP stopbits = uart::STOP_1,
+            uart::FLOW_CTRL flow_ctrl = uart::FLOW_CTRL_NONE)
+
+

set_port

+ +
def set_port(self, port: str) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSet port
paramport: uart port. string type, can get it by uart.list_devices().
returnset port error code, err.Err type.
staticFalse
+

C++ defination code:

+ +
err::Err set_port(const std::string &port)
+
+

get_port

+ +
def get_port(self) -> str
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet port
returnuart port, string type.
staticFalse
+

C++ defination code:

+ +
std::string get_port()
+
+

set_baudrate

+ +
def set_baudrate(self, baudrate: int) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSet baud rate
parambaudrate: baudrate of uart. int type, default 115200.
returnset baud rate error code, err.Err type.
staticFalse
+

C++ defination code:

+ +
err::Err set_baudrate(int baudrate)
+
+

get_baudrate

+ +
def get_baudrate(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet baud rate
returnbaud rate, int type.
staticFalse
+

C++ defination code:

+ +
int get_baudrate()
+
+

open

+ +
def open(self) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefOpen uart device, before open, port must be set in constructor or by set_port().\nIf already opened, do nothing and return err.ERR_NONE.
returnopen device error code, err.Err type.
staticFalse
+

C++ defination code:

+ +
err::Err open()
+
+

is_open

+ +
def is_open(self) -> bool
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefCheck if device is opened.
returntrue if opened, false if not opened.
staticFalse
+

C++ defination code:

+ +
bool is_open()
+
+

close

+ +
def close(self) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefClose uart device, if already closed, do nothing and return err.ERR_NONE.
returnclose device error code, err.Err type.
staticFalse
+

C++ defination code:

+ +
err::Err close()
+
+

write_str

+ +
def write_str(self, str: str) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSend string data
paramstr: string data
returnsent data length, < 0 means error, value is -err.Err.
staticFalse
+

C++ defination code:

+ +
int write_str(const std::string &str)
+
+

write

+ +
def write(self, data: maix.Bytes(bytes)) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSend data to uart
paramdata: direction [in], data to send, bytes type. If you want to send str type, use str.encode() to convert.
returnsent length, int type, if < 0 means error, value is -err.Err.
staticFalse
+

C++ defination code:

+ +
int write(Bytes &data)
+
+

available

+ +
def available(self, timeout: int = 0) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefCheck if data available or wait data available.
paramtimeout: unit ms, timeout to wait data, default 0.
0 means check data available and return immediately,
> 0 means wait until data available or timeout.
- 1 means wait until data available.
returnavailable data number, 0 if timeout or no data, <0 if error, value is -err.Err, can be err::ERR_IO, err::ERR_CANCEL, err::ERR_NOT_OPEN.
throwerr.Exception if fatal error.
staticFalse
+

C++ defination code:

+ +
int available(int timeout = 0)
+
+

read

+ +
def read(*args, **kwargs)
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefRecv data from uart
paramlen: max data length want to receive, default -1.
-1 means read data in uart receive buffer.
>0 means read len data want to receive.
other values is invalid.
timeout: unit ms, timeout to receive data, default 0.
0 means read data in uart receive buffer and return immediately,
-1 means block until read len data,
>0 means block until read len data or timeout.
returnreceived data, bytes type.
Attention, you need to delete the returned object yourself in C++.
staticFalse
+

C++ defination code:

+ +
Bytes *read(int len = -1, int timeout = 0)
+
+

readline

+ +
def readline(*args, **kwargs)
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefRead line from uart, that is read until '\n' or '\r\n'.
paramtimeout: unit ms, timeout to receive data, default -1 means block until read '\n' or '\r\n'.
> 0 means block until read '\n' or '\r\n' or timeout.
returnreceived data, bytes type. If timeout will return the current received data despite not read '\n' or '\r\n'.
e.g. If we want to read b'123\n', but when we only read b'12', timeout, then return b'12'.
staticFalse
+

C++ defination code:

+ +
Bytes *readline(int timeout = -1)
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/maix/peripheral/wdt.html b/maixpy/api/maix/peripheral/wdt.html new file mode 100644 index 00000000..52d98e6e --- /dev/null +++ b/maixpy/api/maix/peripheral/wdt.html @@ -0,0 +1,438 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix.peripheral.wdt - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix.peripheral.wdt

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.peripheral.wdt module

+
+

You can use maix.peripheral.wdt to access this module with MaixPy
+This module is generated from MaixCDK

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

Class

+

WDT

+ + + + + + + + + + + + + +
itemdoc
briefPeripheral wdt class
+

C++ defination code:

+ +
class WDT
+
+

__init__

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefWDT constructor, after construct, the wdt will auto start.
paramid: direction [in], id of wdt, int type
feed_ms: direction [in], feed interval, int type, unit is ms, you must feed wdt in this interval, or system will restart.
staticFalse
+

C++ defination code:

+ +
WDT(int id, int feed_ms)
+
+

feed

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
brieffeed wdt
returnerror code, if feed success, return err::ERR_NONE
staticFalse
+

C++ defination code:

+ +
int feed()
+
+

stop

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefstop wdt
staticFalse
+

C++ defination code:

+ +
int stop()
+
+

restart

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefrestart wdt, stop and start watchdog timer.
staticFalse
+

C++ defination code:

+ +
int restart()
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/maix/protocol.html b/maixpy/api/maix/protocol.html new file mode 100644 index 00000000..6ddae96e --- /dev/null +++ b/maixpy/api/maix/protocol.html @@ -0,0 +1,1075 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix.protocol - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix.protocol

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.protocol module

+
+

You can use maix.protocol to access this module with MaixPy
+This module is generated from MaixCDK

+
+

Module

+

No module

+

Enum

+

CMD

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefprotocol cmd, more doc see MaixCDK document's convention doc
notemax app custom CMD value should < CMD_APP_MAX
valuesCMD_APP_MAX: 200, max app custom CMD value should < CMD_APP_MAX
CMD_SET_UPLOAD: set auto upload data mode
CMD_APP_LIST:
CMD_START_APP:
CMD_EXIT_APP:
CMD_CUR_APP_INFO:
CMD_APP_INFO:
CMD_KEY:
CMD_TOUCH:
+

C++ defination code:

+ +
enum CMD
+        {
+            CMD_APP_MAX = 0xC8,     //  200, max app custom CMD value should < CMD_APP_MAX
+
+            CMD_SET_UPLOAD   = 0xF8, // set auto upload data mode
+            CMD_APP_LIST     = 0xF9,
+            CMD_START_APP    = 0xFA,
+            CMD_EXIT_APP     = 0xFB,
+            CMD_CUR_APP_INFO = 0xFC,
+            CMD_APP_INFO     = 0xFD,
+            CMD_KEY          = 0xFE,
+            CMD_TOUCH        = 0xFF,
+        }
+
+

FLAGS

+ + + + + + + + + + + + + + + + + +
itemdoc
briefprotocol flags, more doc see MaixCDK document's convention doc
valuesFLAG_REQ:
FLAG_RESP:
FLAG_IS_RESP_MASK:
FLAG_RESP_OK:
FLAG_RESP_ERR:
FLAG_RESP_OK_MASK:
FLAG_REPORT:
FLAG_REPORT_MASK:
FLAG_VERSION_MASK:
+

C++ defination code:

+ +
enum FLAGS
+        {
+            FLAG_REQ = 0x00,
+            FLAG_RESP = 0x80,
+            FLAG_IS_RESP_MASK = 0x80,
+
+            FLAG_RESP_OK = 0x40,
+            FLAG_RESP_ERR = 0x00,
+            FLAG_RESP_OK_MASK = 0x40,
+
+            FLAG_REPORT = 0x20,
+            FLAG_REPORT_MASK = 0x20,
+
+            FLAG_VERSION_MASK = 0x03
+        }
+
+

Variable

+

VERSION

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefprotocol version
value1
readonlyTrue
+

C++ defination code:

+ +
const uint8_t VERSION = 1
+
+ + + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefprotocol header
value0xBBACCAAA
readonlyTrue
+

C++ defination code:

+ +
const uint32_t HEADER = 0xBBACCAAA
+
+

Function

+

crc16_IBM

+ +
def crc16_IBM(data: maix.Bytes(bytes)) -> int
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefCRC16-IBM
paramdata: data, bytes type.
returnCRC16-IBM value, uint16_t type.
+

C++ defination code:

+ +
uint16_t crc16_IBM(const Bytes *data)
+
+

Class

+

MSG

+ + + + + + + + + + + + + +
itemdoc
briefprotocol msg
+

C++ defination code:

+ +
class MSG
+
+

version

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefprotocol version
staticFalse
readonlyFalse
+

C++ defination code:

+ +
uint8_t version
+
+

resp_ok

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefIs success response or not, (only for response msg)
staticFalse
readonlyFalse
+

C++ defination code:

+ +
uint8_t resp_ok
+
+

cmd

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefCMD value
staticFalse
readonlyFalse
+

C++ defination code:

+ +
uint8_t cmd
+
+

is_resp

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefmessage is response or not, contrast with is_req
staticFalse
readonlyFalse
+

C++ defination code:

+ +
bool is_resp
+
+

body_len

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefMessage body length, read only, use set_body() to update
attentionDO NOT manually change this value
staticFalse
readonlyFalse
+

C++ defination code:

+ +
int body_len
+
+

encode_resp_ok

+ +
def encode_resp_ok(*args, **kwargs)
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefEncode response ok(success) message
parambody: response body, can be null
returnencoded data, if nullptr, means error, and the error code is -err.Err
staticFalse
+

C++ defination code:

+ +
Bytes *encode_resp_ok(Bytes *body = nullptr)
+
+

encode_report

+ +
def encode_report(*args, **kwargs)
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefEncode proactively report message
parambody: report body, can be null
returnencoded data, if nullptr, means error, and the error code is -err.Err
staticFalse
+

C++ defination code:

+ +
Bytes *encode_report(Bytes *body = nullptr)
+
+

encode_resp_err

+ +
def encode_resp_err(*args, **kwargs)
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefEncode response error message
paramcode: error code
msg: error message
returnencoded data, if nullptr, means error, and the error code is -err.Err
staticFalse
+

C++ defination code:

+ +
Bytes *encode_resp_err(err::Err code, const std::string &msg)
+
+

set_body

+ +
def set_body(self, body_new: maix.Bytes(bytes)) -> None
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefUpdate message body
parambody_new: new body data
staticFalse
+

C++ defination code:

+ +
void set_body(Bytes *body_new)
+
+

get_body

+ +
def get_body(*args, **kwargs)
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet message body
returnmessage body, bytes type
staticFalse
+

C++ defination code:

+ +
Bytes *get_body()
+
+

Protocol

+ + + + + + + + + + + + + +
itemdoc
briefCommunicate protocol
+

C++ defination code:

+ +
class Protocol
+
+

__init__

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefConstruct a new Protocol object
parambuff_size: Data queue buffer size
staticFalse
+

C++ defination code:

+ +
Protocol(int buff_size = 1024)
+
+

buff_size

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefData queue buffer size
staticFalse
+

C++ defination code:

+ +
int buff_size()
+
+

push_data

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefAdd data to data queue
paramnew_data: new data
returnerror code, maybe err.Err.ERR_BUFF_FULL
staticFalse
+

C++ defination code:

+ +
err::Err push_data(const Bytes *new_data)
+
+

decode

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefDecode data in data queue and return a message
paramnew_data: new data add to data queue, if null, only decode.
returndecoded message, if nullptr, means no message decoded.
staticFalse
+

C++ defination code:

+ +
protocol::MSG *decode(const Bytes *new_data = nullptr)
+
+

encode_resp_ok

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefEncode response ok(success) message to buffer
paramcmd: CMD value
body: response body, can be null
returnencoded data, if nullptr, means error, and the error code is -err.Err
staticFalse
+

C++ defination code:

+ +
Bytes *encode_resp_ok(uint8_t cmd, Bytes *body = nullptr)
+
+

encode_report

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefEncode proactively report message to buffer
paramcmd: CMD value
body: report body, can be null
returnencoded data, if nullptr, means error, and the error code is -err.Err
staticFalse
+

C++ defination code:

+ +
Bytes *encode_report(uint8_t cmd, Bytes *body = nullptr)
+
+

encode_resp_err

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefEncode response error message to buffer
paramcmd: CMD value
code: error code
msg: error message
returnencoded data, if nullptr, means error, and the error code is -err.Err
staticFalse
+

C++ defination code:

+ +
Bytes *encode_resp_err(uint8_t cmd, err::Err code, const std::string &msg)
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/maix/rtsp.html b/maixpy/api/maix/rtsp.html new file mode 100644 index 00000000..0e4d3b56 --- /dev/null +++ b/maixpy/api/maix/rtsp.html @@ -0,0 +1,792 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix.rtsp - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix.rtsp

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.rtsp module

+
+

You can use maix.rtsp to access this module with MaixPy
+This module is generated from MaixCDK

+
+

Module

+

No module

+

Enum

+

RtspStreamType

+ + + + + + + + + + + + + + + + + +
itemdoc
briefThe stream type of rtsp
valuesRTSP_STREAM_NONE: format invalid
RTSP_STREAM_H265:
+

C++ defination code:

+ +
enum RtspStreamType
+    {
+        RTSP_STREAM_NONE = 0,  // format invalid
+        RTSP_STREAM_H265,
+    }
+
+

Variable

+

Function

+

Class

+

Region

+ + + + + + + + + + + + + +
itemdoc
briefRegion class
+

C++ defination code:

+ +
class Region
+
+

__init__

+ +
def __init__(self, x: int, y: int, width: int, height: int, format: maix.image.Format, camera: maix.camera.Camera) -> None
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefConstruct a new Region object
paramx: region coordinate x
y: region coordinate y
width: region width
height: region height
format: region format
camera: bind region to camera
staticFalse
+

C++ defination code:

+ +
Region(int x, int y, int width, int height, image::Format format, camera::Camera *camera)
+
+

get_canvas

+ +
def get_canvas(self) -> maix.image.Image
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefReturn an image object from region
returnimage object
staticFalse
+

C++ defination code:

+ +
image::Image *get_canvas()
+
+

update_canvas

+ +
def update_canvas(self) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefUpdate canvas
returnerror code
staticFalse
+

C++ defination code:

+ +
err::Err update_canvas()
+
+

Rtsp

+ + + + + + + + + + + + + +
itemdoc
briefRtsp class
+

C++ defination code:

+ +
class Rtsp
+
+

__init__

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefConstruct a new Video object
paramip: rtsp ip
port: rtsp port
fps: rtsp fps
stream_type: rtsp stream type
staticFalse
+

C++ defination code:

+ +
Rtsp(std::string ip = std::string(), int port = 8554, int fps = 30, rtsp::RtspStreamType stream_type = rtsp::RtspStreamType::RTSP_STREAM_H265)
+
+

start

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefstart rtsp
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+

C++ defination code:

+ +
err::Err start()
+
+

start (overload 1)

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefstop rtsp
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+

C++ defination code:

+ +
err::Err stop()
+
+

bind_camera

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefBind camera
paramcamera: camera object
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+

C++ defination code:

+ +
err::Err bind_camera(camera::Camera *camera)
+
+

write

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefWrite data to rtsp
paramtype: rtsp stream type
data: rtsp stream data
fps: rtsp stream data size
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+

C++ defination code:

+ +
err::Err write(video::Frame &stream)
+
+

get_url

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet url of rtsp
returnurl of rtsp
staticFalse
+

C++ defination code:

+ +
std::string get_url()
+
+

to_camera

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet camera object from rtsp
returncamera object
staticFalse
+

C++ defination code:

+ +
camera::Camera *to_camera()
+
+

rtsp_is_start

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefreturn rtsp start status
returntrue means rtsp is start, false means rtsp is stop.
staticFalse
+

C++ defination code:

+ +
bool rtsp_is_start()
+
+

add_region

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefreturn a region object, you can draw image on the region.
paramx: region coordinate x
y: region coordinate y
width: region width
height: region height
format: region format, support Format::FMT_BGRA8888 only
returnthe reigon object
staticFalse
+

C++ defination code:

+ +
rtsp::Region *add_region(int x, int y, int width, int height, image::Format format = image::Format::FMT_BGRA8888)
+
+

update_region

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefupdate and show region
returnerror code
staticFalse
+

C++ defination code:

+ +
err::Err update_region(rtsp::Region &region)
+
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/maix/sys.html b/maixpy/api/maix/sys.html new file mode 100644 index 00000000..1141e743 --- /dev/null +++ b/maixpy/api/maix/sys.html @@ -0,0 +1,749 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix.sys - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix.sys

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.sys module

+
+

You can use maix.sys to access this module with MaixPy
+This module is generated from MaixCDK

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

os_version

+ +
def os_version() -> str
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet system version
returnversion string, e.g. "2024.4.1-13af4b"
+

C++ defination code:

+ +
std::string os_version()
+
+

device_name

+ +
def device_name() -> str
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet device name
returndevice name, e.g. "MaixCAM"
+

C++ defination code:

+ +
std::string device_name()
+
+

host_name

+ +
def host_name() -> str
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet host name
returnhost name, e.g. "maixcam-2f9f"
+

C++ defination code:

+ +
std::string host_name()
+
+

host_domain

+ +
def host_domain() -> str
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet host domain
returnhost domain, e.g. "maixcam-2f9f.local"
+

C++ defination code:

+ +
std::string host_domain()
+
+

ip_address

+ +
def ip_address() -> dict[str, str]
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet ip address
returnip address, dict type, e.g. {"eth0": "192.168.0.195", "wlan0": "192.168.0.123", "usb0": "10.47.159.1"}
+

C++ defination code:

+ +
std::map<std::string, std::string> ip_address()
+
+

mac_address

+ +
def mac_address() -> dict[str, str]
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet mac address
returnmac address, dict type, e.g. {"eth0": "00:0c:29:2f:9f:00", "wlan0": "00:0c:29:2f:9f:01", "usb0": "00:0c:29:2f:9f:02"}
+

C++ defination code:

+ +
std::map<std::string, std::string> mac_address()
+
+

device_key

+ +
def device_key() -> str
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet device key, can be unique id of device
returndevice key, 32 bytes hex string, e.g. "1234567890abcdef1234567890abcdef"
+

C++ defination code:

+ +
std::string device_key()
+
+

memory_info

+ +
def memory_info() -> dict[str, int]
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet memory info
returnmemory info, dict type, e.g. {"total": 1024, "used": 512, "hw_total": 25610241024}
total: total memory size in Byte.
used: used memory size in Byte.
hw_total: total memory size in Byte of hardware, the total <= hw_total,
OS kernel may reserve some memory for some hardware like camera, npu, display etc.
+

C++ defination code:

+ +
std::map<std::string, int> memory_info()
+
+

bytes_to_human

+ +
def bytes_to_human(bytes: int, precision: int = 2, base: int = 1024, unit: str = 'B', sep: str = ' ') -> str
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefBytes to human readable string
parambytes:: bytes size,e.g. 1234B = 1234/1024 = 1.205 KB
precision:: decimal precision, default 2
base:: base number, default 1024
unit:: unit string, e.g. "B"
sep:: separator string, e.g. " "
returnhuman readable string, e.g. "1.21 KB"
+

C++ defination code:

+ +
std::string bytes_to_human(unsigned long long bytes, int precision = 2, int base = 1024, const std::string &unit = "B", const std::string &sep = " ")
+
+

cpu_freq

+ +
def cpu_freq() -> dict[str, int]
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet CPU frequency
returnCPU frequency, dict type, e.g. {"cpu0": 1000000000, "cpu1": 1000000000}
+

C++ defination code:

+ +
std::map<std::string, unsigned long> cpu_freq()
+
+

cpu_temp

+ +
def cpu_temp() -> dict[str, float]
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet CPU temperature
returnCPU temperature, unit dgree, dict type, e.g. {"cpu": 50.0, "cpu0": 50, "cpu1": 50}
+

C++ defination code:

+ +
std::map<std::string, float> cpu_temp()
+
+

cpu_usage

+ +
def cpu_usage() -> dict[str, float]
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet CPU usage
returnCPU usage, dict type, e.g. {"cpu": 50.0, "cpu0": 50, "cpu1": 50}
+

C++ defination code:

+ +
std::map<std::string, float> cpu_usage()
+
+

npu_freq

+ +
def npu_freq() -> dict[str, int]
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet NPU frequency
returnNPU frequency, dict type, e.g. {"npu0": 500000000}
+

C++ defination code:

+ +
std::map<std::string, unsigned long> npu_freq()
+
+

disk_usage

+ +
def disk_usage(path: str = '/') -> dict[str, int]
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefGet disk usage
parampath:: disk path, default "/"
returndisk usage, dict type, e.g. {"total": 1024, "used": 512}
+

C++ defination code:

+ +
std::map<std::string, unsigned long long> disk_usage(const std::string &path = "/")
+
+

disk_partitions

+ +
def disk_partitions(only_disk: bool = True) -> list[dict[str, str]]
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefGet disk partition and mount point info
paramonly_disk: only return real disk, tempfs sysfs etc. not return, default true.
returndisk partition and mount point info, list type, e.g. [{"device": "/dev/mmcblk0p1", "mountpoint": "/mnt/sdcard", "fstype": "vfat"}]
+

C++ defination code:

+ +
std::vector<std::map<std::string, std::string>> disk_partitions(bool only_disk = true)
+
+

poweroff

+ +
def poweroff() -> None
+
+ + + + + + + + + + + + + +
itemdoc
briefPower off device
+

C++ defination code:

+ +
void poweroff()
+
+

reboot

+ +
def reboot() -> None
+
+ + + + + + + + + + + + + +
itemdoc
briefPower off device and power on
+

C++ defination code:

+ +
void reboot()
+
+

Class

+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/maix/tensor.html b/maixpy/api/maix/tensor.html new file mode 100644 index 00000000..29143225 --- /dev/null +++ b/maixpy/api/maix/tensor.html @@ -0,0 +1,1008 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix.tensor - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix.tensor

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.tensor module

+
+

You can use maix.tensor to access this module with MaixPy
+This module is generated from MaixCDK

+
+

Module

+

No module

+

Enum

+

DType

+ + + + + + + + + + + + + + + + + +
itemdoc
briefTensor data types
valuesUINT8:
INT8:
UINT16:
INT16:
UINT32:
INT32:
FLOAT16:
FLOAT32:
FLOAT64:
BOOL:
DTYPE_MAX:
+

C++ defination code:

+ +
enum DType
+        {
+            UINT8 = 0,
+            INT8,
+            UINT16,
+            INT16,
+            UINT32,
+            INT32,
+            FLOAT16,
+            FLOAT32,
+            FLOAT64,
+            BOOL,
+            // STRING,
+            // OBJECT,
+            DTYPE_MAX
+        }
+
+

Variable

+

dtype_size

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefTensor data type size in bytes
attentionIt's a copy of this variable in MaixPy,
so change it in C++ (e.g. update var in hello function) will not take effect the var inMaixPy.
So we add const for this var to avoid this mistake.
value{
1, // UINT8
1, // INT8
2, // UINT16
2, // INT16
4, // UINT32
4, // INT32
2, // FLOAT16
4, // FLOAT32
8, // FLOAT64
1, // BOOL
// 1, // STRING
// 1, // OBJECT
0
}
readonlyTrue
+

C++ defination code:

+ +
const std::vector<int> dtype_size = {
+            1, // UINT8
+            1, // INT8
+            2, // UINT16
+            2, // INT16
+            4, // UINT32
+            4, // INT32
+            2, // FLOAT16
+            4, // FLOAT32
+            8, // FLOAT64
+            1, // BOOL
+            // 1, // STRING
+            // 1, // OBJECT
+            0
+        }
+
+

dtype_name

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefTensor data type name
value{
"uint8",
"int8",
"uint16",
"int16",
"uint32",
"int32",
"float16",
"float32",
"float64",
"bool",
// "string",
// "object",
"invalid"
}
readonlyTrue
+

C++ defination code:

+ +
const std::vector<std::string> dtype_name = {
+            "uint8",
+            "int8",
+            "uint16",
+            "int16",
+            "uint32",
+            "int32",
+            "float16",
+            "float32",
+            "float64",
+            "bool",
+            // "string",
+            // "object",
+            "invalid"
+        }
+
+

Function

+

Class

+

Tensor

+ + + + + + + + + + + + + +
itemdoc
briefTensor class
+

C++ defination code:

+ +
class Tensor
+
+

__init__

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefTensor constructor
paramshape: tensor shape, a int list
dtype: tensor element data type, see DType of this module
data: pointer to data content, can be nullptr, it will automatically alloc memory
and detroy it when this object is destroyed
staticFalse
+

C++ defination code:

+ +
Tensor(std::vector<int> shape, tensor::DType dtype, void *data = nullptr)
+
+

to_str

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefTo string
staticFalse
+

C++ defination code:

+ +
std::string to_str()
+
+

__str__

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefTo string
staticFalse
+

C++ defination code:

+ +
std::string __str__()
+
+

shape

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget tensor shape
returntensor shape, a int list
staticFalse
+

C++ defination code:

+ +
std::vector<int> shape()
+
+

expand_dims

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefexpand tensor shape
paramaxis: axis to expand
staticFalse
+

C++ defination code:

+ +
void expand_dims(int axis)
+
+

reshape

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefreshape tensor shape, if size not match, it will throw an err::Exception
paramshape: new shape
staticFalse
+

C++ defination code:

+ +
void reshape(std::vector<int> shape)
+
+

flatten

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefFlatten tensor shape to 1D
staticFalse
+

C++ defination code:

+ +
void flatten()
+
+

dtype

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefget tensor data type
returntensor data type, see DType of this module
staticFalse
+

C++ defination code:

+ +
tensor::DType  dtype()
+
+

argmax

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefargmax of tensor
paramaxis: By default, the index is into the flattened array, otherwise along the specified axis., wrong axis will throw an err::Exception
returnargmax result, you need to delete it after use in C++.
staticFalse
+

C++ defination code:

+ +
tensor::Tensor *argmax(int axis = 0xffff)
+
+

argmax1

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefargmax1, flattened data max index
returnargmax result, int type
staticFalse
+

C++ defination code:

+ +
int argmax1()
+
+

Tensors

+ + + + + + + + + + + + + +
itemdoc
briefTensors
+

C++ defination code:

+ +
class Tensors
+
+

__init__

+ +
def __init__(self) -> None
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefConstructor of Tensors
staticFalse
+

C++ defination code:

+ +
Tensors()
+
+

add_tensor

+ +
def add_tensor(self, key: str, tensor: Tensor, copy: bool, auto_delete: bool) -> None
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefAdd tensor
staticFalse
+

C++ defination code:

+ +
void add_tensor(const std::string &key, tensor::Tensor *tensor, bool copy, bool auto_delete)
+
+

rm_tensor

+ +
def rm_tensor(self, key: str) -> None
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefRemove tensor
staticFalse
+

C++ defination code:

+ +
void rm_tensor(const std::string &key)
+
+

get_tensor

+ +
def get_tensor(self, key: str) -> Tensor
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet tensor by key
staticFalse
+

C++ defination code:

+ +
tensor::Tensor *get_tensor(const std::string &key)
+
+

__getitem__

+ +
def __getitem__(self, key: str) -> Tensor
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefOperator []
staticFalse
+

C++ defination code:

+ +
tensor::Tensor *operator[](const std::string &key)
+
+

__len__

+ +
def __len__(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSize
staticFalse
+

C++ defination code:

+ +
size_t size()
+
+

get_names

+ +
def get_names(self) -> list[str]
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet names
staticFalse
+

C++ defination code:

+ +
std::vector<std::string> get_names()
+
+

tensors

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefTensors data, dict type
staticFalse
readonlyFalse
+

C++ defination code:

+ +
std::map<std::string, tensor::Tensor*> tensors
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/maix/thread.html b/maixpy/api/maix/thread.html new file mode 100644 index 00000000..28f3f3ca --- /dev/null +++ b/maixpy/api/maix/thread.html @@ -0,0 +1,438 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix.thread - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix.thread

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.thread module

+
+

You can use maix.thread to access this module with MaixPy
+This module is generated from MaixCDK

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

Class

+

Thread

+ + + + + + + + + + + + + +
itemdoc
briefthread class
+

C++ defination code:

+ +
class Thread
+
+

__init__

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefcreate thread
paramfunc: direction [in], thread function, one args parameter, void* type, no return value
args: direction [in], thread function parameter
staticFalse
+

C++ defination code:

+ +
Thread(std::function<void(void *)> func, void *args = nullptr)
+
+

join

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefwait thread exit
staticFalse
+

C++ defination code:

+ +
void join()
+
+

detach

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefdetach thread
staticFalse
+

C++ defination code:

+ +
void detach()
+
+

joinable

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefCheck if thread is joinable
returntrue if thread is joinable
staticFalse
+

C++ defination code:

+ +
bool joinable()
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/maix/time.html b/maixpy/api/maix/time.html new file mode 100644 index 00000000..37f1560d --- /dev/null +++ b/maixpy/api/maix/time.html @@ -0,0 +1,1086 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix.time - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix.time

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.time module

+
+

You can use maix.time to access this module with MaixPy
+This module is generated from MaixCDK

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

time

+ +
def time() -> float
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet current time in s
returncurrent time in s, double type
+

C++ defination code:

+ +
double time()
+
+

time_ms

+ +
def time_ms() -> int
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet current time in ms
returncurrent time in ms, uint64_t type
+

C++ defination code:

+ +
uint64_t time_ms()
+
+

time_s

+ +
def time_s() -> int
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet current time in s
returncurrent time in s, uint64_t type
+

C++ defination code:

+ +
uint64_t time_s()
+
+

time_us

+ +
def time_us() -> int
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet current time in us
returncurrent time in us, uint64_t type
+

C++ defination code:

+ +
uint64_t time_us()
+
+

time_diff

+ +
def time_diff(last: float, now: float = -1) -> float
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefCalculate time difference
paramlast: last time
now: current time
returntime difference
+

C++ defination code:

+ +
double time_diff(double last, double now = -1)
+
+

sleep

+ +
def sleep(s: float) -> None
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefSleep seconds
params: seconds, double type
+

C++ defination code:

+ +
void sleep(double s)
+
+

sleep_ms

+ +
def sleep_ms(ms: int) -> None
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefSleep milliseconds
paramms: milliseconds, uint64_t type
+

C++ defination code:

+ +
void sleep_ms(uint64_t ms)
+
+

sleep_us

+ +
def sleep_us(us: int) -> None
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefSleep microseconds
paramus: microseconds, uint64_t type
+

C++ defination code:

+ +
void sleep_us(uint64_t us)
+
+

now

+ +
def now() -> DateTime
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet current UTC date and time
returncurrent date and time, DateTime type
+

C++ defination code:

+ +
time::DateTime *now()
+
+

localtime

+ +
def localtime() -> DateTime
+
+ + + + + + + + + + + + + + + + + +
itemdoc
briefGet local time
returnlocal time, DateTime type
+

C++ defination code:

+ +
time::DateTime *localtime()
+
+

strptime

+ +
def strptime(str: str, format: str) -> DateTime
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
briefDateTime from string
paramstr: date time string
format: date time format
returnDateTime
+

C++ defination code:

+ +
time::DateTime *strptime(const std::string &str, const std::string &format)
+
+

gmtime

+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
brieftimestamp to DateTime(time zone is UTC (value 0))
paramtimestamp: double timestamp
returnDateTime
+

C++ defination code:

+ +
time::DateTime *gmtime(double timestamp)
+
+

Class

+

DateTime

+ + + + + + + + + + + + + +
itemdoc
briefDate and time class
+

C++ defination code:

+ +
class DateTime
+
+

year

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefYear
staticFalse
readonlyFalse
+

C++ defination code:

+ +
int year
+
+

month

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefMonth, 1~12
staticFalse
readonlyFalse
+

C++ defination code:

+ +
int month
+
+

day

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefDay
staticFalse
readonlyFalse
+

C++ defination code:

+ +
int day
+
+

hour

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefHour
staticFalse
readonlyFalse
+

C++ defination code:

+ +
int hour
+
+

minute

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefMinute
staticFalse
readonlyFalse
+

C++ defination code:

+ +
int minute
+
+

second

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefSecond
staticFalse
readonlyFalse
+

C++ defination code:

+ +
int second
+
+

microsecond

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefMicrosecond
staticFalse
readonlyFalse
+

C++ defination code:

+ +
int microsecond
+
+

yearday

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefYear day
staticFalse
readonlyFalse
+

C++ defination code:

+ +
int yearday
+
+

weekday

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefWeekday, 0 is Monday, 6 is Sunday
staticFalse
readonlyFalse
+

C++ defination code:

+ +
int weekday
+
+

zone

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefTime zone
staticFalse
readonlyFalse
+

C++ defination code:

+ +
float zone
+
+

zone_name

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typevar
briefTime zone name
staticFalse
readonlyFalse
+

C++ defination code:

+ +
std::string zone_name
+
+

__init__

+ +
def __init__(self, year: int = 0, month: int = 0, day: int = 0, hour: int = 0, minute: int = 0, second: int = 0, microsecond: int = 0, yearday: int = 0, weekday: int = 0, zone: int = 0) -> None
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefConstructor
paramyear: year
month: month
day: day
hour: hour
minute: minute
second: second
microsecond: microsecond
yearday: year day
weekday: weekday
zone: time zone
staticFalse
+

C++ defination code:

+ +
DateTime(int year = 0, int month = 0, int day = 0, int hour = 0, int minute = 0, int second = 0, int microsecond = 0, int yearday = 0, int weekday = 0, int zone = 0)
+
+

strftime

+ +
def strftime(self, format: str) -> str
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefConvert to string
returndate time string
staticFalse
+

C++ defination code:

+ +
std::string strftime(const std::string &format)
+
+

timestamp

+ +
def timestamp(self) -> float
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefConvert to float timestamp
returnfloat timestamp
staticFalse
+

C++ defination code:

+ +
double timestamp()
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/maix/touchscreen.html b/maixpy/api/maix/touchscreen.html new file mode 100644 index 00000000..754a36e9 --- /dev/null +++ b/maixpy/api/maix/touchscreen.html @@ -0,0 +1,551 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix.touchscreen - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix.touchscreen

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.touchscreen module

+
+

You can use maix.touchscreen to access this module with MaixPy
+This module is generated from MaixCDK

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

Class

+

TouchScreen

+ + + + + + + + + + + + + +
itemdoc
briefTouchScreen class
+

C++ defination code:

+ +
class TouchScreen
+
+

__init__

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefConstruct a new TouchScreen object
paramdevice: touchscreen device path, you can get devices by list_devices method, by default(value is NULL(None in MaixPy)) means the first device
open: If true, touchscreen will automatically call open() after creation. default is true.
staticFalse
+

C++ defination code:

+ +
TouchScreen(const std::string &device = "", bool open = true)
+
+

open

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefopen touchscreen device
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+

C++ defination code:

+ +
err::Err open()
+
+

close

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefclose touchscreen device
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+

C++ defination code:

+ +
err::Err close()
+
+

read

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefread touchscreen device
attentionThis method will discard same event in buffer, that is:
if too many move event in buffer when call this method, it will only return the last one,
and if read pressed or released event, it will return immediately.
returnReturns a list include x, y, pressed state
staticFalse
+

C++ defination code:

+ +
std::vector<int> read()
+
+

read (overload 1)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefread touchscreen device
attentionThis method will return immediately if have event, so it's better to use available() to check if have more event in buffer,
or too much event in buffer when your program call this read() interval is too long will make your program slow.
returnReturns a list include x, y, pressed state
staticFalse
+

C++ defination code:

+ +
std::vector<int> read0()
+
+

available

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefIf we need to read from touchscreen, for event driven touchscreen means have event or not
paramtimeout: -1 means block, 0 means no block, >0 means timeout, default is 0, unit is ms.
returntrue if need to read(have event), false if not
staticFalse
+

C++ defination code:

+ +
bool available(int timeout = 0)
+
+

is_opened

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefCheck if touchscreen is opened
returntrue if touchscreen is opened, false if not
staticFalse
+

C++ defination code:

+ +
bool is_opened()
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/maix/util.html b/maixpy/api/maix/util.html new file mode 100644 index 00000000..14bdeaed --- /dev/null +++ b/maixpy/api/maix/util.html @@ -0,0 +1,347 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix.util - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix.util

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.util module

+
+

You can use maix.util to access this module with MaixPy
+This module is generated from MaixCDK

+
+

Module

+

No module

+

Enum

+

Variable

+

Function

+

disable_kernel_debug

+ +
def disable_kernel_debug() -> None
+
+ + + + + + + + + + + + + +
itemdoc
briefdisable the kernel debug
+

C++ defination code:

+ +
void disable_kernel_debug()
+
+

enable_kernel_debug

+ +
def enable_kernel_debug() -> None
+
+ + + + + + + + + + + + + +
itemdoc
briefdisable the kernel debug
+

C++ defination code:

+ +
void enable_kernel_debug()
+
+

Class

+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/maix/video.html b/maixpy/api/maix/video.html new file mode 100644 index 00000000..58f933a7 --- /dev/null +++ b/maixpy/api/maix/video.html @@ -0,0 +1,1108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maix.video - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

maix.video

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

maix.video module

+
+

You can use maix.video to access this module with MaixPy
+This module is generated from MaixCDK

+
+

Module

+

No module

+

Enum

+

VideoType

+ + + + + + + + + + + + + + + + + +
itemdoc
briefVideo type
valuesVIDEO_NONE: format invalid
VIDEO_ENC_H265_CBR:
VIDEO_ENC_MP4_CBR:
VIDEO_DEC_H265_CBR:
VIDEO_DEC_MP4_CBR:
+

C++ defination code:

+ +
enum VideoType
+    {
+        VIDEO_NONE = 0,  // format invalid
+        VIDEO_ENC_H265_CBR,
+        VIDEO_ENC_MP4_CBR,
+        VIDEO_DEC_H265_CBR,
+        VIDEO_DEC_MP4_CBR,
+    }
+
+

Variable

+

Function

+

Class

+

Frame

+ + + + + + + + + + + + + +
itemdoc
briefFrame class
+

C++ defination code:

+ +
class Frame
+
+

Packet

+ + + + + + + + + + + + + +
itemdoc
briefPacket class
+

C++ defination code:

+ +
class Packet
+
+

__init__

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefPacket number (pair of numerator and denominator).
paramdata: src data pointer, use pointers directly without copying.
Note: this object will try to free this memory
len: data len
pts: presentation time stamp. unit: time_base
dts: decoding time stamp. unit: time_base
duration: packet display time. unit: time_base
staticFalse
+

C++ defination code:

+ +
Packet(uint8_t *data, int len, uint64_t pts = -1, uint64_t dts = -1, int64_t duration = 0)
+
+

get

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet raw data of packet
returnraw data
staticFalse
+

C++ defination code:

+ +
std::vector<uint8_t> get()
+
+

data

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet raw data of packet
returnraw data
staticFalse
+

C++ defination code:

+ +
uint8_t *data()
+
+

data_size

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet raw data size of packet
returnsize of raw data
staticFalse
+

C++ defination code:

+ +
size_t data_size()
+
+

is_valid

+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefCheck packet is valid
returntrue, packet is valid; false, packet is invalid
staticFalse
+

C++ defination code:

+ +
bool is_valid()
+
+

set_pts

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSet pts
parampts: presentation time stamp. unit: time_base
returntrue, packet is valid; false, packet is invalid
staticFalse
+

C++ defination code:

+ +
void set_pts(uint64_t pts)
+
+

set_dts

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSet dts
paramdts: decoding time stamp. unit: time_base
returntrue, packet is valid; false, packet is invalid
staticFalse
+

C++ defination code:

+ +
void set_dts(uint64_t dts)
+
+

set_duration

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefSet duration
paramduration: packet display time. unit: time_base
returntrue, packet is valid; false, packet is invalid
staticFalse
+

C++ defination code:

+ +
void set_duration(uint64_t duration)
+
+

Video

+ + + + + + + + + + + + + +
itemdoc
briefVideo class
+

C++ defination code:

+ +
class Video
+
+

__init__

+ +
def __init__(self, path: str = '', width: int = 2560, height: int = 1440, format: maix.image.Format = ..., time_base: int = 30, framerate: int = 30, capture: bool = False, open: bool = True) -> None
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefConstruct a new Video object
parampath: video path. the path determines the location where you load or save the file, if path is none, the video module will not save or load file.
xxx.h265 means video format is H265, xxx.mp4 means video format is MP4
width: picture width. this value may be set automatically. default is 2560.
height: picture height. this value may be set automatically. default is 1440.
format: picture pixel format. this value may be set automatically. default is FMT_YVU420SP.
time_base: frame time base. time_base default is 30, means 1/30 ms
framerate: frame rate. framerate default is 30, means 30 frames per second
for video. 1/time_base is not the average frame rate if the frame rate is not constant.
capture: enable capture, if true, you can use capture() function to get an image object
open: If true, video will automatically call open() after creation. default is true.
staticFalse
+

C++ defination code:

+ +
Video(std::string path = std::string(), int width = 2560, int height = 1440, image::Format format = image::Format::FMT_YVU420SP, int time_base = 30, int framerate = 30, bool capture = false, bool open = true)
+
+

open

+ +
def open(self, path: str = '', fps: float = 30.0) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefOpen video and run
parampath: video path. the path determines the location where you load or save the file, if path is none, the video module will not save or load file.
xxx.h265 means video format is H265, xxx.mp4 means video format is MP4
fps: video fps
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+

C++ defination code:

+ +
err::Err open(std::string path = std::string(), double fps = 30.0)
+
+

close

+ +
def close(self) -> None
+
+ + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefClose video
staticFalse
+

C++ defination code:

+ +
void close()
+
+

bind_camera

+ +
def bind_camera(self, camera: maix.camera.Camera) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefBind camera
paramcamera: camera object
returnerror code, err::ERR_NONE means success, others means failed
staticFalse
+

C++ defination code:

+ +
err::Err bind_camera(camera::Camera *camera)
+
+

encode

+ +
def encode(self, img: maix.image.Image = ...) -> Packet
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefEncode image.
paramimg: the image will be encode.
if the img is NULL, this function will try to get image from camera, you must use bind_camera() function to bind the camera.
returnencode result
staticFalse
+

C++ defination code:

+ +
video::Packet *encode(image::Image *img = maix::video::Video::NoneImage)
+
+

decode

+ +
def decode(self, frame: Frame = None) -> maix.image.Image
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefDecode frame
paramframe: the frame will be decode
returndecode result
staticFalse
+

C++ defination code:

+ +
image::Image *decode(video::Frame *frame = nullptr)
+
+

finish

+ +
def finish(self) -> maix.err.Err
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefEncode or decode finish
returnerror code
staticFalse
+

C++ defination code:

+ +
err::Err finish()
+
+

capture

+ +
def capture(self) -> maix.image.Image
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefCapture image
attentionEach time encode is called, the last captured image will be released.
returnerror code
staticFalse
+

C++ defination code:

+ +
image::Image *capture()
+
+

is_recording

+ +
def is_recording(self) -> bool
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefCheck if video is recording
returntrue if video is recording, false if not
staticFalse
+

C++ defination code:

+ +
bool is_recording()
+
+

is_opened

+ +
def is_opened(self) -> bool
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefCheck if video is opened
returntrue if video is opened, false if not
staticFalse
+

C++ defination code:

+ +
bool is_opened()
+
+

is_closed

+ +
def is_closed(self) -> bool
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefcheck video device is closed or not
returnclosed or not, bool type
staticFalse
+

C++ defination code:

+ +
bool is_closed()
+
+

width

+ +
def width(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet video width
returnvideo width
staticFalse
+

C++ defination code:

+ +
int width()
+
+

height

+ +
def height(self) -> int
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
itemdoc
typefunc
briefGet video height
returnvideo height
staticFalse
+

C++ defination code:

+ +
int height()
+
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/api/sidebar.yaml b/maixpy/api/sidebar.yaml new file mode 100644 index 00000000..fb0d444a --- /dev/null +++ b/maixpy/api/sidebar.yaml @@ -0,0 +1,111 @@ +items: +- file: README.md + label: Brief +- collapsed: false + items: + - collapsed: false + file: maix/err.md + label: err + - collapsed: false + file: maix/tensor.md + label: tensor + - collapsed: false + file: maix/image.md + label: image + - collapsed: false + file: maix/camera.md + label: camera + - collapsed: false + file: maix/display.md + label: display + - collapsed: false + file: maix/video.md + label: video + - collapsed: false + file: maix/touchscreen.md + label: touchscreen + - collapsed: false + file: maix/rtsp.md + label: rtsp + - collapsed: false + file: maix/network.md + items: + - collapsed: false + file: maix/network/wifi.md + label: wifi + label: network + - collapsed: false + file: maix/comm.md + label: comm + - collapsed: false + file: maix/peripheral.md + items: + - collapsed: false + file: maix/peripheral/adc.md + label: adc + - collapsed: false + file: maix/peripheral/spi.md + label: spi + - collapsed: false + file: maix/peripheral/uart.md + label: uart + - collapsed: false + file: maix/peripheral/key.md + label: key + - collapsed: false + file: maix/peripheral/i2c.md + label: i2c + - collapsed: false + file: maix/peripheral/pinmap.md + label: pinmap + - collapsed: false + file: maix/peripheral/timer.md + label: timer + - collapsed: false + file: maix/peripheral/pwm.md + label: pwm + - collapsed: false + file: maix/peripheral/gpio.md + label: gpio + - collapsed: false + file: maix/peripheral/wdt.md + label: wdt + label: peripheral + - collapsed: false + file: maix/util.md + label: util + - collapsed: false + file: maix/time.md + label: time + - collapsed: false + file: maix/app.md + label: app + - collapsed: false + file: maix/example.md + label: example + - collapsed: false + file: maix/i18n.md + label: i18n + - collapsed: false + file: maix/fs.md + label: fs + - collapsed: false + file: maix/protocol.md + label: protocol + - collapsed: false + file: maix/sys.md + label: sys + - collapsed: false + file: maix/thread.md + label: thread + - collapsed: false + file: maix/nn.md + items: + - collapsed: false + file: maix/nn/F.md + label: F + label: nn + - collapsed: false + file: maix/audio.md + label: audio + label: maix diff --git a/maixpy/config.json b/maixpy/config.json new file mode 100644 index 00000000..7689a260 --- /dev/null +++ b/maixpy/config.json @@ -0,0 +1,5 @@ +{ + "import": "config_zh", + "class": "md_page", + "name": "MaixPy 页面" +} diff --git a/maixpy/doc/assets/maixvision_browser.jpg b/maixpy/doc/assets/maixvision_browser.jpg new file mode 100644 index 00000000..3bcda9b9 Binary files /dev/null and b/maixpy/doc/assets/maixvision_browser.jpg differ diff --git a/maixpy/doc/assets/maixvision_browser2.jpg b/maixpy/doc/assets/maixvision_browser2.jpg new file mode 100644 index 00000000..94c2895c Binary files /dev/null and b/maixpy/doc/assets/maixvision_browser2.jpg differ diff --git a/maixpy/doc/en/audio/recognize.html b/maixpy/doc/en/audio/recognize.html new file mode 100644 index 00000000..9987d537 --- /dev/null +++ b/maixpy/doc/en/audio/recognize.html @@ -0,0 +1,338 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/basic/app.html b/maixpy/doc/en/basic/app.html new file mode 100644 index 00000000..85f7e801 --- /dev/null +++ b/maixpy/doc/en/basic/app.html @@ -0,0 +1,364 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + App development and app stores - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

App development and app stores

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

Introduction to Application Ecosystem

+

In order to make the development board ready to use out of the box, make it easy for users to use without barriers, enable developers to share their interesting applications, and provide effective channels for receiving feedback and even profits, we have launched a simple application framework, including:

+
    +
  • App Store: Developers can upload and share applications, which users can download and use without needing to develop them. Developers can receive certain cash rewards (from MaixHub or user tips).
  • +
  • Pre-installed Apps: The official provides some commonly used applications, such as color block detection, AI object detection tracking, QR code scanning, face recognition, etc., which users can use directly or use as serial module.
  • +
  • MaixPy + MaixCDK Software Development Kit: Using MaixPy or MaixCDK, you can quickly develop embedded AI visual and audio applications in Python or C/C++, efficiently realizing your interesting ideas.
  • +
  • MaixVision Desktop Development Tool: A brand-new desktop code development tool for quick start, debugging, running, uploading code, installing applications to devices, one-click development, and even support for graphical block-based programming, making it easy for elementary school students to get started.
  • +
+

Everyone is welcome to pay attention to the App Store and share their applications in the store to build a vibrant community together.

+

Packaging Applications

+

Using MaixPy + MaixVison makes it easy to develop, package, and install applications:

+
    +
  • Develop applications with MaixPy in MaixVision, which can be a single file or a project directory.
  • +
  • Connect the device.
  • +
  • Click the "Install" button at the bottom-left corner of MaixVision, fill in the basic information of the application in the popup window, where the ID is used to identify the application. A device cannot simultaneously install different applications with the same ID, so the ID should be different from the IDs of applications on MaixHub. The application name can be duplicated. You can also upload an icon.
  • +
  • Click "Package Application" to package the application into an installer. If you want to upload it to the MaixHub App Store, you can use this packaged file.
  • +
  • Click "Install Application" to install the packaged application on the device.
  • +
  • Disconnect from the device, and you will see your application in the device's app selection interface. Simply click on it to run the application.
  • +
+
+

If you develop with MaixCDK, you can use maixcdk release to package an application. Refer to the MaixCDK documentation for specifics.

+
+

Exiting Applications

+

If you have developed a relatively simple application without a user interface and a back button, you can exit the application by pressing the device's function button (usually labeled as USER, FUNC, or OK) or the back button (if available, MaixCAM does not have this button by default).

+

Basic Guidelines for Application Development

+
    +
  • Since touchscreens are standard, it is recommended to create a simple interface with touch interaction. You can refer to examples for implementation methods.
  • +
  • Avoid making interfaces and buttons too small, as MaixCAM default screen is 2.3 inches with 552x368 resolution and high PPI. Make sure fingers can easily tap without making mistakes.
  • +
  • Implement a simple serial interaction for the main functionality of each application based on the serial protocol (see example). This way, users can directly use it as a serial module. For instance, in a face detection application, you can output coordinates via serial port when a face is detected.
  • +
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/basic/app_usage.html b/maixpy/doc/en/basic/app_usage.html new file mode 100644 index 00000000..319a6553 --- /dev/null +++ b/maixpy/doc/en/basic/app_usage.html @@ -0,0 +1,338 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Application User Guide - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

Application User Guide

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

After powering on, it will automatically enter the application selection interface, where various built-in applications are available in the MaixHub App Store. Here you can find descriptions and instructions for using each corresponding application.

+

The commonly used settings are Settings -> Language, as well as Settings -> WiFi. The App Store application can be used for upgrading and installing applications. Once connected to a WiFi network that has internet access, you can scan and install applications from the MaixHub App Store.

+

Moreover, applications you develop can also be uploaded to the MaixHub App Store to share with others. High-quality and outstanding applications will receive official red envelope rewards, and excellent applications will gain recognition and support from everyone.

+

Whether it's a simple application for collecting sensor data or a complex function application, let's work together to create more interesting things!

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/basic/linux_basic.html b/maixpy/doc/en/basic/linux_basic.html new file mode 100644 index 00000000..476e8a9b --- /dev/null +++ b/maixpy/doc/en/basic/linux_basic.html @@ -0,0 +1,383 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Basic Knowledge of Linux - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

Basic Knowledge of Linux

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

Introduction

+

For beginners just starting out, you can skip this chapter for now and come back to it after mastering the basics of MaixPy development.

+

The latest MaixPy supports running Linux on the MaixCAM hardware, so the underlying MaixPy development is based on the Linux system. Although Sipeed has done a lot of work for developers with MaixPy, making it possible to enjoy using it without knowledge of the Linux system, there might be situations where some low-level operations are necessary or for the convenience of developers unfamiliar with Linux. In this section, we will cover some basic Linux knowledge.

+

Why Linux System is Needed

+

Specific reasons can be researched individually. Here are a few examples in simplified terms that may not sound too technical but are easy for beginners to understand:

+
    +
  • In microcontrollers, our program is usually a loop, but with Linux, we can run multiple programs simultaneously, each appearing to run independently, where the actual execution is handled by the operating system.
  • +
  • With a large community of Linux-based developers, required functionalities and drivers can be easily found without the need to implement them from scratch.
  • +
  • Linux offers a rich set of accompanying software tools for convenient development and debugging. Some Linux common tools not mentioned in this tutorial can theoretically be used as well.
  • +
+

File System

+

What is a file system?

+
    +
  • Similar to a computer's file system, Linux manages hardware disks using a file system, making it easy for us to read and write data to the disk.
  • +
  • For students who have learned about microcontrollers but not familiar with file system development, imagine having a Flash or TF card where data can be read and written through APIs even after power loss. However, Flash has read/write limitations, requiring a program to ensure its longevity. A file system is like a mature program that manages the Flash space and read/write operations. By calling the file system's APIs, we can significantly reduce development work and ensure stability and security with proven programs.
  • +
+

Transferring Files between Computer and Device (Development Board)

+

Since the device has Linux and a file system, how do we send files to it?

+

For MaixPy, we offer MaixVision for file management in future versions. Before that, you can use the following method:

+

Here we mainly discuss transferring files through the network. Other methods can be explored on your own by searching for "transferring files to Linux":

+
    +
  • Ensure the device and computer are connected to the same local network, for example:
      +
    • When the MaixCAM's USB port is connected to the computer, a virtual network card is created which can be seen in the device manager on the computer, and the device's IP can be found in the device's Settings -> Device Information.
    • +
    • Alternatively, connect to the same local network on the device through Settings -> WiFi.
    • +
    +
  • +
  • Use SCP or SFTP protocols on the computer to transfer files to the device. There are many specific software options and methods, such as:
      +
    • On Windows, you can use WinSCP, FileZilla, or the scp command.
    • +
    • On Linux, use FileZilla or the scp command.
    • +
    • On Mac, use FileZilla or the scp command.
    • +
    +
  • +
+

Terminal and Command Line

+

The terminal is a tool for communicating with and operating the Linux system, similar to Windows' cmd or PowerShell.

+

For example, we can enter ssh root@maixcam-xxxx.local in the Terminal tool on a Windows system with PowerShell or on a Linux system. You can find the specific name in the device's Settings->Device Information, which allows us to connect to the device through the terminal (both username and password are root).

+

Then, we can operate the device by entering commands. For instance, the ls command can list the files in the current directory of the device, while cd is used to switch to a different directory (similar to clicking folders in file management on a computer),

+ +
cd /     # Switch to the root directory
+ls       # Display all files in the current directory (root directory)
+
+

This will display similar content as below:

+ +
bin         lib         media       root        tmp
+boot        lib64       mnt         run         usr
+dev         linuxrc     opt         sbin        var
+etc         lost+found  proc        sys
+
+

For more command learning, please search for Linux command line usage tutorials on your own. This is just to introduce beginners to basic concepts so that when developers mention them, they can understand what they mean.

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/basic/maixpy_upgrade.html b/maixpy/doc/en/basic/maixpy_upgrade.html new file mode 100644 index 00000000..0625c6cb --- /dev/null +++ b/maixpy/doc/en/basic/maixpy_upgrade.html @@ -0,0 +1,348 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Update MaixPy. - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

Update MaixPy.

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

There are two methods to begin with. If you are new to this and want to keep things simple, you can try using the pre-installed MaixPy firmware on the TF card that comes with the device. You can consider updating it later.

+

However, since we don't know when the TF card you received was manufactured, it is recommended to update the system.

+

Updating the System Directly

+

Follow the steps in Upgrading and Flashing the System to upgrade to the latest system, which already includes the newest MaixPy firmware.

+

Updating Only the MaixPy Firmware

+

Check the latest version information and release notes in the MaixPy repository release page. It includes details about the MaixPy firmware and the system information corresponding to each version.

+

If you prefer not to update the system (since system changes are usually minimal, you can check if there are any system-related changes in the MaixPy update notes before deciding whether to update the system), you can simply update the MaixPy firmware.

+
    +
  • Set up WiFi in the settings to connect the system to the internet.
  • +
  • Click on Update MaixPy in the settings app to proceed with the update.
  • +
+
+

If you are comfortable using the terminal, you can also update MaixPy by using pip install MaixPy -U in the terminal.

+
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/basic/maixvision.html b/maixpy/doc/en/basic/maixvision.html new file mode 100644 index 00000000..9dddf5bf --- /dev/null +++ b/maixpy/doc/en/basic/maixvision.html @@ -0,0 +1,417 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixVision -- MaixPy Programming IDE + Graphical Block Programming - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixVision -- MaixPy Programming IDE + Graphical Block Programming

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

Introduction

+

MaixVision is a development tool specifically designed for the Maix ecosystem, supporting MaixPy programming and graphical block programming. It allows for online operation and debugging, real-time image preview, and synchronizing images from device displays, which is convenient for debugging and development.

+

It also supports packaging and installing applications on devices, allowing users to easily generate and install applications with one click.

+

In addition, it integrates several handy tools for development, such as file management, threshold editor, QR code generator, and more.

+

Download

+

Visit the MaixVision homepage to download.

+

Using MaixPy Programming and Online Running

+

Follow the steps in Quick Start to connect your device, and you can easily use MaixPy programming and run it online.

+

Real-time Image Preview

+

MaixPy provides a display module that can show images on the screen. Also, when the show method of the display module is called, it sends the image to be displayed on MaixVision, for example:

+ +
from maix import display, camera
+
+cam = camera.Camera(640, 480)
+disp = display.Display()
+while 1:
+    disp.show(cam.read())
+
+

Here we use the camera to capture an image, then display it on the screen using the disp.show() method, and also send it to MaixVision for display.

+

When we click the 'pause' button in the top right corner, it will stop sending images to MaixVision.

+

Code Auto Completion

+

Code suggestions depend on local Python packages installed on your computer. To enable code suggestions, you need to install Python on your computer and the required Python packages.

+
    +
  • To install Python, visit the Python official website.
  • +
  • To install the required packages, for MaixPy, for instance, you need to install the MaixPy package on your computer using pip install MaixPy. If MaixPy gets updated, you should update it on both your computer and device. On your computer, manually execute pip install MaixPy -U in the terminal. For device updates, update directly in the Settings application.
  • +
+
+

Users in China can use a local mirror pip install -i https://pypi.tuna.tsinghua.edu.cn/simple MaixPy.

+
+
    +
  • Restart MaixVision to see the code suggestions.
  • +
+
+

If suggestions still do not appear, you can manually set the path to the Python executable in settings and restart.

+
+
+

Note that installing Python packages on your computer is just for code suggestions. The actual code runs on the device (development board), and the device must also have the corresponding packages to run properly.

+
+
+

Additionally, while you have the MaixPy package installed on your computer, due to our limited resources, we cannot guarantee that you can directly use the Maix package in your computer's Python. Please run it on supported devices.

+
+

Calculating the Image Histogram

+

In the previous step, we could see the image in real-time in MaixVision. By selecting an area with the mouse, we can view the histogram for that area at the bottom of the screen, displaying different color channels.

+

This feature is helpful when finding suitable parameters for some image processing algorithms.

+

Distinguishing Between Device File System and Computer File System

+

Here we have an important concept to grasp: distinguish between the Device File System and the Computer File System.

+
    +
  • Computer File System: Operates on the computer. Opening a file or project in MaixVision accesses files on the computer, and saving is automatically done to the computer's file system.
  • +
  • Device File System: The program sends the code to the device for execution, so the files used in the code are read from the device's file system.
  • +
+

A common issue is when students save a file on the computer, such as D:\data\a.jpg, and then use this file on the device with img = image.load("D:\data\a.jpg"). Naturally, the file cannot be found because the device does not have D:\data\a.jpg.

+

For specifics on how to send files from the computer to the device, refer to the following section.

+

Transferring Files to the Device

+

First, connect to the device, then click the button to browse the device file system, as shown below. Then you can upload files to the device or download files to the computer.

+

maixvision_browser2

+

maixvision_browser

+
+Alternatively, other tools can be used, click to expand +

First, know the device's IP address or name, which MaixVision can find, or see in the device's Settings->System Information, such as maixcam-xxxx.local or 192.168.0.123.
+ The username and password are root, using the SFTP protocol for file transfer, and the port number is 22.

+

There are many useful tools available for different systems:

+

Windows

+

Use WinSCP or FileZilla to connect to the device and transfer files, choosing the SFTP protocol and entering the device and account information to connect.

+

Specific instructions can be searched online.

+

Linux

+

In the terminal, use the scp command to transfer files to the device, such as:

+ +
scp /path/to/your/file.py root@maixcam-xxxx.local:/root
+
+

Mac

+
    +
  • Method 1: In the terminal, use the scp command to transfer files to the device, such as:
  • +
+ +
scp /path/to/your/file.py root@maixcam-xxxx.local:/root
+
+
    +
  • Method 2: Use FileZilla or other tools to connect to the device and transfer files, choosing the SFTP protocol and entering the device and account information to connect.
  • +
+
+
+

Using Graphical Block Programming

+

Under development, please stay tuned.

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/basic/os.html b/maixpy/doc/en/basic/os.html new file mode 100644 index 00000000..246a5260 --- /dev/null +++ b/maixpy/doc/en/basic/os.html @@ -0,0 +1,355 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Upgrade and burn system. - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

Upgrade and burn system.

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

Introduction

+

If you have purchased the official (Sipeed) package with a TF card, typically the system has already been pre-programmed at the factory and can be used directly without further steps.

+

However, to avoid using an outdated version of the pre-programmed system, it is highly recommended to first upgrade to the latest system following the tutorial.

+

How to Confirm if System Upgrade is Needed

+
    +
  • Upon booting up to the main menu, click on Settings, then Device Info to check the system's version number.

    +
  • +
  • Visit the MaixPy Release History page to review the update logs, which contain information on MaixPy firmware and system image updates. If there are significant updates after your current version, it is advisable to upgrade.

    +
    +

    If the latest system update only includes routine MaixPy firmware updates compared to your current system, you may choose not to upgrade. You can simply update MaixPy separately in Settings under Update MaixPy.

    +
    +
  • +
+

Obtaining the Latest System

+

Visit the MaixPy Release page to find the latest system image file, such as maixcam_os_20240401_maixpy_v4.1.0.xz.

+

Alternate link:

+ +

Burning the System Image to MaixCAM

+

Refer to the MaixCAM System Flashing Guide.

+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/basic/python.html b/maixpy/doc/en/basic/python.html new file mode 100644 index 00000000..2f38f204 --- /dev/null +++ b/maixpy/doc/en/basic/python.html @@ -0,0 +1,375 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Basic Knowledge of Python - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

Basic Knowledge of Python

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

The tutorial documentation of MaixPy does not delve into specific Python syntax tutorials because there are already too many excellent Python tutorials available. Here, we only introduce what needs to be learned, provide guidance on directions and paths.

+

Introduction to Python

+

Python is an interpreted, object-oriented, dynamically typed high-level programming language.

+
    +
  • Interpreted: It does not require compilation, runs directly. The advantage is rapid development, while a minor drawback is the slower execution speed due to code interpretation on each run. However, most often, the bottleneck lies in the developer's code rather than the language itself.
  • +
  • Object-oriented: It supports object-oriented programming, allowing the definition of classes and objects. Compared to procedural languages, it is easier to organize code. For more details, please search independently.
  • +
  • Dynamically typed: Variables do not need to declare types, can be assigned directly, and the type will be automatically determined based on the assignment. This reduces code volume, but can also lead to type errors, requiring the developer's attention.
  • +
+

In conclusion, for developers unfamiliar with Python, it is very easy to get started as Python offers plenty of ready-to-use libraries, a large developer community, short application development cycles, making it highly worthwhile to learn!

+

Python Environment Setup

+

You can install Python on your computer according to the Python tutorial you are following for learning.
+Alternatively, you can connect to a device via MaixVision on MaixVision and then run the program on the development board.

+

What Python Basics are Needed to Use MaixPy?

+
    +
  • Basic concepts of Python.
  • +
  • Basic concepts of object-oriented programming.
  • +
  • Basic syntax of Python, including:
      +
    • Tab indentation alignment syntax.
    • +
    • Variables, functions, classes, objects, comments, etc.
    • +
    • Control statements such as if, for, while, etc.
    • +
    • Modules and importing modules.
    • +
    • Basic data types such as int, float, str, list, dict, tuple, etc.
    • +
    • Difference between bytes and str, and conversion.
    • +
    • Exception handling, try-except.
    • +
    • Common built-in functions like print, open, len, range, etc.
    • +
    • Common built-in modules like os, sys, time, random, math, etc.
    • +
    +
  • +
+

Mastering the above foundational knowledge will enable you to smoothly program with MaixPy. With the help of subsequent tutorials and examples, if unsure, you can refer to search engines, official documentation, or ask ChatGPT to successfully complete your development tasks.

+

For Developers Experienced in Another Object-Oriented Programming Language

+

If you are already proficient in an object-oriented language like C++/Java/C#, you simply need to quickly review Python syntax before starting to use it.

+

You can refer to resources like Runoob Tutorial or the Python Official Tutorial.

+

Alternatively, you can explore individual developers' blogs, such as Wow! It's Python.

+

For Developers with C Language Experience but No Object-Oriented Programming Experience

+

If you only know C and lack understanding of object-oriented concepts, you can start by learning about object-oriented programming concepts before diving into Python. It's relatively quick and you can search for video tutorials for entry-level guidance.

+

After following introductory video tutorials, you can then refer to documentation tutorials such as Runoob Tutorial or the Python Official Tutorial to get started!

+

Once you have acquired the basic knowledge, you can start using MaixPy for programming based on the documentation and examples.

+

For Programming Beginners

+

If you have never dealt with programming before, you will need to start learning Python from scratch. Python is also quite suitable as an introductory language. You can search for video tutorials for specific guidance.

+

After mastering the basic syntax, you will be able to use MaixPy for programming by following examples provided.

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/basic/python_pkgs.html b/maixpy/doc/en/basic/python_pkgs.html new file mode 100644 index 00000000..497ece32 --- /dev/null +++ b/maixpy/doc/en/basic/python_pkgs.html @@ -0,0 +1,353 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Add extra Python packages. - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

Add extra Python packages.

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

Introduction

+

MaixPy is based on the Python language and provides a wide range of functionalities and APIs for embedded application development. In addition to this, you can also use other Python packages to extend its functionality.

+

Installing Additional Python Packages

+
+

Please note that not all Python packages are supported. Generally, only pure Python packages are supported, not C extension packages. C extension packages may require you to manually cross-compile them on a computer (which is quite complex and won't be covered here).

+
+

Method 1: Installing Using Python Code

+

You can install the package you need in MaixVision using Python code, for example:

+ +
import os
+os.system("pip install package_name")
+
+

To update a package, you can use:

+ +
import os
+os.system("pip install --upgrade package_name")
+
+

Method 2: Installing Using the Terminal and pip Command

+

Follow the terminal usage method introduced in Linux Basics and use pip install package_name to install the package you need.

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/config.json b/maixpy/doc/en/config.json new file mode 100644 index 00000000..2c779f44 --- /dev/null +++ b/maixpy/doc/en/config.json @@ -0,0 +1,4 @@ +{ + "import": "config_en", + "name": "MaixPy English Documentation" +} diff --git a/maixpy/doc/en/faq.html b/maixpy/doc/en/faq.html new file mode 100644 index 00000000..a4935908 --- /dev/null +++ b/maixpy/doc/en/faq.html @@ -0,0 +1,393 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy FAQ (Frequently Asked Questions) - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy FAQ (Frequently Asked Questions)

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

This page lists common questions and solutions related to MaixPy. If you encounter any issues, please search for answers here first.
+If you cannot find an answer on this page, you can post your question with detailed steps on the MaixHub Discussion Forum.

+

If you use MaixCAM, you can also refer to MaixCAM FAQ

+

MaixVision cannot find the device?

+

First, confirm whether the connection method is WiFi or USB cable.
+WiFi:

+
    +
  • Ensure that WiFi is correctly connected and has obtained an IP address. You can view the ip in Settings -> Device Info or Settings -> WiFi.
  • +
+

USB Cable:

+
    +
  • Ensure that the device is connected to the computer via a Type-C data cable, and the device is powered on and has entered the function selection interface.
  • +
  • Ensure that the device driver is installed:
      +
    • On Windows, check if there is a USB virtual network adapter device in Device Manager. If there is an exclamation mark, it means the driver is not installed properly. Follow the instructions in Quick Start to install the driver.
    • +
    • On Linux, you can check if there is a usb0 device by running ifconfig or ip addr, or check all USB devices with lsusb. Linux already includes the driver, so if the device is not recognized, check the hardware connection, ensure the device system is up-to-date, and ensure the device has booted up properly.
    • +
    • On macOS, follow the same steps as Linux.
    • +
    +
  • +
  • Additionally, check the quality of the USB cable and try using a high-quality cable.
  • +
  • Additionally, check the quality of the computer's USB port. For example, some small form factor PCs have poor EMI design on their USB ports, and connecting a good quality USB hub may allow the device to work. You can also try a different USB port or a different computer.
  • +
+

MaixVision camera example shows choppy video

+

The default GC4653 camera has a maximum frame rate of 30 frames per second (FPS). Under normal circumstances, the MaixVision display should not appear choppy to the naked eye. If choppiness occurs, first consider transmission issues:

+
    +
  • Check the network connection quality, such as WiFi.
  • +
  • If using a USB connection, check the USB cable quality, computer USB port quality, and try using a different computer, USB port, or USB cable for comparison.
  • +
+

What is the difference between MaixPy v4 and v1/v3?

+
    +
  • MaixPy v4 uses the Python language and is the culmination of the experiences from v1 and v3, offering better supporting software and ecosystem, more features, simpler usage, and more comprehensive documentation. While the hardware has significant improvements, the pricing is even more affordable compared to the other two versions. Additionally, it provides compatibility with the K210 user experience and API, making it easier for users to migrate quickly from v1 to v4.
  • +
  • v1 used the Micropython language and had many limitations, such as limited third-party library support. Additionally, due to the hardware performance limitations of the Maix-I (K210), there was not enough memory, limited AI model support, and lack of hardware acceleration for many codecs.
  • +
  • v3 also used the Python language and was based on the Maix-II-Dock (v831) hardware. However, the hardware had limited AI model support, and the Allwinner ecosystem was not open enough, with an incomplete API. This version was only intended for use with the Maix-II-Dock (v831) and will not receive further updates.
  • +
+

Does MaixPy currently only support MaixCAM, or can it work with other boards using the same chipset?

+

MaixPy currently only supports the MaixCAM series of boards. Other boards using the same chipset, including Sipeed's boards like the LicheeRV-Nano, are not supported. It is strongly recommended not to attempt using MaixPy with other boards, as it may result in device damage (such as smoke or screen burn), for which you will be solely responsible.

+

In the future, Sipeed's Maix series of products will continue to be supported by MaixPy. If you have any needs that cannot be met by MaixCAM, you can post your requirements on the MaixHub Discussion Forum or send an email to support@sipeed.com.

+

Can I use a camera or screen other than the officially bundled ones?

+

It is not recommended to use cameras or screens other than the officially bundled ones, unless you have sufficient software and hardware knowledge and experience. Otherwise, it may result in device damage.

+

The officially bundled accessories have been fine-tuned for both software and hardware, ensuring the best performance and allowing for out-of-the-box usage. Other accessories may have different interfaces, drivers, and software, requiring you to calibrate them yourself, which is an extremely complex process.

+

However, if you are an expert, we welcome you to submit a pull request!

+

Model running error: cvimodel built for xxxcv181x CANNOT run on platform cv181x.

+

Failure to parse the model file is generally caused by file corruption. Ensure that your model file is not damaged. For example:

+
    +
  • If it was downloaded from the internet, make sure the download was not corrupted. Typically, files on the internet provide sha256sum/md5 checksums. After downloading, you can compare these values; for specific methods, please search online or ask ChatGPT.
  • +
  • If it comes from a compressed archive, ensure that the decompression process was error-free. You can decompress the archive again to make sure there were no errors in the process.
  • +
  • Ensure that the file was not damaged during the transfer to the device. You can compare the sha256sum values of the file on the device and on your computer; for specific methods, please search online or ask ChatGPT.
  • +
+

Power-on Black Screen, No Display on the Screen

+
    +
  • Check if the TF (micro-SD) card is installed.
  • +
  • Check if the latest system image is burned onto the TF card (strongly recommended to update to the latest system image); see documentation for specific burning methods.
  • +
  • Check if the TF card is fully inserted into the TF card slot, ensuring there are no gaps and it is not loose.
  • +
  • Check if the screen and camera ribbon cables are correctly and securely connected; there should be no looseness.
  • +
  • Check if the power LED (red light) and the system operation status LED (blue light) on the board are lit. If the red light is off, consider hardware issues such as no power supply, insufficient power supply, or a damaged board.
  • +
  • Connect the board to a computer using a USB to TTL cable, open the serial port assistant on the computer, restart the board, and check the boot logs for any errors.
  • +
+
+

If there is no log output, try swapping the TX and RX wires. For MaixCAM, the orientation of the Type-C to serial port adapter may vary, and TX RX might be reversed, meaning it does not support reversible plugging.

+
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/index.html b/maixpy/doc/en/index.html new file mode 100644 index 00000000..4f512e5a --- /dev/null +++ b/maixpy/doc/en/index.html @@ -0,0 +1,492 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy Quick Start - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy Quick Start

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +
+
+ The only official website for MaixPy: + + wiki.sipeed.com/maixpy + +
+
+ MaixPy examples and source code: + + github.com/sipeed/MaixPy + +
+ +
+
+
+

For an introduction to MaixPy, please see the MaixPy official website homepage

+
+

Get a MaixCAM Device

+

Purchase the MaixCAM development board from the Sipeed Taobao or Sipeed AliExpress store.

+

It is recommended to purchase the bundle with a TF card, camera, 2.3-inch touchscreen, case, Type-C data cable, Type-C one-to-two mini board, and 4P serial port socket+cable, which will be convenient for later use and development. The following tutorials assume that you already have these accessories (including the screen).

+

If you did not purchase a TF card, you will need to prepare a TF card reader to flash the system.

+
+

Note that currently only the MaixCAM development board is supported. Other development boards with the same chip are not supported, including Sipeed's development boards with the same chip. Please be careful not to purchase the wrong board, which could result in unnecessary waste of time and money.

+
+

Getting Started

+

Prepare the TF Image Card and Insert it into the Device

+

If the package you purchased includes a TF card, it already contains the factory image. If the TF card was not installed in the device at the factory, you will first need to carefully open the case (be careful not to tear the ribbon cables inside) and then insert the TF card. Additionally, since the firmware from the factory may be outdated, you can follow the instructions on Upgrading and Flashing the System to upgrade the system to the latest version.

+

If you did not purchase a TF card, you need to flash the system onto a self-provided TF card. Please refer to Upgrading and Flashing the System for the flashing method, and then install it on the board.

+

Power On

+

Use a Type-C data cable to connect the MaixCAM device and power it on. Wait for the device to boot up and enter the function selection interface.

+

maixcam_font

+

If the screen does not display:

+
    +
  • Please confirm that you purchased the bundled TF card. If you confirm that you have a TF card and it is inserted into the device, you can try updating to the latest system.
  • +
  • If you did not purchase the TF card bundle, you need to follow the instructions in Upgrading and Flashing the System to flash the latest system onto the TF card.
  • +
  • Also, ensure that the screen and camera cables are not loose. The screen cable can easily come off when opening the case, so be careful.
  • +
+

Connect to the Network

+

For the first run, you need to connect to the network, as you will need it later to activate the device and use the IDE.

+
    +
  • On the device, click Settings, select WiFi, and click the Scan button to start scanning for nearby WiFi. You can click several times to refresh the list.
  • +
  • Find your WiFi hotspot. If you don't have a router, you can use your phone as a hotspot.
  • +
  • Enter the password and click the Connect button to connect.
  • +
  • Wait for the IP address to be obtained. This may take 10 to 30 seconds. If the interface does not refresh, you can exit the WiFi function and re-enter to check, or you can also see the IP information in Settings -> Device Info.
  • +
+

Update the Runtime Libraries

+

This step is very important!!! If this step is not done properly, other applications and functions may not work (e.g., they may crash).

+
    +
  • First, ensure that you have completed the previous step of connecting to WiFi and have obtained an IP address to access the internet.
  • +
  • On the device, click Settings, and select Install Runtime Libraries.
  • +
  • After the installation is complete, you will see that it has been updated to the latest version. Then exit.
  • +
+

If it shows Request failed or 请求失败 (Request failed), please first check if the network is connected. You need to be able to connect to the internet. If it still doesn't work, please take a photo and contact customer service for assistance.

+

Use Built-in Applications

+

Many applications are built-in, such as Find Blobs, AI Detector, Line Follower, etc. For example, Find Blobs:

+ +

Please explore other applications on your own. More applications will be updated in the future. For usage documentation and application updates, please see the MaixHub App Store.

+

Note: The applications only include a part of the functionality that MaixPy can achieve. Using MaixPy, you can create even more features.

+

Use as a Serial Module

+
+

If you want to use the device as the main controller (or if you don't understand what a serial module is), you can skip this step.

+
+

The built-in applications can be used directly as serial modules, such as Find Blobs, Find Faces, Find QR Codes, etc.

+

Usage:

+
    +
  • Hardware connection: You can connect the device to the Type-C one-to-two mini board, which allows you to connect the device via serial to your main controller, such as Arduino, Raspberry Pi, STM32, etc.
  • +
  • Open the application you want to use, such as QR code recognition. When the device scans a QR code, it will send the result to your main controller via serial.
  • +
+
+

The serial baud rate is 115200, the data format is 8N1, and the protocol follows the Maix Serial Communication Protocol Standard. You can find the corresponding application introduction on the MaixHub APP to view the protocol.

+
+

Prepare to Connect the Computer and Device

+

To allow the computer (PC) and the device (MaixCAM) to communicate later, we need to have them on the same local area network. Two methods are provided:

+
    +
  • Method 1 (strongly recommended): Wireless connection. The device uses WiFi to connect to the same router or WiFi hotspot as the computer. You can connect to your WiFi in the device's Settings -> WiFi Settings.
  • +
  • Method 2: Wired connection. The device connects to the computer via a USB cable, and the device will act as a virtual USB network card, allowing it to be on the same local area network as the computer via USB.
  • +
+
+

Method 2 may encounter some problems due to the need for USB and drivers, so it is recommended to start with WiFi instead. You can find common issues in the FAQ.

+
+
+Method 2 has different setup methods on different computer systems, click to expand +
    +
  • Linux: No additional setup is required. Just plug in the USB cable. Use ifconfig or ip addr to view the usb0 network card. Note that the IP address you see here, e.g., 10.131.167.100, is the computer's IP. The device's IP is the last octet changed to 1, i.e., 10.131.167.1.
  • +
  • Windows: You can first confirm if a RNDIS device has been added in the Network Adapters. If so, you can use it directly. Otherwise, you need to manually install the RNDIS network card driver:
      +
    • Open the computer's Device Manager.
    • +
    • Then find a RNDIS device with a question mark under Other Devices, right-click and select Update Driver Software.
    • +
    • Select Browse my computer for driver software.
    • +
    • Select Let me pick from a list of available drivers on my computer.
    • +
    • Select Network Adapters, then click Next.
    • +
    • On the left, select Microsoft, on the right, select Remote NDIS Compatible Device, then click Next, and select Yes.
    • +
    • After installation, the effect is as follows:
      +RNDIS
    • +
    +
  • +
  • MacOS: No additional setup is required. Just plug in the USB cable. Use ifconfig or ip addr to view the usb0 network card. Note that the IP address you see here, e.g., 10.131.167.100, is the computer's IP. The device's IP is the last octet changed to 1, i.e., 10.131.167.1.
  • +
+
+
+

Prepare the Development Environment

+
    +
  • Download and install MaixVision.
  • +
  • Connect the device and computer with a Type-C cable, open MaixVision, and click the "Connect" button in the bottom left corner. It will automatically search for devices. After a short wait, you will see the device, and you can click the connect button next to it to connect to the device.
  • +
+

If no device is detected, you can also manually enter the device's IP address in the device's Settings -> Device Info. You can also find solutions in the FAQ.

+

After a successful connection, the function selection interface on the device will disappear, and the screen will turn black, releasing all hardware resources. If there is still an image displayed, you can disconnect and reconnect.

+

Here is a video example of using MaixVision:

+

+

Run Examples

+

Click Example Code on the left side of MaixVision, select an example, and click the Run button in the bottom left to send the code to the device for execution.

+

For example:

+
    +
  • hello_maix.py: Click the Run button, and you will see messages printed from the device in the MaixVision terminal, as well as an image in the upper right corner.
  • +
  • camera_display.py: This example will open the camera and display the camera view on the screen.
  • +
+ +
from maix import camera, display, app
+
+disp = display.Display()          # Construct a display object and initialize the screen
+cam = camera.Camera(640, 480)     # Construct a camera object, manually set the resolution to 640x480, and initialize the camera
+while not app.need_exit():        # Keep looping until the program exits (you can exit by pressing the function key on the device or clicking the stop button in MaixVision)
+    img = cam.read()              # Read the camera view and save it to the variable img, you can print(img) to print the details of img
+    disp.show(img)                # Display img on the screen
+
+
    +
  • yolov5.py will detect objects in the camera view, draw bounding boxes around them, and display them on the screen. It supports detection of 80 object types. For more details, please see YOLOv5 Object Detection.
  • +
+

You can try other examples on your own.

+
+

If you encounter image display stuttering when using the camera examples, it may be due to poor network connectivity, or the quality of the USB cable or the host's USB being too poor. You can try changing the connection method or replacing the cable, host USB port, or computer.

+
+

Install Applications on the Device

+

The above examples run code on the device, but the code will stop running when MaixVision is disconnected. If you want the code to appear in the boot menu, you can package it as an application and install it on the device.

+

Click the Install App button in the bottom left corner of MaixVision, fill in the application information, and the application will be installed on the device. Then you will be able to see the application on the device.
+ You can also choose to package the application and share your application to the MaixHub App Store.

+
+

The default examples do not explicitly write an exit function, so you can exit the application by pressing the function key on the device. (For MaixCAM, it is the user key.)

+
+

If you want the program to start automatically on boot, you can set it in Settings -> Boot Startup.

+

Next Steps

+

If you like what you've seen so far, please be sure to give the MaixPy open-source project a star on GitHub (you need to log in to GitHub first). Your star and recognition is the motivation for us to continue maintaining and adding new features!

+

Up to this point, you've experienced the usage and development workflow. Next, you can learn about MaixPy syntax and related features. Please follow the left sidebar to learn. If you have any questions about using the API, you can look it up in the API documentation.

+

It's best to learn with a specific purpose in mind, such as working on an interesting small project. This way, the learning effect will be better. You can share your projects and experiences on the MaixHub Share Plaza and receive cash rewards!

+

Share and Discuss

+
    +
  • MaixHub Project and Experience Sharing: Share your projects and experiences, and receive cash rewards. The basic requirements for receiving official rewards are:
      +
    • Reproducible: A relatively complete process for reproducing the project.
    • +
    • Showcase: No detailed project reproduction process, but an attractive project demonstration.
    • +
    • Bug-solving experience: Sharing the process and specific solution for resolving a particular issue.
    • +
    +
  • +
  • MaixPy Official Forum (for asking questions and discussion)
  • +
  • Telegram: MaixPy
  • +
  • MaixPy Source Code Issues: MaixPy issue
  • +
  • For business cooperation or bulk purchases, please contact support@sipeed.com.
  • +
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/modules/acc.html b/maixpy/doc/en/modules/acc.html new file mode 100644 index 00000000..c9491d46 --- /dev/null +++ b/maixpy/doc/en/modules/acc.html @@ -0,0 +1,338 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/modules/thermal_cam.html b/maixpy/doc/en/modules/thermal_cam.html new file mode 100644 index 00000000..c4c14011 --- /dev/null +++ b/maixpy/doc/en/modules/thermal_cam.html @@ -0,0 +1,338 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/modules/tof.html b/maixpy/doc/en/modules/tof.html new file mode 100644 index 00000000..0d197b92 --- /dev/null +++ b/maixpy/doc/en/modules/tof.html @@ -0,0 +1,338 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/no_translate.html b/maixpy/doc/en/no_translate.html new file mode 100644 index 00000000..7807cf15 --- /dev/null +++ b/maixpy/doc/en/no_translate.html @@ -0,0 +1,351 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + no translation - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

no translation

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +
+
This page not translated yet
+
+ Please visit + +
+
+ +
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/peripheral/gpio.html b/maixpy/doc/en/peripheral/gpio.html new file mode 100644 index 00000000..cab59df5 --- /dev/null +++ b/maixpy/doc/en/peripheral/gpio.html @@ -0,0 +1,372 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy Using GPIO - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy Using GPIO

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

Introduction

+

Using GPIO allows you to control pins for input or output high and low levels, which is commonly used to read signals or output control signals.

+

Using GPIO in MaixPy

+
+

MaixPy Firmware should > 4.1.2(not include)

+
+

First, we need to know which pins and GPIOs the device has. For MaixCAM, each pin corresponds to a GPIO controller, as shown in the figure:

+

+

It is important to note that pins can be used not only as GPIOs but also for other functions like PWM. Before using them, we need to set the pin function to GPIO.

+

For example, on MaixCAM, some pins are already occupied by other functions by default, such as UART0 and WiFi (SDIO1 + A26), so it is not recommended to use them. Other pins can be used, and the A14 pin is connected to the onboard LED, which is used as a system load indicator by default. If initialized, it will automatically disable the system indicator function and can be used as a regular GPIO (note that A14 can only be used as an output). This way, you can control the LED's on and off state.

+ +
from maix import gpio, pinmap, time
+
+pinmap.set_pin_function("A14", "GPIOA14")
+led = gpio.GPIO("A14", gpio.Mode.OUT)
+led.value(0)
+
+while 1:
+    led.toggle()
+    time.sleep_ms(500)
+
+

Here, we first use pinmap to set the function of the A14 pin to GPIO. Of course, for A14, since it only has the GPIO function, it can be omitted. For the sake of generality, other pins may need to be set, so it is set in this example.

+

For more APIs, please refer to the GPIO API Documentation

+

GPIO in Input Mode

+ +
from maix import gpio, pinmap, time
+
+pinmap.set_pin_function("A19", "GPIOA19")
+led = gpio.GPIO("A19", gpio.Mode.IN)
+
+while 1:
+    print(led.value())
+    time.sleep_ms(1) # sleep to make cpu free
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/peripheral/i2c.html b/maixpy/doc/en/peripheral/i2c.html new file mode 100644 index 00000000..dd475c1f --- /dev/null +++ b/maixpy/doc/en/peripheral/i2c.html @@ -0,0 +1,369 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy Using I2C - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy Using I2C

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

For MaixCAM, due to the tight pin resource constraints, the I2C pins overlap with the WiFi module (SDIO1), so you can only use either WiFi or hardware I2C, but not both.

+

Therefore, it is recommended to use IO emulation for I2C.

+
+

Note: Requires MaixPy image and firmware > 4.1.2 (not included)

+
+

IO Emulation I2C

+

To emulate I2C, you only need to use the GPIO functionality for the pins. On MaixCAM, the emulated I2C is fixed to pins A15 (SCL) and A27 (SDA), with the i2c number being 5. To use it, simply:

+ +
from maix import i2c, pinmap
+
+# pinmap.set_pin_function("A15", "GPIOA23")
+# pinmap.set_pin_function("A27", "GPIOA24")
+
+bus1 = i2c.I2C(5, i2c.Mode.MASTER)
+slaves = bus1.scan()
+print("find slaves:", slaves)
+
+

More API visit i2c API doc

+

Hardware I2C

+

As mentioned above, for MaixCAM, hardware I2C and WiFi are mutually exclusive. If you must use hardware I2C, you need to disable WiFi and use the pinmap module to set the pin functions to I2C, then use the maix.i2c module to operate.

+
+

TODO: Provide a method to disable WiFi (requires disabling the WiFi driver in the system, which is relatively complex)

+
+

Hardware I2C and its correspond pin see:

+

+ +
from maix import i2c, pinmap
+
+pinmap.set_pin_function("P18", "I2C1_SCL")
+pinmap.set_pin_function("P21", "I2C1_SDA")
+
+bus1 = i2c.I2C(1, i2c.Mode.MASTER)
+slaves = bus1.scan()
+print("find slaves:", slaves)
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/peripheral/pwm.html b/maixpy/doc/en/peripheral/pwm.html new file mode 100644 index 00000000..a3fe1f49 --- /dev/null +++ b/maixpy/doc/en/peripheral/pwm.html @@ -0,0 +1,375 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Using PWM in MaixPy - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

Using PWM in MaixPy

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

Introduction

+

To use PWM in MaixPy (v4), first set the pin function to PWM using pinmap.

+

Each PWM corresponds to a specific pin, as shown in the pin diagram of MaixCAM:

+

+

We recommend using PWM6 and PWM7.

+

For MaixCAM, since WiFi uses all pins of SDIO1, PWM4~9 can only be used alternatively with WiFi.

+
+

TODO: Provide a method to disable WiFi (requires disabling the WiFi driver in the system, which is quite complex)

+
+

Using PWM to Control a Servo in MaixPy

+

Here we take controlling a servo as an example, using PWM7 and the A19 pin of MaixCAM:

+ +
from maix import pwm, time, pinmap
+
+SERVO_PERIOD = 50     # 50Hz 20ms
+SERVO_MIN_DUTY = 2.5  # 2.5% -> 0.5ms
+SERVO_MAX_DUTY = 12.5  # 12.5% -> 2.5ms
+
+# Use PWM7
+pwm_id = 7
+# !! set pinmap to use PWM7
+pinmap.set_pin_function("A19", "PWM7")
+
+def angle_to_duty(percent):
+    return (SERVO_MAX_DUTY - SERVO_MIN_DUTY) * percent / 100.0 + SERVO_MIN_DUTY
+
+out = pwm.PWM(pwm_id, freq=SERVO_PERIOD, duty=angle_to_duty(0), enable=True)
+
+for i in range(100):
+    out.duty(angle_to_duty(i))
+    time.sleep_ms(100)
+
+for i in range(100):
+    out.duty(angle_to_duty(100 - i))
+    time.sleep_ms(100)
+
+

This code controls the servo to rotate from the minimum angle to the maximum angle and then back to the minimum angle.

+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/peripheral/spi.html b/maixpy/doc/en/peripheral/spi.html new file mode 100644 index 00000000..35b4e62e --- /dev/null +++ b/maixpy/doc/en/peripheral/spi.html @@ -0,0 +1,335 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy ues SPI - MaixPy + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/peripheral/uart.html b/maixpy/doc/en/peripheral/uart.html new file mode 100644 index 00000000..994c7146 --- /dev/null +++ b/maixpy/doc/en/peripheral/uart.html @@ -0,0 +1,391 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Introduction to Using UART in MaixPy - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

Introduction to Using UART in MaixPy

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

Introduction to UART

+

UART (Universal Asynchronous Receiver/Transmitter) is a communication method that includes definitions for both hardware and communication protocols.

+
    +
  • Hardware includes:

    +
      +
    • 3 pins: GND, RX, TX. The communication parties connect RX and TX in a cross configuration, i.e., the TX of one side is connected to the RX of the other side, and both GND pins are connected together.
    • +
    • Controller: Usually inside the chip, also known as a UART peripheral. A chip generally has one or more UART controllers, each with corresponding pins.
    • +
    +
  • +
  • Communication protocol: To ensure smooth communication between both parties, a set of protocols is defined. You can learn the specifics on your own. Common parameters include baud rate and parity bit, with baud rate being the most frequently used parameter.

    +
  • +
+

Using the board's UART, you can communicate with other microcontrollers or SoCs. For instance, you can implement a human detection function on MaixCAM and send the detected coordinates to an STM32 microcontroller via UART.

+

Using UART in MaixPy

+

For MaixCAM, a UART is by default exposed through the USB port. By connecting a Type-C adapter board, you can directly use the UART pins on it. Alternatively, you can use the A16 (TX) and A17 (RX) pins on the board directly, which are equivalent to the ones exposed through the USB port.

+

When using the UART exposed through the USB port on MaixCAM, note that the RX and TX pins on the Type-C adapter board will switch when you flip the Type-C connector. So, if communication fails, it might be due to reversed RX and TX. Try flipping the Type-C connector and check if the communication works properly. This is a design flaw, but it’s manageable with minimal adjustments.

+

After connecting the communicating boards (connecting RX to TX in a cross configuration and both GND pins together), you can use the software.

+

Using UART in MaixPy is simple:

+ +
from maix import uart
+
+devices = uart.list_devices()
+
+serial = uart.UART(devices[0], 115200)
+serial.write_str("hello world")
+print("received:", serial.read(timeout = 2000))
+
+

Here, we list all UART devices in the system and use the first one, which is the one exposed through the Type-C port.

+

For more UART APIs, please refer to the UART API Documentation

+

Other Usage and Using Additional UARTs

+ +
from maix import app, uart, pinmap, time
+import sys
+
+# pinmap.set_pin_function("A16", "UART0_TX")
+# pinmap.set_pin_function("A17", "UART0_RX")
+device = "/dev/ttyS0"
+
+serial0 = uart.UART(device, 115200)
+
+serial0.write("hello 1\r\n".encode())
+serial0.write_str("hello 2\r\n")
+
+while not app.need_exit():
+    data = serial0.read()
+    if data:
+        print("Received, type: {}, len: {}, data: {}".format(type(data), len(data), data))
+        serial0.write(data)
+    time.sleep_ms(1) # sleep 1ms to make CPU free
+
+

Here, we set up pin mapping, especially if you want to use UARTs other than UART0. Use pinmap.set_pin_function based on the pin numbers and UART in the diagram:

+

+

Additionally, a sleep_ms function is added in the loop to briefly release the CPU, ensuring that the program does not occupy the CPU fully. There are other methods to achieve this, but this is the simplest and most straightforward approach.

+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/peripheral/wdt.html b/maixpy/doc/en/peripheral/wdt.html new file mode 100644 index 00000000..67e1ff7d --- /dev/null +++ b/maixpy/doc/en/peripheral/wdt.html @@ -0,0 +1,354 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Using Watchdog Timer in MaixPy - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

Using Watchdog Timer in MaixPy

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

Introduction

+

To prevent program issues, a watchdog timer (WDT) is often used to automatically restart the system when the program encounters a problem.

+

The principle is that there is a countdown timer that we need to periodically reset within the program logic (also called "feeding the dog"). If our program gets stuck and fails to reset the countdown timer, the hardware will trigger a system reboot when the timer reaches 0.

+

Using WDT in MaixPy

+ +
from maix import wdt, app, time
+
+w = wdt.WDT(0, 1000)
+
+while not app.need_exit():
+    w.feed()
+    # Here, sleep operation is our task
+    # 200 ms is normal; if it exceeds 1000 ms, it will cause a system reset
+    time.sleep_ms(200)
+
+

This code sets up a watchdog timer that requires feeding every 1000 ms. If the program fails to feed the watchdog within this period, the system will reset.

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/pro/compile_os.html b/maixpy/doc/en/pro/compile_os.html new file mode 100644 index 00000000..2895aacc --- /dev/null +++ b/maixpy/doc/en/pro/compile_os.html @@ -0,0 +1,333 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/projects/index.html b/maixpy/doc/en/projects/index.html new file mode 100644 index 00000000..22bab9dd --- /dev/null +++ b/maixpy/doc/en/projects/index.html @@ -0,0 +1,356 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Practical Projects with MaixPy, Introduction and Collection - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

Practical Projects with MaixPy, Introduction and Collection

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

Introduction

+

Here we provide some common practical project examples for community members to refer to and replicate for use. This also helps to inspire everyone to create more and better applications and projects.

+

There are several ways to find projects implemented with MaixPy:

+

MaixPy Official Documentation

+

You can find practical projects in the documentation on the left, such as "Line Following Car."

+

If you have a good project or a recommended project, you can also contribute by adding it to the documentation.

+

MaixHub Project Sharing Square

+

Projects can be found in the MaixHub Project Sharing section.

+

High-quality shares will also be linked to the MaixPy official documentation.

+

You can also share your project-making methods, which will receive official rewards (guaranteed) and cash tips from community members (usually, high-quality projects that meet urgent needs are more likely to be tipped).

+

Recommend Projects:

+ +

MaixHub App Sharing

+

In addition to project sharing, you can also find directly runnable applications at the MaixHub App Store, some of which might be written in MaixPy. If the author has provided the source code or written detailed tutorials, these can also be referred to.

+

Recommend Projects:

+ + + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/projects/line_tracking_robot.html b/maixpy/doc/en/projects/line_tracking_robot.html new file mode 100644 index 00000000..72c64a58 --- /dev/null +++ b/maixpy/doc/en/projects/line_tracking_robot.html @@ -0,0 +1,419 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy Line Tracking Robot (/Car) - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy Line Tracking Robot (/Car)

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ + +
+ + Update history +
+ + + + + + + + + + + + + + + + + + + +
DateVersionAuthorUpdate content
2024-05-091.0.0lxowalle + + Initial documentation + +
+
+
+ +
+
+ +

Before reading this article, make sure you know how to develop with MaixCAM. For details, please read Quick Start.

+

Introduction

+

This article describes how to implement a line tracking robot using MaixPy.

+

How to implement line tracking robot using MaixPy

+
    +
  1. Preparation of MaixCAM and trolley
  2. +
  3. Implementing the line tracking function
  4. +
  5. Implement the trolley control function
  6. +
+

Preparation of MaixCAM and trolley

+

TODO

+

Implementing the line tracking function

+

You can quickly find straight lines using the get_regression of the image module, see [Line tracking](. /line_tracking.html).

+

Code:

+ +
from maix import camera, display, image
+
+cam = camera.Camera(320, 240)
+disp = display.Display()
+
+# thresholds = [[0, 80, 40, 80, 10, 80]]      # red
+thresholds = [[0, 80, -120, -10, 0, 30]]    # green
+# thresholds = [[0, 80, 30, 100, -120, -60]]  # blue
+
+while 1:
+    img = cam.read()
+
+    lines = img.get_regression(thresholds, area_threshold = 100)
+    for a in lines:
+        img.draw_line(a.x1(), a.y1(), a.x2(), a.y2(), image.COLOR_GREEN, 2)
+        theta = a.theta()
+        rho = a.rho()
+        if theta > 90:
+            theta = 270 - theta
+        else:
+            theta = 90 - theta
+        img.draw_string(0, 0, "theta: " + str(theta) + ", rho: " + str(rho), image.COLOR_BLUE)
+
+    disp.show(img)
+
+
+

The above code implements the function of finding a straight line, note:

+
    +
  • Use a.theta() to get the angle of the line.
  • +
  • Use a.rho() to get the distance between the line and the origin (the origin is in the upper left corner).
  • +
+

After find the straight line with reference to the above code, you can use a.theta() and a.rho() to control the direction of the cart.

+

Implement the trolley control function

+

TODO

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/sidebar.yaml b/maixpy/doc/en/sidebar.yaml new file mode 100644 index 00000000..3e228221 --- /dev/null +++ b/maixpy/doc/en/sidebar.yaml @@ -0,0 +1,145 @@ +items: +- file: README.md + label: Quick Start +- file: faq.md + label: FAQ + +- label: Base + collapsed: false + items: + - file: basic/os.md + label: Burning system + - file: basic/app_usage.md + label: App uses + - file: basic/maixpy_upgrade.md + label: Update MaixPy + - file: basic/maixvision.md + label: MaixVision uses + - file: basic/python.md + label: Python syntax + - file: basic/linux_basic.md + label: Linux fundamentals + - file: basic/python_pkgs.md + label: Add python packages + - file: basic/app.md + label: Apps development + +- label: Basic images and algorithms + items: + - file: vision/display.md + label: Screen uses + - file: vision/camera.md + label: Camera uses + - file: vision/image_ops.md + label: Image control + - file: vision/find_blobs.md + label: Finding color blocks + - file: vision/line_tracking.md + label: Line tracking + - file: vision/qrcode.md + label: QRcode identity + - file: vision/apriltag.md + label: AprilTag identity + +- label: AI Vision + items: + - file: vision/ai.md + label: AI vision knowledge + - file: vision/classify.md + label: AI object classify + - file: vision/yolov5.md + label: YOLOv5 object detect + - file: vision/face_recognition.md + label: Face detect + - file: vision/body_key_points.md + label: Human critical point detection + - file: vision/self_learn_classifier.md + label: Self-learning classifier + - file: vision/self_learn_detector.md + label: Self-learning detector + - file: vision/object_track.md + label: Object tracking and counting + - file: vision/ocr.md + label: OCR + - file: vision/maixhub_train.md + label: MaixHub online AI training + - file: vision/custmize_model.md + label: Custom model + + +- label: AI audio + items: + - file: audio/record.md + label: Audio record + - file: audio/play.md + label: Play audio + - file: audio/classifier.md + label: AI voice classifier + - file: audio/keyword.md + label: Keyword recognize + - file: audio/recognize.md + label: Real-time voice recognize + - file: audio/synthesis.md + label: Speech synthesis + +- label: Video + items: + - file: video/record.md + label: Video record + - file: video/play.md + label: Play video + - file: video/jpeg_streaming.md + label: JPEG stream + - file: video/rtsp.md + label: RTSP stream + + +- label: On-chip peripherals + items: + - file: peripheral/gpio.md + label: GPIO + - file: peripheral/uart.md + label: UART + - file: peripheral/i2c.md + label: I2C + - file: peripheral/pwm.md + label: PWM + - file: peripheral/spi.md + label: SPI + - file: peripheral/wdt.md + label: WDT watchdog + +- label: Off-chip modules + items: + - file: modules/acc.md + label: Accelerometer + - file: modules/temp_hum.md + label: Temperature and humidity + - file: modules/tof.md + label: TOF + - file: modules/thermal_cam.md + label: Thermal imaging + +- label: Porjects + items: + - file: projects/README.md + label: Intro & Collection + - file: projects/line_tracking_robot.md + label: Line tracking robot + +- label: Advanced + items: + - file: source_code/contribute.md + label: Contribute + - file: source_code/build.md + label: Build source code + - file: source_code/faq.md + label: MaixPy Source FAQ + - file: source_code/add_c_module.md + label: Write in C/C++ + - file: source_code/maixcdk.md + label: MaixCDK develop + - file: pro/compile_os.md + label: Build firmware + + diff --git a/maixpy/doc/en/source_code/add_c_module.html b/maixpy/doc/en/source_code/add_c_module.html new file mode 100644 index 00000000..2cf3286a --- /dev/null +++ b/maixpy/doc/en/source_code/add_c_module.html @@ -0,0 +1,343 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Adding a C/C++ Module to MaixPy - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

Adding a C/C++ Module to MaixPy

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

Introduction

+

Sometimes we need to execute a function efficiently, and the speed of Python cannot meet the requirements. In such cases, we can use C/C++ or other compiled languages to implement the function.

+

General Function Encapsulation

+

If the function you want to encapsulate does not depend on other functionalities of MaixPy, you can directly use the general method of adding C/C++ modules with Python, such as ffi, ctype, etc. You can search for relevant methods online.

+
+

Welcome to contribute methods via PR

+
+

If Your Module Needs to Depend on Other Basic APIs of MaixPy

+

You need to learn how to compile and use MaixCDK first, because MaixPy is generated from MaixCDK APIs. Some functionalities in MaixPy are also available in MaixCDK, and then... TODO

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/source_code/build.html b/maixpy/doc/en/source_code/build.html new file mode 100644 index 00000000..e3ae3713 --- /dev/null +++ b/maixpy/doc/en/source_code/build.html @@ -0,0 +1,403 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy develop source code guide - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy develop source code guide

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

Get source code

+ +
mkdir -p ~/maix
+cd ~/maix
+git clone https://github.com/sipeed/MaixPy
+
+

Getting MaixCDK Source Code

+

The MaixPy project depends on MaixCDK. You need to clone it first and place it in a directory on your computer (do not place it under the MaixPy directory).

+ +
cd ~/maix
+git clone https://github.com/sipeed/MaixCDK
+
+

Then, you need to set the environment variable MAIXCAK_PATH to specify the path to MaixCDK, which can be added in ~/.bashrc or ~/.zshrc (depending on your shell):

+ +
export MAIXCAK_PATH=~/maix/MaixCDK
+
+

Only after successfully setting the environment variable can MaixPy locate the MaixCDK source code.

+

Build and pack to wheel

+ +
cd ~/maix/MaixPy
+python setup.py bdist_wheel maixcam
+
+

maixcam Can be replaced with other board config, see setup.py 's platform_names variable.

+

After build success, you will find wheel file in dist directory, use pip install -U MaixPy****.wheel on your device to install or upgrade.

+
+

python setup.py bdist_wheel maixcam --skip-build will not execute build command and only pack wheel, so you can use maixcdk menuconfig and maixcdk build first to customize building.

+
+
+

Additionally, if you are debugging APIs and need to install frequently, using pip can be slow. You can compile and then copy the maix directory directly to the /usr/lib/python3.11/site-packages directory on your device to overwrite the old files.

+
+

Build manually

+ +
maixcdk build
+
+

Run test after modify source code

+
    +
  • First, build source code by
  • +
+ +
maixcdk build
+
+
    +
  • If build for PC self(platform linux):
  • +
+

Then execute ./run.sh your_test_file_name.py to run python script.

+ +
cd test
+./run.sh examples/hello_maix.py
+
+
    +
  • If cross compile for borad:
      +
    • The fastest way is copy maix dir to device's /usr/lib/python3.11/site-packages/ directory, then run script on device.
    • +
    • Or pack wheel and install on device by pip install -U MaixPy****.wheel, then run script on device.
    • +
    +
  • +
+

Preview documentation locally

+

Documentation in docs directory, use Markdown format, you can use teedoc to generate web version documentation.

+

And the API doc is generated when build MaixPy firmware, if you don't build MaixPy, the API doc will be empty.

+ +
pip install teedoc -U
+cd docs
+teedoc install -i https://pypi.tuna.tsinghua.edu.cn/simple
+teedoc serve
+
+

Then visit http://127.0.0.1:2333 to preview documentation on web browser.

+

For developers who want to contribute

+

See MaixPy develop source code guide

+

If you encounter any problems when use source code, please refer to FAQ first.

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/source_code/contribute.html b/maixpy/doc/en/source_code/contribute.html new file mode 100644 index 00000000..8aad143b --- /dev/null +++ b/maixpy/doc/en/source_code/contribute.html @@ -0,0 +1,369 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Contributing to MaixPy Documentation Modification and Code Contribution - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

Contributing to MaixPy Documentation Modification and Code Contribution

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

Contributing to MaixPy Documentation Modification

+
    +
  • Click the "Edit this page" button in the top right corner of the documentation you want to modify to enter the GitHub source documentation page.
  • +
  • Make sure you are logged in to your GitHub account.
  • +
  • Click the pencil icon in the top right corner of the GitHub preview documentation page to modify the content.
  • +
  • GitHub will prompt you to fork a copy to your own repository. Click the "Fork" button.
  • +
+
+

This step forks the MaixPy source code repository to your own account, allowing you to freely modify it.

+
+
    +
  • Modify the documentation content, then fill in the modification description at the bottom of the page, and click "Commit changes".
  • +
  • Then find the "Pull requests" button in your repository and click to create a new Pull request.
  • +
  • In the pop-up page, fill in the modification description and click "Submit Pull request". Others and administrators can then see your modifications on the Pull requests page.
  • +
  • Wait for the administrator to review and approve, and your modifications will be merged into the MaixPy source code repository.
  • +
  • After the merge is successful, the documentation will be automatically updated to the MaixPy official documentation.
  • +
+
+

Due to CDN caching, it may take some time to see the update. For urgent updates, you can contact the administrator for manual refreshing.
+You can also visit en.wiki.sipeed.com/maixpy to view the GitHub Pages service version, which is updated in real-time without caching.

+
+

Contributing to MaixPy Code Contribution

+
    +
  • Visit the MaixPy code repository address: github.com/sipeed/MaixPy
  • +
  • Before modifying the code, it is best to create an issue first, describing the content you want to modify to let others know your ideas and plans, so that everyone can participate in the modification discussion and avoid duplication of effort.
  • +
  • Click the "Fork" button in the top right corner to fork a copy of the MaixPy code repository to your own account.
  • +
  • Then clone a copy of the code from your account to your local machine.
  • +
  • After modifying the code, commit it to your repository.
  • +
  • Then find the "Pull requests" button in your repository and click to create a new Pull request.
  • +
  • In the pop-up page, fill in the modification description and click "Submit Pull request". Others and administrators can then see your modifications on the Pull requests page.
  • +
  • Wait for the administrator to review and approve, and your modifications will be merged into the MaixPy source code repository.
  • +
+
+

Note that most of the MaixPy code is automatically generated from MaixCDK, so if you modify the C/C++ source code, you may need to modify this repository first.

+
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/source_code/faq.html b/maixpy/doc/en/source_code/faq.html new file mode 100644 index 00000000..7176de57 --- /dev/null +++ b/maixpy/doc/en/source_code/faq.html @@ -0,0 +1,351 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy Source Code FAQ - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy Source Code FAQ

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

subprocess.CalledProcessError: Command '('lsb_release', '-a')' returned non-zero exit status 1.

+

Edit /usr/bin/lsb_release as root, change the first line from #!/usr/bin/python3 to python3.

+

Then compile again and it should work.

+

ImportError: arg(): could not convert default argument 'format: maix::image::Format' in method '<class 'maix._maix.camera.Camera'>.init' into a Python object (type not registered yet?)

+

Pybind11 need you to register image::Format first, then you can use it in camera::Camera, to we must fist define image::Format in generated build/maixpy_wrapper.cpp source file.

+

To achieve this, edit components/maix/headers_priority.txt, the depended on should be placed before the one use it.
+e.g.

+ +
maix_image.hpp
+maix_camera.hpp
+
+

/usr/bin/ld: /lib/libgdal.so.30: undefined reference to `std::condition_variable::wait(std::unique_lockstd::mutex&)@GLIBCXX_3.4.30' collect2: error: ld returned 1 exit status

+

This issue commonly arises when building for Linux and using a conda environment, due to some libraries in the conda environment having compilation parameter problems. The solution is to not use conda, or to individually locate the problematic library within conda and replace it with the system's version or simply delete it (the system will then locate the necessary library).

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/source_code/maixcdk.html b/maixpy/doc/en/source_code/maixcdk.html new file mode 100644 index 00000000..5bcfaa1f --- /dev/null +++ b/maixpy/doc/en/source_code/maixcdk.html @@ -0,0 +1,340 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Switching to MaixCDK for C/C++ Application Development - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

Switching to MaixCDK for C/C++ Application Development

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

In addition to developing with MaixPy, there is also a corresponding C/C++ SDK available, called MaixCDK.

+

Introduction to MaixCDK

+

MaixPy is built on top of MaixCDK, and most of MaixPy's APIs are automatically generated based on MaixCDK's APIs. Therefore, any functionality available in MaixPy is also included in MaixCDK.
+If you are more familiar with C/C++ programming or require higher performance, you can use MaixCDK for development.

+

Using MaixCDK

+

The MaixCDK code repository is located at github.com/sipeed/MaixCDK, where you can find the MaixCDK code and documentation.

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/video/jpeg_streaming.html b/maixpy/doc/en/video/jpeg_streaming.html new file mode 100644 index 00000000..37e61713 --- /dev/null +++ b/maixpy/doc/en/video/jpeg_streaming.html @@ -0,0 +1,399 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy Video Stream JPEG Streaming / Sending Images to Server - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy Video Stream JPEG Streaming / Sending Images to Server

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ + +
+ + Update history +
+ + + + + + + + + + + + + + + + + + + +
DateVersionAuthorUpdate content
2024-04-031.0.0neucrack + + Initial document + +
+
+
+ +
+
+ +

Introduction

+

Sometimes it is necessary to send images to a server or push video from a camera to a server. Here, we provide the simplest method, which is to compress images into JPEG format and send them one by one to the server.

+

Note, this is a very basic method and not a formal way to stream video. It is also not suitable for high-resolution, high-frame-rate video streams, as it involves sending images one by one. For more efficient video streaming, please use the RTSP or RTMP modules discussed later.

+

How to Use

+ +
from maix import image
+import requests
+
+# create image
+img = image.Image(640, 480, image.Format.FMT_RGB)
+# draw something
+img.draw_rect(60, 60, 80, 80, image.Color.from_rgb(255, 0, 0))
+
+# convert to jpeg
+jpeg = img.to_format(image.Format.FMT_JPEG) # image.Format.FMT_PNG
+# get jpeg bytes
+jpeg_bytes = jpeg.to_bytes()
+
+# faster way, borrow memory from jpeg object,
+# but be careful, when jpeg object is deleted, jpeg_bytes object MUST NOT be used, or program will crash
+# jpeg_bytes = jpeg.to_bytes(copy = False)
+
+# send image binary bytes to server
+url = "http://192.168.0.123:8080/upload"
+res = requests.post(url, data=jpeg_bytes)
+print(res.status_code)
+print(res.text)
+
+

As you can see, the image is first converted into JPEG format, and then the binary data of the JPEG image is sent to the server via TCP.

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/vision/ai.html b/maixpy/doc/en/vision/ai.html new file mode 100644 index 00000000..88ea8483 --- /dev/null +++ b/maixpy/doc/en/vision/ai.html @@ -0,0 +1,378 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Basic Knowledge of AI Vision - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

Basic Knowledge of AI Vision

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ + +
+ + Update history +
+ + + + + + + + + + + + + + + + + + + +
DateVersionAuthorUpdate content
2024-04-031.0.0neucrack + + Initial documentation + +
+
+
+ +
+
+ +

Introduction

+

If you don't have an AI background, you can first read What is Artificial Intelligence (AI) and Machine Learning to understand the basic concepts of AI before learning about AI.

+

Then, the visual AI we use is generally based on the deep neural network learning method. If you are interested, you can check out Deep Neural Network (DNN) Basics.

+

Using Visual AI in MaixPy

+

Using visual AI in MaixPy is very simple. By default, commonly used AI models are provided, and you can use them directly without having to train the models yourself. You can find the maixcam models in the MaixHub Model Library.

+

Additionally, the underlying APIs have been well-encapsulated, and you only need to make simple calls to implement them.

+

If you want to train your own model, you can start with MaixHub Online Training. On the online platform, you can train models just by clicking, without the need to purchase expensive machines, set up complex development environments, or write code, making it very suitable for beginners and also for experienced users who are too lazy to read code.

+

Generally, once you have obtained the model file, you can transfer it to the device and call the MaixPy API to use it. The specific calling methods are discussed in the following sections.

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/vision/apriltag.html b/maixpy/doc/en/vision/apriltag.html new file mode 100644 index 00000000..c4694e10 --- /dev/null +++ b/maixpy/doc/en/vision/apriltag.html @@ -0,0 +1,492 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy Apriltag Recognition - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy Apriltag Recognition

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ + +
+ + Update history +
+ + + + + + + + + + + + + + + + + + + +
DateVersionAuthorUpdate content
2024-04-031.0.0lxowalle + + Initial documentation + +
+
+
+ +
+
+ +

Before reading this article, make sure you are familiar with how to develop with MaixCAM. For more details, please read Quick Start.

+

Introduction

+

This article introduces how to use MaixPy to recognize Apriltag labels.

+

Using MaixPy to Recognize Apriltag Labels

+

MaixPy's maix.image.Image provides the find_apriltags method, which can be used to recognize Apriltag labels.

+

How to Recognize Apriltag Labels

+

A simple example of recognizing Apriltag labels and drawing bounding boxes:

+ +
from maix import image, camera, display
+
+cam = camera.Camera()
+disp = display.Display()
+
+families = image.ApriltagFamilies.TAG36H11
+x_scale = cam.width() / 160
+y_scale = cam.height() / 120
+
+while 1:
+    img = cam.read()
+
+    new_img = img.resize(160, 120)
+    apriltags = new_img.find_apriltags(families = families)
+    for a in apriltags:
+        corners = a.corners()
+
+        for i in range(4):
+            corners[i][0] = int(corners[i][0] * x_scale)
+            corners[i][1] = int(corners[i][1] * y_scale)
+        x = int(a.x() * x_scale)
+        y = int(a.y() * y_scale)
+        w = int(a.w() * x_scale)
+        h = int(a.h() * y_scale)
+
+        for i in range(4):
+            img.draw_line(corners[i][0], corners[i][1], corners[(i + 1) % 4][0], corners[(i + 1) % 4][1], image.COLOR_RED)
+        img.draw_string(x + w, y, "id: " + str(a.id()), image.COLOR_RED)
+        img.draw_string(x + w, y + 15, "family: " + str(a.family()), image.COLOR_RED)
+
+    disp.show(img)
+
+

Steps:

+
    +
  1. Import the image, camera, and display modules

    + +
    from maix import image, camera, display
    +
    +
  2. +
  3. Initialize the camera and display

    + +
    cam = camera.Camera()
    +disp = display.Display()
    +
    +
  4. +
  5. Get the image from the camera and display it

    + +
    while 1:
    +    img = cam.read()
    +    disp.show(img)
    +
    +
  6. +
  7. Call the find_apriltags method to recognize Apriltag labels in the camera image

    + +
    new_img = img.resize(160, 120)
    +apriltags = new_img.find_apriltags(families = families)
    +
    +
      +
    • img is the camera image obtained through cam.read()
    • +
    • img.resize(160, 120) is used to scale down the image to a smaller size, allowing the algorithm to compute faster with a smaller image
    • +
    • new_img.find_apriltags(families = families) is used to find Apriltag labels, and the query results are saved in apriltags for further processing. The families parameter is used to select the Apriltag family, defaulting to image.ApriltagFamilies.TAG36H11
    • +
    +
  8. +
  9. Process the recognized label results and display them on the screen

    + +
    for a in apriltags:
    +    # Get position information (and map coordinates to the original image)
    +    x = int(a.x() * x_scale)
    +    y = int(a.y() * y_scale)
    +    w = int(a.w() * x_scale)
    +    corners = a.corners()
    +    for i in range(4):
    +        corners[i][0] = int(corners[i][0] * x_scale)
    +        corners[i][1] = int(corners[i][1] * y_scale)
    +
    +    # Display
    +    for i in range(4):
    +        img.draw_line(corners[i][0], corners[i][1], corners[(i + 1) % 4][0], corners[(i + 1) % 4][1], image.COLOR_RED)
    +        img.draw_string(x + w, y, "id: " + str(a.id()), image.COLOR_RED)
    +        img.draw_string(x + w, y + 15, "family: " + str(a.family()), image.COLOR_RED)
    +        img.draw_string(x + w, y + 30, "rotation : " + str(180 * a.rotation() // 3.1415), image.COLOR_RED)
    +
    +
      +
    • Iterate through the members of apriltags, which is the result of scanning Apriltag labels through img.find_apriltags(). If no labels are found, the members of apriltags will be empty.
    • +
    • x_scale and y_scale are used to map coordinates. Since new_img is a scaled-down image, the coordinates of the Apriltag need to be mapped to be drawn correctly on the original image img.
    • +
    • a.corners() is used to get the coordinates of the four vertices of the detected label, and img.draw_line() uses these four vertex coordinates to draw the shape of the label.
    • +
    • img.draw_string is used to display the label content, where a.x() and a.y() are used to get the x and y coordinates of the top-left corner of the label, a.id() is used to get the label ID, a.family() is used to get the label family type, and a.rotation() is used to get the rotation angle of the label.
    • +
    +
  10. +
+

Common Parameter Explanations

+

Here are explanations for common parameters. If you can't find parameters to implement your application, you may need to consider using other algorithms or extending the required functionality based on the current algorithm's results.

+ + + + + + + + + + + + + + + + + + + + +
ParameterDescriptionExample
roiSet the rectangular region for the algorithm to compute. roi=[x, y, w, h], where x and y represent the coordinates of the top-left corner of the rectangle, and w and h represent the width and height of the rectangle. The default is the entire image.Compute the region with coordinates (50,50) and a width and height of 100:
img.find_apriltags(roi=[50, 50, 100, 100])
familiesApriltag label family typeScan for labels from the TAG36H11 family:
img.find_apriltags(families = image.ApriltagFamilies.TAG36H11)
+

This article introduces common methods. For more API information, please refer to the image section of the API documentation.

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/vision/assets/custmize_model1.png b/maixpy/doc/en/vision/assets/custmize_model1.png new file mode 100644 index 00000000..d33a9332 Binary files /dev/null and b/maixpy/doc/en/vision/assets/custmize_model1.png differ diff --git a/maixpy/doc/en/vision/assets/custmize_model10.png b/maixpy/doc/en/vision/assets/custmize_model10.png new file mode 100644 index 00000000..09261c73 Binary files /dev/null and b/maixpy/doc/en/vision/assets/custmize_model10.png differ diff --git a/maixpy/doc/en/vision/assets/custmize_model11.png b/maixpy/doc/en/vision/assets/custmize_model11.png new file mode 100644 index 00000000..6f1b9ad7 Binary files /dev/null and b/maixpy/doc/en/vision/assets/custmize_model11.png differ diff --git a/maixpy/doc/en/vision/assets/custmize_model2.png b/maixpy/doc/en/vision/assets/custmize_model2.png new file mode 100644 index 00000000..924accfd Binary files /dev/null and b/maixpy/doc/en/vision/assets/custmize_model2.png differ diff --git a/maixpy/doc/en/vision/assets/custmize_model3.png b/maixpy/doc/en/vision/assets/custmize_model3.png new file mode 100644 index 00000000..5e330316 Binary files /dev/null and b/maixpy/doc/en/vision/assets/custmize_model3.png differ diff --git a/maixpy/doc/en/vision/assets/custmize_model4.png b/maixpy/doc/en/vision/assets/custmize_model4.png new file mode 100644 index 00000000..e4832068 Binary files /dev/null and b/maixpy/doc/en/vision/assets/custmize_model4.png differ diff --git a/maixpy/doc/en/vision/assets/custmize_model5.png b/maixpy/doc/en/vision/assets/custmize_model5.png new file mode 100644 index 00000000..9486d6d0 Binary files /dev/null and b/maixpy/doc/en/vision/assets/custmize_model5.png differ diff --git a/maixpy/doc/en/vision/assets/custmize_model6.png b/maixpy/doc/en/vision/assets/custmize_model6.png new file mode 100644 index 00000000..89330047 Binary files /dev/null and b/maixpy/doc/en/vision/assets/custmize_model6.png differ diff --git a/maixpy/doc/en/vision/assets/custmize_model7.png b/maixpy/doc/en/vision/assets/custmize_model7.png new file mode 100644 index 00000000..88fe9d95 Binary files /dev/null and b/maixpy/doc/en/vision/assets/custmize_model7.png differ diff --git a/maixpy/doc/en/vision/assets/custmize_model8.png b/maixpy/doc/en/vision/assets/custmize_model8.png new file mode 100644 index 00000000..b41aa891 Binary files /dev/null and b/maixpy/doc/en/vision/assets/custmize_model8.png differ diff --git a/maixpy/doc/en/vision/assets/custmize_model9.png b/maixpy/doc/en/vision/assets/custmize_model9.png new file mode 100644 index 00000000..f2b8355e Binary files /dev/null and b/maixpy/doc/en/vision/assets/custmize_model9.png differ diff --git a/maixpy/doc/en/vision/body_key_points.html b/maixpy/doc/en/vision/body_key_points.html new file mode 100644 index 00000000..671f8cc5 --- /dev/null +++ b/maixpy/doc/en/vision/body_key_points.html @@ -0,0 +1,352 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy Human Body Keypoint Detection for Pose Estimation - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy Human Body Keypoint Detection for Pose Estimation

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

Introduction

+

Using MaixPy, you can easily detect the coordinates of human joint keypoints, which can be used for pose estimation such as sitting posture detection, motion-controlled game input, and more.

+

Usage

+

Using the maix.nn.BodyKeyPoints class in MaixPy, you can easily implement this functionality:

+ +
from maix import nn, image, camera, display
+
+detector = nn.BodyKeyPoints(model="/root/models/body_key_points.mud")
+cam = camera.Camera(detector.input_width(), detector.input_height(), detector.input_format())
+dis = display.Display()
+
+while 1:
+    img = cam.read()
+    points = detector.detect(img)
+    for point in points:
+        img.draw_circle(point[0], point[1], 3, color=image.COLOR_RED, thickness=-1)
+    dis.show(img)
+
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/vision/camera.html b/maixpy/doc/en/vision/camera.html new file mode 100644 index 00000000..1aed87a3 --- /dev/null +++ b/maixpy/doc/en/vision/camera.html @@ -0,0 +1,407 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy Camera Usage - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy Camera Usage

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ + +
+ + Update history +
+ + + + + + + + + + + + + + + + + + + +
DateVersionAuthorUpdate content
2024-04-031.0.0neucrack + + Initial documentation + +
+
+
+ +
+
+ +

Introduction

+

For the MaixCAM, it comes with a pre-installed GC4653 camera, or an optional OS04A10 camera or global shutter camera, and even an HDMI to MIPI module, all of which can be directly used with simple API calls.

+

API Documentation

+

This article introduces common methods. For more API usage, refer to the documentation of the maix.camera module.

+

Camera Switching

+

Different cameras use different drivers, and the correct driver needs to be selected in the system.

+

TODO: How to switch between cameras, such as between GC4653 and OS04A10.

+

Getting Images from the Camera

+

Using MaixPy to easily get images:

+ +
from maix import camera
+
+cam = camera.Camera(640, 480)
+
+while 1:
+    img = cam.read()
+    print(img)
+
+

Here we import the camera module from the maix module, then create a Camera object, specifying the width and height of the image. Then, in a loop, we continuously read the images. The default output is in RGB format. If you need BGR format or other formats, please refer to the API documentation.

+

Skipping Initial Frames

+

During the brief initialization period of the camera, the image acquisition may not be stable, resulting in strange images. You can use the skip_frames function to skip the initial few frames:

+ +
cam = camera.Camera(640, 480)
+cam.skip_frames(30)           # Skip the first 30 frames
+
+

Displaying Images

+

MaixPy provides the display module, which can conveniently display images:

+ +
from maix import camera, display
+
+cam = camera.Camera(640, 480)
+disp = display.Display()
+
+while 1:
+    img = cam.read()
+    disp.show(img)
+
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/vision/classify.html b/maixpy/doc/en/vision/classify.html new file mode 100644 index 00000000..317d91c4 --- /dev/null +++ b/maixpy/doc/en/vision/classify.html @@ -0,0 +1,361 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Using AI Models for Object Classification in MaixPy - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

Using AI Models for Object Classification in MaixPy

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

Object Classification Concept

+

For example, if there are two images in front of you, one with an apple and the other with an airplane, the task of object classification is to input these two images into an AI model one by one. The model will then output two results, one for apple and one for airplane.

+

Using Object Classification in MaixPy

+

MaixPy provides a pre-trained 1000 classification model based on the imagenet dataset, which can be used directly:

+ +
from maix import camera, display, image, nn
+
+classifier = nn.Classifier(model="/root/models/mobilenetv2.mud")
+cam = camera.Camera(classifier.input_width(), classifier.input_height(), classifier.input_format())
+dis = display.Display()
+
+while 1:
+    img = cam.read()
+    res = classifier.classify(img)
+    max_idx, max_prob = res[0]
+    msg = f"{max_prob:5.2f}: {classifier.labels[max_idx]}"
+    img.draw_string(10, 10, msg, image.COLOR_RED)
+    dis.show(img)
+
+

Result video:

+ +

Here, the camera captures an image, which is then passed to the classifier for recognition. The result is displayed on the screen.

+

For more API usage, refer to the documentation for the maix.nn module.

+

Training Your Own Classification Model

+

Please go to MaixHub to learn and train classification models. When creating a project, select Classification Model.

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/vision/custmize_model.html b/maixpy/doc/en/vision/custmize_model.html new file mode 100644 index 00000000..89d72708 --- /dev/null +++ b/maixpy/doc/en/vision/custmize_model.html @@ -0,0 +1,775 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy Custom (Offline Training) AI Model and Running - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy Custom (Offline Training) AI Model and Running

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ + +
+ + Update history +
+ + + + + + + + + + + + + + + + + + + +
DateVersionAuthorUpdate content
2024-4-23v1.0dragonforward + + Added YOLOv5s deployment + +
+
+
+ +
+
+ +
+

This post is contributed by the community user dragonforward

+
+
+

This blog will show you how to deploy your own YOLOv5s model (the author demonstrates a hard hat model) step by step from scratch. The training part refers to the author's previous work, and those who have already trained their models can skip this part, although there are some differences.

+
+

Obtain Custom-Trained YOLOv5s ONNX Model

+

Prepare Custom Dataset (The author uses the VOC dataset)

+
    +
  • Dataset Directory Structure is as follows:
  • +
+ +
└─VOC2028:        Custom dataset
+    ├─Annotations    Stores the dataset label files in XML format
+    ├─ImageSets        Dataset split files
+    │  └─Main
+    ├─JPEGImages    Stores the dataset images
+
+
    +
  • Split the Dataset
  • +
+

Execute python3 split_train_val.py in the split_train_val.py file path, and you will get the following directory structure:

+ +
└─VOC2028:        Custom dataset
+    ├─Annotations    Stores the dataset label files in XML format
+    ├─ImageSets        Dataset split files
+    │  └─Main test.txt
+          └─test.txt
+          └─train.txt
+          └─val.txt
+    ├─JPEGImages    Stores the dataset images
+    ├─split_train_val.py    Python file for splitting the dataset
+
+

split_train_val.py file code:

+ +
# -*- coding: utf-8 -*-
+"""
+Author: dragonforward
+Description: Split into training, validation, and test sets in the ratio of 8:1:1, 8 for training, 1 for validation, and 1 for testing.
+"""
+import os
+import random
+import argparse
+
+parser = argparse.ArgumentParser()
+# Address of the XML files, modify according to your data. XML files are usually stored in Annotations
+parser.add_argument('--xml_path', default='Annotations/', type=str, help='input xml label path')
+# Dataset split, choose the address under your data's ImageSets/Main
+parser.add_argument('--txt_path', default='ImageSets/Main/', type=str, help='output txt label path')
+opt = parser.parse_args()
+
+train_percent = 0.8  # Proportion of the training set
+val_percent = 0.1    # Proportion of the validation set
+test_persent = 0.1   # Proportion of the test set
+
+xmlfilepath = opt.xml_path
+txtsavepath = opt.txt_path
+total_xml = os.listdir(xmlfilepath)
+
+if not os.path.exists(txtsavepath):
+    os.makedirs(txtsavepath)
+
+num = len(total_xml)  
+list = list(range(num))
+
+t_train = int(num * train_percent)  
+t_val = int(num * val_percent)
+
+train = random.sample(list, t_train)
+num1 = len(train)
+for i in range(num1):
+    list.remove(train[i])
+
+
+val_test = [i for i in list if not i in train]
+val = random.sample(val_test, t_val)
+num2 = len(val)
+for i in range(num2):
+    list.remove(val[i])
+
+
+file_train = open(txtsavepath + '/train.txt', 'w')
+file_val = open(txtsavepath + '/val.txt', 'w')
+file_test = open(txtsavepath + '/test.txt', 'w')
+
+for i in train:
+    name = total_xml[i][:-4] + '\n'
+    file_train.write(name)
+
+for i in val:
+    name = total_xml[i][:-4] + '\n'
+    file_val.write(name)    
+
+for i in list:
+    name = total_xml[i][:-4] + '\n'
+    file_test.write(name)
+
+
+file_train.close()
+file_val.close()
+file_test.close()
+
+
    +
  • Convert VOC to labels to obtain label files
  • +
+

Directory structure:

+ +
└─VOC2028:        Custom dataset
+    ├─Annotations    Stores the dataset label files in XML format
+    ├─ImageSets        Dataset split files
+    │  └─Main
+    ├─JPEGImages    Stores the dataset images
+    └─labels        YOLOv5 treats this folder as the training annotation folder
+└─voc_label.py
+
+

the voc_label.py file code:

+ +
# -*- coding: utf-8 -*-
+import xml.etree.ElementTree as ET
+import os
+
+sets = ['train', 'val', 'test']  # If your Main folder doesn't have test.txt, remove 'test'
+classes = ["hat", "people"]   # Change to your own classes, VOC dataset has the following 20 classes
+# classes = ["brickwork", "coil","rebar"]   # Change to your own classes, VOC dataset has the following 20 classes
+# classes = ["aeroplane", 'bicycle', 'bird', 'boat', 'bottle', 'bus', 'car', 'cat', 'chair', 'cow', 'diningtable', 'dog',
+#            'horse', 'motorbike', 'person', 'pottedplant', 'sheep', 'sofa', 'train', 'tvmonitor']  # class names
+# abs_path = os.getcwd() /root/yolov5/data/voc_label.py 
+abs_path = '/root/yolov5/data/'
+
+def convert(size, box):
+    dw = 1. / (size[0])
+    dh = 1. / (size[1])
+    x = (box[0] + box[1]) / 2.0 - 1
+    y = (box[2] + box[3]) / 2.0 - 1
+    w = box[1] - box[0]
+    h = box[3] - box[2]
+    x = x * dw
+    w = w * dw
+    y = y * dh
+    h = h * dh
+    return x, y, w, h
+
+
+def convert_annotation(image_id):
+    in_file = open(abs_path + '/VOC2028/Annotations/%s.xml' % (image_id), encoding='UTF-8')
+    out_file = open(abs_path + '/VOC2028/labels/%s.txt' % (image_id), 'w')
+    tree = ET.parse(in_file)
+    root = tree.getroot()
+    size = root.find('size')
+    w = int(size.find('width').text)
+    h = int(size.find('height').text)
+    for obj in root.iter('object'):
+        difficult = obj.find('difficult').text
+        # difficult = obj.find('Difficult').text
+        cls = obj.find('name').text
+        if cls not in classes or int(difficult) == 1:
+            continue
+        cls_id = classes.index(cls)
+        xmlbox = obj.find('bndbox')
+        b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
+             float(xmlbox.find('ymax').text))
+        b1, b2, b3, b4 = b
+        # Bounding box correction
+        if b2 > w:
+            b2 = w
+        if b4 > h:
+            b4 = h
+        b = (b1, b2, b3, b4)
+        bb = convert((w, h), b)
+        out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
+
+
+for image_set in sets:
+    if not os.path.exists(abs_path + '/VOC2028/labels/'):
+        os.makedirs(abs_path + '/VOC2028/labels/')
+
+    image_ids = open(abs_path + '/VOC2028/ImageSets/Main/%s.txt' % (image_set)).read().strip().split()
+    list_file = open(abs_path + '/VOC2028/%s.txt' % (image_set), 'w')
+    for image_id in image_ids:
+        list_file.write(abs_path + '/VOC2028/JPEGImages/%s.jpg\n' % (image_id))  # Either complete the path yourself, or only writing half may cause an error
+        convert_annotation(image_id)
+    list_file.close()
+
+

custmize_model8

+

Train the Model

+
    +
  • Configure the environment
  • +
+ +
git clone https://github.com/ultralytics/yolov5
+cd yolov5
+pip install -r requirements.txt
+pip install onnx
+
+
    +
  • Download pre-trained weights (the author tried both v7.0 and v6.0 pt, and both work)
  • +
+ +
https://github.com/ultralytics/yolov5/releases/download/v7.0/yolov5s.pt
+
+

custmize_model11

+
    +
  • Train the model (the author used the school's cluster for training)
  • +
+ +
python3 train.py --weights weights/yolov5s.pt --cfg models/yolov5s.yaml --
+data data/safthat.yaml --epochs 150 --batch-size 16 --multi-scale --device 0
+
+
+

custmize_model9

+ +
python3 detect.py --source /root/yolov5/data/images/000000.jpg --weights /root/yolov5/runs/train/exp13/weights/best.pt --conf-thres 0.25
+
+

custmize_model10

+
    +
  • Export the ONNX model. Since the school server is currently in class, they can allocate me a computer only after their class is over. So I used the local conda environment on my laptop to export it. The reason for using -imgsz 224 320 is that it is more suitable for the screen. I also tried 640_640, but the camera reported an error, suggesting that it should be 640_480. Then I saw that the Sipeed YOLOv5s was 320*224, so I kept it consistent with theirs.
  • +
+ +
python export.py --weights yolov5s_hat.pt --include onnx --opset 16 --imgsz 224 320
+
+

custmize_model5

+

You can view the model by entering netron.app in the URL, and there are three outputs:

+

custmize_model2

+

Here are the author's three outputs:

+ +
onnx::Shape_329
+onnx::Shape_384
+onnx::Shape_439
+
+

Model Conversion (Key Step)

+

Install Docker Environment (Skip if already installed)

+ +
Install the basic software required for Docker
+sudo apt-get update
+sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
+Add official source
+curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
+sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
+Install Docker
+sudo apt-get update
+sudo apt-get install docker-ce docker-ce-cli containerd.io
+
+

Start the Model Quantization Process (!!!)

+

Preparation

+ +
Download from the following URL
+https://github.com/sophgo/tpu-mlir/releases/tag/v1.7
+tpu-mlir-resource.tar and tpu_mlir-1.7-py3-none-any.whl
+
+

custmize_model3

+

The reason for pulling the latest version is that I failed with version 3.1, as the tools are constantly being updated, so it's better to keep up with the latest version. You can see in the image below that I also tried version 3.1.

+

custmize_model7

+ +
docker pull sophgo/tpuc_dev:latest
+
+After entering the container, copy the two prepared files to the workspace directory
+
+root@3d517bc7f51f:/workspace/model_yolov5s# cd ..
+root@3d517bc7f51f:/workspace# ls
+model_yolov5s  tpu-mlir-resource  tpu-mlir-resource.tar  tpu_mlir-1.7-py3-none-any.whl
+root@3d517bc7f51f:/workspace# 
+
+Choose one of the following two options, I recommend the second one for offline installation
+pip install tpu_mlir[all] or pip install tpu_mlir-*-py3-none-any.whl[all]
+The author chose the second option
+pip install tpu_mlir-1.7-py3-none-any.whl
+And install all its dependencies
+pip install tpu_mlir-1.7-py3-none-any.whl[all]
+Extract
+tar -xvf tpu-mlir-resource.tar
+Rename the folder
+mv regression/ tpu-mlir-resource/
+
+
+mkdir model_yolov5s && cd model_yolov5s
+
+cp -rf ../tpu_mlir_resource/dataset/COCO2017 .
+cp -rf ../tpu_mlir_resource/image .
+
+
+Transfer the previously prepared 100 images, one test image, and the ONNX model to the following location
+root@3d517bc7f51f:/workspace# cd model_yolov5s/
+root@3d517bc7f51f:/workspace/model_yolov5s# ls
+COCO2017  image  workspace  yolov5n_hat.onnx  yolov5s_hat.onnx
+root@3d517bc7f51f:/workspace/model_yolov5s# cd COCO2017/
+root@3d517bc7f51f:/workspace/model_yolov5s/COCO2017# ls
+000000.jpg  000011.jpg  000022.jpg  000032.jpg  000042.jpg  000053.jpg  000066.jpg  000076.jpg  000086.jpg  000096.jpg
+000002.jpg  000012.jpg  000023.jpg  000033.jpg  000043.jpg  000054.jpg  000067.jpg  000077.jpg  000087.jpg  000101.jpg
+000003.jpg  000013.jpg  000024.jpg  000034.jpg  000044.jpg  000055.jpg  000068.jpg  000078.jpg  000088.jpg  000102.jpg
+000004.jpg  000014.jpg  000025.jpg  000035.jpg  000045.jpg  000058.jpg  000069.jpg  000079.jpg  000089.jpg  000103.jpg
+000005.jpg  000015.jpg  000026.jpg  000036.jpg  000046.jpg  000059.jpg  000070.jpg  000080.jpg  000090.jpg  000104.jpg
+000006.jpg  000016.jpg  000027.jpg  000037.jpg  000048.jpg  000061.jpg  000071.jpg  000081.jpg  000091.jpg  000105.jpg
+000007.jpg  000017.jpg  000028.jpg  000038.jpg  000049.jpg  000062.jpg  000072.jpg  000082.jpg  000092.jpg  000106.jpg
+000008.jpg  000019.jpg  000029.jpg  000039.jpg  000050.jpg  000063.jpg  000073.jpg  000083.jpg  000093.jpg  000107.jpg
+000009.jpg  000020.jpg  000030.jpg  000040.jpg  000051.jpg  000064.jpg  000074.jpg  000084.jpg  000094.jpg  000108.jpg
+000010.jpg  000021.jpg  000031.jpg  000041.jpg  000052.jpg  000065.jpg  000075.jpg  000085.jpg  000095.jpg  000109.jpg
+root@3d517bc7f51f:/workspace/model_yolov5s/COCO2017# ls -l | grep "^-" | wc -l
+100
+root@3d517bc7f51f:/workspace/model_yolov5s/COCO2017# 
+
+You can use ls -l | grep "^-" | wc -l to check the number of images. The author replaced the 100 helmet images and the test image in the COCO2017 folder.
+
+Go back to model_yolov5s
+root@3d517bc7f51f:/workspace/model_yolov5s/COCO2017# cd ..
+root@3d517bc7f51f:/workspace/model_yolov5s# ls
+COCO2017  image  workspace  yolov5n_hat.onnx  yolov5s_hat.onnx
+root@3d517bc7f51f:/workspace/model_yolov5s# 
+
+Next
+mkdir workspace && cd workspace
+Execute the following command to convert ONNX to MLIR (remember to replace output_names with your own)
+model_transform \
+--model_name yolov5s \
+--model_def ../yolov5s_hat.onnx \
+--input_shapes [[1,3,224,320]] \
+--mean 0.0,0.0,0.0 \
+--scale 0.0039216,0.0039216,0.0039216 \
+--keep_aspect_ratio \
+--pixel_format rgb \
+--output_names onnx::Shape_329,onnx::Shape_439,onnx::Shape_384 \
+--test_input ../image/hat.jpg \
+--test_result yolov5s_top_outputs.npz \
+--mlir yolov5s.mlir
+
+Execute the following command to convert MLIR to INT8 model, before converting to INT8 model, you need to run calibration to obtain the calibration table
+run_calibration yolov5s.mlir \
+--dataset ../COCO2017 \
+--input_num 100 \
+-o yolov5s_cali_table
+Then execute the following
+model_deploy \
+--mlir yolov5s.mlir \
+--quantize INT8 \
+--calibration_table yolov5s_cali_table \
+--processor cv181x \
+--test_input yolov5s_in_f32.npz \
+--test_reference yolov5s_top_outputs.npz \
+--tolerance 0.85,0.45 \
+--model yolov5s_cv181x_int8_sym.cvimodel
+
+Finally, you will get the following:
+root@3d517bc7f51f:/workspace/model_yolov5s/workspace# ls
+_weight_map.csv          yolov5s_cv181x_int8_sym.cvimodel         yolov5s_origin.mlir
+build_flag.json          yolov5s_cv181x_int8_sym_final.mlir       yolov5s_top_f32_all_origin_weight.npz
+final_opt.onnx           yolov5s_cv181x_int8_sym_tensor_info.txt  yolov5s_top_f32_all_weight.npz
+yolov5s.mlir             yolov5s_cv181x_int8_sym_tpu.mlir         yolov5s_top_outputs.npz
+yolov5s_cali_table       yolov5s_in_f32.npz                       yolov5s_tpu_addressed_cv181x_int8_sym_weight.npz
+yolov5s_cv181x_int8_sym  yolov5s_opt.onnx.prototxt                yolov5s_tpu_addressed_cv181x_int8_sym_weight_fix.npz
+root@3d517bc7f51f:/workspace/model_yolov5s/workspace# 
+
+

Through the above steps, you can obtain the quantized model that can be deployed to the development board.

+

Explanation:
+The reason why it's cv181x is because I tried it first and got the following

+ +
-- [I] load cvimodel from: /root/models/yolov5n.cvimodel
+cvimodel built for cv180x CANNOT run on platform cv181x
+failed to parse cvimodel
+
+
+

running the model on an actual device:

+
    +
  • The contents of yolov5s_hat.mud are as follows:
  • +
+ +
[basic]
+type = cvimodel
+model = yolov5s_hat_cv181x_int8_sym.cvimodel
+
+[extra]
+model_type = yolov5
+input_type = rgb
+mean = 0, 0, 0
+scale = 0.00392156862745098, 0.00392156862745098, 0.00392156862745098
+anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
+labels = hat,person
+
+

Run the code:

+ +
from maix import camera, display, image, nn, app
+
+detector = nn.YOLOv5(model="/root/models/yolov5s_hat.mud")
+cam = camera.Camera(detector.input_width(), detector.input_height(), detector.input_format())
+dis = display.Display()
+print("www")
+print(detector.input_width(), detector.input_height(), detector.input_format())
+
+while not app.need_exit():
+    img = cam.read()
+    objs = detector.detect(img, conf_th=0.5, iou_th=0.45)
+    for obj in objs:
+        img.draw_rect(obj.x, obj.y, obj.w, obj.h, color=image.COLOR_RED)
+        msg = f'{detector.labels[obj.class_id]}: {obj.score:.2f}'
+        img.draw_string(obj.x, obj.y, msg, color=image.COLOR_RED)
+    dis.show(img)
+
+

custmize_model4

+

Where 10.84.117.1 is the IP address. Upload the cvmodel and mud files to the /root/models/ path.

+

After packaging, install the application and run it, or you can run it in the IDE.

+

custmize_model6

+

Video link:

+ +
https://www.bilibili.com/video/BV1xz421S7Rx/?spm_id_from=333.999.0.0&vd_source=b1fff0f773136d7d05331087929c7739
+
+

Acknowledgments

+

Thanks to 谁说现在是冬天呢 for some insights.

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/vision/display.html b/maixpy/doc/en/vision/display.html new file mode 100644 index 00000000..661dbfc8 --- /dev/null +++ b/maixpy/doc/en/vision/display.html @@ -0,0 +1,446 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy Screen Usage - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy Screen Usage

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ + +
+ + Update history +
+ + + + + + + + + + + + + + + + + + + +
DateVersionAuthorUpdate content
2024-03-311.0.0neucrack + + Initial document + +
+
+
+ +
+
+ +

Introduction

+

MaixPy provides the display module, which can display images on the screen, and can also send images to MaixVision for display, facilitating debugging and development.

+

API Documentation

+

This document introduces commonly used methods. For more APIs, please refer to the display section of the API documentation.

+

Using the Screen

+
    +
  • Import the display module:
  • +
+ +
from maix import display
+
+
    +
  • Create a Display object:
  • +
+ +
disp = display.Display()
+
+
    +
  • Display an image:
  • +
+ +
disp.show(img)
+
+

Here, the img object is a maix.image.Image object, which can be obtained through the read method of the camera module, or loaded from an image file in the file system using the load method of the image module, or created as a blank image using the Image class of the image module.

+

For example:

+ +
from maix import image, display
+
+disp = display.Display()
+img = image.load("/root/dog.jpg")
+disp.show(img)
+
+

Here, you need to transfer the dog.jpg file to the /root directory on the device first.

+

Display text:

+ +
from maix import image, display
+
+disp = display.Display()
+img = image.Image(320, 240)
+img.draw_rectangle(0, 0, disp.width(), disp.height(), color=image.Color.from_rgb(255, 0, 0), thickness=-1)
+img.draw_rectangle(10, 10, 100, 100, color=image.Color.from_rgb(255, 0, 0))
+img.draw_string(10, 10, "Hello MaixPy!", color=image.Color.from_rgb(255, 255, 255))
+disp.show(img)
+
+

Read an image from the camera and display it:

+ +
from maix import camera, display, app
+
+disp = display.Display()
+cam = camera.Camera(320, 240)
+while not app.need_exit():
+    img = cam.read()
+    disp.show(img)
+
+
+

Here, while not app.need_exit(): is used to facilitate exiting the loop when the app.set_exit_flag() method is called elsewhere.

+
+

Adjusting Backlight Brightness

+

You can manually adjust the backlight brightness in the system's "Settings" app. If you want to adjust the backlight brightness programmatically, you can use the set_backlight method, with the parameter being the brightness percentage, ranging from 0 to 100:

+ +
disp.set_backlight(50)
+
+

Note that when the program exits and returns to the app selection interface, the backlight brightness will automatically revert to the system setting.

+

Displaying on MaixVision

+

When running code in MaixVision, images can be displayed on MaixVision for easier debugging and development.

+

When calling the show method, the image will be automatically compressed and sent to MaixVision for display.

+

Of course, if you don't have a screen, or to save memory by not initializing the screen, you can also directly call the send_to_maixvision method of the image.Image object to send the image to MaixVision for display.

+ +
from maix import image
+
+img = image.Image(320, 240)
+img.draw_rectangle(0, 0, img.width(), img.height(), color=image.Color.from_rgb(255, 0, 0), thickness=-1)
+img.draw_rectangle(10, 10, 100, 100, color=image.Color.from_rgb(255, 0, 0))
+img.draw_string(10, 10, "Hello MaixPy!", color=image.Color.from_rgb(255, 255, 255))
+img.send_to_maixvision()
+
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/vision/face_recognition.html b/maixpy/doc/en/vision/face_recognition.html new file mode 100644 index 00000000..e486b106 --- /dev/null +++ b/maixpy/doc/en/vision/face_recognition.html @@ -0,0 +1,376 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy Face Recognition - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy Face Recognition

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

Introduction to Face Recognition

+

Face recognition is the process of identifying the location of faces in the current image and determining who they are.
+In addition to detecting faces, face recognition generally involves a database of known and unknown individuals.

+

Recognition Principle

+
    +
  • Use an AI model to detect faces and obtain the coordinates and coordinates of facial features.
  • +
  • Use the coordinates of facial features to perform affine transformation on the face in the image, aligning it to a standard face shape, making it easier for the model to extract facial features.
  • +
  • Use a feature extraction model to extract facial feature values.
  • +
  • Compare the extracted feature values with the recorded facial feature values in the database (calculate the cosine distance between the saved and current facial feature values, and find the smallest distance match in the database. If the distance is smaller than a set threshold, it is considered to be the same person in the database.)
  • +
+

Using MaixPy

+

The MaixPy maix.nn module provides an API for face recognition, which can be used directly, and the model is also built-in. You can also download it from the MaixHub Model Zoo (filter for the corresponding hardware platform, such as maixcam).

+

Recognition:

+ +
from maix import nn
+
+recognizer = nn.Face_Recognizer(model="/root/models/face_recognizer.mud")
+if os.path.exists("/root/faces.bin"):
+    recognizer.load_faces("/root/faces.bin")
+cam = camera.Camera(recognizer.input_width(), recognizer.input_height(), recognizer.input_format())
+dis = display.Display()
+
+while 1:
+    img = cam.read()
+    faces = recognizer.recognize(img)
+    for obj in faces:
+        img.draw_rect(obj.x, obj.y, obj.w, obj.h, color = image.COLOR_RED)
+        msg = f'{recognizer.labels[obj.class_id]}: {obj.score:.2f}'
+        img.draw_string(obj.x, obj.y, msg, color = image.COLOR_RED)
+    dis.show(img)
+
+

When running this code for the first time, you will find that it can detect faces, but it doesn't recognize anyone. We need to enter the add face mode to learn faces first.
+For example, we can learn faces when the user presses a button:

+ +
faces = recognizer.detect_faces(img)
+for face in faces:
+    print(face)
+    # Here we consider the case where there are multiple faces in one image
+    # You can decide whether to add the face to the database based on the coordinates of `face`
+    recognizer.add_face(face)
+recognizer.save_(faces)("/too/faces.bin")
+
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/vision/find_blobs.html b/maixpy/doc/en/vision/find_blobs.html new file mode 100644 index 00000000..f0e68c5a --- /dev/null +++ b/maixpy/doc/en/vision/find_blobs.html @@ -0,0 +1,532 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy Find Blobs - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy Find Blobs

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ + +
+ + Update history +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
DateVersionAuthorUpdate content
2024-04-031.0.0neucrack + + Initial documentation + +
2024-04-031.0.1lxowalle + + Added detailed usage for finding blobs + +
+
+
+ +
+
+ +

Before reading this article, make sure you know how to develop with MaixCAM. For details, please read Quick Start.

+

Introduction

+

This article will introduce how to use MaixPy to find color blobs and how to use the default application of MaixCam to find color blobs.

+

In vision applications, finding color blobs is a very common requirement, such as robots finding color blobs, automated production lines finding color blobs, etc., which requires identifying specific color areas in the image and obtaining information such as the position and size of these areas.

+

Using MaixPy to Find Blobs

+

The maix.image.Image module in MaixPy provides the find_blobs method, which can conveniently find color blobs.

+

How to Find Blobs

+

A simple example to find color blobs and draw bounding boxes:

+ +
from maix import image, camera, display
+
+cam = camera.Camera(320, 240)
+disp = display.Display()
+
+# Select the corresponding configuration based on the color of the blob
+thresholds = [[0, 80, 40, 80, 10, 80]]      # red
+# thresholds = [[0, 80, -120, -10, 0, 30]]    # green
+# thresholds = [[0, 80, 30, 100, -120, -60]]  # blue
+
+while 1:
+    img = cam.read()
+    blobs = img.find_blobs(thresholds, pixels_threshold=500)
+    for blob in blobs:
+        img.draw_rect(blob[0], blob[1], blob[2], blob[3], image.COLOR_GREEN)
+    disp.show(img)
+
+

Steps:

+
    +
  1. Import the image, camera, and display modules

    + +
    from maix import image, camera, display
    +
    +
  2. +
  3. Initialize the camera and display

    + +
    cam = camera.Camera(320, 240)	# Initialize the camera with an output resolution of 320x240 in RGB format
    +disp = display.Display()
    +
    +
  4. +
  5. Get the image from the camera and display it

    + +
    while 1:
    +    img = cam.read()
    +    disp.show(img)
    +
    +
  6. +
  7. Call the find_blobs method to find color blobs in the camera image and draw them on the screen

    + +
    blobs = img.find_blobs(thresholds, pixels_threshold=500)
    +for blob in blobs:
    +    img.draw_rect(blob[0], blob[1], blob[2], blob[3], image.COLOR_GREEN)
    +
    +
      +
    • img is the camera image obtained through cam.read(). When initialized with cam = camera.Camera(320, 240), the img object is an RGB image with a resolution of 320x240.
    • +
    • img.find_blobs is used to find color blobs. thresholds is a list of color thresholds, where each element is a color threshold. Multiple thresholds can be passed in to find multiple colors simultaneously. Each color threshold is in the format [L_MIN, L_MAX, A_MIN, A_MAX, B_MIN, B_MAX], where L, A, and B are the three channels in the LAB color space. The L channel represents brightness, the A channel represents the red-green component, and the B channel represents the blue-yellow component. pixels_threshold is a pixel count threshold used to filter out unwanted small blobs.
    • +
    • img.draw_rect is used to draw bounding boxes around the color blobs. blob[0], blob[1], blob[1], and blob[1] represent the x-coordinate of the top-left corner of the blob, the y-coordinate of the top-left corner of the blob, the width of the blob, and the height of the blob, respectively.
    • +
    +
  8. +
+

Common Parameter Explanations

+

Here are explanations of commonly used parameters. If you cannot find parameters that can implement your application, you may need to consider using other algorithms or extending the required functionality based on the current algorithm's results.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterDescriptionExample
thresholdsThresholds based on the LAB color space, thresholds=[[l_min, l_max, a_min, a_max, b_min, b_max]], representing:
Brightness range [l_min, l_max]
Green to red component range [a_min, a_max]
Blue to yellow component range [b_min, b_max]
Multiple thresholds can be set simultaneously
Set two thresholds to detect red and green
img.find_blobs(thresholds=[[0, 80, 40, 80, 10, 80], [0, 80, -120, -10, 0, 30]])
Red threshold is [0, 80, 40, 80, 10, 80]
Green threshold is [0, 80, -120, -10, 0, 30]
invertEnable threshold inversion, when enabled, the passed thresholds are inverted. Default is False.Enable threshold inversion
img.find_blobs(invert=True)
roiSet the rectangular region for the algorithm to compute, roi=[x, y, w, h], where x and y represent the coordinates of the top-left corner of the rectangle, and w and h represent the width and height of the rectangle, respectively. The default is the entire image.Compute the region at (50, 50) with a width and height of 100
img.find_blobs(roi=[50, 50, 100, 100])
area_thresholdFilter out blobs with a pixel area smaller than area_threshold, in units of pixels. The default is 10. This parameter can be used to filter out some useless small blobs.Filter out blobs with an area smaller than 1000
img.find_blobs(area_threshold=1000)
pixels_thresholdFilter out blobs with fewer valid pixels than pixels_threshold. The default is 10. This parameter can be used to filter out some useless small blobs.Filter out blobs with fewer than 1000 valid pixels
img.find_blobs(pixels_threshold=1000)
+

This article introduces commonly used methods. For more APIs, please see the image section of the API documentation.

+

Using the Find Blobs App

+

To quickly verify the find blobs functionality, you can first use the find blobs application provided by MaixCam to experience the effect of finding color blobs.

+

Usage

+

Open the device, select the Find Blobs app, then select the color to be recognized from the bottom options or customize a color, and you can recognize the corresponding color. At the same time, the serial port will also output the recognized coordinates and color information.

+

+

Detailed Explanation

+

The app interface is as follows:

+

+

Using Default Configuration

+

The find blobs app provides four default configurations: red, green, blue, and user. red, green, and blue are used to find red, green, and blue color blobs, respectively, while user is mainly provided for user-defined color blob finding. The method for customizing configurations is described below. For a quick experience, you can switch to the corresponding configuration by clicking the buttons at the bottom of the interface.

+

Finding Custom Color Blobs

+

The app provides two ways to find custom color blobs: using adaptive LAB thresholds and manually setting LAB thresholds.

+
1. Finding Color Blobs with Adaptive LAB Thresholds
+

Steps:

+
    +
  1. Click the options icon in the bottom-left corner to enter configuration mode.
  2. +
  3. Point the camera at the object you need to find, click on the target object on the screen, and the left side will display a rectangular frame of the object's color and show the LAB values of that color.
  4. +
  5. Click on the appearing rectangular frame, and the system will automatically set the LAB thresholds. At this point, the image will outline the edges of the object.
  6. +
+
2. Manually Setting LAB Thresholds to Find Color Blobs
+

Manual setting allows for more precise targeting of the desired color blobs.

+

Steps:

+
    +
  1. Click the options icon in the bottom-left corner to enter configuration mode.
  2. +
  3. Point the camera at the object you need to find, click on the target object on the screen, and the left side will display a rectangular frame of the object's color and show the LAB values of that color.
  4. +
  5. Click on the bottom options L Min, L Max, A Min, A Max, B Min, B Max. After clicking, a slider will appear on the right side to set the value for that option. These values correspond to the minimum and maximum values of the L, A, and B channels in the LAB color format, respectively.
  6. +
  7. Referring to the LAB values of the object color calculated in step 2, adjust L Min, L Max, A Min, A Max, B Min, B Max to appropriate values to identify the corresponding color blobs. For example, if LAB = (20, 50, 80), since L=20, to accommodate a certain range, set L Min=10 and L Max=30. Similarly, since A=50, set A Min=40 and A Max=60. Since B=80, set B Min=70 and B Max=90.
  8. +
+

Getting Detection Data via Serial Protocol

+

The find blobs app supports reporting information about detected color blobs via the serial port (default baud rate is 115200).

+

Since only one report message is sent, we can illustrate the content of the report message with an example.

+

For instance, if the report message is:

+ +
shellCopy code
+
+AA CA AC BB 14 00 00 00 E1 08 EE 00 37 00 15 01 F7 FF 4E 01 19 00 27 01 5A 00 A7 20
+
+
    +
  • AA CA AC BB: Protocol header, content is fixed
  • +
  • 14 00 00 00: Data length, the total length excluding the protocol header and data length
  • +
  • E1: Flag, used to identify the serial message flag
  • +
  • 08: Command type, for the find blobs app application, this value is fixed at 0x08
  • +
  • EE 00 37 00 15 01 F7 FF 4E 01 19 00 27 01 5A 00: Coordinates of the four vertices of the found color blob, with each value represented by 2 bytes in little-endian format. EE 00 and 37 00 represent the first vertex coordinate as (238, 55), 15 01 and F7 FF represent the second vertex coordinate as (277, -9), 4E 01 and 19 00 represent the third vertex coordinate as (334, 25), 27 01 and 5A 00 represent the fourth vertex coordinate as (295, 90).
  • +
  • A7 20: CRC checksum value, used to verify if the frame data has errors during transmission.
  • +
+

About the LAB Color Space

+

The LAB color space, like the RGB color space, is a way to represent colors. LAB can represent all colors visible to the human eye. If you need to learn more about LAB, you can search for relevant articles online, which will provide more details. However, for you, it should be sufficient to understand why LAB is advantageous for MaixPy.

+

Advantages of LAB for MaixPy:

+
    +
  1. The color gamut of the LAB color space is larger than that of RGB, so it can completely replace RGB.
  2. +
  3. In the LAB color space, since the L channel is the brightness channel, we often set it to a relatively large range (commonly [0, 80]), and when coding, we mainly focus on the A and B channels. This can save a lot of time spent struggling with how to select color thresholds.
  4. +
  5. The color perception in the LAB color space is more uniform and easier to debug with code. For example, if you only need to find red color blobs, you can fix the values of the L and B channels and only adjust the value of the A channel (in cases where high color accuracy is not required). For RGB channels, you generally need to adjust all three R, G, and B channels simultaneously to find suitable thresholds.
  6. +
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/vision/image_ops.html b/maixpy/doc/en/vision/image_ops.html new file mode 100644 index 00000000..bc902ac7 --- /dev/null +++ b/maixpy/doc/en/vision/image_ops.html @@ -0,0 +1,606 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy Basic Image Operations - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy Basic Image Operations

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ + +
+ + Update history +
+ + + + + + + + + + + + + + + + + + + +
DateVersionAuthorUpdate content
2024-04-031.0.0neucrack + + Initial document + +
+
+
+ +
+
+ +

Introduction

+

Images play a very important role in visual applications. Whether it's a picture or a video, since a video is essentially a series of frames, image processing is the foundation of visual applications.

+

API Documentation

+

This document introduces common methods. For more APIs, refer to the documentation of the maix.image module.

+

Image Formats

+

MaixPy provides a basic image module image, where the most important part is the image.Image class, which is used for image creation and various basic image operations, as well as image loading and saving.

+

There are many image formats, and we generally use image.Format.FMT_RGB888 or image.Format.FMT_RGBA8888 or image.Format.FMT_GRAYSCALE or image.Format.FMT_BGR888, etc.

+

We all know that the three colors RGB can synthesize any color, so in most cases, we use image.Format.FMT_RGB888, which is sufficient. RGB888 is RGB packed in memory, i.e., the arrangement in memory is:
+pixel1_red, pixel1_green, pixel1_blue, pixel2_red, pixel2_green, pixel2_blue, ... arranged in sequence.

+

Creating an Image

+

Creating an image is very simple, you only need to specify the width and height of the image, and the image format:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+print(img)
+print(img.width(), img.height(), img.format())
+
+

320 is the width of the image, 240 is the height of the image, and image.Format.FMT_RGB888 is the format of the image. The format parameter can be omitted, and the default is image.Format.FMT_RGB888.

+

Here, you can get the width, height, and format of the image using img.width(), img.height(), and img.format().

+

Displaying on the Screen

+

MaixPy provides the maix.display.Display class, which can conveniently display images:

+ +
from maix import image, display
+
+disp = display.Display()
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+disp.show(img)
+
+

Note that here, since there is no image data, a black image is displayed. See the following sections for how to modify the image.

+

Reading Images from the File System

+

MaixPy provides the maix.image.load method, which can read images from the file system:

+ +
from maix import image
+
+img = image.load("/root/image.jpg")
+print(img)
+
+

Note that here, /root/image.jpg has been transferred to the board in advance. You can refer to the previous tutorials for the method.
+It supports jpg and png image formats.

+

Saving Images to the File System

+

MaixPy's maix.image.Image provides the save method, which can save images to the file system:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+
+# do something with img
+img.save("/root/image.jpg")
+
+

Drawing Rectangles

+

image.Image provides the draw_rect method, which can draw rectangles on the image:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+img.draw_rect(10, 10, 100, 100, image.Color.from_rgb(255, 0, 0))
+
+

Here, the parameters are: x, y, w, h, color. x and y are the coordinates of the top-left corner of the rectangle, w and h are the width and height of the rectangle, and color is the color of the rectangle, which can be created using the image.Color.from_rgb method.
+You can specify the line width of the rectangle using thickness, which defaults to 1.

+

You can also draw a solid rectangle by passing thickness=-1:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+img.draw_rect(10, 10, 100, 100, (255, 0, 0), thickness=-1)
+
+

Writing Strings

+

image.Image provides the draw_string method, which can write text on the image:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+img.draw_string(10, 10, "Hello MaixPy", image.Color.from_rgb(255, 0, 0))
+
+

Here, the parameters are: x, y, text, color. x and y are the coordinates of the top-left corner of the text, text is the text to be written, and color is the color of the text, which can be created using the image.Color.from_rgb method.

+

You can also enlarge the font by passing the scale parameter:

+ +
img.draw_string(10, 10, "Hello MaixPy", image.Color.from_rgb(255, 0, 0), scale=2)
+
+

Get the width and height of the font:

+ +
w, h = img.string_size("Hello MaixPy", scale=2)
+print(w, h)
+
+

Note that here, scale is the magnification factor, and the default is 1. It should be consistent with draw_string.

+

Drawing Lines

+

image.Image provides the draw_line method, which can draw lines on the image:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+img.draw_line(10, 10, 100, 100, image.Color.from_rgb(255, 0, 0))
+
+

Here, the parameters are: x1, y1, x2, y2, color. x1 and y1 are the coordinates of the starting point of the line, x2 and y2 are the coordinates of the end point of the line, and color is the color of the line, which can be created using the image.Color.from_rgb method.

+

Drawing Circles

+

image.Image provides the draw_circle method, which can draw circles on the image:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+img.draw_circle(100, 100, 50, image.Color.from_rgb(255, 0, 0))
+
+

Here, the parameters are: x, y, r, color. x and y are the coordinates of the center of the circle, r is the radius, and color is the color of the circle, which can be created using the image.Color.from_rgb method.

+

Resizing Images

+

image.Image provides the resize method, which can resize images:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+img_new = img.resize(160, 120)
+print(img, img_new)
+
+

Note that here, the resize method returns a new image object, and the original image remains unchanged.

+

Cropping Images

+

image.Image provides the crop method, which can crop images:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+img_new = img.crop(10, 10, 100, 100)
+print(img, img_new)
+
+

Note that here, the crop method returns a new image object, and the original image remains unchanged.

+

Rotating Images

+

image.Image provides the rotate method, which can rotate images:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+img_new = img.rotate(90)
+print(img, img_new)
+
+

Note that here, the rotate method returns a new image object, and the original image remains unchanged.

+

Copying Images

+

image.Image provides the copy method, which can copy an independent image:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888) 
+img_new = img.copy()
+print(img, img_new)
+
+

Affine Transformations

+

image.Image provides the affine method, which can perform affine transformations. By providing the coordinates of three or more points in the current image and the corresponding coordinates in the target image, you can automatically perform operations such as rotation, scaling, and translation on the image to transform it into the target image:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+img_new = img.affine([(10, 10), (100, 10), (10, 100)], [(10, 10), (100, 20), (20, 100)])
+print(img, img_new)
+
+

For more parameters and usage, please refer to the API documentation.

+

Drawing Keypoints

+

image.Image provides the draw_keypoints method, which can draw keypoints on the image:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+
+keypoints = [(10, 10), (100, 10), (10, 100)]
+img.draw_keypoints(keypoints, image.Color.from_rgb(255, 0, 0), size=10, thickness=1, fill=False)
+
+

This draws three red keypoints at the coordinates (10, 10), (100, 10), and (10, 100). The size of the keypoints is 10, the line width is 1, and they are not filled.

+

Drawing Crosses

+

image.Image provides the draw_cross method, which can draw crosses on the image:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+img.draw_cross(100, 100, image.Color.from_rgb(255, 0, 0), size=5, thickness=1)
+
+

This draws a red cross at the coordinate (100, 100). The extension size of the cross is 5, so the length of the line segment is 2 * size + thickness, and the line width is 1.

+

Drawing Arrows

+

image.Image provides the draw_arrow method, which can draw arrows on the image:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+img.draw_arrow(10, 10, 100, 100, image.Color.from_rgb(255, 0, 0), thickness=1)
+
+

This draws a red arrow starting from the coordinate (10, 10), with the end point at (100, 100), and a line width of 1.

+

Drawing Images

+

image.Image provides the draw_image method, which can draw images on the image:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+img2 = image.Image(100, 100, image.Format.FMT_RGB888)
+img2.draw_rect(10, 10, 90, 90, image.Color.from_rgb(255, 0, 0))
+img.draw_image(10, 10, img2)
+
+

Converting Formats

+

image.Image provides the to_format method, which can convert image formats:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+img_new = img.to_format(image.Format.FMT_BGR888)
+print(img, img_new)
+img_jpg = img.to_format(image.Format.FMT_JPEG)
+print(img, img_new)
+
+

Note that here, the to_format method returns a new image object, and the original image remains unchanged.

+

Converting between Numpy/OpenCV Formats

+

You can also convert to a numpy array, which can then be used by libraries such as numpy and opencv:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+img_np = image.image2cv(img)
+img2   = image.cv2image(img_np)
+print(type(img_np), img_np, img_np.shape)
+print(type(img2), img2)
+
+

Converting between bytes Data

+

image.Image provides the to_bytes method, which can convert an image to bytes data:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+data = img.to_bytes()
+print(type(data), len(data), img.data_size())
+
+img2 = image.Image(320, 240, image.Format.FMT_RGB888, data)
+print(img2)
+
+

Here, to_bytes returns a new bytes object, which is independent memory and does not affect the original image.
+The image.Image constructor can directly construct an image object from bytes data by passing the data parameter. Note that the new image is also independent memory and does not affect data.

+

Since memory copying is involved, this method is relatively time-consuming and should not be used frequently.

+
+

If you want to optimize your program without copying (not recommended for casual use, as poorly written code can easily cause crashes), please refer to the API documentation.

+
+

More Basic API Usage

+

For more API usage, please refer to the documentation of the maix.image module.

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/vision/line_tracking.html b/maixpy/doc/en/vision/line_tracking.html new file mode 100644 index 00000000..4e5141bb --- /dev/null +++ b/maixpy/doc/en/vision/line_tracking.html @@ -0,0 +1,535 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy Line Tracking - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy Line Tracking

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ + +
+ + Update history +
+ + + + + + + + + + + + + + + + + + + +
DateVersionAuthorUpdate content
2024-05-091.0.0lxowalle + + Initial document + +
+
+
+ +
+
+ +

Before reading this article, make sure you already know how to develop MaixCAM. For details, please read Quick Start.

+

Introduction

+

In vision applications, the function of tracking line is often required in applications such as line-following robot. In this article, we will describe:

+
    +
  • How to use MaixPy to tracking line.

    +
  • +
  • How to tracking line using MaixCam's default application

    +
  • +
+

How to use MaixPy to tracking line

+

The maix.image.Image module in MaixPy provides the get_regression method, which can conveniently tracking line.

+

Code example

+

A simple example of finding and drawing a line.

+ +
from maix import camera, display, image
+
+cam = camera.Camera(320, 240)
+disp = display.Display()
+
+# thresholds = [[0, 80, 40, 80, 10, 80]] # red
+thresholds = [[0, 80, -120, -10, 0, 30]] # green
+# thresholds = [[0, 80, 30, 100, -120, -60]] # blue
+
+while 1:
+    img = cam.read()
+
+    lines = img.get_regression(thresholds, area_threshold = 100)
+    for a in lines:
+        img.draw_line(a.x1(), a.y1(), a.x2(), a.y2(), image.COLOR_GREEN, 2)
+        theta = a.theta()
+        rho = a.rho()
+        if theta > 90:
+            theta = 270 - theta
+        else:
+            theta = 90 - theta
+        img.draw_string(0, 0, "theta: " + str(theta) + ", rho: " + str(rho), image.COLOR_BLUE)
+
+    disp.show(img)
+
+

Steps:

+
    +
  1. import image, camera, display modules

    + +
    from maix import image, camera, display
    +
    +
  2. +
  3. Initialize camera and display

    + +
    cam = camera.Camera(320, 240) # Initialise camera, output resolution 320x240 in RGB format.
    +disp = display.Display()
    +
    +
  4. +
  5. Get the image from the camera and display it

    + +
    while 1:
    +    img = cam.read()
    +    disp.show(img)
    +
    +
  6. +
  7. Call the get_regression method to find the straight line in the camera image and draw it to the screen

    + +
    lines = img.get_regression(thresholds, area_threshold = 100)
    +for a in lines:
    +   img.draw_line(a.x1(), a.y1(), a.x2(), a.y2(), image.COLOR_GREEN, 2)
    +   theta = a.theta()
    +   rho = a.rho()
    +   if theta > 90:
    +      theta = 270 - theta
    +   else:
    +      theta = 90 - theta
    +   img.draw_string(0, 0, "theta: " + str(theta) + ", rho: " + str(rho), image.COLOR_BLUE)
    +
    +
      +
    • img is the camera image read via cam.read(), when initialised as cam = camera.Camera(320, 240), the img object is an RGB image with a resolution of 320x240.
    • +
    • img.get_regression is used to find straight lines, thresholds is a list of colour thresholds, each element is a colour threshold, multiple thresholds are passed in if multiple thresholds are found at the same time, and each colour threshold has the format [L_MIN, L_MAX, A_MIN, A_MAX, B_MIN, B_MAX], where L, A, B are the three channels of LAB colour space, L channel is the luminance, A channel is the red-green channel, B channel is the blue-yellow channel. pixels_threshold is a pixel area threshold used to filter some unwanted straight lines.
    • +
    • for a in lines is used to iterate through the returned Line objects, where a is the current Line object. Normally the get_regression function will only return one Line object, but if you need to find more than one line, try the find_line method.
    • +
    • Use img.draw_line to draw the found line, a.x1(), a.y1(), a.x2(), a.y2() represent the coordinates of the ends of the line.
    • +
    • Use img.draw_string to show the angle between the line and the x-axis in the upper left corner, and a.theta() is the angle between the line and the y-axis, which is converted to theta for easier understanding, a.rho() is the length of the vertical line from the origin to the line.
    • +
    +
  8. +
  9. Run the code through the maixvision, you can find the line, look at the effect!

    +

    image-20240509110204007

    +
  10. +
+

Common Parameter Explanations

+

Here are explanations of commonly used parameters. If you cannot find parameters that can implement your application, you may need to consider using other algorithms or extending the required functionality based on the current algorithm's results.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterDescriptionExample
thresholdsThresholds based on the LAB color space, thresholds=[[l_min, l_max, a_min, a_max, b_min, b_max]], representing:
Brightness range [l_min, l_max]
Green to red component range [a_min, a_max]
Blue to yellow component range [b_min, b_max]
Multiple thresholds can be set simultaneously
Set two thresholds to detect red and green
img.find_blobs(thresholds=[[0, 80, 40, 80, 10, 80], [0, 80, -120, -10, 0, 30]])
Red threshold is [0, 80, 40, 80, 10, 80]
Green threshold is [0, 80, -120, -10, 0, 30]
invertEnable threshold inversion, when enabled, the passed thresholds are inverted. Default is False.Enable threshold inversion
img.find_blobs(invert=True)
roiSet the rectangular region for the algorithm to compute, roi=[x, y, w, h], where x and y represent the coordinates of the top-left corner of the rectangle, and w and h represent the width and height of the rectangle, respectively. The default is the entire image.Compute the region at (50, 50) with a width and height of 100
img.find_blobs(roi=[50, 50, 100, 100])
area_thresholdFilter out blobs with a pixel area smaller than area_threshold, in units of pixels. The default is 10. This parameter can be used to filter out some useless small blobs.Filter out blobs with an area smaller than 1000
img.find_blobs(area_threshold=1000)
pixels_thresholdFilter out blobs with fewer valid pixels than pixels_threshold. The default is 10. This parameter can be used to filter out some useless small blobs.Filter out blobs with fewer than 1000 valid pixels
img.find_blobs(pixels_threshold=1000)
+

This article introduces commonly used methods. For more APIs, please see the image section of the API documentation.

+

How to tracking line using MaixCam's default application

+

To quickly verify the line tracking functionality, you can use the line_tracking application provided by MaixCam to experience the line finding effect.

+

How to use it

+
    +
  1. Select and open the Line tracking application.
  2. +
  3. Click on the line in the screen that needs to be identified and the colour of the line will be displayed on the left hand side
  4. +
  5. Click on the colour to be detected on the left (the colour below L A B in the screen)
  6. +
  7. The line will be identified and the coordinates and angle of the line will be output from the serial port.
  8. +
+

Demo

+

+

Advanced operations

+

Manual adjustment of LAB threshold to tracking line

+

The application provides manual setting of LAB threshold to tracking line accurately.

+

Steps:

+
    +
  1. Click the options icon in the bottom-left corner to enter configuration mode.
  2. +
  3. Point the camera at the object you need to find, click on the target object on the screen, and the left side will display a rectangular frame of the object's color and show the LAB values of that color.
  4. +
  5. Click on the bottom options L Min, L Max, A Min, A Max, B Min, B Max. After clicking, a slider will appear on the right side to set the value for that option. These values correspond to the minimum and maximum values of the L, A, and B channels in the LAB color format, respectively.
  6. +
  7. Referring to the LAB values of the object color calculated in step 2, adjust L Min, L Max, A Min, A Max, B Min, B Max to appropriate values to identify the corresponding color blobs. For example, if LAB = (20, 50, 80), since L=20, to accommodate a certain range, set L Min=10 and L Max=30. Similarly, since A=50, set A Min=40 and A Max=60. Since B=80, set B Min=70 and B Max=90.
  8. +
+

Getting Detection Data via Serial Protocol

+

The line tracking application supports reporting detected straight line information via the serial port (default baud rate is 115200).

+

Since only one report message is sent, we can illustrate the content of the report message with an example.

+

For instance, if the report message is:

+ +
AA CA AC BB 0E 00 00 00 00 E1 09 FC 01 01 00 E9 01 6F 01 57 00 C1 C6
+
+
    +
  • AA CA AC BB: Protocol header, fixed content

    +
  • +
  • 0E 00 00 00: Data length, the total length excluding the protocol header and data length, here means the length is 14.

    +
  • +
  • E1: Flag bit, used to identify the serial message flag

    +
  • +
  • 09: Command type, for the line tracking application, this value is fixed at 0x09.

    +
  • +
  • FC 01 01 00 E9 01 6F 01 57 00: The coordinates and angle information for both ends of line, with each value represented as a 2-byte value in little-end format. FC 01 and 01 00 indicate that the coordinates of the first endpoint are (508, 1), E9 01 and 6F 01 indicate that the coordinates of the second endpoint are (489, 367), and 57 00 indicates that the angle of the line to the x-axis is 87 degrees

    +
  • +
  • C1 C6: CRC checksum value, used to verify if the frame data has errors during transmission.

    +
  • +
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/vision/maixhub_train.html b/maixpy/doc/en/vision/maixhub_train.html new file mode 100644 index 00000000..b7079069 --- /dev/null +++ b/maixpy/doc/en/vision/maixhub_train.html @@ -0,0 +1,394 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Using MaixHub to Train AI Models for MaixPy - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

Using MaixHub to Train AI Models for MaixPy

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ + +
+ + Update history +
+ + + + + + + + + + + + + + + + + + + +
DateVersionAuthorUpdate content
2024-04-031.0.0neucrack + + Initial document + +
+
+
+ +
+
+ +

Introduction

+

MaixHub offers the functionality to train AI models online, directly within a browser. This eliminates the need for expensive hardware, complex development environments, or coding skills, making it highly suitable for beginners as well as experts who prefer not to delve into code.

+

Basic Steps to Train a Model Using MaixHub

+

Identify the Data and Model Types

+

To train an AI model, you first need to determine the type of data and model. As of April 2024, MaixHub provides models for image data including Object Classification Models and Object Detection Models. Object classification models are simpler than object detection models, as the latter require marking the position of objects within images, which can be more cumbersome. Object classification merely requires identifying what is in the image without needing coordinates, making it simpler and recommended for beginners.

+

Collect Data

+

As discussed in AI basics, training a model requires a dataset for the AI to learn from. For image training, you need to create a dataset and upload images to it.

+

Ensure the device is connected to the internet (WiFi).
+Open the MaixHub app on your device and choose to collect data to take photos and upload them directly to MaixHub. You need to create a dataset on MaixHub first, then click on device upload data, which will display a QR code. Scan this QR code with your device to connect to MaixHub.

+

It's important to distinguish between training and validation datasets. To ensure the performance during actual operation matches the training results, the validation dataset must be of the same image quality as those taken during actual operation. It's also advisable to use images taken by the device for the training set. If using internet images, restrict them to the training set only, as the closer the dataset is to actual operational conditions, the better.

+

Annotate Data

+

For classification models, images are annotated during upload by selecting the appropriate category for each image.

+

For object detection models, after uploading, you need to manually annotate each image by marking the coordinates, size, and category of the objects to be recognized.
+This annotation process can also be done offline on your own computer using software like labelimg, then imported into MaixHub using the dataset import feature.
+Utilize shortcuts during annotation to speed up the process. MaixHub will also add more annotation aids and automatic annotation tools in the future (there is already an automatic annotation tool available for videos that you can try).

+

Train the Model

+

Select training parameters, choose the corresponding device platform, select maixcam, and wait in the training queue. You can monitor the training progress in real-time and wait for it to complete.

+

Deploy the Model

+

Once training is complete, you can use the deploy function in the MaixHub app on your device to scan a code and deploy.
+The device will automatically download and run the model, storing it locally for future use.

+

If you find the recognition results satisfactory, you can share the model to the model library with a single click for others to use.

+

How to Use

+

Please visit MaixHub to register an account, then log in. There are video tutorials on the homepage for learning.

+

Note that if the tutorial uses the M2dock development board, the process is similar for MaixCAM, although the MaixHub application on the device might differ slightly. The overall process is the same, so please apply the knowledge flexibly.

+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/vision/object_track.html b/maixpy/doc/en/vision/object_track.html new file mode 100644 index 00000000..9615181a --- /dev/null +++ b/maixpy/doc/en/vision/object_track.html @@ -0,0 +1,338 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/vision/qrcode.html b/maixpy/doc/en/vision/qrcode.html new file mode 100644 index 00000000..c94df467 --- /dev/null +++ b/maixpy/doc/en/vision/qrcode.html @@ -0,0 +1,456 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy QR Code Recognition - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy QR Code Recognition

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ + +
+ + Update history +
+ + + + + + + + + + + + + + + + + + + +
DateVersionAuthorUpdate content
2024-04-031.0.0lxowalle + + Initial document + +
+
+
+ +
+
+ +

Before reading this article, make sure you are familiar with how to develop with MaixCAM. For details, please read Quick Start.

+

Introduction

+

This article explains how to use MaixPy for QR code recognition.

+

Using MaixPy to Recognize QR Codes

+

MaixPy's maix.image.Image includes the find_qrcodes method for QR code recognition.

+

How to Recognize QR Codes

+

A simple example that recognizes QR codes and draws a bounding box:

+ +
from maix import image, camera, display
+
+cam = camera.Camera(320, 240)
+disp = display.Display()
+
+while True:
+    img = cam.read()
+    qrcodes = img.find_qrcodes()
+    for qr in qrcodes:
+        corners = qr.corners()
+        for i in range(4):
+            img.draw_line(corners[i][0], corners[i][1], corners[(i + 1) % 4][0], corners[(i + 1) % 4][1], image.COLOR_RED)
+        img.draw_string(qr.x(), qr.y() - 15, qr.payload(), image.COLOR_RED)
+    disp.show(img)
+
+

Steps:

+
    +
  1. Import the image, camera, and display modules:

    + +
    from maix import image, camera, display
    +
    +
  2. +
  3. Initialize the camera and display:

    + +
    cam = camera.Camera(320, 240)  # Initialize the camera with a resolution of 320x240 in RGB format
    +disp = display.Display()
    +
    +
  4. +
  5. Capture and display images from the camera:

    + +
    while True:
    +    img = cam.read()
    +    disp.show(img)
    +
    +
  6. +
  7. Use the find_qrcodes method to detect QR codes in the camera image:

    + +
    qrcodes = img.find_qrcodes()
    +
    +
      +
    • img is the camera image captured by cam.read(). When initialized as cam = camera.Camera(320, 240), the img object is a 320x240 resolution RGB image.
    • +
    • img.find_qrcodes searches for QR codes and saves the results in qrcodes for further processing.
    • +
    +
  8. +
  9. Process and display the results of QR code recognition on the screen:

    + +
    for qr in qrcodes:
    +    corners = qr.corners()
    +    for i in range(4):
    +        img.draw_line(corners[i][0], corners[i][1], corners[(i + 1) % 4][0], corners[(i + 1) % 4][1], image.COLOR_RED)
    +    img.draw_string(qr.x(), qr.y() - 15, qr.payload(), image.COLOR_RED)
    +
    +
      +
    • qrcodes contains the results from img.find_qrcodes(). If no QR codes are found, qrcodes will be empty.
    • +
    • qr.corners() retrieves the coordinates of the four corners of the detected QR code. img.draw_line() uses these coordinates to draw the QR code outline.
    • +
    • img.draw_string displays information about the QR code content and position. qr.x() and qr.y() retrieve the x and y coordinates of the QR code's top-left corner, and qr.payload() retrieves the content of the QR code.
    • +
    +
  10. +
+

Common Parameter Explanation

+

List common parameters and their explanations. If you cannot find parameters that fit your application, consider whether to use a different algorithm or extend the functionality based on the current algorithm's results.

+ + + + + + + + + + + + + + + +
ParameterDescriptionExample
roiSets the rectangular area for the algorithm to compute, where roi=[x, y, w, h], x and y denote the top-left coordinates of the rectangle, and w and h denote the width and height of the rectangle, defaulting to the entire image.Compute the area with coordinates (50,50) and width and height of 100:
img.find_qrcodes(roi=[50, 50, 100, 100])
+

This article introduces common methods. For more API details, refer to the image section of the API documentation.

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/vision/self_learn_classifier.html b/maixpy/doc/en/vision/self_learn_classifier.html new file mode 100644 index 00000000..f700d12f --- /dev/null +++ b/maixpy/doc/en/vision/self_learn_classifier.html @@ -0,0 +1,378 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy Self-Learning Classifier - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy Self-Learning Classifier

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

Introduction to MaixPy Self-Learning Classifier

+

Typically, to recognize new categories, it is necessary to collect a new dataset and train on a computer, which can be cumbersome and complex. This method eliminates the need for computer-based training, allowing for immediate learning of new objects directly on the device, suitable for less complex scenarios.

+

For example, if there are a drink bottle and a mobile phone in front of you, take a photo of each to serve as the basis for two categories. Then, collect several photos from different angles of each item, extract their features and save them. During recognition, the image's features are compared with the saved feature values, and the closest match determines the classification.

+

Using the Self-Learning Classifier in MaixPy

+

Steps:

+
    +
  • Collect n classification images.
  • +
  • Collect n*m images, m images for each category, order does not matter.
  • +
  • Start learning.
  • +
  • Recognize images and output results.
  • +
+

Simplified version of the code, for the full version please refer to the complete code in the example.

+ +
from maix import nn, image
+
+classifier = nn.SelfLearnClassifier(model="/root/models/mobilenetv2.mud", feature_layer=None)
+
+img1 = image.load("/root/1.jpg")
+img2 = image.load("/root/2.jpg")
+img3 = image.load("/root/3.jpg")
+sample_1 = image.load("/root/sample_1.jpg")
+sample_2 = image.load("/root/sample_2.jpg")
+sample_3 = image.load("/root/sample_3.jpg")
+sample_4 = image.load("/root/sample_4.jpg")
+sample_5 = image.load("/root/sample_5.jpg")
+sample_6 = image.load("/root/sample_6.jpg")
+
+
+classifier.add_class(img1)
+classifier.add_class(img2)
+classifier.add_class(img3)
+classifier.add_sample(sample_1)
+classifier.add_sample(sample_2)
+classifier.add_sample(sample_3)
+classifier.add_sample(sample_4)
+classifier.add_sample(sample_5)
+classifier.add_sample(sample_6)
+
+classifier.learn()
+
+img = image.load("/root/test.jpg")
+max_idx, max_score = classifier.classify(img)
+print(max_idx, max_score)
+
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/vision/self_learn_detector.html b/maixpy/doc/en/vision/self_learn_detector.html new file mode 100644 index 00000000..bdd21b33 --- /dev/null +++ b/maixpy/doc/en/vision/self_learn_detector.html @@ -0,0 +1,339 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy Self-Learning Detector - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy Self-Learning Detector

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

MaixPy Self-Learning Detector

+

Similar to the self-learning classifier, the self-learning detector does not require training. Simply taking a few photos of the object to be detected can enable detection, which is very useful in simple detection scenarios.
+Unlike the self-learning classifier, since it is a detector, it will provide the coordinates and size of the object.

+

Using the Self-Learning Detector in MaixPy

+

TODO:

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/en/vision/yolov5.html b/maixpy/doc/en/vision/yolov5.html new file mode 100644 index 00000000..c3d0f4ce --- /dev/null +++ b/maixpy/doc/en/vision/yolov5.html @@ -0,0 +1,362 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Using YOLOv5 Model for Object Detection with MaixPy - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

Using YOLOv5 Model for Object Detection with MaixPy

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

Concept of Object Detection

+

Object detection refers to identifying the position and category of targets in an image or video, such as detecting objects like apples and airplanes in a picture, and marking the position of these objects.

+

Unlike classification, object detection includes positional information, so the result is usually a rectangular box that frames the location of the object.

+

Using Object Detection in MaixPy

+

MaixPy comes with the YOLOv5 model by default, which can be used directly:

+ +
from maix import camera, display, image, nn, app
+
+detector = nn.YOLOv5(model="/root/models/yolov5s.mud")
+
+cam = camera.Camera(detector.input_width(), detector.input_height(), detector.input_format())
+dis = display.Display()
+
+while not app.need_exit():
+    img = cam.read()
+    objs = detector.detect(img, conf_th = 0.5, iou_th = 0.45)
+    for obj in objs:
+        img.draw_rect(obj.x, obj.y, obj.w, obj.h, color = image.COLOR_RED)
+        msg = f'{detector.labels[obj.class_id]}: {obj.score:.2f}'
+        img.draw_string(obj.x, obj.y, msg, color = image.COLOR_RED)
+    dis.show(img)
+
+

Demonstration video:

+
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/audio/recognize.html b/maixpy/doc/zh/audio/recognize.html new file mode 100644 index 00000000..559faa3b --- /dev/null +++ b/maixpy/doc/zh/audio/recognize.html @@ -0,0 +1,338 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/basic/app.html b/maixpy/doc/zh/basic/app.html new file mode 100644 index 00000000..8352bf5a --- /dev/null +++ b/maixpy/doc/zh/basic/app.html @@ -0,0 +1,364 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 应用开发和应用商店 - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

应用开发和应用商店

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

应用生态简介

+

为了让开发板做到开箱即用,以及方便用户无门槛地使用,以及方便开发者分享自己的有趣应用,并且能有有效的渠道获取到反馈甚至是收益,我们推出了一个简易的应用框架,包括:

+
    +
  • 应用商店: 开发者上传分享应用,用户无需开发直接下载使用,开发者可以获取到一定的现金收益(来自 MaixHub 官方以及用户打赏)。
  • +
  • 出厂内置大量应用: 官方提供了一些常用的应用,比如找色块、AI 物体检测追踪、找二维码、人脸识别等等,用户可以直接使用,也可以作为串口模块直接使用。
  • +
  • MaixPy + MaixCDK 软件开发包:使用 MaixPy 或者 MaixCDK 可以用 Python 或者 C/C++ 语言快速开发嵌入式 AI 视觉听觉应用,超高效率实现你的有趣想法。
  • +
  • MaixVision 配套电脑端开发工具: 全新的电脑端代码开发工具,快速上手、调试、运行、上传代码、安装应用到设备,一键式开发,甚至支持图像化积木式编程,小学生也能轻松上手。
  • +
+

大家可以多多关注应用商店,也可以在应用商店中分享自己的应用,大家一起共建活跃的社区。

+

打包应用

+

使用 MaixPy + MaixVison 可以方便地开发、打包、安装应用:

+
    +
  • 在 MaixVision 中使用 MaixPy 开发应用程序,可以是单个文件,也可以是一个工程目录。
  • +
  • 连接设备。
  • +
  • 点点击 MaixVision 左下角的 安装 按钮,会弹出一个界面填写应用的基本信息,id 是用来判别应用的 id,一个设备不能同时安装相同 id 的不同应用,所以 id 应该与 MaixHub 上面已经有的应用 id 不同,应用名字可以重复。以及图标等。
  • +
  • 点击打包应用,会将应用打包成一个安装包,如果你要上传到 MaixHub 应用商店,用这个打包好的文件即可。
  • +
  • 点击 安装应用,这会将打包好的应用安装到设备。
  • +
  • 断开与设备的连接,就能看到设备功能选择界面多了一个你的应用,直接点进去就能运行。
  • +
+
+

如果你用 MaixCDK 开发,使用 maixcdk relrease 就能打包出来一个应用,具体看 MaixCDK 的文档。

+
+

退出应用

+

如果你只是写了比较简单的应用,没有做界面和返回按钮,默认可以按设备上的功能按键(一般是 USER 或者 FUNC 或者 OK 按钮)或者返回按钮(如果有这个按键,MaixCAM 默认没有这个按键)来退出应用。

+

应用开发基本准则

+
    +
  • 因为默认都配了触摸屏幕,推荐都写一个简单的界面显示,最好有触摸交互。实现方法可以在例子里面找找参考。
  • +
  • 界面和按钮不要太小,因为 MaixCAM 默认的屏幕是 2.3寸 552x368分辨率,PPI 比较高屏幕比较小,要让手指能很容易戳到并且不会点错。
  • +
  • 每个应用实现的主要功能实现一个简单的串口交互,基于串口协议例程),这样用户可以直接当成串口模块使用,比如人脸检测应用,可以在检测到人脸后通过串口输出坐标。
  • +
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/basic/app_usage.html b/maixpy/doc/zh/basic/app_usage.html new file mode 100644 index 00000000..7f684b8f --- /dev/null +++ b/maixpy/doc/zh/basic/app_usage.html @@ -0,0 +1,338 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 应用使用说明 - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

应用使用说明

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

开机后会自动进入应用选择界面,内置各种应用均发布在 MaixHub 应用商店, 可以在这里找到对应应用的介绍和使用说明。

+

上手用得比较多的是 设置 -> 语言, 以及 设置 -> WiFi应用商店应用可以用来升级和安装应用,连接上可以连接互联网的 WiFi 后即可在MaixHub 应用商店扫码安装应用。

+

另外,你编写的应用也可以上传到MaixHub 应用商店分享给其他人使用,质量合格和优秀的应用都会得到官方红包打赏,优秀应用也会得到大家的赞同和支持。

+

无论是小到一个采集传感器的数据小应用还是功能复杂的应用,让我们一起来创造更多有趣的东西吧!

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/basic/linux_basic.html b/maixpy/doc/zh/basic/linux_basic.html new file mode 100644 index 00000000..f57d062d --- /dev/null +++ b/maixpy/doc/zh/basic/linux_basic.html @@ -0,0 +1,384 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Linux 基础知识 - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

Linux 基础知识

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

简介

+

本章内容对于刚入门的同学来说,可以先跳过此章节,在学会 MaixPy 基础开发后再来学习也是可以的。

+

最新的 MaixPy 支持的 MaixCAM 硬件支持跑 Linux 系统,所以 MaixPy 底层都是基于 Linux 系统进行开发的。
+虽然 Sipeed 开发的 MaixPy 已经为开发者们做了很多工作,即使不知道 Linux 系统知识也能愉快使用,但是以防在某些情况下需要一些底层操作,以及方便未接触过 Linux 的开发者学习,这里写一些 Linux 基础知识。

+

为什么需要 Linux 系统

+

具体的原因大家可以自行查阅,这里用通俗的看起来不太专业的话语简单举几个例子方便初学者理解:

+
    +
  • 在单片机中,我们的程序是一个死循环程序,用上 Linux 后我们可以同时跑很多程序,每个程序看起来都独立在同时运行,每个程序具体怎么执行的由操作系统实现。
  • +
  • 基于 Linux 的开发者众多,需要功能和驱动可以很方便地找到,不需要自己再实现一遍。
  • +
  • 基于 Linux 配套的软件工具丰富,可以很方便地进行开发和调试,比如在本教程没有提到的一些 Linux 通用工具理论上也是可以使用的。
  • +
+

文件系统

+

什么是文件系统?

+
    +
  • 就像电脑的文件系统一样,Linux 上会将硬件磁盘用文件系统进行管理,这样我们可以很方便地向磁盘读写数据。
  • +
  • 对于学过单片机没有接触过文件系统开发的同学来讲,可以理解为我们有一个 Flash 或者 TF 卡,我们可以通过 API 读写 Flash 存取数据,断电后也能保存数据,但是 Flash 具有读写寿命,我们往往需要写一套程序去保证 Flash 读写寿命,而文件系统就可以理解成这样一套成熟的程序,文件系统帮我们完成了具体如何管理 Flash 空间和读写,我们只需调用文件系统的 API 即可,大大减少了我们的开发工作量并且用成熟的程序保证了稳定性和安全性。
  • +
+

在电脑和设备(开发板)之间传输文件

+

既然设备有 Linux 和文件系统,那我们怎么发送文件到设备呢?

+

对于 MaixPy 我们配套了 MaixVision, 在后面的版本也会支持文件管理功能,在此之前可以用下面的方法:

+

这里我们主要介绍通过网络传输的方式,其它方式可自行探索传输文件到 Linux

+
    +
  • 确保设备和电脑连接到了同一个局域网,比如:
      +
    • MaixCAM 的 USB 口连接到电脑会创建一个虚拟网卡,在电脑端的设备管理器就能看到,设备的 IP 可以在设备的设置->设备信息中看到设备名和 IP。
    • +
    • 也可以在设备设置->WiFi中连接到和电脑相同的局域网。
    • +
    +
  • +
  • 电脑使用 SCP 或者 SFTP 协议传输文件到设备,具体的软件有很多,具体的软件和使用方法可以自行搜索,比如:
      +
    • 在 Windows 上可以使用 WinSCP 或者 FileZilla,或者 scp 命令等。
    • +
    • 在 Linux 上可以使用 FileZilla 或者 scp 命令 等。
    • +
    • 在 Mac 上可以使用 FileZilla 或者 scp 命令 等。
    • +
    +
  • +
+

终端和命令行

+

终端就是通过终端这个软件与 Linux 系统进行通信和操作的工具,类似于 Windows 的cmd或者PowerShell

+

比如我们可以在电脑的 Window 系统中的 powershell 或者 Linux系统中的 终端 工具中输入ssh root@maixcam-xxxx.local 这里具体的名字在设备的设置->设备信息中可以看到,这样我们就可以通过终端连接到设备了(用户名和密码都是root)。
+然后我们通过输入命令来操作设备,比如ls命令可以列出设备文件系统中当前目录下的文件, cd 用来切换当前所在的目录(就像电脑文件管理中点击文件夹切换目录一样),

+ +
cd /     # 切换到根目录
+ls       # 显示当前目录(根目录)下的所有文件
+
+

然后会显示类似下面的内容:

+ +
bin         lib         media       root        tmp
+boot        lib64       mnt         run         usr
+dev         linuxrc     opt         sbin        var
+etc         lost+found  proc        sys
+
+

更多命令学习请自行搜索Linux 命令行使用教程,这里只是为了让初学者知道基本概念,这样有开发者提到时可以知道是什么意思。

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/basic/maixpy_upgrade.html b/maixpy/doc/zh/basic/maixpy_upgrade.html new file mode 100644 index 00000000..a658d658 --- /dev/null +++ b/maixpy/doc/zh/basic/maixpy_upgrade.html @@ -0,0 +1,348 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 更新 MaixPy - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

更新 MaixPy

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

有两种方法,如果第一次上手使用,为了降低难度,可以直接使用出厂 TF 卡自带的 MaixPy 固件尝试,以后再考虑更新。

+

不过因为不知道你拿到手的是什么时候出厂的 TF 卡,所以建议都更新一下系统。

+

直接更新系统

+

按照 升级和烧录系统 中的操作升级到最新的系统,里面就包含了最新的 MaixPy 固件。

+

只更新 MaixPy 固件

+

MaixPy 仓库 release 页面 看到最新的版本信息和更新日志,其中包含了 MaixPy 固件信息,以及对应版本使用的系统信息。

+

如果不想更新系统(因为一般系统变动不大,可以看 MaixPy 更新日志中是否有系统改动相关,再决定是否更新系统),则可以只更新 MaixPy 固件。

+
    +
  • 在设置中设置 WiFi, 让系统联网。
  • +
  • 点击设置应用中的 更新 MaixPy 进行更新。
  • +
+
+

如果你会使用终端, 也可以在终端中使用 pip install MaixPy -U 来更新 MaixPy。

+
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/basic/maixvision.html b/maixpy/doc/zh/basic/maixvision.html new file mode 100644 index 00000000..d2bdc4df --- /dev/null +++ b/maixpy/doc/zh/basic/maixvision.html @@ -0,0 +1,417 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixVision -- MaixPy 编程 IDE + 图形化积木编程 - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixVision -- MaixPy 编程 IDE + 图形化积木编程

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

简介

+

MaixVision 是专为 Maix 生态打造的一款开发者编程工具,支持 MaixPy 编程和图形化积木编程,同时支持在线运行和调试,以及实时预览图像,可以同步设备显示屏的图像,方便调试和开发。

+

以及支持打包应用和安装应用到设备,方便用户一键生成、安装应用。

+

同时还集成一些方便开发的小工具,比如文件管理,阈值编辑器,二维码生成等等。

+

下载

+

访问 MaixVision 主页 下载。

+

使用 MaixPy 编程和在线运行

+

按照快速开始的步骤连接设备,我们可以很方便地使用 MaixPy 编程和在线运行。

+

实时预览图像

+

MaixPy 提供display模块,可以将图像显示到屏幕上,同时,在调用display模块的show方法时,会将图像发送到 MaixVision 显示,比如代码:

+ +
from maix import display, camera
+
+cam = camera.Camera(640, 480)
+disp = display.Display()
+while 1:
+    disp.show(cam.read())
+
+

这里我们用摄像头读取了图像,然后通过disp.show()方法将图像显示到屏幕上,同时也会发送到 MaixVision 显示。

+

当我们点击了右上角的暂停按钮,就会停止发送图像到 MaixVision 显示。

+

代码自动补全

+

代码提示依赖电脑本地的 Python 包,为了实现代码提示,我们需要在电脑中安装 Python,并且安装需要提示的 Python 包。

+
    +
  • 安装 Python 请访问 Python 官网安装。
  • +
  • 安装需要提示的包,比如对于 MaixPy, 你需要在电脑也安装一份 MaixPy 包,在电脑使用pip install MaixPy即可安装好,如果MaixPy更新了,你也需要在电脑和设备更新到MaixPy,电脑手动在终端执行pip install MaixPy -U即可,设备更新直接在设置应用中更新即可。
  • +
+
+

中国国内用户可以使用国内镜像pip install -i https://pypi.tuna.tsinghua.edu.cn/simple MaixPy

+
+
    +
  • 重启 MaixVision 就能够看到代码提示了。
  • +
+
+

如果仍然不能提示,可以手动在设置中设置 python 可执行文件的路径后重启。

+
+
+

注意在电脑安装 Python 包这里只是为了用作代码提示,实际代码运行还是在设备(开发板)上,设备上也要有对应的包才能正常运行。

+
+
+

另外,虽然你在电脑上安装了 MaixPy 包,但是由于我们精力有限,我们不确保你能直接在电脑的 Python 导入 maix 包进行使用,请在支持的设备上运行。

+
+

计算图像的直方图

+

在上一步中我们可以在 MaixVision 中实时看到图像,我们用鼠标框选一个区域,图像下方就能看到这个区域的直方图了,选择不同的颜色表示方法,可以看到不同的颜色通道的直方图。

+

这个功能方便我们在做某些图像处理算法时找到一些合适的参数。

+

区分设备文件系统电脑文件系统

+

这里我们有一个比较重要的概念需要掌握:分清楚设备文件系统电脑文件系统

+
    +
  • 电脑文件系统:运行在电脑上,在 MaixVision 中打开文件或者工程都是打开的电脑里面的文件,保存也是自动保存到电脑的文件系统。
  • +
  • 设备文件系统:程序运行时会将程序发送到设备上运行,所以代码里面使用的文件都是从设备文件系统读取。
  • +
+

所以常见的问题是有同学在电脑上保存了文件D:\data\a.jpg,然后在设备上使用这个文件img = image.load("D:\data\a.jpg"),这样当然是找不到文件的,因为设备上没有D:\data\a.jpg这个文件。

+

具体如何将电脑的文件发送到设备上,参考下面的章节。

+

传输文件到设备

+

先连接设备,然后点击浏览设备文件系统的按钮,有两个入口,如下图,然后就能上传文件到设备,或者从设备下载文件到电脑了。

+

maixvision_browser2

+

maixvision_browser

+
+也可以用其它工具代替,点击展开 +

先知道设备的 ip 地址或者设备名称,MaixVision 就可以搜索到, 或者在设备设置->系统信息中看到,比如类似 maixcam-xxxx.local 或者 192.168.0.123
+ 用户名和密码都是 root, 使用 SFTP 协议传输文件,端口号是 22

+

然后不同系统下都有很多好用的软件:

+

Windows 下

+

使用 WinSCP 或者 FileZilla 等工具连接设备,将文件传输到设备上,选择 SFTP 协议填写设备和账号信息连接即可。

+

具体不懂的可以自行搜索。

+

Linux 下

+

终端使用 scp 命令传输文件到设备上,比如:

+ +
scp /path/to/your/file.py root@maixcam-xxxx.local:/root
+
+

Mac 下

+
    +
  • 方法一:终端使用 scp 命令传输文件到设备上,比如:
  • +
+ +
scp /path/to/your/file.py root@maixcam-xxxx.local:/root
+
+
    +
  • 方法二:使用 FileZilla 等工具连接设备,将文件传输到设备上,选择 SFTP 协议填写设备和账号信息连接即可。
  • +
+
+
+

使用图形化积木编程

+

开发中,敬请期待。

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/basic/os.html b/maixpy/doc/zh/basic/os.html new file mode 100644 index 00000000..594e37db --- /dev/null +++ b/maixpy/doc/zh/basic/os.html @@ -0,0 +1,353 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 升级和烧录系统 - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

升级和烧录系统

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

介绍

+

如果你购买了官方(Sipeed)的带 TF 卡的套餐,一般来说出厂已经烧录好了系统,可以跳过这一步直接使用。

+

但是为了防止出厂烧录的系统版本过旧,强烈建议先按照教程升级到最新的系统。

+

如何确认系统是否需要升级

+
    +
  • 在开机后的功能选择界面,点击设置,然后点击设备信息,可以看到系统的版本号。
  • +
  • MaixPy 发布历史页面查看更新日志,里面有 MaixPy 固件和系统镜像的更新说明,如果在你的版本后有重要更新,建议升级。
  • +
+
+

如果最新系统和当前系统对比只是 MaixPy 固件的常规更新,也可以不升级,在 设置 中的 更新 MaixPy 中单独更新 MaixPy 即可。

+
+

获得最新系统

+

MaixPy 发布页面 找到最新的系统镜像文件,比如maixcam_os_20240401_maixpy_v4.1.0.xz

+

备用地址:

+ +

烧录系统到 MaixCAM

+

参考 MaixCAM 系统烧录 教程。

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/basic/python.html b/maixpy/doc/zh/basic/python.html new file mode 100644 index 00000000..f6fba52d --- /dev/null +++ b/maixpy/doc/zh/basic/python.html @@ -0,0 +1,375 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Python 基础知识 - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

Python 基础知识

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

MaixPy 的教程文档里面就不涉及具体的 Python 语法教程了,因为 Python 的教程实在是太多了,都做得很好,这里只介绍需要学什么,方向和线路指导即可。

+

Python 简介

+

Python 是一门解释性、面向对象、动态类型的高级编程语言。

+
    +
  • 解释性:不需要编译,直接运行,优点是开发快速,缺点是因为每次运行都要解释一遍代码,运行速度慢一点点,但是往往瓶颈还是开发者写的代码而不是语言本身。
  • +
  • 面向对象:支持面向对象编程,可以定义类和对象,相比面向过程语言,更容易组织代码。更多自行搜索。
  • +
  • 动态类型:变量不需要声明类型,可以直接赋值,类型会根据赋值自动确定,这样可以减少代码量,但是也容易出现类型错误,需要开发者自己注意。
  • +
+

总之,对于没有接触过 Python 的开发者来说,Python 非常容易上手,有大量现成的库,开发者群体巨大,开发应用周期短,非常值得学习!

+

Python 环境安装

+

你可以按照你学习的 Python 教程在电脑上安装 Python;
+也可以在 MaixVisioin 上连接设备后使用 MaixVision 编程然后在开发板运行。

+

使用 MaixPy 需要的 Python 基础有哪些?

+
    +
  • Python 的基本概念。
  • +
  • 面向对象编程的基本概念。
  • +
  • Python 的基本语法,包括:
      +
    • tab 缩进对齐语法
    • +
    • 变量、函数、类、对象、注释等
    • +
    • 控制语句比如 if、for、while 等等
    • +
    • 模块和导入模块
    • +
    • 基本数据类型比如 int、float、str、list、dict、tuple 等等
    • +
    • bytes 和 str 的区别和转换
    • +
    • 异常处理,try except
    • +
    • 常用的内置函数,比如 print、open、len、range 等等
    • +
    • 常用的内置模块,比如 os、sys、time、random、math 等等
    • +
    +
  • +
+

掌握以上的基础知识就可以顺畅使用 MaixPy 编程了,配合后面的教程和例程,在不懂的时候查询搜索引擎或者官方文档,或者问 ChatGPT 就能顺利完成开发。

+

对于已经有一门面向对象编程语言经验的开发者

+

如果你已经会一门面向对象语言比如 C++/Java/C# 等等,那只需要快速浏览一下 Python 的语法,就可以开始使用了。

+

比如 菜鸟教程 或者 Python 官方教程

+

或者个人开发者的博客,比如 哇!是 Python

+

对于没有面向对象编程经验但是有 C 语言经验的开发者

+

如果只学了 C,缺乏对面向对象的理解,那么可以先学习一下面向对象的概念,然后再学习 Python,也是比较快的,可以自行搜索视频教程入门。

+

跟着视频教程入门之后可以看看文档教程,比如 菜鸟教程 或者 Python 官方教程 就可以开动了!

+

在学了入门知识后,就可以按照 MaixPy 的文档和例程开始使用 MaixPy 编程了。

+

对于编程新手

+

如果你从未接触过编程,那么你需要重头开始学习 Python,Python 作为入门语言也是比较合适的,具体可以搜一搜视频教程。

+

在学会了基础语法后,就能按照例程使用 MaixPy 编程了。

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/basic/python_pkgs.html b/maixpy/doc/zh/basic/python_pkgs.html new file mode 100644 index 00000000..98620181 --- /dev/null +++ b/maixpy/doc/zh/basic/python_pkgs.html @@ -0,0 +1,353 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 添加额外的 Python 软件包 - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

添加额外的 Python 软件包

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

简介

+

MaixPy 基于 Python 语言,提供了大量方便嵌入式应用开发的功能和 API,除此之外,你也可以使用其它的 Python 包来扩展功能。

+

安装额外的 Python 包

+
+

注意可能不是所有 Python 包都支持,一般只支持纯 Python 包,不支持 C 扩展包, C 扩展包可能需要你手动在电脑交叉编译(比较复杂,这里就不介绍了)。

+
+

方法一: 使用 Python 代码来安装

+

在 MaixVision 中使用 Python 代码来安装你需要的包,比如:

+ +
import os
+os.system("pip install 包名")
+
+

要更新一个包,可以使用:

+ +
import os
+os.system("pip install --upgrade 包名")
+
+

方法二: 终端使用 pip 命令安装

+

使用Linux 基础中介绍的终端使用方法,使用 pip install 包名 安装你需要的包。

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/config.json b/maixpy/doc/zh/config.json new file mode 100644 index 00000000..b44cb82a --- /dev/null +++ b/maixpy/doc/zh/config.json @@ -0,0 +1,4 @@ +{ + "import": "config_zh", + "name": "MaixPy 中文文档" +} diff --git a/maixpy/doc/zh/faq.html b/maixpy/doc/zh/faq.html new file mode 100644 index 00000000..d1052a77 --- /dev/null +++ b/maixpy/doc/zh/faq.html @@ -0,0 +1,394 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy FAQ(常见问题) - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy FAQ(常见问题)

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

此页面列出了 MaixPy 相关的常见问题和解决方案,如果你遇到了问题,请先在这里找寻答案。
+如果这个页面找不到答案,可以到 MaixHub 讨论版块 将问题的详细步骤发贴提问。

+

如果你使用的是 MaixCAM, 也可以参考 MaixCAM FAQ

+

MaixVision 无法搜索到设备?

+

先确认连接方式是 WiFi 还是 USB 线,
+WiFi:

+
    +
  • 确认 WiFi 是否正确连接上并且获取到 IP 地址, 可以在 设置->设备信息 或者设置->WiFi 里面看到 ip
  • +
+

USB线:

+
    +
  • 确保设备通过 Type-C 数据线连接到电脑,设备处于开机状态并且进入了功能选择界面。
  • +
  • 确保设备驱动已经安装:
      +
    • Windows 下可以在设备管理器中查看是否有 USB 虚拟网卡设备,如果有感叹号则是去动没有安装好,按照快速开始 中的方法安装驱动即可。
    • +
    • Linux 下可以通过ifconfig或者ip addr查看是否有usb0设备或者lsusb查看所有 USB 设备。 Linux 已经自带去动,所以识别不到检查硬件连接,设备系统是否是最新,以及设备是否已经正常启动即可。
    • +
    • Mac OS 同 Linux 方法。
    • +
    +
  • +
  • 另外 检查 USB 线缆的质量,换一个高质量的线缆。
  • +
  • 另外 检查电脑 USB 口的质量,比如实测某些小主机 USB 口 EMI 设计太糟糕,外接一个质量好点的 USB HUB 反而可以使用了,也可以换 USB 口 或者直接换台电脑。
  • +
+

MaixVision 运行摄像头例程显示图像卡顿

+

默认配的 GC4653 摄像头最高帧率为 30 帧,摄像头例程正常情况下 MaixVision 的显示肉眼不会有卡顿感,如果卡顿,首先考虑传输问题:

+
    +
  • 检查网络连接质量,比如 WiFi。
  • +
  • 如果用的 USB 连接,检查 USB 线质量, 电脑 USB 口质量,可以尝试换台电脑或者 USB 口 或者 USB 线缆尝试对比。
  • +
+

MaixPy v4 和 v1 v3 有什么区别?

+
    +
  • MaixPy v4 使用 Python 语言,是吸取了 v1 v3 经验的集大成之作,有更好的配套软件和生态,更多的功能,更简单的使用方式和更完善的文档;硬件有很大提升的同时加个和另外两者的硬件价格想当甚至更便宜;另外也做了兼容 K210 的使用体验和 API,方便用户从 v1 快速迁移到 v4。
  • +
  • v1 使用了 Micropython 语言,有很多局限性,比如第三方库支持有限;同时受限于 Maix-I (K210) 的硬件性能,内存不够用,AI 模型支持有限,很多编解码不支持硬件加速等缺点。
  • +
  • v3 也是使用了 Python 语言,基于 Maix-II-Dock (v831) 硬件,硬件 AI 模型支持有限,而且全志的基础生态不够开放,API 也不够完善,此版本仅作为 Maix-II-Dock (v831)上面使用,不会继续更新。
  • +
+

MaixPy 目前只支持 MaixCAM 吗,用其它同款芯片的板子行不行?

+

MaixPy 目前仅支持 MaixCAM 系列板子,其它同款芯片的板子也不支持(包括 Sipeed 的同款芯片板子 比如 LicheeRV-Nano),强烈不建议尝试,导致设备损坏(比如冒烟烧屏等)后果自负。

+

未来 Sipeed 出的 Maix 系列的产品都将继续得到 MaixPy 支持,目前如果 MaixCAM 有什么无法满足的需求,可以到 MaixHub 讨论版块 提出需求或者发送邮件到 support@sipeed.com.

+

可以用除了官方搭配的摄像头或者屏幕以外的自己的摄像头或者屏幕吗?

+

不建议这样操作,除非你有够丰富的软硬件知识和经验,否则可能导致设备损坏。

+

官方搭配的配件对应的软硬件是调教过的,表现效果是最好的,上手即可使用,其它配件可能接口不同,驱动不同,软件不同,需要自己去调教,这是一个非常复杂的过程,不建议尝试。

+

当然,如果你是大佬,我们也欢迎你提交 PR!

+

运行模型报错 cvimodel built for xxxcv181x CANNOT run on platform cv181x

+

解析模型文件失败了,一般情况是模型文件损坏造成的,确保你的模型文件是没有损坏的。
+比如:

+
    +
  • 如果是从网上下载的,保证下载没有出问题,一般网上的文件提供 sha256sum/md5 校验值,下载下来后可以对比一下,具体方法请自行搜索或者问 ChatGPT。
  • +
  • 如果是来自压缩包,请确认解压过程没有出错,可以从压缩包重新解压一遍保证中间没有出错。
  • +
  • 保证传输到设备的过程没有造成文件损坏,可以对比一下设备中的文件和电脑中的文件 sha256sum 值,具体方法请自性搜索或者问 ChatGPT。
  • +
+

上电启动黑屏,屏幕无显示

+
    +
  • 检查是否安装了 TF(micro-SD)卡。
  • +
  • 检查 TF 卡里面是否烧录了最新的系统镜像(强烈推荐烧录到最新的系统镜像),具体烧录方法看文档。
  • +
  • 检查 TF 卡是否完全插进到了 TF 卡口,确保没有缝隙和松动。
  • +
  • 检查屏幕和摄像头排线是否正确扣紧了,不能出现松动现象。
  • +
  • 检查板子上的电源灯(红灯)以及系统运行状态灯(蓝灯)是否亮起,如果红灯不亮则考虑硬件问题,比如无供电或者供电不足或者板子烧坏了。
  • +
  • 用 USB 转 TTL 连接电脑和板子的串口,电脑打开串口助手,让板子重启,查看启动日志里面是否有报错。
  • +
+
+

如果没有日志输出,可以尝试交换一下 TX 和 RX 接线, 对于 MaixCAM, Type-C 转 串口小板插的方向不一样 TX RX 可能反向,即不支持正反插。

+
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/index.html b/maixpy/doc/zh/index.html new file mode 100644 index 00000000..15e4656a --- /dev/null +++ b/maixpy/doc/zh/index.html @@ -0,0 +1,494 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy 快速开始 - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy 快速开始

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +
+
+ MaixPy 唯一官网: + + wiki.sipeed.com/maixpy + +
+
+ MaixPy 例程和源码: + + github.com/sipeed/MaixPy + +
+ +
+
+
+

关于 MaixPy 介绍请看 MaixPy 官网首页

+
+

获得 MaixCAM 设备

+

Sipeed 淘宝 或者 Sipeed 速卖通 店铺购买 MaixCAM 开发板。

+

建议购买带 TF 卡摄像头2.3寸触摸屏外壳Type-C 数据线Type-C一转二小板4P串口座子+线的套餐,方便后续使用和开发,后面的教程都默认你已经有了这些配件(包括屏幕)。

+

如果你没有购买 TF 卡,则你需要自备一个 TF 读卡器用来烧录系统。

+
+

注意,目前只支持 MaixCAM 开发板,其它同型号芯片的开发板均不支持,包括 Sipeed 的同型号芯片开发板,请注意不要买错造成不必要的时间和金钱浪费。

+
+

上手配置

+

准备 TF 镜像卡和插入到设备

+

如果你买的套餐里面有 TF 卡,里面已经有出厂镜像了,如果出厂时 TF 卡没有安装到设备,需要先小心打开外壳(注意里面有排线连接不要扯断了),然后插入 TF 卡。另外因为出厂的固件可能比较老旧,可以插按照升级和烧录系统先将系统升级到最新版本。

+

如果没买 TF 卡,则需要将系统烧录进自备的 TF 卡中,烧录方法请看升级和烧录系统,然后再安装到板子。

+

上电开机

+

使用 Type-C 数据线连接 MaixCAM 设备给设备供电,等待设备开机,开机会进入功能选择界面。

+

maixcam_font

+

如果屏幕没有显示

+
    +
  • 请确认购买了配套的 TF 卡,如果确认有 TF 卡,并且已经插入到设备,可以尝试更新到最新的系统
  • +
  • 如果你没有购买 TF 卡套餐,你需要按照升级和烧录系统的方法烧录最新的系统到 TF 卡。
  • +
  • 另外请确认屏幕和摄像头的排线没有松动,屏幕的排线在拆开外壳时很容易脱落,需要注意。
  • +
+

联网

+

首次运行需要连接网络,后面会激活设备和使用 IDE 会用到。

+
    +
  • 设备上点击 设置(Settings),选择WiFi,点击 扫描 按钮开始扫描周围 WiFi, 可以多次点击刷新列表。
  • +
  • 找到你的 WiFi 热点,如果没有路由器可以用手机开一个热点。
  • +
  • 输入密码点击连接按钮进行连接。
  • +
  • 等待获取到 IP 地址,这可能需要 1030 秒,如果界面没有刷新可以退出WiFi功能重新进入查看,或者在设置 -> 设备信息 中也可以看到 IP 信息。
  • +
+

升级运行库

+

这一步很重要 !!! 这一步如果不做好,其它应用和功能可能无法运行(比如闪退等)。

+
    +
  • 首先保证上一步连接 WiFi 已经完成,并且获取到 IP 地址能访问公网。
  • +
  • 设备上点击 设置(Settings),选择安装运行库
  • +
  • 安装完成后可以看到更新到了最新版本,然后退出即可。
  • +
+

如果显示Request failed 或者请求失败,请先检查网络是否已经连接,需要能连接到互联网,如果还不行,请拍照联系客服处理即可。

+

使用内置应用

+

内置了很多应用,比如 找色块,AI 检测器,巡线等等,找色块举例:

+ +

其它的请自行摸索,以后还会更新更多应用,使用文档以及应用更新请看 MaixHub 应用商店

+

注意:应用只包含了 MaixPy 能实现的一部分功能,使用 MaixPy 能创造更多功能

+

作为串口模块使用

+
+

如果是想把设备当成主控使用(或者你还不懂什么是串口模块)可以跳过这一步。

+
+

内置的各种应用可以直接当成串口模块使用,比如找色块找人脸找二维码等等,

+

使用方法:

+
    +
  • 硬件连接: 可以给设备接上Type-C一转二小板,这样我们就能将设备通过串口连接到你的主控上了,比如Arduino树莓派STM32等等。
  • +
  • 打开你想用的应用,比如二维码识别,当设备扫描到二维码就会通过串口把结果发送给你的主控了。
  • +
+
+

发送的串口波特率是 115200,数据格式是 8N1,协议遵循 Maix 串口通信协议标准,可以在MaixHub APP 找到对应的应用介绍查看协议。

+
+

准备连接电脑和设备

+

为了后面电脑(PC)能和 设备(MaixCAM)通信,我们要让它们在同一个局域网内,提供了两种方式:

+
    +
  • 方法一 (强烈推荐):无线连接, 设备使用 WiFi 连接到电脑连接的同一个路由器或者 WiFi 热点下: 在设备的设置 -> WiFi 设置中连接到你的 WiFi 即可。
  • +
  • 方法二:有线连接, 设备通过 USB 线连接到电脑,设备会虚拟成一个 USB 网卡,这样和电脑就通过 USB 在同一局域网了。
  • +
+
+

方案二因为要用 USB 和驱动,可能会遇到一些问题,所以推荐直接用 WiFi 开始,可以在 FAQ 中找常见问题。

+
+
+方案二在不同电脑系统中有不同设置方法,点击展开 +
    +
  • Linux: 无需额外设置,插上 USB 线即可, 使用 ifconfig 或者 ip addr 查看到 usb0 网卡,注意 这里看到的 ip 比如 10.131.167.100 是电脑的 ip, 设备的 ip 是最后一位改为110.131.167.1
  • +
  • Windows: 可以先确认网络适配器里面是否多了一个 RNDIS 设备,如果有就直接能用。否则需要手动安装 RNDIS 网卡驱动:
      +
    • 打开电脑的设备管理器
    • +
    • 然后在其它设备里面找个一个带问号的 RNDIS 设备,右键选择更新驱动程序
    • +
    • 选择浏览计算机以查找驱动程序,然后选择让我从计算机上的可用驱动程序列表中选择
    • +
    • 选择网络适配器,然后点击下一步
    • +
    • 左边选择Microsoft,右边选择远程 NDIS 兼容设备,然后点击下一步, 选择
    • +
    • 装好后的效果
    • +
    +RNDIS
  • +
  • MacOS: 无需额外设置,插上 USB 线即可, 使用 ifconfig 或者 ip addr 查看到 usb0 网卡,注意 这里看到的 ip 比如 10.131.167.100 是电脑的 ip, 设备的 ip 是最后一位改为110.131.167.1
  • +
+
+
+

开发环境准备

+
    +
  • 下载 MaixVision 并安装。
  • +
  • 使用 Type-C 连接设备和电脑,打开 MaixVision,点击左下角的“连接”按钮,会自动搜索设备,稍等一下就能看到设备,点击设备有点的连接按钮以连接设备。
  • +
+

如果没有扫描到设备,你也可以在设备设置 -> 设备信息 中查看设备的 IP 地址手动输入, 也可以在 FAQ 中找到解决方法。

+

连接成功后,设备的功能选择界面会消失,屏幕会黑屏,释放了所有硬件资源,如果仍然有画面显示,可以断开连接重连。

+

这里有 MaixVision 的使用示例视频:

+

+

运行例程

+

点击 MaixVision 左侧的示例代码,选择一个例程,点击左下角运行按钮将代码发送到设备上运行。

+

比如:

+
    +
  • hello_maix.py,点击运行按钮,就能看到 MaixVision 终端有来自设备打印的消息,以及右上角出现了图像。
  • +
  • camera_display.py,这个例程会打开摄像头并在屏幕上显示摄像头的画面。
  • +
+ +
from maix import camera, display, app
+
+disp = display.Display()          # 构造一个显示对象,并初始化屏幕
+cam = camera.Camera(640, 480)     # 构造一个摄像头对象,手动设置了分辨率为 640x480, 并初始化摄像头
+while not app.need_exit():        # 一直循环,直到程序退出(可以通过按下设备的功能按键退出或者 MaixVision 点击停止按钮退出)
+    img = cam.read()              # 读取摄像头画面保存到 img 变量,可以通过 print(img) 来打印 img 的详情
+    disp.show(img)                # 将 img 显示到屏幕上
+
+
    +
  • yolov5.py 会检测摄像头画面中的物体框出来并显示到屏幕上,支持 80 种物体的检测,具体请看YOLOv5 物体检测
  • +
+

其它例程可以自行尝试。

+
+

如果你使用相机例程遇到了图像显示卡顿,可能是网络不通畅,或者 USB 线质量或者主机 USB 质量太差造成,可以更换连接方式或者更换线缆、主机 USB 口或者电脑等。

+
+

安装应用到设备

+

上面是在设备中运行代码,MaixVision 断开后代码就会停止运行,如果想让代码出现在开机菜单中,可以打包成应用安装到设备上。

+

点击 MaixVision 左下侧的安装应用按钮,填写应用信息,会将应用安装到设备上,然后在设备上就能看到应用了。
+也可以选择打包应用,将你的应用分享到MaixHub 应用商店

+
+

默认例程没有显式编写退出功能,进入应用后按下设备的功能按键即可退出应用。(对于 MaixCAM 是 user 键)

+
+

如果想让程序开机自启动,可以在 设置 -> 开机启动 中设置。

+

下一步

+

看到这里,如果你觉得不错,请务必来 github 给 MaixPy 开源项目点一个 star(需要先登录 github), 你的 star 和认同是我们不断维护和添加新功能的动力!

+

到这里你已经体验了一遍使用和开发流程了,接下来可以学习 MaixPy 语法和功能相关的内容,请按照左边的目录进行学习,如果遇到 API 使用问题,可以在API 文档中查找。

+

学习前最好带着自己学习的目的学,比如做一个有趣的小项目,这样学习效果会更好,项目和经验都可以分享到MaixHub 分享广场,会获得现金奖励哦!

+

分享交流

+
    +
  • MaixHub 项目和经验分享 :分享你的项目和经验,获得现金打赏,获得官方打赏的基本要求:
      +
    • 可复现型:较为完整的项目制作复现过程。
    • +
    • 炫耀型:无详细的项目复现过程,但是项目展示效果吸引人。
    • +
    • Bug 解决经验型:解决了某个难题的过程和具体解决方法分享。
    • +
    +
  • +
  • MaixPy 官方论坛(提问和交流)
  • +
  • QQ 群: (建议在 QQ 群提问前先发个帖,方便群友快速了解你需要了什么问题,复现过程是怎样的)
      +
    • MaixPy (v4) AI 视觉交流大群: 862340358
    • +
    +
  • +
  • Telegram: MaixPy
  • +
  • MaixPy 源码问题: MaixPy issue
  • +
  • 商业合作或批量购买请联系 support@sipeed.com 。
  • +
+ + +
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/modules/acc.html b/maixpy/doc/zh/modules/acc.html new file mode 100644 index 00000000..6c00b1c7 --- /dev/null +++ b/maixpy/doc/zh/modules/acc.html @@ -0,0 +1,338 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/modules/thermal_cam.html b/maixpy/doc/zh/modules/thermal_cam.html new file mode 100644 index 00000000..36b384a8 --- /dev/null +++ b/maixpy/doc/zh/modules/thermal_cam.html @@ -0,0 +1,338 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/modules/tof.html b/maixpy/doc/zh/modules/tof.html new file mode 100644 index 00000000..863d0ba6 --- /dev/null +++ b/maixpy/doc/zh/modules/tof.html @@ -0,0 +1,338 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/peripheral/gpio.html b/maixpy/doc/zh/peripheral/gpio.html new file mode 100644 index 00000000..5b7b40a4 --- /dev/null +++ b/maixpy/doc/zh/peripheral/gpio.html @@ -0,0 +1,368 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy 使用 GPIO - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy 使用 GPIO

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

简介

+

使用 GPIO 可以控制引脚输入或者输出高低电平,用来读取信号或者输出控制信号,十分常用。

+

MaixPy 中使用 GPIO

+
+

MaixPy 固件版本应该 > 4.1.2(不包含)

+
+

首先我们需要知道设备有哪些引脚和 GPIO,对于 MaixCAM 每个引脚都对应了一个 GPIO 控制器,如图:

+

+

需要注意的是,引脚除了作为 GPIO 使用,还能用作其它功能比如 PWM 使用,使用前我们需要设置一下引脚的功能为 GPIO。

+

比如在 MaixCAM 上有些引脚默认已经被其它功能占用,比如 UART0, WiFi(SDIO1 + A26), 不建议使用它们,其它的可以使用,另外 A14 引脚连接到了板载的 LED,默认是作为系统的负载提示灯,如果初始化它会自动取消系统提示灯功能作为普通 GPIO 被使用(注意A14只能作为输出),这样你就能控制这颗 LED 的亮灭了。

+ +
from maix import gpio, pinmap, time
+
+pinmap.set_pin_function("A14", "GPIOA14")
+led = gpio.GPIO("A14", gpio.Mode.OUT)
+led.value(0)
+
+while 1:
+    led.toggle()
+    time.sleep_ms(500)
+
+

这里先使用pinmap设置了A14引脚的功能为GPIO,当然,对于A14因为只有GPIO功能,可以不设置,为了程序通用起见,其它引脚可能需要设置,所以这里例程设置了。

+

更多 API 请看 GPIO API 文档

+

GPIO 作为输入模式

+ +
from maix import gpio, pinmap, time
+
+pinmap.set_pin_function("A19", "GPIOA19")
+led = gpio.GPIO("A19", gpio.Mode.IN)
+
+while 1:
+    print(led.value())
+    time.sleep_ms(1) # sleep to make cpu free
+
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/peripheral/i2c.html b/maixpy/doc/zh/peripheral/i2c.html new file mode 100644 index 00000000..51d81231 --- /dev/null +++ b/maixpy/doc/zh/peripheral/i2c.html @@ -0,0 +1,371 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy 使用 I2C - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy 使用 I2C

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

对于 MaixCAM,由于引脚资源比较紧张,引出的 I2C 引脚和 WiFi 模块(SDIO1)重合了,所以 WiFi 和硬件 I2C 只能二选一使用。

+

所以推荐使用 IO 模拟 I2C。

+
+

注意需要 MaixPy 镜像和固件 > 4.1.2(不包含)

+
+

IO 模拟 I2C

+

模拟 I2C 只需要引脚使用 GPIO 功能即可,在 MaixCAM 上,模拟 I2C 被固定在引脚A15(SCL),A27(SDA),并且i2c编号为5, 要使用,只需要:

+ +
from maix import i2c, pinmap
+
+# pinmap.set_pin_function("A15", "GPIOA23")
+# pinmap.set_pin_function("A27", "GPIOA24")
+
+bus1 = i2c.I2C(5, i2c.Mode.MASTER)
+slaves = bus1.scan()
+print("find slaves:", slaves)
+
+
+

更多 API 看 i2c API 文档

+

硬件 I2C

+

如上面所说, 对于 MaixCAM 硬件 I2CWiFi 只能二选一,如果一定要用,需要禁用WiFi,使用pinmap模块设置引脚功能为 I2C,在使用maix.i2c模块操作。

+
+

TODO: 提供禁用 WiFi 的方法(需要系统里面禁用掉 WiFi 驱动,比较复杂)

+
+

硬件I2C及对应的引脚看图:

+

+ +
from maix import i2c, pinmap
+
+pinmap.set_pin_function("P18", "I2C1_SCL")
+pinmap.set_pin_function("P21", "I2C1_SDA")
+
+bus1 = i2c.I2C(1, i2c.Mode.MASTER)
+slaves = bus1.scan()
+print("find slaves:", slaves)
+
+
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/peripheral/pwm.html b/maixpy/doc/zh/peripheral/pwm.html new file mode 100644 index 00000000..1ac799a0 --- /dev/null +++ b/maixpy/doc/zh/peripheral/pwm.html @@ -0,0 +1,374 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy 使用 PWM - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy 使用 PWM

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

简介

+

在 MaixPy (v4) 中使用 PWM,先使用pinmap设置引脚的功能为 PWM,在使用。

+

以及每个 PWM 有对应的引脚,根据 MaixCAM 的引脚图可以看到:

+

+

这里我们推荐使用PWM6PWM7

+

对于 MaixCAM 因为WiFi 使用了SDIO1的所有引脚,所以PWM4~9只能和WiFi二选一使用。

+
+

TODO: 提供禁用 WiFi 的方法(需要系统里面禁用掉 WiFi 驱动,比较复杂)

+
+

MaixPy 使用 PWM 控制舵机

+

这里我们以控制舵机为例, 使用MaixCAMPWM7A19引脚:

+ +
from maix import pwm, time, pinmap
+
+SERVO_PERIOD = 50     # 50Hz 20ms
+SERVO_MIN_DUTY = 2.5  # 2.5% -> 0.5ms
+SERVO_MAX_DUTY = 12.5  # 12.5% -> 2.5ms
+
+# Use PWM7
+pwm_id = 7
+# !! set pinmap to use PWM7
+pinmap.set_pin_function("A19", "PWM7")
+
+
+
+def angle_to_duty(percent):
+    return (SERVO_MAX_DUTY - SERVO_MIN_DUTY) * percent / 100.0 + SERVO_MIN_DUTY
+
+
+out = pwm.PWM(pwm_id, freq=SERVO_PERIOD, duty=angle_to_duty(0), enable=True)
+
+for i in range(100):
+    out.duty(angle_to_duty(i))
+    time.sleep_ms(100)
+
+for i in range(100):
+    out.duty(angle_to_duty(100 - i))
+    time.sleep_ms(100)
+
+

这里的功能是控制舵机从最小角度旋转到最大角度再旋转回最小角度。

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/peripheral/spi.html b/maixpy/doc/zh/peripheral/spi.html new file mode 100644 index 00000000..1b6992be --- /dev/null +++ b/maixpy/doc/zh/peripheral/spi.html @@ -0,0 +1,335 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy 使用 SPI - MaixPy + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/peripheral/uart.html b/maixpy/doc/zh/peripheral/uart.html new file mode 100644 index 00000000..60a144b7 --- /dev/null +++ b/maixpy/doc/zh/peripheral/uart.html @@ -0,0 +1,387 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy UART 串口使用介绍 - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy UART 串口使用介绍

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

串口简介

+

串口是一种通信方式,包含了硬件和通信协议的定义。

+
    +
  • 硬件包括:
      +
    • 3 个引脚: GNDRXTX,通信双发交叉连接 RX TX, 即一方 TX 发送到另一方的 RX, 双方 GND 连接到一起。
    • +
    • 控制器,一般在芯片内部,也叫 UART 外设,一般一个芯片有一个或者多个 UART 控制器,每个控制器有相对应的引脚。
    • +
    +
  • +
  • 通信协议: 为了让双方能顺利通信,规定了一套协议,具体可以自行学习,常见的参数有 波特率 校验位等,波特率是我们用得最多的参数。
  • +
+

通过板子的串口,可以和其它单片机或者 SOC 进行数据通信,比如可以在 MaixCAM 上实现人体检测功能,检测到坐标后通过串口发送给 STM32 单片机。

+

MaixPy 中使用串口

+

对于 MaixCAM 默认从 USB 口引出了一个串口,可以插上配套的 Type-C 转接小板,就能直接使用上面的串口引脚,
+也可以不用转接板,直接使用板子上的 A16(TX)A17(RX)引脚, 和 USB 口引出的是同样的引脚,是等效的。

+

对于 MaixCAM 使用 USB 引出的串口时需要注意,Typc-C 正插和反插,转接小板上的 RXTX会交换,所以当你发现无法通信时,有可能就是 RX TX 反了,可以尝试将 Type-C 翻转一面插再看看通信是否正常。这个算是设计缺陷,不过一般也不会经常拔插所以适应一下也能接受。

+

将两个通信的板子双方连接好后(通信双发交叉连接 RX TX, 即一方 TX 发送到另一方的 RX, 双方 GND 连接到一起),就可以使用软件了。

+

通过 MaixPy 使用串口很简单:

+ +
from maix import uart
+
+devices = uart.list_devices()
+
+serial = uart.UART(devices[0], 115200)
+serial.write_str("hello world")
+print("received:", serial.read(timeout = 2000))
+
+

先列出了系统的所有串口设备,然后这里使用了第一个,也就是上面说的 Type-C 出 引出的串口。

+

更多串口的 API 请看 UART API 文档

+

其它写法,以及使用其它串口

+ +

+from maix import app, uart, pinmap, time
+import sys
+
+# pinmap.set_pin_function("A16", "UART0_TX")
+# pinmap.set_pin_function("A17", "UART0_RX")
+device = "/dev/ttyS0"
+
+serial0 = uart.UART(device, 115200)
+
+serial0.write("hello 1\r\n".encode())
+serial0.write_str("hello 2\r\n")
+
+while not app.need_exit():
+    data = serial0.read()
+    if data:
+        print("Received, type: {}, len: {}, data: {}".format(type(data), len(data), data))
+        serial0.write(data)
+    time.sleep_ms(1) # sleep 1ms to make CPU free
+
+

这里先设置了引脚映射,特别是如果你要使用除了 UART0 以外的串口,根据图中的引脚号和 UART 使用pinmap.set_pin_function来设置

+

+

另外,这里循环里面加了一个 sleep_ms 是简单地释放一下 CPU,以达到程序不会占满 CPU 的效果,当然也有其它方式,这种方式最简单粗暴。

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/peripheral/wdt.html b/maixpy/doc/zh/peripheral/wdt.html new file mode 100644 index 00000000..1b9bc555 --- /dev/null +++ b/maixpy/doc/zh/peripheral/wdt.html @@ -0,0 +1,350 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy 使用看门狗定时器 - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy 使用看门狗定时器

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

简介

+

为了防止程序出现问题,常常会用到看门狗定时器(WDT), 在程序出问题时自动重启系统。

+

原理就是有一个倒计时计数器,我们需要在程序的逻辑中定期地去设置这个倒计时时间(也叫喂狗),如果我们的程序在哪儿卡住了导致没有定期去设置倒计时,倒计时到 0 后硬件就会出发系统重启。

+

MaixPy 中使用 WDT

+ +
from maix import wdt, app, time
+
+w = wdt.WDT(0, 1000)
+
+while not app.need_exit():
+    w.feed()
+    # here sleep op is our operation
+    # 200 ms is normal, if > 1000ms will cause system reset
+    time.sleep_ms(200)
+
+
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/pro/compile_os.html b/maixpy/doc/zh/pro/compile_os.html new file mode 100644 index 00000000..b1df8d92 --- /dev/null +++ b/maixpy/doc/zh/pro/compile_os.html @@ -0,0 +1,333 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/projects/index.html b/maixpy/doc/zh/projects/index.html new file mode 100644 index 00000000..a86081f0 --- /dev/null +++ b/maixpy/doc/zh/projects/index.html @@ -0,0 +1,356 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy 项目实战 介绍和汇总 - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy 项目实战 介绍和汇总

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

简介

+

这里提供一些常见的项目实战示例,方便社区成员可以参考复现使用,也方便激发大家的灵感做出更多更好的应用和项目出来。

+

要找到用 MaixPy 实现的相关的项目,有几种方式:

+

MaixPy 官方文档

+

也就是本文档左边目录可以找到的项目实战,比如小车巡线

+

如果你有好的项目,或者好的项目推荐,也可以贡献文档添加进来。

+

MaixHub 项目分享广场

+

MaixHub 项目分享 栏目可以找到项目分享。

+

有高质量的分享也会被链接到 MaixPy 官方文档。

+

你也可以分享你的项目制作方法,会获得官方(必获得)以及社区成员的现金打赏(通常高质量能解决急需需求的更容易被打赏)。

+

推荐项目:

+ +

MaixHub 应用分享

+

除了项目分享以外,还可以在MaixHub 应用商店 找到可以直接运行的应用,有部分应用可能是用 MaixPy 编写的,如果作者提供了源码或者写了详细的教程也都可以参考。

+

推荐项目:

+ + + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/projects/line_tracking_robot.html b/maixpy/doc/zh/projects/line_tracking_robot.html new file mode 100644 index 00000000..720fffe3 --- /dev/null +++ b/maixpy/doc/zh/projects/line_tracking_robot.html @@ -0,0 +1,421 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy 小车巡线 - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy 小车巡线

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ + +
+ + 更新历史 +
+ + + + + + + + + + + + + + + + + + + +
日期版本作者更新内容
2024-05-091.0.0lxowalle + + 初版文档 + +
+
+
+ +
+
+ +

阅读本文前,确保已经知晓如何开发MaixCAM,详情请阅读快速开始

+

简介

+

本文将介绍如何使用MaixPy实现寻线小车

+

如何使用MaixPy实现寻线小车

+
    +
  1. 准备MaixCAM与小车
  2. +
  3. 实现寻线功能
  4. +
  5. 实现小车控制功能
  6. +
+

准备MaixCAM与小车

+

TODO

+

实现寻线功能

+

使用image模块的get_regression可以快速寻找到直线,详情见寻找直线

+

代码实现:

+ +
from maix import camera, display, image
+
+cam = camera.Camera(320, 240)
+disp = display.Display()
+
+# thresholds = [[0, 80, 40, 80, 10, 80]]      # red
+thresholds = [[0, 80, -120, -10, 0, 30]]    # green
+# thresholds = [[0, 80, 30, 100, -120, -60]]  # blue
+
+while 1:
+    img = cam.read()
+
+    lines = img.get_regression(thresholds, area_threshold = 100)
+    for a in lines:
+        img.draw_line(a.x1(), a.y1(), a.x2(), a.y2(), image.COLOR_GREEN, 2)
+        theta = a.theta()
+        rho = a.rho()
+        if theta > 90:
+            theta = 270 - theta
+        else:
+            theta = 90 - theta
+        img.draw_string(0, 0, "theta: " + str(theta) + ", rho: " + str(rho), image.COLOR_BLUE)
+
+    disp.show(img)
+
+
+

上述代码实现了寻线功能, 上述参数中需注意:

+
    +
  • 设置合适的thresholds值来寻找到对应的直线
  • +
  • 设置合适的area_threshold值来过滤环境干扰,可以过滤一些面积小的直线
  • +
  • 使用a.theta()获取直线的角度
  • +
  • 使用a.rho()获取直线与原点(原点在左上角)的距离
  • +
+

根据实际环境调试好寻线参数后, 就可以利用a.theta()a.rho()控制小车方向了。

+

实现小车控制功能

+

TODO

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/sidebar.yaml b/maixpy/doc/zh/sidebar.yaml new file mode 100644 index 00000000..4152540b --- /dev/null +++ b/maixpy/doc/zh/sidebar.yaml @@ -0,0 +1,145 @@ +items: +- file: README.md + label: 快速开始 +- file: faq.md + label: FAQ 常见问题 + +- label: 基础 + collapsed: false + items: + - file: basic/os.md + label: 升级和烧录系统 + - file: basic/app_usage.md + label: 应用使用说明 + - file: basic/maixpy_upgrade.md + label: 更新 MaixPy + - file: basic/maixvision.md + label: MaixVision 使用 + - file: basic/python.md + label: Python 语法 + - file: basic/linux_basic.md + label: Linux 基础知识 + - file: basic/python_pkgs.md + label: 添加额外的 Python 包 + - file: basic/app.md + label: 应用开发和商店 + +- label: 基础图像和算法 + items: + - file: vision/display.md + label: 屏幕使用 + - file: vision/camera.md + label: 摄像头使用 + - file: vision/image_ops.md + label: 基本图像操作 + - file: vision/find_blobs.md + label: 寻找色块 + - file: vision/line_tracking.md + label: 寻找直线 + - file: vision/qrcode.md + label: 二维码识别 + - file: vision/apriltag.md + label: AprilTag 识别 + +- label: AI 视觉 + items: + - file: vision/ai.md + label: AI 视觉基本知识 + - file: vision/classify.md + label: AI 物体分类 + - file: vision/yolov5.md + label: YOLOv5 物体检测 + - file: vision/face_recognition.md + label: 人脸识别 + - file: vision/body_key_points.md + label: 人体关键点检测 + - file: vision/self_learn_classifier.md + label: 自学习分类器 + - file: vision/self_learn_detector.md + label: 自学习检测器 + - file: vision/object_track.md + label: 物体轨迹跟踪和计数 + - file: vision/ocr.md + label: OCR 文字识别 + - file: vision/maixhub_train.md + label: MaixHub 在线 AI 模型训练 + - file: vision/custmize_model.md + label: 自定义(离线训练转换)模型 + + +- label: AI 听觉 + items: + - file: audio/record.md + label: 录音 + - file: audio/play.md + label: 播放音频 + - file: audio/classifier.md + label: AI 声音分类器 + - file: audio/keyword.md + label: 关键词识别 + - file: audio/recognize.md + label: 语音实时识别 + - file: audio/synthesis.md + label: 语音合成 + +- label: 视频 + items: + - file: video/record.md + label: 录像 + - file: video/play.md + label: 播放视频 + - file: video/jpeg_streaming.md + label: JPEG 串流 + - file: video/rtsp.md + label: RTSP 串流 + + +- label: 片上外设 + items: + - file: peripheral/gpio.md + label: GPIO 和 点灯 + - file: peripheral/uart.md + label: UART 串口使用 + - file: peripheral/i2c.md + label: I2C 使用 + - file: peripheral/pwm.md + label: PWM 使用 + - file: peripheral/spi.md + label: SPI 使用 + - file: peripheral/wdt.md + label: WDT 看门狗使用 + +- label: 片外模块 + items: + - file: modules/acc.md + label: 加速度计使用 + - file: modules/temp_hum.md + label: 温湿度传感器 + - file: modules/tof.md + label: TOF 测距 + - file: modules/thermal_cam.md + label: 热成像摄像头 + +- label: 项目实战 + items: + - file: projects/README.md + label: 介绍和汇总 + - file: projects/line_tracking_robot.md + label: 小车巡线 + +- label: 进阶 + items: + - file: source_code/contribute.md + label: 贡献文档和代码 + - file: source_code/build.md + label: 构建 MaixPy 源码 + - file: source_code/faq.md + label: MaixPy 源码 FAQ + - file: source_code/add_c_module.md + label: 使用 C/C++ 写一个模块 + - file: source_code/maixcdk.md + label: 使用 MaixCDK 开发 + - file: pro/compile_os.md + label: 编译系统 + + diff --git a/maixpy/doc/zh/source_code/add_c_module.html b/maixpy/doc/zh/source_code/add_c_module.html new file mode 100644 index 00000000..5116ba63 --- /dev/null +++ b/maixpy/doc/zh/source_code/add_c_module.html @@ -0,0 +1,343 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 给 MaixPy 添加一个 C/C++ 模块 - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

给 MaixPy 添加一个 C/C++ 模块

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

简介

+

有时候需要高效地执行某个函数, Python 的速度无法满足时,就可以使用 C/C++ 或者其它编译型语言来实现。

+

通用函数封装

+

如果你想封装的函数实现的功能不依赖 MaixPy 的其它功能,直接使用 Python 使用 C/C++ 添加模块的通用方法,具体方法可以自行百度,比如 ffi, ctype 等

+
+

欢迎 PR 添加方法

+
+

如果你的模块还想依赖 MaixPy 的其它基础 API

+

你需要先学会编译使用 MaixCDK, 因为 MaixPy 就是从 MaixCDK 生成的 API, MaixPy 里面有的功能 MaixCDK 里面也有, 然后 。。。TODO

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/source_code/build.html b/maixpy/doc/zh/source_code/build.html new file mode 100644 index 00000000..df0ef5dc --- /dev/null +++ b/maixpy/doc/zh/source_code/build.html @@ -0,0 +1,403 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy 开发源代码指南 - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy 开发源代码指南

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

获取源代码

+ +
mkdir -p ~/maix
+cd ~/maix
+git clone https://github.com/sipeed/MaixPy
+
+

获取 MaixCDK 源码

+

MaixPy 项目依赖于 MaixCDK,需要先克隆它,放到电脑的某个目录(勿放在 MaixPy 目录下)

+ +
cd ~/maix
+git clone https://github.com/sipeed/MaixCDK
+
+

然后需要设置环境变量 MAIXCAK_PATH 指定 MaixCDK 的路径,可以在 ~/.bashrc 或者~/.zshrc(根据你使用的shell决定)添加:

+ +
export MAIXCAK_PATH=~/maix/MaixCDK
+
+

只有在成功设置环境变量后, MaixPy 才能找到 MaixCDK 源码。

+

构建并打包成 wheel 文件

+ +
cd ~/maix/MaixPy
+python setup.py bdist_wheel maixcam
+
+

maixcam 可以被替换为其他板卡配置, 请查看 MaixPy/platforms 目录。

+

构建成功后, 你会在 dist 目录中找到 wheel 文件, 传输到设备(开发板),在设备终端中使用 pip install -U MaixPy****.wheel 在你的设备上安装或升级。

+
+

python setup.py bdist_wheel maixcam --skip-build 不会执行构建命令, 只会打包 wheel 文件, 因此你可以先使用 maixcdk menuconfigmaixcdk build 来自定义构建。

+
+
+

另外如果你是在调试 API,需要频繁安装,使用 pip 安装会比较慢,可以直接编译后拷贝 maix 目录到设备的 /usr/lib/python3.11/site-packages目录下覆盖旧的文件即可。

+
+

手动构建

+ +
maixcdk build
+
+

修改源代码后运行测试

+
    +
  • 首先, 构建源代码
  • +
+ +
maixcdk build
+
+
    +
  • 如果为 PC 自身构建(平台 linux):
  • +
+

然后执行 ./run.sh your_test_file_name.py 来运行 Python 脚本。

+ +
cd test
+./run.sh examples/hello_maix.py
+
+
    +
  • 如果为板卡交叉编译:
      +
    • 最快的方式是将 maix 目录复制到设备的 /usr/lib/python3.11/site-packages/ 目录, 然后在设备上运行脚本。
    • +
    • 或者打包 wheel 文件并在设备上使用 pip install -U MaixPy****.wheel 安装, 然后在设备上运行脚本。
    • +
    +
  • +
+

本地预览文档

+

文档位于 docs 目录, 使用 Markdown 格式, 你可以使用 teedoc 来生成网页版本的文档。

+

API 文档会在构建 MaixPy 固件时生成, 如果你没有构建 MaixPy, API 文档将会是空的

+ +
pip install teedoc -U
+cd docs
+teedoc install -i https://pypi.tuna.tsinghua.edu.cn/simple
+teedoc serve
+
+

然后访问 http://127.0.0.1:2333 在网页浏览器中预览文档。

+

对于想要贡献的开发者

+

请查看 MaixPy 开发源代码指南

+

如果在使用源代码时遇到任何问题, 请先参考 FAQ

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/source_code/contribute.html b/maixpy/doc/zh/source_code/contribute.html new file mode 100644 index 00000000..1c52f634 --- /dev/null +++ b/maixpy/doc/zh/source_code/contribute.html @@ -0,0 +1,369 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 参与 MaixPy 文档修改和贡献代码 - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

参与 MaixPy 文档修改和贡献代码

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

参与 MaixPy 文档修改

+
    +
  • 点击要修改的文档右上角的编辑本页按钮,进入 github 源文档页面。
  • +
  • 保证已经登录了 GitHub 账号。
  • +
  • 在 github 预案文档页面点击右上角铅笔按钮修改文档内容。
  • +
  • github 会提示需要 fork 一份到自己的仓库,点击 fork 按钮。
  • +
+
+

这一步就是将 MaixPy 源码仓库复刻一份到你自己的账号下,这样你就可以自由修改了。

+
+
    +
  • 修改文档内容,然后在页面底部填写修改说明,点击提交修改。
  • +
  • 然后在你的仓库中找到 Pull requests 按钮,点击创建一个 Pull requests。
  • +
  • 然后在弹出的页面中填写修改说明,点击提交 Pull requests,其它人和管理员就可以在Pull requests 页面看到你的修改了。
  • +
  • 等待管理员审核通过后,你的修改就会合并到 MaixPy 源码仓库中了。
  • +
  • 合并成功后,文档会自动更新到 MaixPy 官方文档
  • +
+
+

文档经过 CDN 缓存了的,可能需要等待一段时间才能看到更新,紧急更新可以联系管理员手动刷新。
+也可以访问 en.wiki.sipeed.com/maixpy 查看 github pages 服务版本,这个是没有缓存实时更新的。

+
+

参与 MaixPy 代码贡献

+
    +
  • 访问 MaixPy 代码仓库地址:github.com/sipeed/MaixPy
  • +
  • 在修改代码前最好先创建一个 issue ,描述你要修改的内容让大家知道你的想法和计划,这样大家可以参与修改讨论,以免重复劳动。
  • +
  • 点击右上角的 fork 按钮,将 MaixPy 代码仓库复刻一份到你自己的账号下。
  • +
  • 然后在你的账号下 clone 一份代码到本地。
  • +
  • 修改代码后提交到你的仓库中。
  • +
  • 然后在你的仓库中找到 Pull requests 按钮,点击创建一个 Pull requests。
  • +
  • 然后在弹出的页面中填写修改说明,点击提交 Pull requests,其它人和管理员就可以在Pull requests 页面看到你的修改了。
  • +
  • 等待管理员审核通过后,你的修改就会合并到 MaixPy 源码仓库中了。
  • +
+
+

需要注意的是 MaixPy 的代码大多数是从 MaixCDK 自动生成的,所以如果你修改 C/C++ 源码,很有可能你需要先修改这个仓库。

+
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/source_code/faq.html b/maixpy/doc/zh/source_code/faq.html new file mode 100644 index 00000000..dd5abed6 --- /dev/null +++ b/maixpy/doc/zh/source_code/faq.html @@ -0,0 +1,351 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy 源代码常见问题 - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy 源代码常见问题

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

subprocess.CalledProcessError: Command '('lsb_release', '-a')' returned non-zero exit status 1.

+

以 root 身份编辑 /usr/bin/lsb_release,将第一行从 #!/usr/bin/python3 更改为 python3

+

然后重新编译,应该就可以工作了。

+

ImportError: arg(): could not convert default argument 'format: maix::image::Format' in method '<class 'maix._maix.camera.Camera'>.init' into a Python object (type not registered yet?)

+

Pybind11 需要你先注册 image::Format,然后才能在 camera::Camera 中使用它,所以我们必须先在生成的 build/maixpy_wrapper.cpp 源文件中定义 image::Format

+

要实现这一点,请编辑 components/maix/headers_priority.txt,被依赖的应该放在依赖它的前面。
+例如:

+ +
maix_image.hpp
+maix_camera.hpp
+
+

/usr/bin/ld: /lib/libgdal.so.30: undefined reference to `std::condition_variable::wait(std::unique_lockstd::mutex&)@GLIBCXX_3.4.30' collect2: error: ld returned 1 exit status

+

一般在为 Linux 构建时并且使用 conda 环境时容易出现,conda 环境中的一些库编译参数问题,解决方法就是不用 conda 即可, 或者单独找到 conda 中的那个库,替换成系统的或者直接删掉(会从系统找)

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/source_code/maixcdk.html b/maixpy/doc/zh/source_code/maixcdk.html new file mode 100644 index 00000000..31738358 --- /dev/null +++ b/maixpy/doc/zh/source_code/maixcdk.html @@ -0,0 +1,340 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 切换到 MaixCDK 使用 C/C++ 开发应用 - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

切换到 MaixCDK 使用 C/C++ 开发应用

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

除了使用 MaixPy 开发,还有对应的 C/C++ SDK 可以使用,项目名称为 MaixCDK

+

MaixCDK 介绍

+

MaixPy 基于 MaixCDK 构建,MaixPy 的大多数 API 都是基于 MaixCDK 的 API 自动生成的,所以 MaixPy 有的功能 MaixCDK 都包含。
+如果你更熟悉 C/C++ 编程,或者需要更高的性能,可以使用 MaixCDK 进行开发。

+

MaixCDK 使用

+

MaixCDK 代码仓库地址:github.com/sipeed/MaixCDK, 你可以在这里找到 MaixCDK 的代码和文档。

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/video/jpeg_streaming.html b/maixpy/doc/zh/video/jpeg_streaming.html new file mode 100644 index 00000000..9deb010f --- /dev/null +++ b/maixpy/doc/zh/video/jpeg_streaming.html @@ -0,0 +1,399 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy 视频流 JPEG 推流 / 发送图片到服务器 - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy 视频流 JPEG 推流 / 发送图片到服务器

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ + +
+ + 更新历史 +
+ + + + + + + + + + + + + + + + + + + +
日期版本作者更新内容
2024-04-031.0.0neucrack + + 初版文档 + +
+
+
+ +
+
+ +

简介

+

有时需要将图像发送到服务器,或者将摄像头的视频推送到服务器,这里提供一个最简单的方法,即压缩成 JPEG 图片,然后一张一张地发送到服务器。

+

注意,这是一种最简单的方法,不算很正规的视频推流方法,也不适合高分辨率高帧率的视频流,因为这只是一张一张发送图片,如果要高效推送视频流,请使用后文的 RTSP 或者 RTMP 模块。

+

使用方法

+ +
from maix import image
+import requests
+
+# create image
+img = image.Image(640, 480, image.Format.FMT_RGB)
+# draw something
+img.draw_rect(60, 60, 80, 80, image.Color.from_rgb(255, 0, 0))
+
+# convert to jpeg
+jpeg = img.to_format(image.Format.FMT_JPEG) # image.Format.FMT_PNG
+# get jpeg bytes
+jpeg_bytes = jpeg.to_bytes()
+
+# faster way, borrow memory from jpeg object,
+# but be carefully, when jpeg object is deleted, jpeg_bytes object MUST NOT be used, or program will crash
+# jpeg_bytes = jpeg.to_bytes(copy = False)
+
+# send image binary bytes to server
+url = "http://192.168.0.123:8080/upload"
+res = requests.post(url, data=jpeg_bytes)
+print(res.status_code)
+print(res.text)
+
+

可以看到,先将图片转换成了 JPEG 格式,然后将 JPEG 图片的二进制数据通过TCP发送到服务器。

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/vision/ai.html b/maixpy/doc/zh/vision/ai.html new file mode 100644 index 00000000..99e3ec84 --- /dev/null +++ b/maixpy/doc/zh/vision/ai.html @@ -0,0 +1,378 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AI 视觉基本知识 - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

AI 视觉基本知识

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ + +
+ + 更新历史 +
+ + + + + + + + + + + + + + + + + + + +
日期版本作者更新内容
2024-04-031.0.0neucrack + + 初版文档 + +
+
+
+ +
+
+ +

简介

+

如果没有 AI 基础,在学习 AI 前可以先看什么是人工智能(AI)和机器学习 了解一下 AI 的基本概念。

+

然后我们使用的视觉 AI 一般都是基于深度神经网络学习这个方法,有兴趣可以看看深度神经网络(DNN)基础知识

+

MaixPy 中使用视觉 AI

+

在 MaixPy 中使用视觉 AI 很简单,默认提供了常用的 AI 模型,不需要自己训练模型就可以直接使用,在MaixHub 模型库 中选择maixcam 就可以找到。

+

并且在底层已经封装好的 API,只需要简单的调用就可以实现。

+

如果你想训练自己的模型,也可以先从MaixHub 在线训练 开始,在线平台只需要点点点就能训练出模型,不需要购买昂贵的机器,不需要搭建复杂的开发环境,也不需要写代码,非常适合入门,也适合懒得翻代码的老手。

+

一般训练得到了模型文件,直接传输到设备上,调用 MaixPy 的 API 就可以使用了,具体的调用方法看后文。

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/vision/apriltag.html b/maixpy/doc/zh/vision/apriltag.html new file mode 100644 index 00000000..2f9b9325 --- /dev/null +++ b/maixpy/doc/zh/vision/apriltag.html @@ -0,0 +1,492 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy 识别Apriltag标签 - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy 识别Apriltag标签

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ + +
+ + 更新历史 +
+ + + + + + + + + + + + + + + + + + + +
日期版本作者更新内容
2024-04-031.0.0lxowalle + + 初版文档 + +
+
+
+ +
+
+ +

阅读本文前,确保已经知晓如何开发MaixCAM,详情请阅读快速开始

+

简介

+

本文介绍如何使用MaixPy来识别Apriltag标签

+

使用 MaixPy 识别Apriltag标签

+

MaixPy的 maix.image.Image中提供了find_apriltags方法,可以可以识别apriltag标签。

+

如何识别Apriltag标签

+

一个简单的示例,实现识别apriltag标签并画框

+ +
from maix import image, camera, display
+
+cam = camera.Camera()
+disp = display.Display()
+
+families = image.ApriltagFamilies.TAG36H11
+x_scale = cam.width() / 160
+y_scale = cam.height() / 120
+
+while 1:
+    img = cam.read()
+
+    new_img = img.resize(160, 120)
+    apriltags = new_img.find_apriltags(families = families)
+    for a in apriltags:
+        corners = a.corners()
+
+        for i in range(4):
+            corners[i][0] = int(corners[i][0] * x_scale)
+            corners[i][1] = int(corners[i][1] * y_scale)
+        x = int(a.x() * x_scale)
+        y = int(a.y() * y_scale)
+        w = int(a.w() * x_scale)
+        h = int(a.h() * y_scale)
+
+        for i in range(4):
+            img.draw_line(corners[i][0], corners[i][1], corners[(i + 1) % 4][0], corners[(i + 1) % 4][1], image.COLOR_RED)
+        img.draw_string(x + w, y, "id: " + str(a.id()), image.COLOR_RED)
+        img.draw_string(x + w, y + 15, "family: " + str(a.family()), image.COLOR_RED)
+
+    disp.show(img)
+
+

步骤:

+
    +
  1. 导入image、camera、display模块

    + +
    from maix import image, camera, display
    +
    +
  2. +
  3. 初始化摄像头和显示

    + +
    cam = camera.Camera()
    +disp = display.Display()
    +
    +
  4. +
  5. 从摄像头获取图片并显示

    + +
    while 1:
    +    img = cam.read()
    +    disp.show(img)
    +
    +
  6. +
  7. 调用find_apriltags方法识别摄像头图片中的apriltag标签

    + +
    new_img = img.resize(160, 120)
    +apriltags = new_img.find_apriltags(families = families)
    +
    +
      +
    • img是通过cam.read()读取到的摄像头图像
    • +
    • img.resize(160, 120)是用来将图像缩放得更小,用更小的图像来让算法计算得更快
    • +
    • new_img.find_apriltags(families = families)用来寻找apriltag标签,并将查询结果保存到apriltags,以供后续处理。其中families用来选择apriltag族,默认为image.ApriltagFamilies.TAG36H11
    • +
    +
  8. +
  9. 处理识别标签的结果并显示到屏幕上

    + +
    for a in apriltags:
    +    # 获取位置信息(并映射坐标到原图)
    +    x = int(a.x() * x_scale)
    +    y = int(a.y() * y_scale)
    +    w = int(a.w() * x_scale)
    +    corners = a.corners()
    +    for i in range(4):
    +        corners[i][0] = int(corners[i][0] * x_scale)
    +        corners[i][1] = int(corners[i][1] * y_scale)
    +
    +    # 显示
    +    for i in range(4):
    +        img.draw_line(corners[i][0], corners[i][1], corners[(i + 1) % 4][0], corners[(i + 1) % 4][1], image.COLOR_RED)
    +        img.draw_string(x + w, y, "id: " + str(a.id()), image.COLOR_RED)
    +        img.draw_string(x + w, y + 15, "family: " + str(a.family()), image.COLOR_RED)
    +        img.draw_string(x + w, y + 30, "rotation : " + str(180 * a.rotation() // 3.1415), image.COLOR_RED)
    +
    +
      +
    • 遍历apriltags的成员,apriltags是通过img.find_apriltags()扫描apriltag标签的结果,如果找不到标签则apriltags的成员为空
    • +
    • x_scaley_scale用来映射坐标,由于new_img是缩放后的图像,计算apriltag的坐标时需要经过映射后才能正常的画在原图img
    • +
    • a.corners()用来获取已扫描到的标签的四个顶点坐标,img.draw_line()利用这四个顶点坐标画出标签的形状
    • +
    • img.draw_string用来显示标签的内容,其中a.x()a.y()用来获取标签左上角坐标x和坐标y,a.id()用来获取标签的id,a.family()用来获取标签族类型,a.rotation()用来获取标签的旋转角度。
    • +
    +
  10. +
+

常用参数说明

+

列举常用参数说明,如果没有找到可以实现应用的参数,则需要考虑是否使用其他算法实现,或者基于目前算法的结果扩展所需的功能

+ + + + + + + + + + + + + + + + + + + + +
参数说明示例
roi设置算法计算的矩形区域,roi=[x, y, w, h],x,y表示矩形区域左上角坐标,w,h表示矩形区域的宽度和高度,默认为整张图片计算坐标为(50,50),宽和高为100的区域
img.find_apriltags(roi=[50, 50, 100, 100])
familiesapriltag标签家族类型扫描TAG36H11家族的标签
img.find_apriltags(families = image.ApriltagFamilies.TAG36H11)
+

本文介绍常用方法,更多 API 请看 API 文档的 image 部分。

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/vision/assets/custmize_model1.png b/maixpy/doc/zh/vision/assets/custmize_model1.png new file mode 100644 index 00000000..d33a9332 Binary files /dev/null and b/maixpy/doc/zh/vision/assets/custmize_model1.png differ diff --git a/maixpy/doc/zh/vision/assets/custmize_model10.png b/maixpy/doc/zh/vision/assets/custmize_model10.png new file mode 100644 index 00000000..09261c73 Binary files /dev/null and b/maixpy/doc/zh/vision/assets/custmize_model10.png differ diff --git a/maixpy/doc/zh/vision/assets/custmize_model11.png b/maixpy/doc/zh/vision/assets/custmize_model11.png new file mode 100644 index 00000000..6f1b9ad7 Binary files /dev/null and b/maixpy/doc/zh/vision/assets/custmize_model11.png differ diff --git a/maixpy/doc/zh/vision/assets/custmize_model2.png b/maixpy/doc/zh/vision/assets/custmize_model2.png new file mode 100644 index 00000000..924accfd Binary files /dev/null and b/maixpy/doc/zh/vision/assets/custmize_model2.png differ diff --git a/maixpy/doc/zh/vision/assets/custmize_model3.png b/maixpy/doc/zh/vision/assets/custmize_model3.png new file mode 100644 index 00000000..5e330316 Binary files /dev/null and b/maixpy/doc/zh/vision/assets/custmize_model3.png differ diff --git a/maixpy/doc/zh/vision/assets/custmize_model4.png b/maixpy/doc/zh/vision/assets/custmize_model4.png new file mode 100644 index 00000000..e4832068 Binary files /dev/null and b/maixpy/doc/zh/vision/assets/custmize_model4.png differ diff --git a/maixpy/doc/zh/vision/assets/custmize_model5.png b/maixpy/doc/zh/vision/assets/custmize_model5.png new file mode 100644 index 00000000..9486d6d0 Binary files /dev/null and b/maixpy/doc/zh/vision/assets/custmize_model5.png differ diff --git a/maixpy/doc/zh/vision/assets/custmize_model6.png b/maixpy/doc/zh/vision/assets/custmize_model6.png new file mode 100644 index 00000000..89330047 Binary files /dev/null and b/maixpy/doc/zh/vision/assets/custmize_model6.png differ diff --git a/maixpy/doc/zh/vision/assets/custmize_model7.png b/maixpy/doc/zh/vision/assets/custmize_model7.png new file mode 100644 index 00000000..88fe9d95 Binary files /dev/null and b/maixpy/doc/zh/vision/assets/custmize_model7.png differ diff --git a/maixpy/doc/zh/vision/assets/custmize_model8.png b/maixpy/doc/zh/vision/assets/custmize_model8.png new file mode 100644 index 00000000..b41aa891 Binary files /dev/null and b/maixpy/doc/zh/vision/assets/custmize_model8.png differ diff --git a/maixpy/doc/zh/vision/assets/custmize_model9.png b/maixpy/doc/zh/vision/assets/custmize_model9.png new file mode 100644 index 00000000..f2b8355e Binary files /dev/null and b/maixpy/doc/zh/vision/assets/custmize_model9.png differ diff --git a/maixpy/doc/zh/vision/body_key_points.html b/maixpy/doc/zh/vision/body_key_points.html new file mode 100644 index 00000000..94b9c0fb --- /dev/null +++ b/maixpy/doc/zh/vision/body_key_points.html @@ -0,0 +1,352 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy 检测人体关键点姿态检测 - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy 检测人体关键点姿态检测

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

简介

+

使用 MaixPy 可以轻松检测人体关节的关键点的坐标,用在姿态检测比如坐姿检测,体感游戏输入等。

+

使用

+

使用 MaixPy 的 maix.nn.BodyKeyPoints 类可以轻松实现:

+ +
from maix import nn, image, display
+
+detector = nn.BodyKeyPoints(model="/root/models/body_key_points.mud")
+cam = camera.Camera(recognizer.input_width(), recognizer.input_height(), recognizer.input_format())
+dis = display.Display()
+
+while 1:
+    img = cam.read()
+    points = detector.detect(img)
+    for point in points:
+        img.draw_circle(point[0], point[1], 3, color = image.COLOR_RED, thickness=-1)
+    dis.show(img)
+
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/vision/camera.html b/maixpy/doc/zh/vision/camera.html new file mode 100644 index 00000000..a9b0ccff --- /dev/null +++ b/maixpy/doc/zh/vision/camera.html @@ -0,0 +1,407 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy 摄像头使用 - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy 摄像头使用

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ + +
+ + 更新历史 +
+ + + + + + + + + + + + + + + + + + + +
日期版本作者更新内容
2024-04-031.0.0neucrack + + 初版文档 + +
+
+
+ +
+
+ +

简介

+

对于 MaixCAM 默认搭载了 GC4653 摄像头,或者可选的 OS04A10 摄像头或者全局快门摄像头,甚至是 HDMI 转 MIPI 模块,都可以直接用简单的 API 调用。

+

API 文档

+

本文介绍常用方法,更多 API 使用参考 maix.camera 模块的文档。

+

摄像头切换

+

不同的摄像头使用不同的驱动,需要在系统中选择正确的驱动。

+

TODO:如何切换摄像头,比如 GC4653 和 OS04A10 之间的切换。

+

从摄像头获取图像

+

使用 MaixPy 轻松获取:

+ +
from maix import camera
+
+cam = camera.Camera(640, 480)
+
+while 1:
+    img = cam.read()
+    print(img)
+
+

这里我们从maix模块导入camera模块,然后创建一个Camera对象,指定图像的宽度和高度。然后在一个循环中不断读取图像, 默认出的图为RGB格式,如果需要BGR格式,其它格式请看 API 文档。

+

跳过 开头的帧

+

摄像头初始化的一小段时间,可能图像采集还没稳定出现奇怪的画面,可以通过skip_frames函数跳过开头的几帧:

+ +
cam = camera.Camera(640, 480)
+cam.skip_frames(30)           # 跳过开头的30帧
+
+

显示图像

+

MaixPy 提供了display模块,可以方便的显示图像:

+ +
from maix import camera, display
+
+cam = camera.Camera(640, 480)
+disp = display.Display()
+
+while 1:
+    img = cam.read()
+    disp.show(img)
+
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/vision/classify.html b/maixpy/doc/zh/vision/classify.html new file mode 100644 index 00000000..71afe330 --- /dev/null +++ b/maixpy/doc/zh/vision/classify.html @@ -0,0 +1,361 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy 使用 AI 模型进行物体分类 - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy 使用 AI 模型进行物体分类

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

物体分类概念

+

比如眼前有两张图片,一张图里面是苹果,另一张是飞机,物体分类的任务就是把两张图分别依次输入给 AI 模型,模型会依次输出两个结果,一个是苹果,一个是飞机。

+

MaixPy 中使用物体分类

+

MaixPy 默认提供了 imagenet 数据集训练得到的 1000分类模型,可以直接使用:

+ +
from maix import camera, display, image, nn
+
+classifier = nn.Classifier(model="/root/models/mobilenetv2.mud")
+cam = camera.Camera(classifier.input_width(), classifier.input_height(), classifier.input_format())
+dis = display.Display()
+
+while 1:
+    img = cam.read()
+    res = classifier.classify(img)
+    max_idx, max_prob = res[0]
+    msg = f"{max_prob:5.2f}: {classifier.labels[max_idx]}"
+    img.draw_string(10, 10, msg, image.COLOR_RED)
+    dis.show(img)
+
+

效果视频:

+ +

这里使用了摄像头拍摄图像,然后传给 classifier进行识别,得出结果后,将结果显示在屏幕上。

+

更多 API 使用参考 maix.nn 模块的文档。

+

训练自己的分类模型

+

请到MaixHub 学习并训练分类模型,创建项目时选择分类模型即可。

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/vision/custmize_model.html b/maixpy/doc/zh/vision/custmize_model.html new file mode 100644 index 00000000..7163b7c7 --- /dev/null +++ b/maixpy/doc/zh/vision/custmize_model.html @@ -0,0 +1,780 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy 自定义(离线训练) AI 模型和运行 - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy 自定义(离线训练) AI 模型和运行

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ + +
+ + 更新历史 +
+ + + + + + + + + + + + + + + + + + + +
日期版本作者更新内容
2024-4-23v1.0dragonforward + + 加入了YOLOv5s部署 + +
+
+
+ +
+
+ +
+

本文来自社区用户 dragonforward 的贡献

+
+
+

本博客将向你展示零基础一步步的部署好自己的yolov5s模型(博主展示的是安全帽模型),训练就引用我自己之前写过的,已经训练好的可以跳过该部分,其中有部分不一样。

+
+

获得自定义训练得到的yolov5s onnx模型

+

准备自定义数据集(博主用的是VOC数据集)

+
    +
  • 数据集目录结构如下:
  • +
+ +
└─VOC2028:		自定义数据集
+    ├─Annotations	存放的是数据集标签文件,xml格式
+    ├─ImageSets		数据集的划分文件
+    │  └─Main
+    ├─JPEGImages	存放的是数据集图片
+
+
    +
  • 分割数据集
  • +
+

在split_train_val.py文件路径下执行python3 split_train_val.py会得到一下目录结构:

+ +
└─VOC2028:		自定义数据集
+    ├─Annotations	存放的是数据集标签文件,xml格式
+    ├─ImageSets		数据集的划分文件
+    │  └─Main test.txt
+          └─test.txt
+          └─train.txt
+          └─val.txt
+    ├─JPEGImages	存放的是数据集图片
+    ├─split_train_val.py	分割数据集的py文件
+
+
+

split_train_val.py文件代码如下

+ +
# -*- coding: utf-8 -*-
+"""
+Author:dragonforward
+简介:分训练集、验证集和测试集,按照 8:1:1 的比例来分,训练集8,验证集1,测试集1
+"""
+import os
+import random
+import argparse
+
+parser = argparse.ArgumentParser()
+# xml文件的地址,根据自己的数据进行修改 xml一般存放在Annotations下
+parser.add_argument('--xml_path', default='Annotations/', type=str, help='input xml label path')
+# 数据集的划分,地址选择自己数据下的ImageSets/Main
+parser.add_argument('--txt_path', default='ImageSets/Main/', type=str, help='output txt label path')
+opt = parser.parse_args()
+
+train_percent = 0.8  # 训练集所占比例
+val_percent = 0.1    # 验证集所占比例
+test_persent = 0.1   # 测试集所占比例
+
+xmlfilepath = opt.xml_path
+txtsavepath = opt.txt_path
+total_xml = os.listdir(xmlfilepath)
+
+if not os.path.exists(txtsavepath):
+    os.makedirs(txtsavepath)
+
+num = len(total_xml)  
+list = list(range(num))
+
+t_train = int(num * train_percent)  
+t_val = int(num * val_percent)
+
+train = random.sample(list, t_train)
+num1 = len(train)
+for i in range(num1):
+    list.remove(train[i])
+
+
+val_test = [i for i in list if not i in train]
+val = random.sample(val_test, t_val)
+num2 = len(val)
+for i in range(num2):
+    list.remove(val[i])
+
+
+file_train = open(txtsavepath + '/train.txt', 'w')
+file_val = open(txtsavepath + '/val.txt', 'w')
+file_test = open(txtsavepath + '/test.txt', 'w')
+
+for i in train:
+    name = total_xml[i][:-4] + '\n'
+    file_train.write(name)
+
+for i in val:
+    name = total_xml[i][:-4] + '\n'
+    file_val.write(name)    
+
+for i in list:
+    name = total_xml[i][:-4] + '\n'
+    file_test.write(name)
+
+
+file_train.close()
+file_val.close()
+file_test.close()
+
+
    +
  • voc转label得到label文件
  • +
+

目录结构如下:

+ +
└─VOC2028:		自定义数据集
+    ├─Annotations	存放的是数据集标签文件,xml格式
+    ├─ImageSets		数据集的划分文件
+    │  └─Main
+    ├─JPEGImages	存放的是数据集图片
+    └─labels		yolov5将此文件夹当作训练的标注文件夹
+└─voc_label.py
+
+

voc_label.py文件代码如下

+ +
# -*- coding: utf-8 -*-
+import xml.etree.ElementTree as ET
+import os
+
+sets = ['train', 'val', 'test']  # 如果你的Main文件夹没有test.txt,就删掉'test'
+classes = ["hat", "people"]   # 改成自己的类别,VOC数据集有以下20类别
+# classes = ["brickwork", "coil","rebar"]   # 改成自己的类别,VOC数据集有以下20类别
+# classes = ["aeroplane", 'bicycle', 'bird', 'boat', 'bottle', 'bus', 'car', 'cat', 'chair', 'cow', 'diningtable', 'dog',
+#            'horse', 'motorbike', 'person', 'pottedplant', 'sheep', 'sofa', 'train', 'tvmonitor']  # class names
+# abs_path = os.getcwd() /root/yolov5/data/voc_label.py 
+abs_path = '/root/yolov5/data/'
+
+def convert(size, box):
+    dw = 1. / (size[0])
+    dh = 1. / (size[1])
+    x = (box[0] + box[1]) / 2.0 - 1
+    y = (box[2] + box[3]) / 2.0 - 1
+    w = box[1] - box[0]
+    h = box[3] - box[2]
+    x = x * dw
+    w = w * dw
+    y = y * dh
+    h = h * dh
+    return x, y, w, h
+
+
+def convert_annotation(image_id):
+    in_file = open(abs_path + '/VOC2028/Annotations/%s.xml' % (image_id), encoding='UTF-8')
+    out_file = open(abs_path + '/VOC2028/labels/%s.txt' % (image_id), 'w')
+    tree = ET.parse(in_file)
+    root = tree.getroot()
+    size = root.find('size')
+    w = int(size.find('width').text)
+    h = int(size.find('height').text)
+    for obj in root.iter('object'):
+        difficult = obj.find('difficult').text
+        # difficult = obj.find('Difficult').text
+        cls = obj.find('name').text
+        if cls not in classes or int(difficult) == 1:
+            continue
+        cls_id = classes.index(cls)
+        xmlbox = obj.find('bndbox')
+        b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
+             float(xmlbox.find('ymax').text))
+        b1, b2, b3, b4 = b
+        # 标注越界修正
+        if b2 > w:
+            b2 = w
+        if b4 > h:
+            b4 = h
+        b = (b1, b2, b3, b4)
+        bb = convert((w, h), b)
+        out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
+
+
+for image_set in sets:
+    if not os.path.exists(abs_path + '/VOC2028/labels/'):
+        os.makedirs(abs_path + '/VOC2028/labels/')
+
+    image_ids = open(abs_path + '/VOC2028/ImageSets/Main/%s.txt' % (image_set)).read().strip().split()
+    list_file = open(abs_path + '/VOC2028/%s.txt' % (image_set), 'w')
+    for image_id in image_ids:
+        list_file.write(abs_path + '/VOC2028/JPEGImages/%s.jpg\n' % (image_id))  # 要么自己补全路径,只写一半可能会报错
+        convert_annotation(image_id)
+    list_file.close()
+
+
+
+

picture 0

+

训练模型

+
    +
  • 配置环境
  • +
+ +
git clone https://github.com/ultralytics/yolov5
+cd yolov5
+pip install -r requirements.txt
+pip install onnx
+
+
    +
  • 下载预训练权重(博主尝试了v7.0的和v6.0的pt都可以)
  • +
+ +
https://github.com/ultralytics/yolov5/releases/download/v7.0/yolov5s.pt
+
+

picture 1

+
    +
  • 训练(博主使用的是学校的集群进行训练)
  • +
+ +
python3 train.py --weights weights/yolov5s.pt --cfg models/yolov5s.yaml --data data/safthat.yaml --epochs 150 --batch-size 16 --multi-scale --device 0 
+
+

picture 2

+ +
python3 detect.py --source /root/yolov5/data/images/000000.jpg --weights /root/yolov5/runs/train/exp13/weights/best.pt --conf-thres 0.25
+
+

picture 3

+
    +
  • 导出onnx模型,由于学校服务器目前去教学上课去了,他们上完课才能分配我就用电脑本机的conda环境导出
  • +
+

下面为啥使用-imgsz 224 320,原因就是比较适配屏幕,加上我尝试640640的,摄像头报错,提示是640480这样,然后我就看到sipeed那个yolov5s是320*224的,我也就和他保持一致吧

+ +
python export.py --weights yolov5s_hat.pt --include onnx --opset 16 --imgsz 224 320
+
+

picture 4

+

模型查看通过网址输入netron.app查看三个输出:

+

picture 5

+

下面是博主的三个输出

+ +
onnx::Shape_329
+onnx::Shape_384
+onnx::Shape_439
+
+

模型转化(关键)

+

安装docker环境(已安装过的可以跳过)

+ +
安装docker依赖的基础软件
+sudo apt-get update
+sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
+添加官方来源
+curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
+sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
+安装 docker
+sudo apt-get update
+sudo apt-get install docker-ce docker-ce-cli containerd.io
+
+

开始量化模型实操(!!!)

+

准备工作

+ +
https://github.com/sophgo/tpu-mlir/releases/tag/v1.7
+上面网址下载
+tpu-mlir-resource.tar 和 tpu_mlir-1.7-py3-none-any.whl 
+
+

picture 6

+

为什么拉取最新版,因为我用3.1版本失败了,工具在一直更新,最好保持最新,可以看下面图片我使用3.1版本也试过

+

picture 7

+ +

+docker pull sophgo/tpuc_dev:latest
+
+进入容器后将上面的准备的两个文件拷贝到workspace目录
+
+root@3d517bc7f51f:/workspace/model_yolov5s# cd ..
+root@3d517bc7f51f:/workspace# ls
+model_yolov5s  tpu-mlir-resource  tpu-mlir-resource.tar  tpu_mlir-1.7-py3-none-any.whl
+root@3d517bc7f51f:/workspace# 
+
+下面两个二选一,我建议是第二个,离线安装
+pip install tpu_mlir[all]或者pip install tpu_mlir-*-py3-none-any.whl[all]
+博主是选的第二个
+pip install tpu_mlir-1.7-py3-none-any.whl
+以及安装它的全部依赖
+pip install tpu_mlir-1.7-py3-none-any.whl[all] 
+解压
+tar -xvf tpu-mlir-resource.tar
+修改文件夹名字
+mv regression/ tpu-mlir-resource/
+
+
+mkdir model_yolov5s && cd model_yolov5s
+
+cp -rf ../tpu_mlir_resource/dataset/COCO2017 .
+cp -rf ../tpu_mlir_resource/image .
+
+
+把之前准备好的图片100张一集一张测试图片和onnx模型传递到如下
+root@3d517bc7f51f:/workspace# cd model_yolov5s/
+root@3d517bc7f51f:/workspace/model_yolov5s# ls
+COCO2017  image  workspace  yolov5n_hat.onnx  yolov5s_hat.onnx
+root@3d517bc7f51f:/workspace/model_yolov5s# cd COCO2017/
+root@3d517bc7f51f:/workspace/model_yolov5s/COCO2017# ls
+000000.jpg  000011.jpg  000022.jpg  000032.jpg  000042.jpg  000053.jpg  000066.jpg  000076.jpg  000086.jpg  000096.jpg
+000002.jpg  000012.jpg  000023.jpg  000033.jpg  000043.jpg  000054.jpg  000067.jpg  000077.jpg  000087.jpg  000101.jpg
+000003.jpg  000013.jpg  000024.jpg  000034.jpg  000044.jpg  000055.jpg  000068.jpg  000078.jpg  000088.jpg  000102.jpg
+000004.jpg  000014.jpg  000025.jpg  000035.jpg  000045.jpg  000058.jpg  000069.jpg  000079.jpg  000089.jpg  000103.jpg
+000005.jpg  000015.jpg  000026.jpg  000036.jpg  000046.jpg  000059.jpg  000070.jpg  000080.jpg  000090.jpg  000104.jpg
+000006.jpg  000016.jpg  000027.jpg  000037.jpg  000048.jpg  000061.jpg  000071.jpg  000081.jpg  000091.jpg  000105.jpg
+000007.jpg  000017.jpg  000028.jpg  000038.jpg  000049.jpg  000062.jpg  000072.jpg  000082.jpg  000092.jpg  000106.jpg
+000008.jpg  000019.jpg  000029.jpg  000039.jpg  000050.jpg  000063.jpg  000073.jpg  000083.jpg  000093.jpg  000107.jpg
+000009.jpg  000020.jpg  000030.jpg  000040.jpg  000051.jpg  000064.jpg  000074.jpg  000084.jpg  000094.jpg  000108.jpg
+000010.jpg  000021.jpg  000031.jpg  000041.jpg  000052.jpg  000065.jpg  000075.jpg  000085.jpg  000095.jpg  000109.jpg
+root@3d517bc7f51f:/workspace/model_yolov5s/COCO2017# ls -l | grep "^-" | wc -l
+100
+root@3d517bc7f51f:/workspace/model_yolov5s/COCO2017# 
+
+ls -l | grep "^-" | wc -l可以查看一下图片多少个,COCO2017文件下的图片博主替换了安全帽的100张图片以及测试图片同样
+
+回到 model_yolov5s
+root@3d517bc7f51f:/workspace/model_yolov5s/COCO2017# cd ..
+root@3d517bc7f51f:/workspace/model_yolov5s# ls
+COCO2017  image  workspace  yolov5n_hat.onnx  yolov5s_hat.onnx
+root@3d517bc7f51f:/workspace/model_yolov5s# 
+
+接着
+mkdir workspace && cd workspace
+执行下面命令ONNX 转 MLIR(记得output_names换为自己的)
+model_transform \
+--model_name yolov5s \
+--model_def ../yolov5s_hat.onnx \
+--input_shapes [[1,3,224,320]] \
+--mean 0.0,0.0,0.0 \
+--scale 0.0039216,0.0039216,0.0039216 \
+--keep_aspect_ratio \
+--pixel_format rgb \
+--output_names onnx::Shape_329,onnx::Shape_439,onnx::Shape_384 \
+--test_input ../image/hat.jpg \
+--test_result yolov5s_top_outputs.npz \
+--mlir yolov5s.mlir
+
+执行下面命令MLIR 转 INT8 模型,转 INT8 模型前需要跑 calibration, 得到校准表
+run_calibration yolov5s.mlir \
+--dataset ../COCO2017 \
+--input_num 100 \
+-o yolov5s_cali_table
+接着执行下面
+model_deploy \
+--mlir yolov5s.mlir \
+--quantize INT8 \
+--calibration_table yolov5s_cali_table \
+--processor cv181x \
+--test_input yolov5s_in_f32.npz \
+--test_reference yolov5s_top_outputs.npz \
+--tolerance 0.85,0.45 \
+--model yolov5s_cv181x_int8_sym.cvimodel
+
+最后你会得到如下:
+root@3d517bc7f51f:/workspace/model_yolov5s/workspace# ls
+_weight_map.csv          yolov5s_cv181x_int8_sym.cvimodel         yolov5s_origin.mlir
+build_flag.json          yolov5s_cv181x_int8_sym_final.mlir       yolov5s_top_f32_all_origin_weight.npz
+final_opt.onnx           yolov5s_cv181x_int8_sym_tensor_info.txt  yolov5s_top_f32_all_weight.npz
+yolov5s.mlir             yolov5s_cv181x_int8_sym_tpu.mlir         yolov5s_top_outputs.npz
+yolov5s_cali_table       yolov5s_in_f32.npz                       yolov5s_tpu_addressed_cv181x_int8_sym_weight.npz
+yolov5s_cv181x_int8_sym  yolov5s_opt.onnx.prototxt                yolov5s_tpu_addressed_cv181x_int8_sym_weight_fix.npz
+root@3d517bc7f51f:/workspace/model_yolov5s/workspace# 
+
+

通过上述步骤,你就可以得到量化后的可以部署到开发板上的模型的
+解答:
+上面为什么会是cv181x,因为我自己先用了一个实验了一下,然后报错如下:

+ +
-- [I] load cvimodel from: /root/models/yolov5n.cvimodel
+cvimodel built for cv180x CANNOT run on platform cv181x
+failed to parse cvimodel
+
+
+

实机运行

+
    +
  • yolov5s_hat.mud内容如下如下:
  • +
+ +
[basic]
+type = cvimodel
+model = yolov5s_hat_cv181x_int8_sym.cvimodel
+
+[extra]
+model_type = yolov5
+input_type = rgb
+mean = 0, 0, 0
+scale = 0.00392156862745098, 0.00392156862745098, 0.00392156862745098
+anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
+labels = hat,person
+
+
+

运行代码

+ +
from maix import camera, display, image, nn, app
+
+detector = nn.YOLOv5(model="/root/models/yolov5s_hat.mud")
+cam = camera.Camera(detector.input_width(), detector.input_height(), detector.input_format())
+dis = display.Display()
+print("www")
+print(detector.input_width(),detector.input_height(), detector.input_format())
+
+while not app.need_exit():
+    img = cam.read()
+    objs = detector.detect(img, conf_th = 0.5, iou_th = 0.45)
+    for obj in objs:
+        img.draw_rect(obj.x, obj.y, obj.w, obj.h, color = image.COLOR_RED)
+        msg = f'{detector.labels[obj.class_id]}: {obj.score:.2f}'
+        img.draw_string(obj.x, obj.y, msg, color = image.COLOR_RED)
+    dis.show(img)
+
+

picture 8

+

其中10.84.117.1就是ip地址,将cvmodel和mud上传到/root/models/ 路径下

+

picture 9

+

打包完成后安装应用然后运行就行,也可以ide运行

+

picture 10

+

视频链接:

+ +
https://www.bilibili.com/video/BV1xz421S7Rx/?spm_id_from=333.999.0.0&vd_source=b1fff0f773136d7d05331087929c7739
+
+

感谢

+

感谢谁说现在是冬天呢一些思路

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/vision/display.html b/maixpy/doc/zh/vision/display.html new file mode 100644 index 00000000..146741a9 --- /dev/null +++ b/maixpy/doc/zh/vision/display.html @@ -0,0 +1,446 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy 屏幕使用 - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy 屏幕使用

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ + +
+ + 更新历史 +
+ + + + + + + + + + + + + + + + + + + +
日期版本作者更新内容
2024-03-311.0.0neucrack + + 初版文档 + +
+
+
+ +
+
+ +

简介

+

MaixPy 提供了display模块,可以将图像显示到屏幕上,同时,也可以将图像发送到 MaixVision 显示,方便调试和开发。

+

API 文档

+

本文介绍常用方法,更多 API 请看 API 文档的 display 部分。

+

使用屏幕

+
    +
  • 导入display模块:
  • +
+ +
from maix import display
+
+
    +
  • 创建一个Display对象:
  • +
+ +
disp = display.Display()
+
+
    +
  • 显示图像:
  • +
+ +
disp.show(img)
+
+

这里img对象是maix.image.Image对象,可以通过camera模块的read方法获取,也可以通过image模块的load方法加载文件系统中的图像,也可以通过image模块的Image类创建一个空白图像。

+

比如:

+ +
from maix import image, display
+
+disp = display.Display()
+img = image.load("/root/dog.jpg")
+disp.show(img)
+
+

这里需要先把dog.jpg文件传到设备的/root目录下。

+

显示文字:

+ +
from maix import image, display
+
+disp = display.Display()
+img = image.Image(320, 240)
+img.draw_rectangle(0, 0, disp.width(), disp.height(), color=image.Color.from_rgb(255, 0, 0), thickness=-1)
+img.draw_rectangle(10, 10, 100, 100, color=image.Color.from_rgb(255, 0, 0))
+img.draw_string(10, 10, "Hello MaixPy!", color=image.Color.from_rgb(255, 255, 255))
+disp.show(img)
+
+

从摄像头读取图像并显示:

+ +
from maix import camera, display, app
+
+disp = display.Display()
+cam = camera.Camera(320, 240)
+while not app.need_exit():
+    img = cam.read()
+    disp.show(img)
+
+
+

这里用了一个while not app.need_exit(): 是方便程序在其它地方调用app.set_exit_flag()方法后退出循环。

+
+

调整背光亮度

+

在系统的设置应用中可以手动调整背光亮度,如果你想在程序中调整背光亮度,可以使用set_backlight方法,参数就是亮度百分比,取值范围是 0-100:

+ +
disp.set_backlight(50)
+
+

注意,程序退出回到应用选择界面后会自动恢复到系统设置的背光亮度。

+

显示到 MaixVision

+

在使用 MaixVision 运行代码时,能够将图像显示到 MaixVision 上,方便调试和开发。

+

在调用show方法时,会自动压缩图像并发送到 MaixVision 显示。

+

当然,如果你没有屏幕,或者为了节省内存不想初始化屏幕,也可以直接调用image.Image对象的send_to_maixvision方法发送图像到 MaixVision 显示。

+ +
from maix import image
+
+img = image.Image(320, 240)
+img.draw_rectangle(0, 0, img.width(), img.height(), color=image.Color.from_rgb(255, 0, 0), thickness=-1)
+img.draw_rectangle(10, 10, 100, 100, color=image.Color.from_rgb(255, 0, 0))
+img.draw_string(10, 10, "Hello MaixPy!", color=image.Color.from_rgb(255, 255, 255))
+img.send_to_maixvision()
+
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/vision/face_recognition.html b/maixpy/doc/zh/vision/face_recognition.html new file mode 100644 index 00000000..2c31199b --- /dev/null +++ b/maixpy/doc/zh/vision/face_recognition.html @@ -0,0 +1,376 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy 人脸识别 - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy 人脸识别

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

人脸识别简介

+

人脸识别就是识别当前画面中的人脸的位置以及是谁。
+所以人脸识别除了要检测到人脸,一般会有一个库来保存认识的人和不认识的人。

+

识别原理

+
    +
  • 使用 AI 模型检测人脸,获得坐标和五官的坐标。
  • +
  • 利用五官的坐标仿射变换将图中的脸拉正对其到标准脸的样子,方便模型提取脸的特征。
  • +
  • 使用特征提取模型提取脸的特征值。
  • +
  • 与库中记录的人脸特征值进行对比(计算保存的和当前画面中的脸的特征值的余弦距离,得出最小的距离的库中的人脸,小于设定的阈值就认为当前画面中就是这个库中的人)
  • +
+

MaixPy 使用

+

MaixPy maix.nn 模块中提供了人脸识别的 API, 可以直接使用,模型也内置了,也可以到 MaixHub 模型库 下载(筛选选则对应的硬件平台,比如 maixcam)。

+

识别:

+ +
from maix import nn
+
+recognizer = nn.Face_Recognizer(model="/root/models/face_recognizer.mud")
+if os.path.exists("/root/faces.bin"):
+    recognizer.load_faces("/root/faces.bin")
+cam = camera.Camera(recognizer.input_width(), recognizer.input_height(), recognizer.input_format())
+dis = display.Display()
+
+while 1:
+    img = cam.read()
+    faces = recognizer.recognize(img)
+    for obj in faces:
+        img.draw_rect(obj.x, obj.y, obj.w, obj.h, color = image.COLOR_RED)
+        msg = f'{recognizer.labels[obj.class_id]}: {obj.score:.2f}'
+        img.draw_string(obj.x, obj.y, msg, color = image.COLOR_RED)
+    dis.show(img)
+
+

第一次运行这个代码会发现能检测到人脸,但是都不认识,需要我们进入添加人脸模式学习人脸才行。
+比如可以在用户按下按键的时候学习人脸:

+ +
faces = recognizer.detect_faces(img)
+for face in faces:
+    print(face)
+    # 这里考虑到了一个画面中有多个人脸的情况
+    # 可以在这里根据 face 的坐标决定要不要添加到库里面
+    recognizer.add_face(face)
+recognizer.save_(faces)("/too/faces.bin")
+
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/vision/find_blobs.html b/maixpy/doc/zh/vision/find_blobs.html new file mode 100644 index 00000000..8e27e03f --- /dev/null +++ b/maixpy/doc/zh/vision/find_blobs.html @@ -0,0 +1,541 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy 寻找色块 - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy 寻找色块

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ + +
+ + 更新历史 +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
日期版本作者更新内容
2024-04-031.0.0neucrack + + 初版文档 + +
2024-04-031.0.1lxowalle + + 添加寻找色块的详细用法 + +
+
+
+ +
+
+ +

阅读本文前,确保已经知晓如何开发MaixCAM,详情请阅读快速开始

+

简介

+

本文将介绍如何使用MaixPy来寻找色块,以及如何使用MaixCam的默认应用程序寻找色块。

+

在视觉应用中,寻找色块是一个非常常见的需求,比如机器人找色块,自动化生产线找色块等等,即需要识别画面中的特定的颜色区域,获取这个区域的位置和大小等信息。

+

使用 MaixPy 寻找色块

+

MaixPy的 maix.image.Image中提供了find_blobs方法,可以方便的找色块。

+

如何寻找色块

+

一个简单的示例,实现寻找色块并画框

+ +
from maix import image, camera, display
+
+cam = camera.Camera(320, 240)
+disp = display.Display()
+
+# 根据色块颜色选择对应配置
+thresholds = [[0, 80, 40, 80, 10, 80]]      # red
+# thresholds = [[0, 80, -120, -10, 0, 30]]    # green
+# thresholds = [[0, 80, 30, 100, -120, -60]]  # blue
+
+while 1:
+    img = cam.read()
+    blobs = img.find_blobs(thresholds, pixels_threshold=500)
+    for blob in blobs:
+        img.draw_rect(blob[0], blob[1], blob[2], blob[3], image.COLOR_GREEN)
+    disp.show(img)
+
+

步骤:

+
    +
  1. 导入image、camera、display模块

    + +
    from maix import image, camera, display
    +
    +
  2. +
  3. 初始化摄像头和显示

    + +
    cam = camera.Camera(320, 240)	# 初始化摄像头,输出分辨率320x240 RGB格式
    +disp = display.Display()
    +
    +
  4. +
  5. 从摄像头获取图片并显示

    + +
    while 1:
    +    img = cam.read()
    +    disp.show(img)
    +
    +
  6. +
  7. 调用find_blobs方法寻找摄像头图片中的色块,并画到屏幕上

    + +
    blobs = img.find_blobs(thresholds, pixels_threshold=500)
    +for blob in blobs:
    +    img.draw_rect(blob[0], blob[1], blob[2], blob[3], image.COLOR_GREEN)
    +
    +
      +
    • img是通过cam.read()读取到的摄像头图像,当初始化的方式为cam = camera.Camera(320, 240)时,img对象是一张分辨率为320x240的RGB图。
    • +
    • img.find_blobs用来寻找色块, thresholds 是一个颜色阈值列表,每个元素是一个颜色阈值,同时找到多个阈值就传入多个,每个颜色阈值的格式为 [L_MIN, L_MAX, A_MIN, A_MAX, B_MIN, B_MAX],这里的 LABLAB颜色空间的三个通道,L 通道是亮度,A 通道是红绿通道,B 通道是蓝黄通道。pixels_threshold是一个像素点数量的阈值,用来过滤一些不需要的小色块。
    • +
    • img.draw_rect用来画色块框,blob[0]blob[1]blob[1]blob[1]分别代表色块左上角坐标x,色块左上角坐标y,色块宽度w和色块高度h
    • +
    +
  8. +
+

常用参数说明

+

列举常用参数说明,如果没有找到可以实现应用的参数,则需要考虑是否使用其他算法实现,或者基于目前算法的结果扩展所需的功能

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
参数说明示例
thresholds基于lab颜色空间的阈值,threshold=[[l_min, l_max, a_min, a_max, b_min, b_max]],分别表示:
亮度范围为[l_min, l_max]|
绿色到红色的分量范围为[l_min, l_max]
蓝色到黄色的分量范围为[b_min, b_max]
可同时设置多个阈值
设置两个阈值来检测红色和绿色
img.find_blobs(threshold=[[0, 80, 40, 80, 10, 80], [0, 80, -120, -10, 0, 30]])
红色阈值为[0, 80, 40, 80, 10, 80]
绿色阈值为[0, 80, -120, -10, 0, 30]
invert使能阈值反转,使能后传入阈值与实际阈值相反,默认为False使能阈值反转
img.find_blobs(invert=True)
roi设置算法计算的矩形区域,roi=[x, y, w, h],x,y表示矩形区域左上角坐标,w,h表示矩形区域的宽度和高度,默认为整张图片计算坐标为(50,50),宽和高为100的区域
img.find_blobs(roi=[50, 50, 100, 100])
area_threshold过滤像素面积小于area_threshold的色块,单位为像素点,默认为10。该参数可用于过滤一些无用的小色块过滤面积小于1000的色块
img.find_blobs(area_threshold=1000)
pixels_threshold过滤有效像素点小于pixels_threshold的色块,默认为10。该参数可用于过滤一些无用的小色块过滤有效像素点小于1000的色块
img.find_blobs(pixels_threshold=1000)
+

本文介绍常用方法,更多 API 请看 API 文档的 image 部分。

+

使用寻找色块APP

+

为了快速验证寻找色块的功能,可以先使用MaixCam提供的寻找色块应用程序来体验寻找色块的效果。

+

使用方法

+

打开设备,选择找色块应用,然后在下方选择要识别的颜色,或者自定义颜色,即可以识别到对应的颜色了,同时串口也会输出识别到的坐标和颜色信息。

+

+

详细说明

+

APP界面参考如下:

+

+

使用默认配置

+

寻找色块APP默认提供了red、green、blue、user四种配置,其中red、green和blue用来寻找红色、绿色和蓝色的色块user主要提供给用户自定义寻找色块,自定义配置的方法见下文。快速体验时通过点击界面下方按钮即可切换到对应配置,

+

寻找自定义色块

+

APP提供两种方式来寻找自定义的色块:通过自适应LAB阈值寻找和手动设置LAB阈值寻找

+
1. 自适应LAB阈值寻找色块
+

操作方法:

+
    +
  1. 点击左下角选项图标,进入配置模式
  2. +
  3. 摄像头对准需要寻找的物体点击屏幕上的目标物体,此时左侧会显示该物体对应颜色的矩形框,并显示该物体颜色的LAB值。
  4. +
  5. 点击出现的矩形框,系统将会自动设置LAB阈值,此时画面将会画出该物体边缘。
  6. +
+
2. 手动设置LAB阈值寻找色块
+

手动设置可以更精确的找到目标色块。

+

操作方法:

+
    +
  1. 点击左下角选项图标,进入配置模式

    +
  2. +
  3. 摄像头对准需要寻找的物体点击屏幕上的目标物体,此时左侧会显示该物体对应颜色的矩形框,并显示该物体颜色的LAB值

    +
  4. +
  5. 点击下方选项L Min,L Max,A Min,A Max,B Min,B Max,点击后右侧会出现滑动条来设置该选项值。这些值分别对应LAB颜色格式的L通道、A通道和B通道的最小值和最大值

    +
  6. +
  7. 参考步骤2计算的物体颜色的LAB值,将L Min,L Max,A Min,A Max,B Min,B Max调整到合适的值,即可识别到对应的色块。

    +

    例如LAB=(20, 50, 80),由于L=20,为了适配一定范围让L Min=10L Max=30;同理,由于A=50,让A Min=40A Max=60; 由于B=80,让B Min=70B Max=90

    +
  8. +
+

通过串口协议获取检测数据

+

寻找色块APP支持通过串口(默认波特率为115200)上报检测到的色块信息。

+

由于上报信息只有一条,这里直接用示例来说明上报信息的内容。

+

例如上报信息为:

+ +
AA CA AC BB 14 00 00 00 E1 08 EE 00 37 00 15 01 F7 FF 4E 01 19 00 27 01 5A 00 A7 20
+
+
    +
  • AA CA AC BB:协议头部,内容固定

    +
  • +
  • 14 00 00 00:数据长度,除了协议头部和数据长度外的总长度

    +
  • +
  • E1:标志位,用来标识串口消息标志

    +
  • +
  • 08:命令类型,对于寻找色块APP应用该值固定为0x08

    +
  • +
  • EE 00 37 00 15 01 F7 FF 4E 01 19 00 27 01 5A 00:已找到色块的四个顶点坐标,每个值用小端格式的2字节表示。EE 0037 00表示第一个顶点坐标为(238, 55),15 01F7 FF表示第二个顶点坐标为(277, -9),4E 0119 00表示第三个顶点坐标为(334, 25),27 015A 00表示第四个顶点坐标为(295, 90)。

    +
  • +
  • A7 20:CRC 校验值,用以校验帧数据在传输过程中是否出错

    +
  • +
+

关于LAB颜色空间

+

LAB颜色空间和RGB颜色空间一样是一种表示颜色的方法,LAB可以表示人眼能看到的所有颜色。如果需要了解LAB可以去网络上搜索相关文章,那样更详细,而对于你应该只需要了解为什么选用LAB对于MaixPy的优势。

+

LAB对于MaixPy的优势:

+
    +
  1. LAB颜色空间的色域比RGB都要大,因此完全可以替换RGB。
  2. +
  3. LAB颜色空间下,由于L通道是亮度通道,我们常常设置到较大的范围即可(常用[0,80]),而编写代码时主要关注是A通道和B通道,这样可以减少大量的时间在纠结颜色阈值如何选择的问题上。
  4. +
  5. LAB颜色空间的颜色感知更均匀,更容易用代码调试。例如,对于只需要寻找红色色块,可以固定L通道和B通道值,只需要调整A通道的值即可(这是在颜色精度要求不高的情况下);如果是RGB通道则基本需要R、G、B三个通道同时变动才能找到合适的阈值。
  6. +
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/vision/image_ops.html b/maixpy/doc/zh/vision/image_ops.html new file mode 100644 index 00000000..802a6989 --- /dev/null +++ b/maixpy/doc/zh/vision/image_ops.html @@ -0,0 +1,606 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy 图像基础操作 - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy 图像基础操作

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ + +
+ + 更新历史 +
+ + + + + + + + + + + + + + + + + + + +
日期版本作者更新内容
2024-04-031.0.0neucrack + + 初版文档 + +
+
+
+ +
+
+ +

简介

+

视觉应用中图像占据非常重要的位置,不管是图片还是视频,因为视频本质上就是一帧帧的图像,所以图像处理是视觉应用的基础。

+

API 文档

+

本文介绍常用方法, 更多 API 参考 maix.image 模块的文档。

+

图像格式

+

MaixPy 提供基础图像模块image,里面最重要的就是image.Image类,用于图像的创建以及各种图像基础操作,以及图像加载和保存等。

+

图像格式有很多,一般我们用image.Format.FMT_RGB888 或者 image.Format.FMT_RGBA8888 或者 image.Format.FMT_GRAYSCALE或者image.Format.FMT_BGR888等。

+

大家知道 RGB 三色可以合成任意颜色,所以一般情况下我们使用 image.Format.FMT_RGB888就足够, RGB888 在内存中是 RGB packed 排列,即在内存中的排列:
+像素1_红色, 像素1_绿色, 像素1_蓝色, 像素2_红色, 像素2_绿色, 像素2_蓝色, ... 依次排列。

+

创建图像

+

创建图像很简单,只需要指定图像的宽度和高度以及图像格式即可:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+print(img)
+print(img.width(), img.height(), img.format())
+
+

320 是图像的宽度,240 是图像的高度,image.Format.FMT_RGB888 是图像的格式,格式参数可以省略,默认是image.Format.FMT_RGB888

+

这里通过img.width()img.height()img.format()可以获取图像的宽度、高度和格式。

+

显示到屏幕

+

MaixPy 提供了maix.display.Display类,可以方便的显示图像:

+ +
from maix import image, display
+
+disp = display.Display()
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+disp.show(img)
+
+

注意这里因为没有图像数据,所以显示的是黑色的图像,修改画面看后文。

+

从文件系统读取图像

+

MaixPy 提供了maix.image.load方法,可以从文件系统读取图像:

+ +
from maix import image
+
+img = image.load("/root/image.jpg")
+print(img)
+
+

注意这里/root/image.jpg 是提前传输到了板子上的,方法可以看前面的教程。
+可以支持 jpgpng 格式的图像。

+

保存图像到文件系统

+

MaixPy 的maix.image.Image提供了save方法,可以保存图像到文件系统:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+
+# do something with img
+img.save("/root/image.jpg")
+
+

画框

+

image.Image提供了draw_rect方法,可以在图像上画框:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+img.draw_rect(10, 10, 100, 100, image.Color.from_rgb(255, 0, 0))
+
+

这里的参数依次是:x, y, w, h, colorxy 是框的左上角坐标,wh 是框的宽度和高度,color 是框的颜色,可以使用image.Color.from_rgb方法创建颜色。
+可以用thickness指定框的线宽,默认是1

+

也可以画实心框,传参 thickness=-1 即可:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+img.draw_rect(10, 10, 100, 100, (255, 0, 0), thickness=-1)
+
+

写字符串

+

image.Image提供了draw_string方法,可以在图像上写字:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+img.draw_string(10, 10, "Hello MaixPy", image.Color.from_rgb(255, 0, 0))
+
+

这里的参数依次是:x, y, text, colorxy 是文字的左上角坐标,text 是要写的文字,color 是文字的颜色,可以使用image.Color.from_rgb方法创建颜色。

+

还可以放大字体,传参 scale 即可:

+ +
img.draw_string(10, 10, "Hello MaixPy", image.Color.from_rgb(255, 0, 0), scale=2)
+
+

获取字体的宽度和高度:

+ +
w, h = img.string_size("Hello MaixPy", scale=2)
+print(w, h)
+
+

注意这里scale是放大倍数,默认是1,和draw_string应该保持一致。

+

画线

+

image.Image提供了draw_line方法,可以在图像上画线:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+img.draw_line(10, 10, 100, 100, image.Color.from_rgb(255, 0, 0))
+
+

这里的参数依次是:x1, y1, x2, y2, colorx1y1 是线的起点坐标,x2y2 是线的终点坐标,color 是线的颜色,可以使用image.Color.from_rgb方法创建颜色。

+

画圆

+

image.Image提供了draw_circle方法,可以在图像上画圆:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+img.draw_circle(100, 100, 50, image.Color.from_rgb(255, 0, 0))
+
+

这里的参数依次是:x, y, r, colorxy 是圆心坐标,r 是半径,color 是圆的颜色,可以使用image.Color.from_rgb方法创建颜色。

+

缩放图像

+

image.Image提供了resize方法,可以缩放图像:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+img_new = img.resize(160, 120)
+print(img, img_new)
+
+

注意这里resize方法返回一个新的图像对象,原图像不变。

+

剪裁图像

+

image.Image提供了crop方法,可以剪裁图像:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+img_new = img.crop(10, 10, 100, 100)
+print(img, img_new)
+
+

注意这里crop方法返回一个新的图像对象,原图像不变。

+

旋转图像

+

image.Image提供了rotate方法,可以旋转图像:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+img_new = img.rotate(90)
+print(img, img_new)
+
+

注意这里rotate方法返回一个新的图像对象,原图像不变。

+

拷贝图像

+

image.Image提供了copy方法,可以拷贝一份独立的图像:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+img_new = img.copy()
+print(img, img_new)
+
+

仿射变换

+

image.Image提供了affine方法,可以进行仿射变换,即提供当前图中三个及以上的点坐标,以及目标图中对应的点坐标,可以自动进行图像的旋转、缩放、平移等操作变换到目标图像:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+img_new = img.affine([(10, 10), (100, 10), (10, 100)], [(10, 10), (100, 20), (20, 100)])
+print(img, img_new)
+
+

更多参数和用法请参考 API 文档。

+

画关键点

+

image.Image提供了draw_keypoints方法,可以在图像上画关键点:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+
+keypoints = [(10, 10), (100, 10), (10, 100)]
+img.draw_keypoints(keypoints, image.Color.from_rgb(255, 0, 0), size=10, thickness=1, fill=False)
+
+

在坐标(10, 10)(100, 10)(10, 100)画三个红色的关键点,关键点的大小是10,线宽是1,不填充。

+

画十字

+

image.Image提供了draw_cross方法,可以在图像上画十字:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+img.draw_cross(100, 100, image.Color.from_rgb(255, 0, 0), size=5, thickness=1)
+
+

在坐标(100, 100)画一个红色的十字,十字的延长大小是5,所以线段长度为2 * size + thickness, 线宽是1

+

画箭头

+

image.Image提供了draw_arrow方法,可以在图像上画箭头:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+img.draw_arrow(10, 10, 100, 100, image.Color.from_rgb(255, 0, 0), thickness=1)
+
+

在坐标(10, 10)画一个红色的箭头,箭头的终点是(100, 100),线宽是1

+

画图

+

image.Image提供了draw_image方法,可以在图像上画图:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+img2 = image.Image(100, 100, image.Format.FMT_RGB888)
+img2.draw_rect(10, 10, 90, 90, image.Color.from_rgb(255, 0, 0))
+img.draw_image(10, 10, img2)
+
+

转换格式

+

image.Image提供了to_format方法,可以转换图像格式:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+img_new = img.to_format(image.Format.FMT_BGR888)
+print(img, img_new)
+img_jpg = img.to_format(image.Format.FMT_JPEG)
+print(img, img_new)
+
+

注意这里to_format方法返回一个新的图像对象,原图像不变。

+

和 Numpy/OpenCV 格式互相转换

+

另外还可以转换成numpy数组,这样就能给numpyopencv等库使用:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+img_np = image.image2cv(img)
+img2   = image.cv2image(img_np)
+print(type(img_np), img_np, img_np.shape)
+print(type(img2), img2)
+
+

和 bytes 数据互相转换

+

image.Image提供了to_bytes方法,可以转换图像为bytes数据:

+ +
from maix import image
+
+img = image.Image(320, 240, image.Format.FMT_RGB888)
+data = img.to_bytes()
+print(type(data), len(data), img.data_size())
+
+img2 = image.Image(320, 240, image.Format.FMT_RGB888, data)
+print(img2)
+
+

这里to_bytes获得一个新的bytes对象,是独立的内存,不会影响原图。
+image.Image构造函数中传入data参数可以直接从bytes数据构造图像对象,注意新的图像也是独立的内存,不会影响到data

+

因为涉及到内存拷贝,所以这个方法比较耗时,不建议频繁使用。

+
+

如果你想用不拷贝的方式优化程序(不建议轻易使用,写不好代码会导致程序容易崩溃,),请看 API 文档。

+
+

更多基础 API 使用方法

+

更多 API 使用方法请参考 maix.image 模块的文档。

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/vision/line_tracking.html b/maixpy/doc/zh/vision/line_tracking.html new file mode 100644 index 00000000..6706515a --- /dev/null +++ b/maixpy/doc/zh/vision/line_tracking.html @@ -0,0 +1,540 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy 寻找直线 - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy 寻找直线

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ + +
+ + 更新历史 +
+ + + + + + + + + + + + + + + + + + + +
日期版本作者更新内容
2024-05-091.0.0lxowalle + + 初版文档 + +
+
+
+ +
+
+ +

阅读本文前,确保已经知晓如何开发MaixCAM,详情请阅读快速开始

+

简介

+

在视觉应用中,在巡迹小车、巡线机器人等应用中经常需要寻找线条的功能。本文将介绍:

+
    +
  • 如何使用MaixPy来实现巡线功能

    +
  • +
  • 如何使用MaixCam的默认应用程序巡线

    +
  • +
+

如何使用MaixPy来寻找直线

+

MaixPy的 maix.image.Image中提供了get_regression方法来寻找直线

+

代码示例

+

一个简单的示例,实现寻找并画出直线

+ +
from maix import camera, display, image
+
+cam = camera.Camera(320, 240)
+disp = display.Display()
+
+# thresholds = [[0, 80, 40, 80, 10, 80]]      # red
+thresholds = [[0, 80, -120, -10, 0, 30]]    # green
+# thresholds = [[0, 80, 30, 100, -120, -60]]  # blue
+
+while 1:
+    img = cam.read()
+
+    lines = img.get_regression(thresholds, area_threshold = 100)
+    for a in lines:
+        img.draw_line(a.x1(), a.y1(), a.x2(), a.y2(), image.COLOR_GREEN, 2)
+        theta = a.theta()
+        rho = a.rho()
+        if theta > 90:
+            theta = 270 - theta
+        else:
+            theta = 90 - theta
+        img.draw_string(0, 0, "theta: " + str(theta) + ", rho: " + str(rho), image.COLOR_BLUE)
+
+    disp.show(img)
+
+

步骤:

+
    +
  1. 导入image、camera、display模块

    + +
    from maix import image, camera, display
    +
    +
  2. +
  3. 初始化摄像头和显示

    + +
    cam = camera.Camera(320, 240)	# 初始化摄像头,输出分辨率320x240 RGB格式
    +disp = display.Display()
    +
    +
  4. +
  5. 从摄像头获取图片并显示

    + +
    while 1:
    +    img = cam.read()
    +    disp.show(img)
    +
    +
  6. +
  7. 调用get_regression方法寻找摄像头图片中的直线,并画到屏幕上

    + +
    lines = img.get_regression(thresholds, area_threshold = 100)
    +for a in lines:
    +   img.draw_line(a.x1(), a.y1(), a.x2(), a.y2(), image.COLOR_GREEN, 2)
    +   theta = a.theta()
    +   rho = a.rho()
    +   if theta > 90:
    +      theta = 270 - theta
    +   else:
    +      theta = 90 - theta
    +   img.draw_string(0, 0, "theta: " + str(theta) + ", rho: " + str(rho), image.COLOR_BLUE)
    +
    +
      +
    • img是通过cam.read()读取到的摄像头图像,当初始化的方式为cam = camera.Camera(320, 240)时,img对象是一张分辨率为320x240的RGB图。
    • +
    • img.get_regression用来寻找直线, thresholds 是一个颜色阈值列表,每个元素是一个颜色阈值,同时找到多个阈值就传入多个,每个颜色阈值的格式为 [L_MIN, L_MAX, A_MIN, A_MAX, B_MIN, B_MAX],这里的 LABLAB颜色空间的三个通道,L 通道是亮度,A 通道是红绿通道,B 通道是蓝黄通道。pixels_threshold是一个像素面积的阈值,用来过滤一些不需要直线。
    • +
    • for a in lines用来遍历返回的Line对象, 其中a就是当前的Line对象。通常get_regression函数只会返回一个Line对象,如果需要寻找多条直线,可以尝试使用find_line方法
    • +
    • 使用img.draw_line来画出找到的线条,a.x1(), a.y1(), a.x2(), a.y2()分别代表直线两端的坐标
    • +
    • 使用img.draw_string在左上角显示直线与x轴的夹角, a.theta()是直线与y轴的夹角, 这里为了方便理解转换成直线与x轴的夹角thetaa.rho()是原点与直线的垂线的长度.
    • +
    +
  8. +
  9. 通过maixvision运行代码,就可以寻线啦,看看效果吧

    +

    image-20240509110204007

    +
  10. +
+

常用参数说明

+

列举常用参数说明,如果没有找到可以实现应用的参数,则需要考虑是否使用其他算法实现,或者基于目前算法的结果扩展所需的功能

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
参数说明示例
thresholds基于lab颜色空间的阈值,threshold=[[l_min, l_max, a_min, a_max, b_min, b_max]],分别表示:
亮度范围为[l_min, l_max]|
绿色到红色的分量范围为[l_min, l_max]
蓝色到黄色的分量范围为[b_min, b_max]
可同时设置多个阈值
设置两个阈值来检测红色和绿色
img.find_blobs(threshold=[[0, 80, 40, 80, 10, 80], [0, 80, -120, -10, 0, 30]])
红色阈值为[0, 80, 40, 80, 10, 80]
绿色阈值为[0, 80, -120, -10, 0, 30]
invert使能阈值反转,使能后传入阈值与实际阈值相反,默认为False使能阈值反转
img.find_blobs(invert=True)
roi设置算法计算的矩形区域,roi=[x, y, w, h],x,y表示矩形区域左上角坐标,w,h表示矩形区域的宽度和高度,默认为整张图片计算坐标为(50,50),宽和高为100的区域
img.find_blobs(roi=[50, 50, 100, 100])
area_threshold过滤像素面积小于area_threshold的直线,单位为像素点,默认为10。该参数可用于过滤一些无用的小直线过滤面积小于1000的直线
img.find_blobs(area_threshold=1000)
pixels_threshold过滤有效像素点小于pixels_threshold的直线,默认为10。该参数可用于过滤一些无用的小直线过滤有效像素点小于1000的直线
img.find_blobs(pixels_threshold=1000)
+

本文介绍常用方法,更多 API 请看 API 文档的 image 部分。

+

如何使用MaixCam的默认应用程序寻找直线

+

为了快速验证寻找直线的功能,可以先使用MaixCam提供的line_tracking应用程序来体验寻找直线的效果。

+

使用方法

+
    +
  1. 选择并打开Line tracking应用
  2. +
  3. 点击屏幕中需要识别的直线,左侧会显示该直线的颜色
  4. +
  5. 点击左侧(界面中L A B下方的颜色)需要检测的颜色
  6. +
  7. 此时就可以识别到对应的直线了,同时串口也会输出直线的坐标和角度信息。
  8. +
+

演示

+

+

进阶操作

+

手动设置LAB阈值寻找直线

+

APP提供手动设置LAB阈值来精确的寻找直线

+

操作方法:

+
    +
  1. 点击左下角选项图标,进入配置模式

    +
  2. +
  3. 摄像头对准需要寻找的物体点击屏幕上的目标直线,此时界面中L A B下方会显示该物体对应颜色的矩形框,并显示该物体颜色的LAB值

    +
  4. +
  5. 点击下方选项L Min,L Max,A Min,A Max,B Min,B Max,点击后右侧会出现滑动条来设置该选项值。这些值分别对应LAB颜色格式的L通道、A通道和B通道的最小值和最大值

    +
  6. +
  7. 参考步骤2计算的物体颜色的LAB值,将L Min,L Max,A Min,A Max,B Min,B Max调整到合适的值,即可识别到对应的直线。

    +

    例如LAB=(20, 50, 80),由于L=20,为了适配一定范围让L Min=10L Max=30;同理,由于A=50,让A Min=40A Max=60; 由于B=80,让B Min=70B Max=90

    +
  8. +
+

通过串口协议获取检测数据

+

寻找直线应用支持通过串口(默认波特率为115200)上报检测到的直线信息。

+

由于上报信息只有一条,这里直接用示例来说明上报信息的内容。

+

例如上报信息为:

+ +
AA CA AC BB 0E 00 00 00 E1 09 FC 01 01 00 E9 01 6F 01 57 00 C1 C6
+
+
    +
  • AA CA AC BB:协议头部,内容固定

    +
  • +
  • 0E 00 00 00:数据长度,除了协议头部和数据长度外的总长度,这里表示长度为14

    +
  • +
  • E1:标志位,用来标识串口消息标志

    +
  • +
  • 09:命令类型,对于寻找直线APP应用该值固定为0x09

    +
  • +
  • FC 01 01 00 E9 01 6F 01 57 00:直线的两端坐标和角度信息,每个值用小端格式的2字节表示。FC 0101 00表示第一个端点坐标为(508, 1),E9 016F 01表示第二个端点坐标为(489, 367),57 00表示直线与x轴的角度为87度

    +
  • +
  • C1 C6:CRC 校验值,用以校验帧数据在传输过程中是否出错

    +
  • +
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/vision/maixhub_train.html b/maixpy/doc/zh/vision/maixhub_train.html new file mode 100644 index 00000000..ebf002dd --- /dev/null +++ b/maixpy/doc/zh/vision/maixhub_train.html @@ -0,0 +1,394 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 使用 MaixHub 在线训练 AI 模型给 MaixPy 使用 - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

使用 MaixHub 在线训练 AI 模型给 MaixPy 使用

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ + +
+ + 更新历史 +
+ + + + + + + + + + + + + + + + + + + +
日期版本作者更新内容
2024-04-031.0.0neucrack + + 初版文档 + +
+
+
+ +
+
+ +

简介

+

MaixHub 提供了在线训练 AI 模型的功能,可以直接在浏览器中训练模型,不需要购买昂贵的机器,不需要搭建复杂的开发环境,也不需要写代码,非常适合入门,也适合懒得翻代码的老手。

+

使用 MaixHub 训练模型的基本步骤

+

确认要识别的数据类型和模型类型

+

要训练一个 AI 模型,需要先确定是什么数据和模型,目前 MaixHub(2024.4)提供了图像数据的物体分类模型物体检测模型,都是图像识别模型, 物体分类模型物体检测模型 更简单,因为物体检测需要标注物体在图中的位置,会比较麻烦,物体分类则只需要给出图像中是什么,不需要坐标,所以更简单, 如果是初学者建议先从物体分类开始。

+

采集数据

+

如前面的 AI 基础所说,要训练模型,必须准备训练用的数据集让 AI 学习,对于图像训练,我们需要创建一个数据集,并且上传图片到数据集。

+

保证设备已经连接网络(WiFi)。
+打开设备上的 MaixHub 应用选择 采集数据 来拍照并一键上传到 MaixHub。需要先在 MaixHub 创建数据集,然后点击 设备 上传数据,会出现一个 二维码,设备扫描二维码来与MaixHub 建立连接。

+

注意要分清训练集和验证集的区别,要想实机运行的效果和训练效果相当,验证集的数据一定要和实机运行拍摄的图像质量一样,训练集也建议用设备拍摄的,如果要用网上的图片,一定只能用在训练集,不要用在验证集,因为数据量小,数据集与实机运行越接近越好。

+

标注数据

+

对于分类模型,在上传的时候就顺便已经标注好了,即上传时选择好了图片属于那个分类。

+

对于目标检测模型,上传完成后需要进行手动标注,即在每一张图中框出要被识别物体的坐标大小和分类。
+这个标注过程你也可以选择自己在自己的电脑中离线用比如 labelimg 这样的软件标注完毕后使用数据集中的导入功能导入到 MaixHub。
+标注时善用快捷键标注起来会更快,后面MaixHub 也会增加更多辅助标注和自动标注工具(目前在上传视频处有自动标注工具也可以尝试使用)。

+

训练模型

+

选择训练参数训练,选择对应的设备平台,选择 maixcam,等待排队训练,可以实时看到训练进度,等待完成即可。

+

部署模型

+

训练完成后,可以设备的 MaixHub 应用中选择 部署 功能,扫码进行部署。
+设备开会自动下载模型并且运行起来,模型会被存在本地,后面也能选择再次运行。

+

如果你觉得识别效果很不错,可以一键分享到模型库让更多人使用。

+

使用方法

+

请到 MaixHub 注册账号,然后登录,主页有视频教程,学习即可。

+

注意教程如果是使用了 M2dock 这个开发板,和 MaixCAM也是类似的,只是设备(板子)上使用的 MaixHub 应用可能稍微有点区别,大体上是相同的,请注意举一反三。

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/vision/object_track.html b/maixpy/doc/zh/vision/object_track.html new file mode 100644 index 00000000..bda71742 --- /dev/null +++ b/maixpy/doc/zh/vision/object_track.html @@ -0,0 +1,338 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/vision/qrcode.html b/maixpy/doc/zh/vision/qrcode.html new file mode 100644 index 00000000..6d7c6bc0 --- /dev/null +++ b/maixpy/doc/zh/vision/qrcode.html @@ -0,0 +1,456 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy 二维码识别 - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy 二维码识别

+ +
+
+
    + +
+
+
+
+ + + + +
+
+ + + +
+
+
+
+ + +
+
+ + +
+ + 更新历史 +
+ + + + + + + + + + + + + + + + + + + +
日期版本作者更新内容
2024-04-031.0.0lxowalle + + 初版文档 + +
+
+
+ +
+
+ +

阅读本文前,确保已经知晓如何开发MaixCAM,详情请阅读快速开始

+

简介

+

本文介绍如何使用MaixPy来识别二维码

+

使用 MaixPy 识别二维码

+

MaixPy的 maix.image.Image中提供了find_qrcodes方法,用来识别二维码。

+

如何识别二维码

+

一个简单的示例,实现识别二维码并画框

+ +
from maix import image, camera, display
+
+cam = camera.Camera(320, 240)
+disp = display.Display()
+
+while 1:
+    img = cam.read()
+    qrcodes = img.find_qrcodes()
+    for qr in qrcodes:
+        corners = qr.corners()
+        for i in range(4):
+            img.draw_line(corners[i][0], corners[i][1], corners[(i + 1) % 4][0], corners[(i + 1) % 4][1], image.COLOR_RED)
+        img.draw_string(qr.x(), qr.y() - 15, qr.payload(), image.COLOR_RED)
+    disp.show(img)
+
+

步骤:

+
    +
  1. 导入image、camera、display模块

    + +
    from maix import image, camera, display
    +
    +
  2. +
  3. 初始化摄像头和显示

    + +
    cam = camera.Camera(320, 240) # 初始化摄像头,输出分辨率320x240 RGB格式
    +disp = display.Display()
    +
    +
  4. +
  5. 从摄像头获取图片并显示

    + +
    while 1:
    +    img = cam.read()
    +    disp.show(img)
    +
    +
  6. +
  7. 调用find_qrcodes方法识别摄像头中的二维码

    + +
    qrcodes = img.find_qrcodes()
    +
    +
      +
    • img是通过cam.read()读取到的摄像头图像,当初始化的方式为cam = camera.Camera(320, 240)时,img对象是一张分辨率为320x240的RGB图。
    • +
    • img.find_qrcodes用来寻找二维码,并将查询结果保存到qrocdes,以供后续处理
    • +
    +
  8. +
  9. 处理识别二维码的结果并显示到屏幕上

    + +
    for qr in qrcodes:
    +    corners = qr.corners()
    +    for i in range(4):
    +        img.draw_line(corners[i][0], corners[i][1], corners[(i + 1) % 4][0], corners[(i + 1) % 4][1], image.COLOR_RED)
    +    img.draw_string(qr.x(), qr.y() - 15, qr.payload(), image.COLOR_RED)
    +
    +
      +
    • qrcodes是通过img.find_qrcodes()查询二维码的结果,如果找不到二维码则qrcodes内部为空
    • +
    • qr.corners()用来获取已扫描到的二维码的四个顶点坐标,img.draw_line()利用这四个顶点坐标画出二维码的形状
    • +
    • img.draw_string用来显示二维码的内容和位置等信息,其中qr.x()qr.y()用来获取二维码左上角坐标x和坐标y,qr.payload()用来获取二维码的内容
    • +
    +
  10. +
+

常用参数说明

+

列举常用参数说明,如果没有找到可以实现应用的参数,则需要考虑是否使用其他算法实现,或者基于目前算法的结果扩展所需的功能

+ + + + + + + + + + + + + + + +
参数说明示例
roi设置算法计算的矩形区域,roi=[x, y, w, h],x,y表示矩形区域左上角坐标,w,h表示矩形区域的宽度和高度,默认为整张图片计算坐标为(50,50),宽和高为100的区域
img.find_qrcodes(roi=[50, 50, 100, 100])
+

本文介绍常用方法,更多 API 请看 API 文档的 image 部分。

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/vision/self_learn_classifier.html b/maixpy/doc/zh/vision/self_learn_classifier.html new file mode 100644 index 00000000..dfca46b3 --- /dev/null +++ b/maixpy/doc/zh/vision/self_learn_classifier.html @@ -0,0 +1,378 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy 自学习分类器 - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy 自学习分类器

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

MaixPy 自学习分类器介绍

+

一般情况下我们要识别新的类别,需要在电脑端重新采集数据集并训练,步骤很麻烦,难度较高,这里提供一种不需要电脑端训练,而是直接在设备端就能秒学习新的物体,适合场景不太复杂的使用场景。

+

比如眼前有饮料瓶和手机,使用设备分别拍一张它们的照片作为两个分类的依据,然后再采集几张他们各个角度的照片,提取它们的特征保存,然后识别时根据图像的特征值分别和保存的特征值进行对比,和保存的哪个更相近就认为是对应的分类。

+

MaixPy 中使用自学习分类器

+

步骤:

+
    +
  • 采集 n 张分类图。
  • +
  • 采集 n*m 张图,每个分类采集 m 张,顺序无所谓。
  • +
  • 启动学习。
  • +
  • 识别图像输出结果。
  • +
+

简洁版本代码,完整版本请看例程里面的完整代码。

+ +
from maix import nn, image
+
+classifier = nn.SelfLearnClassifier(model="/root/models/mobilenetv2.mud", feature_layer=None)
+
+img1 = image.load("/root/1.jpg")
+img2 = image.load("/root/2.jpg")
+img3 = image.load("/root/3.jpg")
+sample_1 = image.load("/root/sample_1.jpg")
+sample_2 = image.load("/root/sample_2.jpg")
+sample_3 = image.load("/root/sample_3.jpg")
+sample_4 = image.load("/root/sample_4.jpg")
+sample_5 = image.load("/root/sample_5.jpg")
+sample_6 = image.load("/root/sample_6.jpg")
+
+
+classifier.add_class(img1)
+classifier.add_class(img2)
+classifier.add_class(img3)
+classifier.add_sample(sample_1)
+classifier.add_sample(sample_2)
+classifier.add_sample(sample_3)
+classifier.add_sample(sample_4)
+classifier.add_sample(sample_5)
+classifier.add_sample(sample_6)
+
+classifier.learn()
+
+img = image.load("/root/test.jpg")
+max_idx, max_score = classifier.classify(img)
+print(maix_idx, max_score)
+
+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/vision/self_learn_detector.html b/maixpy/doc/zh/vision/self_learn_detector.html new file mode 100644 index 00000000..a6613114 --- /dev/null +++ b/maixpy/doc/zh/vision/self_learn_detector.html @@ -0,0 +1,339 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy 自学习检测器 - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy 自学习检测器

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

MaixPy 自学习检测器

+

和自学习分类器类似,不需要训练,直接拍摄几张要检测的物体照片即可实现检测,在简单检测场景下十分好用。
+和自学习分类器不同的是因为是检测器,会有物体的坐标和大小。

+

MaixPy 中使用自学习检测器

+

TODO:

+ + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/doc/zh/vision/yolov5.html b/maixpy/doc/zh/vision/yolov5.html new file mode 100644 index 00000000..198bf493 --- /dev/null +++ b/maixpy/doc/zh/vision/yolov5.html @@ -0,0 +1,362 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaixPy 使用 YOLOv5 模型进行目标检测 - MaixPy + + + + + + + + + + +
+ +
+ +
+
+
+
+ +

MaixPy 使用 YOLOv5 模型进行目标检测

+ +
+
+
    + +
+
+
+
+ + +
+
+ + + +
+
+
+
+ + +
+
+ +
+
+ +

目标检测概念

+

目标检测是指在图像或视频中检测出目标的位置和类别,比如在一张图中检测出苹果、飞机等物体,并且标出物体的位置。

+

和分类不同的是多了一个位置信息,所以目标检测的结果一般是一个矩形框,框出物体的位置。

+

MaixPy 中使用目标检测

+

MaixPy 默认提供了 YOLOv5 模型,可以直接使用:

+ +
from maix import camera, display, image, nn, app
+
+detector = nn.YOLOv5(model="/root/models/yolov5s.mud")
+
+cam = camera.Camera(detector.input_width(), detector.input_height(), detector.input_format())
+dis = display.Display()
+
+while not app.need_exit():
+    img = cam.read()
+    objs = detector.detect(img, conf_th = 0.5, iou_th = 0.45)
+    for obj in objs:
+        img.draw_rect(obj.x, obj.y, obj.w, obj.h, color = image.COLOR_RED)
+        msg = f'{detector.labels[obj.class_id]}: {obj.score:.2f}'
+        img.draw_string(obj.x, obj.y, msg, color = image.COLOR_RED)
+    dis.show(img)
+
+

效果视频:

+
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/en/config.json b/maixpy/en/config.json new file mode 100644 index 00000000..04d94f89 --- /dev/null +++ b/maixpy/en/config.json @@ -0,0 +1,5 @@ +{ + "import": "config_en", + "class": "md_page", + "name": "MaixPy Pages" +} diff --git a/maixpy/en/index.html b/maixpy/en/index.html new file mode 100644 index 00000000..3053ae32 --- /dev/null +++ b/maixpy/en/index.html @@ -0,0 +1,766 @@ + + + + + + + + + + + + + + + + + + MaixPy - MaixPy + + + + + + + + + + +
+
+
+ +
+ +
+ +
+
+ MaixPy Banner +
+

MaixPy (v4)

+

Easily create AI projects with Python on edge device

+
+ +
+

GitHub Repo starsApache 2.0PyPIPyPI - DownloadsGitHub repo size Build MaixCAMTrigger wiki

+
+
+

English | 中文

+
+
+
+

MaixPy-v1 (Maix-I K210) refer to MaixPy-v1 doc。 MaixPy v4 not support Maix-I Maix-II, please upgrade to MaixCAM 硬件平台。
+Give a star ⭐️ to MaixPy source code on GitHub to let us known you love it, and encourage us to add more features.

+
+
+
+
+

Easy-to-use API, AI vision classify in 10 lines

+ +
from maix import camera, display, image, nn
+
+classifier = nn.Classifier(model="/root/models/mobilenetv2.mud")
+cam = camera.Camera(classifier.input_width(), classifier.input_height(), classifier.input_format())
+dis = display.Display()
+
+while 1:
+    img = cam.read()
+    res = classifier.classify(img)
+    max_idx, max_prob = res[0]
+    msg = f"{max_prob:5.2f}: {classifier.labels[max_idx]}"
+    img.draw_string(10, 10, msg, image.COLOR_RED)
+    dis.show(img)
+
+
+ +
+ +
+

Hardware peripheral control:

+
+
+

Serial send and receive:

+ +
from maix import uart
+
+dvices = uart.list_devices()
+
+serial = uart.UART(devices[0], 115200)
+serial.write_str("hello world")
+print("received:", serial.read(timeout = 2000))
+
+
+
+

I2C send and receive:

+ +
from maix import i2c
+
+devices = i2c.list_devices()
+dev1 = i2c.I2C(devices[0], freq=100000)
+slaves = dev1.scan()
+print("find slaves:", slaves)
+dev1.writeto(0x12, b'hello')
+print("received:", dev1.readfrom(0x12, 5))
+
+
+
+
+ + +

MaixVision Workstation

+

Simplify the development environment, make development easier and faster:

+ +

Online AI training platform MaixHub

+

One-click training AI model and deployment to MaixCAM even you have no AI knowledge and expensive training equipment.

+ + +

Powerful MaixCAM hardware platform

+

MaixCAM

+
+
    +
  • CPU: 1GHz RISC-V(Linux)/ARM A53 + 700MHz RISC-V(RTOS) + 25~300MHz 8051(Low Power)
  • +
+
+

Big core can choose one of RISC-V and ARM A53.

+
+
    +
  • NPU: 1Tops@INT8 NPU, support BF16, support YOLOv5 YOLOv8 etc.
  • +
  • Memory: 256MB DDR3.
  • +
  • Connecting: USB2.0/WiFi6/BLE5.4.
  • +
  • Peripheral: IIC/PWM/SPI/UART/WDT/ADC
  • +
  • MultiMedia: 4M Camera, 2.3" 552x368 Touchscreen, H.264/H.265/MJPEG codec.
  • +
  • Price: 169/249 RMB (out of stock, please consult the store)
  • +
+

More detalils: MaixCAM

+
+

Attention, only MaixCAM is supported, other boards with the same chip are not supported, including Sipeed's boards with the same chip, please be careful not to waste time and money by buying the wrong one.

+
+ +
+

Features

+

Below are some of the features, for more please see the documentation, app store or community sharing MaixHub.

+
+
+
+ +

Python + MaixVision IDE

+

Simple API, with hardware acceleration, including many libraries, such as numpy, opencv, MaixVision IDE programming

+
+
+
+
+
+
+ +

C++ Version

+

MaixCDK C++ version SDK,API the same as MaixPy's

+
+
+
+
+
+
+ +

As a serial module

+

Other MCU control by serial command

+
+
+
+
+
+
+ +

App Store

+

Share your APP to community, and one-click install APPs.

+
+
+
+
+
+
+ +

MaixPy-v1 compatible package

+

Quickly migrate from MaixPy-v1(K210) to MaixPy-v4

+
+
+
+
+
+
+ +

AI Classifier

+

Classify object type

+
+
+
+
+
+
+ +

AI Object Detection

+

Classify object type and position

+
+
+
+
+
+
+ +

AI Face Recognition

+

Recognize different face

+
+
+
+
+
+
+ +

AI Body Keypoint Detection

+

Pose recognition, body sense game

+
+
+
+
+
+
+ +

AI Self Learning Classifier

+

No need to train on PC, learning any object on device in a flash

+
+
+
+
+
+
+ +

AI Self Learning Detector

+

No need to train on PC, learning any object on device in a flash

+
+
+
+
+
+
+ +

AI Object Tracking

+

Trajectory tracking, traffic statistics

+
+
+
+
+
+
+ +

AI Monitor, Stream

+

Security monitor, can stream, even can live to platforms like Bilibili.com

+
+
+
+
+
+
+ +

Find Blobs

+

Find color blobs

+
+
+
+
+
+
+ +

Line Tracking

+

Car line tracking, logistics handling

+
+
+
+
+
+
+ +

QR Code and AprilTag

+

Recognize QR code and AprilTag

+
+
+
+
+
+
+ +

OCR

+

Recognize characters in the image, digitize old items

+
+
+
+
+
+
+ +

Speech Recognition

+

Real-time continuous speech recognition

+
+
+
+
+
+
+ +

Desktop Monitor

+

Monitor PC information, such as CPU, memory, network, etc.

+
+
+
+
+
+
+ +

Weather Station

+

Monitor weather information, such as temperature, humidity, etc.

+
+
+
+
+
+
+ +

Thermal Camera

+

Optional camera, temprature image capture/measure

+
+
+
+
+
+
+ +

HDMI Capture Video

+

Optional, Capture HDMI image, as server monitor(KVM), external AI, streaming device etc.

+
+
+
+
+
+
+

Who are using MaixPy?

+
    +
  • AI Algorithm Engineer who want to deploy your AI model to embedded devices.
  • +
+
+

MaixPy provide easy-to-use API to access NPU, and docs to help you develop your AI model.

+
+
    +
  • STEM teacher who want to teach AI and embeded to students.
  • +
+
+

MaixPy provide easy-to-use API, PC tools, online AI train service ... Let you focus on teaching AI, not the hardware and complicated software usage.

+
+
    +
  • Maker who want to make some cool projects but don't want to learn complicated hardware and software.
  • +
+
+

MaixPy provide Python API, so all you need is learn basic Python syntax, and MaixPy's API is so easy to use, you can make your project even in a few minutes.

+
+
    +
  • Engineer who want to make some projects but want a prototype as soon as possible.
  • +
+
+

MaixPy is easy to build projects, and provide corresponding C++ SDK, so you can directly use MaixPy to deploy or transfer Python code to C++ in a few minutes.

+
+
    +
  • Students who want to learn AI, embedded development.
  • +
+
+

We provide many docs and tutorials, and lot of open source code, to help you find learning route, and grow up step by step. From simple Python programming to Vision, AI, Audio, Linux, RTOS etc.

+
+
    +
  • Enterprise who want to develop AI vision products but have no time or engineers to develop complicated embedded system.
  • +
+
+

Use MaixPy even graphic programming to develop your products with no more employees and time. For example, add a AI QA system to your production line, or add a AI security monitor to your office as your demand.

+
+
    +
  • Contestants who want to win the competition.
  • +
+
+

MaixPy integrate many functions and easy to use, fasten your work to win the competition in limited time. There are already many contestants win the competition with MaixPy.

+
+

Performance comparison

+

K210 and v831 are outdated, they have many limitations in memory, performance, NPU operators missing etc.

+No matter you are using them or new comer, it's recommended to upgrade to MaixCAM and MaixPy v4.

+

Here's the comparison between them:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureMaix-I K210Maix-II v831MaixCAM
CPU400MHz RISC-V x2800MHz ARM71GHz RISC-V(Linux)
700MHz RISC-V(RTOS)
25~300MHz 8051(Low Power)
Memory6MB SRAM64MB DDR2256MB DDR3
NPU0.25Tops@INT8
official says 1T but...
0.25Tops@INT81Tops@INT8
Encoder1080p@30fps2K@30fps
Screen2.4" 320x2401.3" 240x2402.28" 552x368 / 5" 1280x720 / 7" 1280x800 / 10“ 1280x800
TouchScreen2.3" 552x368
Camera30W200W500W
WiFi2.4G2.4GWiFi6 2.4G/5G
USBUSB2.0USB2.0
Eth100M(Optional)100M(Optional)
SD InterfaceSPISDIOSDIO
BLEBLE5.4
OSRTOSTina LinuxLinux + RTOS
LanguageC / C++ / MicroPythonC / C++ / Python3C / C++ / Python3
SoftwareMaixPyMaixPy3MaixCDK + MaixPy v4 + opencv + numpy + ...
PC softwareMaixPy IDEMaixPy3 IDEMaixVision Workstation
Docs⭐️⭐️⭐️⭐️⭐️⭐️⭐️🌟🌟🌟🌟🌟
Online AI train⭐️⭐️⭐️⭐️⭐️⭐️⭐️🌟🌟🌟🌟🌟
Official APPs⭐️⭐️⭐️⭐️⭐️🌟🌟🌟🌟🌟
AI classify(224x224)MobileNetv1 50fps
MobileNetv2 ✖
Resnet ✖
MobileNet ✖
Resnet18 20fps
Resnet50 ✖
MobileNetv2 130fps
Resnet18 62fps
Resnet50 28fps
AI detectYOLOv2(224x224) 15fpsYOLOv2(224x224) 15fpsYOLOv5s(224x224) 100fps
YOLOv5s(320x256) 70fps
YOLOv5s(640x640) 15fps
YOLOv8n(640x640) 23fps
Ease of use⭐️⭐️⭐️⭐️⭐️⭐️⭐️🌟🌟🌟🌟🌟
+

Maix ecosystem

+

+

What difference between MaixPy v1, MaixPy3 and MaixPy v4?

+
    +
  • MaixPy v1 use MicroPython programming language, only support Sipeed Maix-I K210 series hardware, have limited third-party packages.
  • +
  • MaixPy3 is designed for Sipeed Maix-II-Dock v831, not a long-term support version.
  • +
  • MaixPy v4 use Python programming language, so there's much package we can use directly. MaixPy v4 support new hardware platforms of Sipeed, it's a long-term support version, the future's hardware platforms will support this version. MaixPy v4 have a MaixPy-v1 compatible API, so you can quickly migrate your MaixPy v1 project to MaixPy v4.
  • +
+

(MaixPy v4 Will not support Maix-I K210 series, if you are using Maix-I K210 series, it's recommended to upgrade hardware platform to use this to get more features and better performance.)

+

License

+

All files in this repository are under the terms of the Apache License 2.0 Sipeed Ltd. except the third-party libraries or have their own license.

+

Community

+ + + +
+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/en/no_translate.html b/maixpy/en/no_translate.html new file mode 100644 index 00000000..c10df971 --- /dev/null +++ b/maixpy/en/no_translate.html @@ -0,0 +1,175 @@ + + + + + + + + + + + + + + + + + + no translation - MaixPy + + + + + + + + + + +
+
+
+ +
+
This page not translated yet
+
+ Please visit + +
+
+ +
+ + +
+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/favicon.ico b/maixpy/favicon.ico new file mode 100644 index 00000000..3d8e88b1 Binary files /dev/null and b/maixpy/favicon.ico differ diff --git a/maixpy/index.html b/maixpy/index.html new file mode 100644 index 00000000..4dfdd3e4 --- /dev/null +++ b/maixpy/index.html @@ -0,0 +1,764 @@ + + + + + + + + + + + + + + + + + + MaixPy - MaixPy + + + + + + + + + + +
+
+
+ +
+ +
+ +
+
+ MaixPy Banner +
+

MaixPy (v4)

+

快速落地 AI 视觉、听觉应用

+
+ +
+

GitHub Repo starsApache 2.0PyPIPyPI - DownloadsGitHub repo size Build MaixCAMTrigger wiki

+
+
+

English | 中文

+
+
+
+

MaixPy-v1 (Maix-I K210) 用户请查看 MaixPy-v1 文档。 MaixPy v4 不支持 Maix-I Maix-II 系列硬件,请更新到 MaixCAM 硬件平台。
+喜欢 MaixPy 请到 GitHub 给 MaixPy 源码 点个 Star ⭐️ 以鼓励我们开发更多功能。

+
+
+
+
+

简易的 API 设计, 10 行代码进行 AI 图像识别:

+ +
from maix import camera, display, image, nn
+
+classifier = nn.Classifier(model="/root/models/mobilenetv2.mud")
+cam = camera.Camera(classifier.input_width(), classifier.input_height(), classifier.input_format())
+dis = display.Display()
+
+while 1:
+    img = cam.read()
+    res = classifier.classify(img)
+    max_idx, max_prob = res[0]
+    msg = f"{max_prob:5.2f}: {classifier.labels[max_idx]}"
+    img.draw_string(10, 10, msg, image.COLOR_RED)
+    dis.show(img)
+
+
+ +
+ +
+

硬件外设控制,不在话下:

+
+
+

串口收发:

+ +
from maix import uart
+
+devices = uart.list_devices()
+
+serial = uart.UART(devices[0], 115200)
+serial.write_str("hello world")
+print("received:", serial.read(timeout = 2000))
+
+
+
+

I2C 收发:

+ +
from maix import i2c
+
+devices = i2c.list_devices()
+dev1 = i2c.I2C(devices[0], freq=100000)
+slaves = dev1.scan()
+print("find slaves:", slaves)
+dev1.writeto(0x12, b'hello')
+print("received:", dev1.readfrom(0x12, 5))
+
+
+
+
+ + +

便捷的 MaixVision 工作站

+

简化开发环境,让开发更简单快速:

+ +

在线 AI 训练平台 MaixHub

+

无需 AI 基础和昂贵的训练设备,一键训练模型,一键部署到 MaixCAM。

+ + +

性能强劲 MaixCAM 硬件平台

+

MaixCAM

+
+
    +
  • CPU: 1GHz RISC-V(Linux)/ARM A53 + 700MHz RISC-V(RTOS) + 25~300MHz 8051(Low Power)
  • +
+
+

大核 RISC-V 和 ARM A53 二选一运行,MaixPy 使用 RISC-V 核心。

+
+
    +
  • NPU: 1Tops@INT8 NPU, 支持 BF16,支持 YOLOv5 YOLOv8 等。
  • +
  • 内存: 256MB DDR3。
  • +
  • 通信: USB2.0/WiFi6/BLE5.4。
  • +
  • 外设: IIC/PWM/SPI/UART/WDT/GPIO/ADC
  • +
  • 多媒体:4M 摄像头,2.3" 552x368 高清电容触摸屏,H.264/H.265/MJPEG 2K 硬件编解码。
  • +
  • 价格: 169 元 / 249 元。 (缺货时咨询店家)
  • +
+

更多细节看: MaixCAM

+
+

注意,目前只支持 MaixCAM 开发板,其它同型号芯片的开发板均不支持,包括 Sipeed 的同型号芯片开发板,请注意不要买错造成不必要的时间和金钱浪费。

+
+ +
+

特性介绍

+

以下为部分功能简介,更多请看文档应用商店 或者社区分享MaixHub

+
+
+
+ +

Python + MaixVision IDE

+

简单的API,带有硬件加速,包含许多库,如numpy,opencv,MaixVision IDE 编程

+
+
+
+
+
+
+ +

C++版本

+

MaixCDK C++版本的SDK,与MaixPy的API相同

+
+
+
+
+
+
+ +

作为串口模块

+

其它 MCU 通过串口命令控制

+
+
+
+
+
+
+ +

APP商店

+

将您的APP分享给社区,并一键安装APPs

+
+
+
+
+
+
+ +

提供 MaixPy-v1 兼容 API

+

快速从MaixPy-v1(K210)迁移到MaixPy-v4

+
+
+
+
+
+
+ +

AI 分类

+

识别物体类别

+
+
+
+
+
+
+ +

AI 对象检测

+

识别物体类别和坐标

+
+
+
+
+
+
+ +

AI 人脸识别

+

识别不同人脸特征

+
+
+
+
+
+
+ +

AI 人体关键点检测

+

姿态识别、体感游戏

+
+
+
+
+
+
+ +

AI 自学习分类器

+

无需在PC上训练,在设备上瞬间学习任意物体

+
+
+
+
+
+
+ +

AI 自学习检测器

+

无需在PC上训练,在设备上瞬间学习任意物体

+
+
+
+
+
+
+ +

AI 物体轨迹跟踪

+

轨迹追踪,流量统计

+
+
+
+
+
+
+ +

AI 监控,串流

+

安防监控,可串流,甚至可以向直播平台 比如 Bilibili.com 直播

+
+
+
+
+
+
+ +

查找颜色

+

查找颜色斑点

+
+
+
+
+
+
+ +

巡线

+

小车巡线,物流搬运

+
+
+
+
+
+
+ +

QR码和AprilTag

+

识别QR码和AprilTag

+
+
+
+
+
+
+ +

OCR

+

识别图片中的字符,旧物数字化

+
+
+
+
+
+
+ +

语音识别

+

实时连续语音识别

+
+
+
+
+
+
+ +

桌面监视器

+

监视PC信息,如CPU,内存,网络等。

+
+
+
+
+
+
+ +

天气站

+

监视天气信息,如温度,湿度等。

+
+
+
+
+
+
+ +

热红外摄像头

+

选配摄像头,温度图像获取/测量

+
+
+
+
+
+
+ +

HDMI 捕获视频

+

选配,通过 HDMI 捕获图像,作为服务器监控(KVM)、外挂 AI、推流设备等

+
+
+
+
+
+
+

谁在用 MaixPy?

+
    +
  • AI 算法工程师: 轻松将你的 AI 模型部署到嵌入式设备。
  • +
+
+

MaixPy 提供了易于使用的 API 来访问 NPU,以及帮助你开发 AI 模型的文档。

+
+
    +
  • STEM:想要教学生 AI 和嵌入式开发的老师。
  • +
+
+

MaixPy 提供了易于使用的 API,PC 工具,在线 AI 训练服务... 让你专注于教授 AI,而不是硬件和复杂的软件使用。

+
+
    +
  • 创客: 想要制作一些酷炫的项目,但不想学习复杂的硬件和软件。
  • +
+
+

MaixPy 提供了 Python API,所以你需要做的就是学习基础 Python 语法,而 MaixPy 的 API 非常易于使用,你甚至可以在几分钟内完成你的项目。

+
+
    +
  • 工程师: 想要做一些项目,但希望尽快有一个原型。
  • +
+
+

MaixPy 易于构建项目,并提供相应的 C++ SDK,所以你可以直接使用 MaixPy 来部署或在几分钟内将 Python 代码转换为 C++。

+
+
    +
  • 学生: 想要学习 AI,嵌入式开发。
  • +
+
+

我们提供了许多文档和教程,以及大量开源代码,帮助你找到学习路线,并逐步成长。从简单的 Python 编程到视觉,AI,音频,Linux,RTOS等。

+
+
    +
  • 企业: 想要开发 AI 视觉产品,但没有时间或工程师来开发复杂的嵌入式系统。
  • +
+
+

使用 MaixPy 甚至图形编程来开发你的产品,不需要更多的员工和时间。例如,向你的生产线添加一个 AI QA 系统,或者根据你的需求向你的办公室添加一个 AI 安全监控器。

+
+
    +
  • 竞赛者: 想要赢得比赛的比赛人们。
  • +
+
+

MaixPy 集成了许多功能,易于使用,加快你作品产出速度,以在有限的时间内赢得比赛,国内常见比赛都有很多同学使用 MaixPy 赢得比赛。

+
+

性能对比

+

相比上两代 Maix 系列产品有限的 NPU 算子支持和内存限制,MaixCAM 在保持超高性价比的同时,性能和体验有了很大的提升,强烈建议升级到最新的 MaixCAM 以及 MaixPy v4。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
特征Maix-I K210Maix-II v831MaixCAM
CPU400MHz RISC-V x2800MHz ARM71GHz RISC-V(Linux)
700MHz RISC-V(RTOS)
25~300MHz 8051(Low Power)
内存6MB SRAM64MB DDR2256MB DDR3
NPU0.25Tops@INT8
official says 1T but...
0.25Tops@INT81Tops@INT8
Encoder1080p@30fps2K@30fps
屏幕2.4" 320x2401.3" 240x2402.28" 552x368 / 5" 1280x720 / 7" 1280x800 / 10“ 1280x800
触摸屏2.3" 552x368
摄像头30W200W500W
WiFi2.4G2.4GWiFi6 2.4G/5G
USBUSB2.0USB2.0
以太网100M(选配)100M(选配)
SD 卡接口SPISDIOSDIO
BLEBLE5.4
操作系统RTOSTina LinuxLinux + RTOS
编程语言C / C++ / MicroPythonC / C++ / Python3C / C++ / Python3
SoftwareMaixPyMaixPy3MaixCDK + MaixPy v4 + opencv + numpy + ...
PC 软件MaixPy IDEMaixPy3 IDEMaixVision Workstation
文档⭐️⭐️⭐️⭐️⭐️⭐️⭐️🌟🌟🌟🌟🌟
在线 AI 训练⭐️⭐️⭐️⭐️⭐️⭐️⭐️🌟🌟🌟🌟🌟
官方应用⭐️⭐️⭐️⭐️⭐️🌟🌟🌟🌟🌟
AI 分类(224x224)MobileNetv1 50fps
MobileNetv2 ✖
Resnet ✖
MobileNet ✖
Resnet18 20fps
Resnet50 ✖
MobileNetv2 130fps
Resnet18 62fps
Resnet50 28fps
AI 检测YOLOv2(224x224) 15fpsYOLOv2(224x224) 15fpsYOLOv5s(224x224) 100fps
YOLOv5s(320x256) 70fps
YOLOv5s(640x640) 15fps
YOLOv8n(640x640) 23fps
易用性⭐️⭐️⭐️⭐️⭐️⭐️⭐️🌟🌟🌟🌟🌟
+

Maix 生态

+

+

MaixPy v1, MaixPy3 and MaixPy v4 有什么区别?

+
    +
  • MaixPy v1 使用 MicroPython 编程语言,仅支持 Sipeed Maix-I K210 系列硬件,有限的第三方包。
  • +
  • MaixPy3 专为 Sipeed Maix-II-Dock v831 设计,不是长期支持版本。
  • +
  • MaixPy v4 使用 Python 编程语言,因此我们可以直接使用许多包。MaixPy v4 支持 Sipeed 的新硬件平台,这是一个长期支持版本,未来的硬件平台将支持这个版本。MaixPy v4 有一个 MaixPy-v1 兼容的 API,所以你可以快速将你的 MaixPy v1 项目迁移到 MaixPy v4。
  • +
+

(MaixPy v4 不支持 Maix-I K210 系列,如果你正在使用 Maix-I K210 系列,建议升级硬件平台以使用此版本,以获得更多功能和更好的性能。)

+

开源协议

+

所有在本仓库中的文件都遵循 Apache License 2.0 Sipeed Ltd. 协议,除了第三方库或者有自己的协议。

+

社区

+ + + +
+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/maixpy/robots.txt b/maixpy/robots.txt new file mode 100644 index 00000000..fbd77f3f --- /dev/null +++ b/maixpy/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Sitemap: https://wiki.sipeed.com/sitemap.xml diff --git a/maixpy/sitemap.xml b/maixpy/sitemap.xml new file mode 100644 index 00000000..b8e4c5b3 --- /dev/null +++ b/maixpy/sitemap.xml @@ -0,0 +1,771 @@ + + + + https://wiki.sipeed.com/maixpy/api/maix/audio.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/api/maix/sys.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/api/maix/tensor.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/api/maix/i18n.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/api/maix/rtsp.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/api/maix/peripheral.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/api/maix/peripheral/timer.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/api/maix/peripheral/pinmap.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/api/maix/peripheral/i2c.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/api/maix/peripheral/pwm.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/api/maix/peripheral/spi.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/api/maix/peripheral/key.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/api/maix/peripheral/uart.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/api/maix/peripheral/gpio.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/api/maix/peripheral/adc.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/api/maix/peripheral/wdt.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/api/maix/example.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/api/maix/touchscreen.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/api/maix/util.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/api/maix/err.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/api/maix/video.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/api/maix/nn/F.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/api/maix/network.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/api/maix/nn.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/api/maix/display.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/api/index.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/api/maix/fs.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/api/maix/image.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/api/maix/thread.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/api/maix/network/wifi.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/api/maix/comm.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/api/maix/protocol.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/api/maix/time.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/api/maix/app.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/api/maix/camera.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/vision/qrcode.html + 2024-04-03 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/vision/self_learn_classifier.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/vision/line_tracking.html + 2024-05-09 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/vision/ai.html + 2024-04-03 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/vision/camera.html + 2024-04-03 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/vision/custmize_model.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/vision/object_track.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/vision/maixhub_train.html + 2024-04-03 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/basic/app_usage.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/basic/maixpy_upgrade.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/basic/os.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/faq.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/source_code/faq.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/source_code/add_c_module.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/source_code/maixcdk.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/source_code/build.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/source_code/contribute.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/projects/index.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/projects/line_tracking_robot.html + 2024-05-09 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/pro/compile_os.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/modules/acc.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/modules/tof.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/peripheral/i2c.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/peripheral/pwm.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/peripheral/spi.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/peripheral/uart.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/peripheral/gpio.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/peripheral/wdt.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/video/jpeg_streaming.html + 2024-04-03 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/audio/recognize.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/basic/python.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/basic/linux_basic.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/basic/maixvision.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/basic/python_pkgs.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/basic/app.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/vision/image_ops.html + 2024-04-03 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/vision/find_blobs.html + 2024-04-03 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/vision/display.html + 2024-03-31 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/vision/body_key_points.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/vision/self_learn_detector.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/vision/face_recognition.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/vision/classify.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/vision/yolov5.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/vision/apriltag.html + 2024-04-03 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/index.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/zh/modules/thermal_cam.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/vision/qrcode.html + 2024-04-03 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/vision/self_learn_classifier.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/vision/line_tracking.html + 2024-05-09 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/vision/ai.html + 2024-04-03 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/vision/camera.html + 2024-04-03 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/vision/custmize_model.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/vision/object_track.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/vision/maixhub_train.html + 2024-04-03 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/basic/app_usage.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/basic/maixpy_upgrade.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/basic/os.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/faq.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/source_code/faq.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/source_code/add_c_module.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/source_code/maixcdk.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/source_code/build.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/source_code/contribute.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/projects/index.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/projects/line_tracking_robot.html + 2024-05-09 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/pro/compile_os.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/vision/image_ops.html + 2024-04-03 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/vision/find_blobs.html + 2024-04-03 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/vision/display.html + 2024-03-31 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/vision/body_key_points.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/vision/self_learn_detector.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/vision/face_recognition.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/vision/classify.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/vision/yolov5.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/vision/apriltag.html + 2024-04-03 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/index.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/modules/thermal_cam.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/modules/acc.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/modules/tof.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/peripheral/i2c.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/peripheral/pwm.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/peripheral/spi.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/peripheral/uart.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/peripheral/gpio.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/peripheral/wdt.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/video/jpeg_streaming.html + 2024-04-03 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/audio/recognize.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/basic/python.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/basic/linux_basic.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/basic/maixvision.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/basic/python_pkgs.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/basic/app.html + 2024-05-14 + weekly + 1.0 + + + https://wiki.sipeed.com/maixpy/doc/en/no_translate.html + 2024-05-14 + weekly + 1.0 + + diff --git a/maixpy/static/css/custom.css b/maixpy/static/css/custom.css new file mode 100644 index 00000000..db773d3b --- /dev/null +++ b/maixpy/static/css/custom.css @@ -0,0 +1,15 @@ + + +#home_page h1 { + color: #c33d45; +} +.dark #home_page h1{ + color: white; +} + +@media screen and (max-width: 900px) { + #home_page h1 { + color: #eb4848; + } +} + diff --git a/maixpy/static/css/search/style.css b/maixpy/static/css/search/style.css new file mode 100644 index 00000000..532536a9 --- /dev/null +++ b/maixpy/static/css/search/style.css @@ -0,0 +1,330 @@ +/** + teedoc search plugin css + @author neucrack + @copyright (c) neucrack CZD666666@gmail.com with MIT License + @changes 2021.2.1 add basic attrributes + */ +.blur { + -webkit-filter: blur(9px); + filter: blur(9px); +} +.pointer { + cursor: pointer; +} +.dark #search { + background-color: #2d2d2d; +} +#search { + border-radius: 2em; + background-color: #f1f1f1; + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + transition: 0.4s; +} + +#search .icon { + transition: transform 0.4s linear; + background: url("/maixpy/static/image/search/search.svg"); + background-size: contain; + background-repeat: no-repeat; + background-position: center; + align-self: center; + min-height: 1.8rem; + min-width: 1.8rem; + transition: 0.2s; +} +#search .placeholder { + padding: 0 1em; + color: #a5a5a5; +} +#search_hints { + display: none; +} + +#search_wrapper { + display: none; + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + background-color: rgba(0, 0, 0, 0.73); + z-index: 100; +} +.dark #search_wrapper { + background-color: transparent; +} +#search_wrapper input:focus{ + outline: none; + border: 1px solid #58b195; +} +#search_wrapper .close { + background: url("/maixpy/static/image/search/close.svg"); + background-size: contain; + background-repeat: no-repeat; + background-position: center; + border-radius: 0.5em; + min-height: 2.5rem; + min-width: 2.5rem; + z-index: 100; + position: fixed; + top: 3em; + right: 3em; + cursor: pointer; +} +#search_title { + margin: 1em; +} +#search_wrapper #search_title > div { + display: flex; + flex-direction: row; + justify-content: center; +} +#search_wrapper input { + height: 60px; + width: 60%; + border: none; + border-radius: 0.5em; + margin: 0; + text-align: center; + color: #222222; + font-size: 1.2em; + display: inline-block; + box-shadow: 0 0 12px 0 #e8e8e8; +} +.dark #search_wrapper input { + box-shadow: 0 0 12px 0 #000000; + background-color: black; + color: white; +} +#search_wrapper > div { + display: flex; + height: 100%; +} +#search_wrapper #search_content { + display: flex; + flex-direction: column; + width: 75%; + height: 100%; + background-color: white; + margin: auto; + padding: 0; + border-radius: 0.5em; +} +.dark #search_wrapper #search_content { + background-color: #3c3c3c; +} +#search_result { + height: 100%; + display: flex; + flex-direction: row; + overflow: auto; +} +#search_result h1 { + font-size: 1.2em; +} +#search_result_name { + overflow-y: auto; + min-width: max-content; +} +#search_result_content { + overflow-y: auto; + flex-grow: 1; +} +#search_result ul { + padding-left: 0; + list-style: none; +} +#search_result li { + box-shadow: 0 0 10px #e0e0e0; + list-style: none; + padding: 1em; + margin: 1em; + border-radius: 0.5em; + transition: 0.4s; + background-color: white; +} +.dark #search_result li { + background-color: #2d2d2d; + box-shadow: 0 0 2px #000000; +} +#search_result #search_result_name li { + margin: 0.5em 1em 0.5em 0; + background: #4caf7d; + color: white; + border-radius: 0; +} +.dark #search_result #search_result_name li { + background: #1b4c33; +} +#search_result #search_result_name li:hover { + margin-right: 0; +} +#search_result li:hover { + box-shadow: 0px 5px 14px #868686; +} +.dark #search_result li:hover{ + box-shadow: 0px 5px 14px #1d1d1d; +} + +#search_result code { + background-color: #4caf7d; + color: white; + border-radius: 0.2em; + padding: 0.1em; +} +#search_result .loading_hint { + color: red; +} +#search_curr_result { + margin-top: 0; + padding-bottom: 3em; + border: 1px solid #4caf7d; + border-radius: 5px; +} +#search_others_result { + padding-bottom: 3em; + border: 1px solid #bdbdbd; + border-radius: 5px; +} +.dark #search_curr_result { + border: 1px solid #1b4c33; +} +.dark #search_others_result { + border: 1px solid #696969; +} +#search_curr_result:first-child, +#search_others_result:first-child { + border-radius: 5px; +} +#search_result .hint { + height: 2em; + color: white; + font-size: 1.5em; + display: flex; + justify-content: center; + flex-direction: column; + text-align: center; + border-top: none; + box-shadow: 0 6px 7px rgba(76, 175, 125, 0.38); + background: #4caf7d; +} +.dark #search_result .hint { + background: #1b4c33; +} +#search_curr_result > .hint { + background-color: #4caf7d; +} +#search_curr_result .searching { + background-color: #ff9800; +} +.search_highlight { + background-color: #FFEB3B; + border-radius: 0.2em; + padding: 0.1em; + +} +.dark .search_highlight{ + color: #1b1b1b; +} +.selected_highlight { + background-color: #ff9823; +} + +#search_ctrl_btn { + position: fixed; + top: 2em; + right: 1em; + display: flex; + flex-direction: row; + z-index: 999; + user-select: none; +} +#search_ctrl_btn > div { + border-radius: 0.2em; + min-width: 5em; + min-height: 2.5em; + background-color: #fae94e; + margin: 0.2em; + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + padding: 0.2em; + cursor: pointer; + box-shadow: 0 0 12px 0 rgb(0, 0, 0, 0.06); + transition: 0.4s; + color: #8b7000; +} +#search_ctrl_btn > div:hover { + box-shadow: 0 0 12px 0 rgb(0, 0, 0, 0.2); +} +#search_ctrl_btn > .previous .icon { + background-image: url("/static/image/search/up.svg"); + -ms-transform: rotate(270deg); + -moz-transform: rotate(270deg); + -webkit-transform: rotate(270deg); + transform: rotate(270deg); + background-size: 2em; + background-repeat: no-repeat; + background-position: center; + min-height: 1.5em; + min-width: 1.5em; + height: 1.5em; + width: 1.5em; +} +#search_ctrl_btn > .next .icon { + background-image: url("/static/image/search/up.svg"); + -ms-transform: rotate(90deg); + -moz-transform: rotate(90deg); + -webkit-transform: rotate(90deg); + transform: rotate(90deg); + background-size: 2em; + background-repeat: no-repeat; + background-position: center; + min-height: 1.5em; + min-width: 1.5em; + height: 1.5em; + width: 1.5em; +} + +#remove_search > .icon { + background-image: url("/static/image/search/cancel.svg"); + background-size: 2em; + background-repeat: no-repeat; + background-position: center; + min-height: 1.5em; + min-width: 1.5em; + height: 1.5em; + width: 1.5em; +} + + +@media screen and (max-width: 900px) { + #search_wrapper #search_content { + width: 100%; + height: 100%; + border-radius: 0; + } + #search_wrapper input { + font-size: 0.8em; + } + #search_wrapper .close { + top: 1.5em; + right: 1em; + } + #search_result li { + margin: 0; + } + #search_result #search_result_name li { + font-size: 0.8em; + } + #search_curr_result > .hint { + font-size: 1.2em; + } + #search_result .hint { + font-size: 1.2em; + } +} diff --git a/maixpy/static/css/tailwind.css b/maixpy/static/css/tailwind.css new file mode 100644 index 00000000..d705193e --- /dev/null +++ b/maixpy/static/css/tailwind.css @@ -0,0 +1,63 @@ +(()=>{var Sb=Object.create;var li=Object.defineProperty;var Cb=Object.getOwnPropertyDescriptor;var Ab=Object.getOwnPropertyNames;var _b=Object.getPrototypeOf,Eb=Object.prototype.hasOwnProperty;var uu=i=>li(i,"__esModule",{value:!0});var fu=i=>{if(typeof require!="undefined")return require(i);throw new Error('Dynamic require of "'+i+'" is not supported')};var C=(i,e)=>()=>(i&&(e=i(i=0)),e);var v=(i,e)=>()=>(e||i((e={exports:{}}).exports,e),e.exports),Ae=(i,e)=>{uu(i);for(var t in e)li(i,t,{get:e[t],enumerable:!0})},Ob=(i,e,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of Ab(e))!Eb.call(i,r)&&r!=="default"&&li(i,r,{get:()=>e[r],enumerable:!(t=Cb(e,r))||t.enumerable});return i},K=i=>Ob(uu(li(i!=null?Sb(_b(i)):{},"default",i&&i.__esModule&&"default"in i?{get:()=>i.default,enumerable:!0}:{value:i,enumerable:!0})),i);var m,l=C(()=>{m={platform:"",env:{},versions:{node:"14.17.6"}}});var Tb,te,ze=C(()=>{l();Tb=0,te={readFileSync:i=>self[i]||"",statSync:()=>({mtimeMs:Tb++}),promises:{readFile:i=>Promise.resolve(self[i]||"")}}});var Xn=v((X5,pu)=>{l();"use strict";var cu=class{constructor(e={}){if(!(e.maxSize&&e.maxSize>0))throw new TypeError("`maxSize` must be a number greater than 0");if(typeof e.maxAge=="number"&&e.maxAge===0)throw new TypeError("`maxAge` must be a number greater than 0");this.maxSize=e.maxSize,this.maxAge=e.maxAge||1/0,this.onEviction=e.onEviction,this.cache=new Map,this.oldCache=new Map,this._size=0}_emitEvictions(e){if(typeof this.onEviction=="function")for(let[t,r]of e)this.onEviction(t,r.value)}_deleteIfExpired(e,t){return typeof t.expiry=="number"&&t.expiry<=Date.now()?(typeof this.onEviction=="function"&&this.onEviction(e,t.value),this.delete(e)):!1}_getOrDeleteIfExpired(e,t){if(this._deleteIfExpired(e,t)===!1)return t.value}_getItemValue(e,t){return t.expiry?this._getOrDeleteIfExpired(e,t):t.value}_peek(e,t){let r=t.get(e);return this._getItemValue(e,r)}_set(e,t){this.cache.set(e,t),this._size++,this._size>=this.maxSize&&(this._size=0,this._emitEvictions(this.oldCache),this.oldCache=this.cache,this.cache=new Map)}_moveToRecent(e,t){this.oldCache.delete(e),this._set(e,t)}*_entriesAscending(){for(let e of this.oldCache){let[t,r]=e;this.cache.has(t)||this._deleteIfExpired(t,r)===!1&&(yield e)}for(let e of this.cache){let[t,r]=e;this._deleteIfExpired(t,r)===!1&&(yield e)}}get(e){if(this.cache.has(e)){let t=this.cache.get(e);return this._getItemValue(e,t)}if(this.oldCache.has(e)){let t=this.oldCache.get(e);if(this._deleteIfExpired(e,t)===!1)return this._moveToRecent(e,t),t.value}}set(e,t,{maxAge:r=this.maxAge===1/0?void 0:Date.now()+this.maxAge}={}){this.cache.has(e)?this.cache.set(e,{value:t,maxAge:r}):this._set(e,{value:t,expiry:r})}has(e){return this.cache.has(e)?!this._deleteIfExpired(e,this.cache.get(e)):this.oldCache.has(e)?!this._deleteIfExpired(e,this.oldCache.get(e)):!1}peek(e){if(this.cache.has(e))return this._peek(e,this.cache);if(this.oldCache.has(e))return this._peek(e,this.oldCache)}delete(e){let t=this.cache.delete(e);return t&&this._size--,this.oldCache.delete(e)||t}clear(){this.cache.clear(),this.oldCache.clear(),this._size=0}resize(e){if(!(e&&e>0))throw new TypeError("`maxSize` must be a number greater than 0");let t=[...this._entriesAscending()],r=t.length-e;r<0?(this.cache=new Map(t),this.oldCache=new Map,this._size=t.length):(r>0&&this._emitEvictions(t.slice(0,r)),this.oldCache=new Map(t.slice(r)),this.cache=new Map,this._size=0),this.maxSize=e}*keys(){for(let[e]of this)yield e}*values(){for(let[,e]of this)yield e}*[Symbol.iterator](){for(let e of this.cache){let[t,r]=e;this._deleteIfExpired(t,r)===!1&&(yield[t,r.value])}for(let e of this.oldCache){let[t,r]=e;this.cache.has(t)||this._deleteIfExpired(t,r)===!1&&(yield[t,r.value])}}*entriesDescending(){let e=[...this.cache];for(let t=e.length-1;t>=0;--t){let r=e[t],[n,a]=r;this._deleteIfExpired(n,a)===!1&&(yield[n,a.value])}e=[...this.oldCache];for(let t=e.length-1;t>=0;--t){let r=e[t],[n,a]=r;this.cache.has(n)||this._deleteIfExpired(n,a)===!1&&(yield[n,a.value])}}*entriesAscending(){for(let[e,t]of this._entriesAscending())yield[e,t.value]}get size(){if(!this._size)return this.oldCache.size;let e=0;for(let t of this.oldCache.keys())this.cache.has(t)||e++;return Math.min(this._size+e,this.maxSize)}};pu.exports=cu});var du,hu=C(()=>{l();du=i=>i&&i._hash});function ui(i){return du(i,{ignoreUnknown:!0})}var mu=C(()=>{l();hu()});function Xe(i){if(i=`${i}`,i==="0")return"0";if(/^[+-]?(\d+|\d*\.\d+)(e[+-]?\d+)?(%|\w+)?$/.test(i))return i.replace(/^[+-]?/,t=>t==="-"?"":"-");let e=["var","calc","min","max","clamp"];for(let t of e)if(i.includes(`${t}(`))return`calc(${i} * -1)`}var fi=C(()=>{l()});var gu,yu=C(()=>{l();gu=["preflight","container","accessibility","pointerEvents","visibility","position","inset","isolation","zIndex","order","gridColumn","gridColumnStart","gridColumnEnd","gridRow","gridRowStart","gridRowEnd","float","clear","margin","boxSizing","lineClamp","display","aspectRatio","height","maxHeight","minHeight","width","minWidth","maxWidth","flex","flexShrink","flexGrow","flexBasis","tableLayout","captionSide","borderCollapse","borderSpacing","transformOrigin","translate","rotate","skew","scale","transform","animation","cursor","touchAction","userSelect","resize","scrollSnapType","scrollSnapAlign","scrollSnapStop","scrollMargin","scrollPadding","listStylePosition","listStyleType","listStyleImage","appearance","columns","breakBefore","breakInside","breakAfter","gridAutoColumns","gridAutoFlow","gridAutoRows","gridTemplateColumns","gridTemplateRows","flexDirection","flexWrap","placeContent","placeItems","alignContent","alignItems","justifyContent","justifyItems","gap","space","divideWidth","divideStyle","divideColor","divideOpacity","placeSelf","alignSelf","justifySelf","overflow","overscrollBehavior","scrollBehavior","textOverflow","hyphens","whitespace","wordBreak","borderRadius","borderWidth","borderStyle","borderColor","borderOpacity","backgroundColor","backgroundOpacity","backgroundImage","gradientColorStops","boxDecorationBreak","backgroundSize","backgroundAttachment","backgroundClip","backgroundPosition","backgroundRepeat","backgroundOrigin","fill","stroke","strokeWidth","objectFit","objectPosition","padding","textAlign","textIndent","verticalAlign","fontFamily","fontSize","fontWeight","textTransform","fontStyle","fontVariantNumeric","lineHeight","letterSpacing","textColor","textOpacity","textDecoration","textDecorationColor","textDecorationStyle","textDecorationThickness","textUnderlineOffset","fontSmoothing","placeholderColor","placeholderOpacity","caretColor","accentColor","opacity","backgroundBlendMode","mixBlendMode","boxShadow","boxShadowColor","outlineStyle","outlineWidth","outlineOffset","outlineColor","ringWidth","ringColor","ringOpacity","ringOffsetWidth","ringOffsetColor","blur","brightness","contrast","dropShadow","grayscale","hueRotate","invert","saturate","sepia","filter","backdropBlur","backdropBrightness","backdropContrast","backdropGrayscale","backdropHueRotate","backdropInvert","backdropOpacity","backdropSaturate","backdropSepia","backdropFilter","transitionProperty","transitionDelay","transitionDuration","transitionTimingFunction","willChange","content"]});function wu(i,e){return i===void 0?e:Array.isArray(i)?i:[...new Set(e.filter(r=>i!==!1&&i[r]!==!1).concat(Object.keys(i).filter(r=>i[r]!==!1)))]}var bu=C(()=>{l()});var vu={};Ae(vu,{default:()=>_e});var _e,ci=C(()=>{l();_e=new Proxy({},{get:()=>String})});function Kn(i,e,t){typeof m!="undefined"&&m.env.JEST_WORKER_ID||t&&xu.has(t)||(t&&xu.add(t),console.warn(""),e.forEach(r=>console.warn(i,"-",r)))}function Zn(i){return _e.dim(i)}var xu,F,Ee=C(()=>{l();ci();xu=new Set;F={info(i,e){Kn(_e.bold(_e.cyan("info")),...Array.isArray(i)?[i]:[e,i])},warn(i,e){["content-problems"].includes(i)||Kn(_e.bold(_e.yellow("warn")),...Array.isArray(i)?[i]:[e,i])},risk(i,e){Kn(_e.bold(_e.magenta("risk")),...Array.isArray(i)?[i]:[e,i])}}});var ku={};Ae(ku,{default:()=>es});function nr({version:i,from:e,to:t}){F.warn(`${e}-color-renamed`,[`As of Tailwind CSS ${i}, \`${e}\` has been renamed to \`${t}\`.`,"Update your configuration file to silence this warning."])}var es,ts=C(()=>{l();Ee();es={inherit:"inherit",current:"currentColor",transparent:"transparent",black:"#000",white:"#fff",slate:{50:"#f8fafc",100:"#f1f5f9",200:"#e2e8f0",300:"#cbd5e1",400:"#94a3b8",500:"#64748b",600:"#475569",700:"#334155",800:"#1e293b",900:"#0f172a",950:"#020617"},gray:{50:"#f9fafb",100:"#f3f4f6",200:"#e5e7eb",300:"#d1d5db",400:"#9ca3af",500:"#6b7280",600:"#4b5563",700:"#374151",800:"#1f2937",900:"#111827",950:"#030712"},zinc:{50:"#fafafa",100:"#f4f4f5",200:"#e4e4e7",300:"#d4d4d8",400:"#a1a1aa",500:"#71717a",600:"#52525b",700:"#3f3f46",800:"#27272a",900:"#18181b",950:"#09090b"},neutral:{50:"#fafafa",100:"#f5f5f5",200:"#e5e5e5",300:"#d4d4d4",400:"#a3a3a3",500:"#737373",600:"#525252",700:"#404040",800:"#262626",900:"#171717",950:"#0a0a0a"},stone:{50:"#fafaf9",100:"#f5f5f4",200:"#e7e5e4",300:"#d6d3d1",400:"#a8a29e",500:"#78716c",600:"#57534e",700:"#44403c",800:"#292524",900:"#1c1917",950:"#0c0a09"},red:{50:"#fef2f2",100:"#fee2e2",200:"#fecaca",300:"#fca5a5",400:"#f87171",500:"#ef4444",600:"#dc2626",700:"#b91c1c",800:"#991b1b",900:"#7f1d1d",950:"#450a0a"},orange:{50:"#fff7ed",100:"#ffedd5",200:"#fed7aa",300:"#fdba74",400:"#fb923c",500:"#f97316",600:"#ea580c",700:"#c2410c",800:"#9a3412",900:"#7c2d12",950:"#431407"},amber:{50:"#fffbeb",100:"#fef3c7",200:"#fde68a",300:"#fcd34d",400:"#fbbf24",500:"#f59e0b",600:"#d97706",700:"#b45309",800:"#92400e",900:"#78350f",950:"#451a03"},yellow:{50:"#fefce8",100:"#fef9c3",200:"#fef08a",300:"#fde047",400:"#facc15",500:"#eab308",600:"#ca8a04",700:"#a16207",800:"#854d0e",900:"#713f12",950:"#422006"},lime:{50:"#f7fee7",100:"#ecfccb",200:"#d9f99d",300:"#bef264",400:"#a3e635",500:"#84cc16",600:"#65a30d",700:"#4d7c0f",800:"#3f6212",900:"#365314",950:"#1a2e05"},green:{50:"#f0fdf4",100:"#dcfce7",200:"#bbf7d0",300:"#86efac",400:"#4ade80",500:"#22c55e",600:"#16a34a",700:"#15803d",800:"#166534",900:"#14532d",950:"#052e16"},emerald:{50:"#ecfdf5",100:"#d1fae5",200:"#a7f3d0",300:"#6ee7b7",400:"#34d399",500:"#10b981",600:"#059669",700:"#047857",800:"#065f46",900:"#064e3b",950:"#022c22"},teal:{50:"#f0fdfa",100:"#ccfbf1",200:"#99f6e4",300:"#5eead4",400:"#2dd4bf",500:"#14b8a6",600:"#0d9488",700:"#0f766e",800:"#115e59",900:"#134e4a",950:"#042f2e"},cyan:{50:"#ecfeff",100:"#cffafe",200:"#a5f3fc",300:"#67e8f9",400:"#22d3ee",500:"#06b6d4",600:"#0891b2",700:"#0e7490",800:"#155e75",900:"#164e63",950:"#083344"},sky:{50:"#f0f9ff",100:"#e0f2fe",200:"#bae6fd",300:"#7dd3fc",400:"#38bdf8",500:"#0ea5e9",600:"#0284c7",700:"#0369a1",800:"#075985",900:"#0c4a6e",950:"#082f49"},blue:{50:"#eff6ff",100:"#dbeafe",200:"#bfdbfe",300:"#93c5fd",400:"#60a5fa",500:"#3b82f6",600:"#2563eb",700:"#1d4ed8",800:"#1e40af",900:"#1e3a8a",950:"#172554"},indigo:{50:"#eef2ff",100:"#e0e7ff",200:"#c7d2fe",300:"#a5b4fc",400:"#818cf8",500:"#6366f1",600:"#4f46e5",700:"#4338ca",800:"#3730a3",900:"#312e81",950:"#1e1b4b"},violet:{50:"#f5f3ff",100:"#ede9fe",200:"#ddd6fe",300:"#c4b5fd",400:"#a78bfa",500:"#8b5cf6",600:"#7c3aed",700:"#6d28d9",800:"#5b21b6",900:"#4c1d95",950:"#2e1065"},purple:{50:"#faf5ff",100:"#f3e8ff",200:"#e9d5ff",300:"#d8b4fe",400:"#c084fc",500:"#a855f7",600:"#9333ea",700:"#7e22ce",800:"#6b21a8",900:"#581c87",950:"#3b0764"},fuchsia:{50:"#fdf4ff",100:"#fae8ff",200:"#f5d0fe",300:"#f0abfc",400:"#e879f9",500:"#d946ef",600:"#c026d3",700:"#a21caf",800:"#86198f",900:"#701a75",950:"#4a044e"},pink:{50:"#fdf2f8",100:"#fce7f3",200:"#fbcfe8",300:"#f9a8d4",400:"#f472b6",500:"#ec4899",600:"#db2777",700:"#be185d",800:"#9d174d",900:"#831843",950:"#500724"},rose:{50:"#fff1f2",100:"#ffe4e6",200:"#fecdd3",300:"#fda4af",400:"#fb7185",500:"#f43f5e",600:"#e11d48",700:"#be123c",800:"#9f1239",900:"#881337",950:"#4c0519"},get lightBlue(){return nr({version:"v2.2",from:"lightBlue",to:"sky"}),this.sky},get warmGray(){return nr({version:"v3.0",from:"warmGray",to:"stone"}),this.stone},get trueGray(){return nr({version:"v3.0",from:"trueGray",to:"neutral"}),this.neutral},get coolGray(){return nr({version:"v3.0",from:"coolGray",to:"gray"}),this.gray},get blueGray(){return nr({version:"v3.0",from:"blueGray",to:"slate"}),this.slate}}});function rs(i,...e){for(let t of e){for(let r in t)i?.hasOwnProperty?.(r)||(i[r]=t[r]);for(let r of Object.getOwnPropertySymbols(t))i?.hasOwnProperty?.(r)||(i[r]=t[r])}return i}var Su=C(()=>{l()});function Ke(i){if(Array.isArray(i))return i;let e=i.split("[").length-1,t=i.split("]").length-1;if(e!==t)throw new Error(`Path is invalid. Has unbalanced brackets: ${i}`);return i.split(/\.(?![^\[]*\])|[\[\]]/g).filter(Boolean)}var pi=C(()=>{l()});function J(i,e){return di.future.includes(e)?i.future==="all"||(i?.future?.[e]??Cu[e]??!1):di.experimental.includes(e)?i.experimental==="all"||(i?.experimental?.[e]??Cu[e]??!1):!1}function Au(i){return i.experimental==="all"?di.experimental:Object.keys(i?.experimental??{}).filter(e=>di.experimental.includes(e)&&i.experimental[e])}function _u(i){if(m.env.JEST_WORKER_ID===void 0&&Au(i).length>0){let e=Au(i).map(t=>_e.yellow(t)).join(", ");F.warn("experimental-flags-enabled",[`You have enabled experimental features: ${e}`,"Experimental features in Tailwind CSS are not covered by semver, may introduce breaking changes, and can change at any time."])}}var Cu,di,De=C(()=>{l();ci();Ee();Cu={optimizeUniversalDefaults:!1,generalizedModifiers:!0,get disableColorOpacityUtilitiesByDefault(){return!1},get relativeContentPathsByDefault(){return!1}},di={future:["hoverOnlyWhenSupported","respectDefaultRingColorOpacity","disableColorOpacityUtilitiesByDefault","relativeContentPathsByDefault"],experimental:["optimizeUniversalDefaults","generalizedModifiers"]}});function Eu(i){(()=>{if(i.purge||!i.content||!Array.isArray(i.content)&&!(typeof i.content=="object"&&i.content!==null))return!1;if(Array.isArray(i.content))return i.content.every(t=>typeof t=="string"?!0:!(typeof t?.raw!="string"||t?.extension&&typeof t?.extension!="string"));if(typeof i.content=="object"&&i.content!==null){if(Object.keys(i.content).some(t=>!["files","relative","extract","transform"].includes(t)))return!1;if(Array.isArray(i.content.files)){if(!i.content.files.every(t=>typeof t=="string"?!0:!(typeof t?.raw!="string"||t?.extension&&typeof t?.extension!="string")))return!1;if(typeof i.content.extract=="object"){for(let t of Object.values(i.content.extract))if(typeof t!="function")return!1}else if(!(i.content.extract===void 0||typeof i.content.extract=="function"))return!1;if(typeof i.content.transform=="object"){for(let t of Object.values(i.content.transform))if(typeof t!="function")return!1}else if(!(i.content.transform===void 0||typeof i.content.transform=="function"))return!1;if(typeof i.content.relative!="boolean"&&typeof i.content.relative!="undefined")return!1}return!0}return!1})()||F.warn("purge-deprecation",["The `purge`/`content` options have changed in Tailwind CSS v3.0.","Update your configuration file to eliminate this warning.","https://tailwindcss.com/docs/upgrade-guide#configure-content-sources"]),i.safelist=(()=>{let{content:t,purge:r,safelist:n}=i;return Array.isArray(n)?n:Array.isArray(t?.safelist)?t.safelist:Array.isArray(r?.safelist)?r.safelist:Array.isArray(r?.options?.safelist)?r.options.safelist:[]})(),i.blocklist=(()=>{let{blocklist:t}=i;if(Array.isArray(t)){if(t.every(r=>typeof r=="string"))return t;F.warn("blocklist-invalid",["The `blocklist` option must be an array of strings.","https://tailwindcss.com/docs/content-configuration#discarding-classes"])}return[]})(),typeof i.prefix=="function"?(F.warn("prefix-function",["As of Tailwind CSS v3.0, `prefix` cannot be a function.","Update `prefix` in your configuration to be a string to eliminate this warning.","https://tailwindcss.com/docs/upgrade-guide#prefix-cannot-be-a-function"]),i.prefix=""):i.prefix=i.prefix??"",i.content={relative:(()=>{let{content:t}=i;return t?.relative?t.relative:J(i,"relativeContentPathsByDefault")})(),files:(()=>{let{content:t,purge:r}=i;return Array.isArray(r)?r:Array.isArray(r?.content)?r.content:Array.isArray(t)?t:Array.isArray(t?.content)?t.content:Array.isArray(t?.files)?t.files:[]})(),extract:(()=>{let t=(()=>i.purge?.extract?i.purge.extract:i.content?.extract?i.content.extract:i.purge?.extract?.DEFAULT?i.purge.extract.DEFAULT:i.content?.extract?.DEFAULT?i.content.extract.DEFAULT:i.purge?.options?.extractors?i.purge.options.extractors:i.content?.options?.extractors?i.content.options.extractors:{})(),r={},n=(()=>{if(i.purge?.options?.defaultExtractor)return i.purge.options.defaultExtractor;if(i.content?.options?.defaultExtractor)return i.content.options.defaultExtractor})();if(n!==void 0&&(r.DEFAULT=n),typeof t=="function")r.DEFAULT=t;else if(Array.isArray(t))for(let{extensions:a,extractor:s}of t??[])for(let o of a)r[o]=s;else typeof t=="object"&&t!==null&&Object.assign(r,t);return r})(),transform:(()=>{let t=(()=>i.purge?.transform?i.purge.transform:i.content?.transform?i.content.transform:i.purge?.transform?.DEFAULT?i.purge.transform.DEFAULT:i.content?.transform?.DEFAULT?i.content.transform.DEFAULT:{})(),r={};return typeof t=="function"&&(r.DEFAULT=t),typeof t=="object"&&t!==null&&Object.assign(r,t),r})()};for(let t of i.content.files)if(typeof t=="string"&&/{([^,]*?)}/g.test(t)){F.warn("invalid-glob-braces",[`The glob pattern ${Zn(t)} in your Tailwind CSS configuration is invalid.`,`Update it to ${Zn(t.replace(/{([^,]*?)}/g,"$1"))} to silence this warning.`]);break}return i}var Ou=C(()=>{l();De();Ee()});function ie(i){if(Object.prototype.toString.call(i)!=="[object Object]")return!1;let e=Object.getPrototypeOf(i);return e===null||e===Object.prototype}var xt=C(()=>{l()});function Ze(i){return Array.isArray(i)?i.map(e=>Ze(e)):typeof i=="object"&&i!==null?Object.fromEntries(Object.entries(i).map(([e,t])=>[e,Ze(t)])):i}var hi=C(()=>{l()});function ht(i){return i.replace(/\\,/g,"\\2c ")}var mi=C(()=>{l()});var is,Tu=C(()=>{l();is={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}});function sr(i,{loose:e=!1}={}){if(typeof i!="string")return null;if(i=i.trim(),i==="transparent")return{mode:"rgb",color:["0","0","0"],alpha:"0"};if(i in is)return{mode:"rgb",color:is[i].map(a=>a.toString())};let t=i.replace(Db,(a,s,o,u,c)=>["#",s,s,o,o,u,u,c?c+c:""].join("")).match(Pb);if(t!==null)return{mode:"rgb",color:[parseInt(t[1],16),parseInt(t[2],16),parseInt(t[3],16)].map(a=>a.toString()),alpha:t[4]?(parseInt(t[4],16)/255).toString():void 0};let r=i.match(Ib)??i.match(qb);if(r===null)return null;let n=[r[2],r[3],r[4]].filter(Boolean).map(a=>a.toString());return n.length===2&&n[0].startsWith("var(")?{mode:r[1],color:[n[0]],alpha:n[1]}:!e&&n.length!==3||n.length<3&&!n.some(a=>/^var\(.*?\)$/.test(a))?null:{mode:r[1],color:n,alpha:r[5]?.toString?.()}}function ns({mode:i,color:e,alpha:t}){let r=t!==void 0;return i==="rgba"||i==="hsla"?`${i}(${e.join(", ")}${r?`, ${t}`:""})`:`${i}(${e.join(" ")}${r?` / ${t}`:""})`}var Pb,Db,et,gi,Pu,tt,Ib,qb,ss=C(()=>{l();Tu();Pb=/^#([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})?$/i,Db=/^#([a-f\d])([a-f\d])([a-f\d])([a-f\d])?$/i,et=/(?:\d+|\d*\.\d+)%?/,gi=/(?:\s*,\s*|\s+)/,Pu=/\s*[,/]\s*/,tt=/var\(--(?:[^ )]*?)\)/,Ib=new RegExp(`^(rgba?)\\(\\s*(${et.source}|${tt.source})(?:${gi.source}(${et.source}|${tt.source}))?(?:${gi.source}(${et.source}|${tt.source}))?(?:${Pu.source}(${et.source}|${tt.source}))?\\s*\\)$`),qb=new RegExp(`^(hsla?)\\(\\s*((?:${et.source})(?:deg|rad|grad|turn)?|${tt.source})(?:${gi.source}(${et.source}|${tt.source}))?(?:${gi.source}(${et.source}|${tt.source}))?(?:${Pu.source}(${et.source}|${tt.source}))?\\s*\\)$`)});function Ie(i,e,t){if(typeof i=="function")return i({opacityValue:e});let r=sr(i,{loose:!0});return r===null?t:ns({...r,alpha:e})}function se({color:i,property:e,variable:t}){let r=[].concat(e);if(typeof i=="function")return{[t]:"1",...Object.fromEntries(r.map(a=>[a,i({opacityVariable:t,opacityValue:`var(${t})`})]))};let n=sr(i);return n===null?Object.fromEntries(r.map(a=>[a,i])):n.alpha!==void 0?Object.fromEntries(r.map(a=>[a,i])):{[t]:"1",...Object.fromEntries(r.map(a=>[a,ns({...n,alpha:`var(${t})`})]))}}var ar=C(()=>{l();ss()});function le(i,e){let t=[],r=[],n=0,a=!1;for(let s=0;s{l()});function yi(i){return le(i,",").map(t=>{let r=t.trim(),n={raw:r},a=r.split(Mb),s=new Set;for(let o of a)Du.lastIndex=0,!s.has("KEYWORD")&&Rb.has(o)?(n.keyword=o,s.add("KEYWORD")):Du.test(o)?s.has("X")?s.has("Y")?s.has("BLUR")?s.has("SPREAD")||(n.spread=o,s.add("SPREAD")):(n.blur=o,s.add("BLUR")):(n.y=o,s.add("Y")):(n.x=o,s.add("X")):n.color?(n.unknown||(n.unknown=[]),n.unknown.push(o)):n.color=o;return n.valid=n.x!==void 0&&n.y!==void 0,n})}function Iu(i){return i.map(e=>e.valid?[e.keyword,e.x,e.y,e.blur,e.spread,e.color].filter(Boolean).join(" "):e.raw).join(", ")}var Rb,Mb,Du,as=C(()=>{l();or();Rb=new Set(["inset","inherit","initial","revert","unset"]),Mb=/\ +(?![^(]*\))/g,Du=/^-?(\d+|\.\d+)(.*?)$/g});function os(i){return Bb.some(e=>new RegExp(`^${e}\\(.*\\)`).test(i))}function U(i,e=!0){return i.startsWith("--")?`var(${i})`:i.includes("url(")?i.split(/(url\(.*?\))/g).filter(Boolean).map(t=>/^url\(.*?\)$/.test(t)?t:U(t,!1)).join(""):(i=i.replace(/([^\\])_+/g,(t,r)=>r+" ".repeat(t.length-1)).replace(/^_/g," ").replace(/\\_/g,"_"),e&&(i=i.trim()),i=Nb(i),i)}function Nb(i){return i.replace(/(calc|min|max|clamp)\(.+\)/g,e=>{let t=[];return e.replace(/var\((--.+?)[,)]/g,(r,n)=>(t.push(n),r.replace(n,qu))).replace(/(-?\d*\.?\d(?!\b-\d.+[,)](?![^+\-/*])\D)(?:%|[a-z]+)?|\))([+\-/*])/g,"$1 $2 ").replace(Fb,()=>t.shift())})}function ls(i){return i.startsWith("url(")}function us(i){return!isNaN(Number(i))||os(i)}function lr(i){return i.endsWith("%")&&us(i.slice(0,-1))||os(i)}function ur(i){return i==="0"||new RegExp(`^[+-]?[0-9]*.?[0-9]+(?:[eE][+-]?[0-9]+)?${$b}$`).test(i)||os(i)}function Ru(i){return jb.has(i)}function Mu(i){let e=yi(U(i));for(let t of e)if(!t.valid)return!1;return!0}function Bu(i){let e=0;return le(i,"_").every(r=>(r=U(r),r.startsWith("var(")?!0:sr(r,{loose:!0})!==null?(e++,!0):!1))?e>0:!1}function Fu(i){let e=0;return le(i,",").every(r=>(r=U(r),r.startsWith("var(")?!0:ls(r)||Vb(r)||["element(","image(","cross-fade(","image-set("].some(n=>r.startsWith(n))?(e++,!0):!1))?e>0:!1}function Vb(i){i=U(i);for(let e of zb)if(i.startsWith(`${e}(`))return!0;return!1}function Nu(i){let e=0;return le(i,"_").every(r=>(r=U(r),r.startsWith("var(")?!0:Ub.has(r)||ur(r)||lr(r)?(e++,!0):!1))?e>0:!1}function Lu(i){let e=0;return le(i,",").every(r=>(r=U(r),r.startsWith("var(")?!0:r.includes(" ")&&!/(['"])([^"']+)\1/g.test(r)||/^\d/g.test(r)?!1:(e++,!0)))?e>0:!1}function $u(i){return Wb.has(i)}function ju(i){return Gb.has(i)}function zu(i){return Hb.has(i)}var Bb,qu,Fb,Lb,$b,jb,zb,Ub,Wb,Gb,Hb,fr=C(()=>{l();ss();as();or();Bb=["min","max","clamp","calc"];qu="--tw-placeholder",Fb=new RegExp(qu,"g");Lb=["cm","mm","Q","in","pc","pt","px","em","ex","ch","rem","lh","rlh","vw","vh","vmin","vmax","vb","vi","svw","svh","lvw","lvh","dvw","dvh","cqw","cqh","cqi","cqb","cqmin","cqmax"],$b=`(?:${Lb.join("|")})`;jb=new Set(["thin","medium","thick"]);zb=new Set(["conic-gradient","linear-gradient","radial-gradient","repeating-conic-gradient","repeating-linear-gradient","repeating-radial-gradient"]);Ub=new Set(["center","top","right","bottom","left"]);Wb=new Set(["serif","sans-serif","monospace","cursive","fantasy","system-ui","ui-serif","ui-sans-serif","ui-monospace","ui-rounded","math","emoji","fangsong"]);Gb=new Set(["xx-small","x-small","small","medium","large","x-large","x-large","xxx-large"]);Hb=new Set(["larger","smaller"])});function Vu(i){let e=["cover","contain"];return le(i,",").every(t=>{let r=le(t,"_").filter(Boolean);return r.length===1&&e.includes(r[0])?!0:r.length!==1&&r.length!==2?!1:r.every(n=>ur(n)||lr(n)||n==="auto")})}var Uu=C(()=>{l();fr();or()});function Wu(i,e){i.walkClasses(t=>{t.value=e(t.value),t.raws&&t.raws.value&&(t.raws.value=ht(t.raws.value))})}function Gu(i,e){if(!rt(i))return;let t=i.slice(1,-1);if(!!e(t))return U(t)}function Yb(i,e={},t){let r=e[i];if(r!==void 0)return Xe(r);if(rt(i)){let n=Gu(i,t);return n===void 0?void 0:Xe(n)}}function wi(i,e={},{validate:t=()=>!0}={}){let r=e.values?.[i];return r!==void 0?r:e.supportsNegativeValues&&i.startsWith("-")?Yb(i.slice(1),e.values,t):Gu(i,t)}function rt(i){return i.startsWith("[")&&i.endsWith("]")}function Hu(i){let e=i.lastIndexOf("/");return e===-1||e===i.length-1?[i,void 0]:rt(i)&&!i.includes("]/[")?[i,void 0]:[i.slice(0,e),i.slice(e+1)]}function kt(i){if(typeof i=="string"&&i.includes("")){let e=i;return({opacityValue:t=1})=>e.replace("",t)}return i}function Yu(i){return U(i.slice(1,-1))}function Qb(i,e={},{tailwindConfig:t={}}={}){if(e.values?.[i]!==void 0)return kt(e.values?.[i]);let[r,n]=Hu(i);if(n!==void 0){let a=e.values?.[r]??(rt(r)?r.slice(1,-1):void 0);return a===void 0?void 0:(a=kt(a),rt(n)?Ie(a,Yu(n)):t.theme?.opacity?.[n]===void 0?void 0:Ie(a,t.theme.opacity[n]))}return wi(i,e,{validate:Bu})}function Jb(i,e={}){return e.values?.[i]}function he(i){return(e,t)=>wi(e,t,{validate:i})}function Xb(i,e){let t=i.indexOf(e);return t===-1?[void 0,i]:[i.slice(0,t),i.slice(t+1)]}function cs(i,e,t,r){if(t.values&&e in t.values)for(let{type:a}of i??[]){let s=fs[a](e,t,{tailwindConfig:r});if(s!==void 0)return[s,a,null]}if(rt(e)){let a=e.slice(1,-1),[s,o]=Xb(a,":");if(!/^[\w-_]+$/g.test(s))o=a;else if(s!==void 0&&!Qu.includes(s))return[];if(o.length>0&&Qu.includes(s))return[wi(`[${o}]`,t),s,null]}let n=ps(i,e,t,r);for(let a of n)return a;return[]}function*ps(i,e,t,r){let n=J(r,"generalizedModifiers"),[a,s]=Hu(e);if(n&&t.modifiers!=null&&(t.modifiers==="any"||typeof t.modifiers=="object"&&(s&&rt(s)||s in t.modifiers))||(a=e,s=void 0),s!==void 0&&a===""&&(a="DEFAULT"),s!==void 0&&typeof t.modifiers=="object"){let u=t.modifiers?.[s]??null;u!==null?s=u:rt(s)&&(s=Yu(s))}for(let{type:u}of i??[]){let c=fs[u](a,t,{tailwindConfig:r});c!==void 0&&(yield[c,u,s??null])}}var fs,Qu,cr=C(()=>{l();mi();ar();fr();fi();Uu();De();fs={any:wi,color:Qb,url:he(ls),image:he(Fu),length:he(ur),percentage:he(lr),position:he(Nu),lookup:Jb,"generic-name":he($u),"family-name":he(Lu),number:he(us),"line-width":he(Ru),"absolute-size":he(ju),"relative-size":he(zu),shadow:he(Mu),size:he(Vu)},Qu=Object.keys(fs)});function N(i){return typeof i=="function"?i({}):i}var ds=C(()=>{l()});function St(i){return typeof i=="function"}function pr(i,...e){let t=e.pop();for(let r of e)for(let n in r){let a=t(i[n],r[n]);a===void 0?ie(i[n])&&ie(r[n])?i[n]=pr({},i[n],r[n],t):i[n]=r[n]:i[n]=a}return i}function Kb(i,...e){return St(i)?i(...e):i}function Zb(i){return i.reduce((e,{extend:t})=>pr(e,t,(r,n)=>r===void 0?[n]:Array.isArray(r)?[n,...r]:[n,r]),{})}function e0(i){return{...i.reduce((e,t)=>rs(e,t),{}),extend:Zb(i)}}function Ju(i,e){if(Array.isArray(i)&&ie(i[0]))return i.concat(e);if(Array.isArray(e)&&ie(e[0])&&ie(i))return[i,...e];if(Array.isArray(e))return e}function t0({extend:i,...e}){return pr(e,i,(t,r)=>!St(t)&&!r.some(St)?pr({},t,...r,Ju):(n,a)=>pr({},...[t,...r].map(s=>Kb(s,n,a)),Ju))}function*r0(i){let e=Ke(i);if(e.length===0||(yield e,Array.isArray(i)))return;let t=/^(.*?)\s*\/\s*([^/]+)$/,r=i.match(t);if(r!==null){let[,n,a]=r,s=Ke(n);s.alpha=a,yield s}}function i0(i){let e=(t,r)=>{for(let n of r0(t)){let a=0,s=i;for(;s!=null&&a(t[r]=St(i[r])?i[r](e,hs):i[r],t),{})}function Xu(i){let e=[];return i.forEach(t=>{e=[...e,t];let r=t?.plugins??[];r.length!==0&&r.forEach(n=>{n.__isOptionsFunction&&(n=n()),e=[...e,...Xu([n?.config??{}])]})}),e}function n0(i){return[...i].reduceRight((t,r)=>St(r)?r({corePlugins:t}):wu(r,t),gu)}function s0(i){return[...i].reduceRight((t,r)=>[...t,...r],[])}function ms(i){let e=[...Xu(i),{prefix:"",important:!1,separator:":"}];return Eu(rs({theme:i0(t0(e0(e.map(t=>t?.theme??{})))),corePlugins:n0(e.map(t=>t.corePlugins)),plugins:s0(i.map(t=>t?.plugins??[]))},...e))}var hs,Ku=C(()=>{l();fi();yu();bu();ts();Su();pi();Ou();xt();hi();cr();ar();ds();hs={colors:es,negative(i){return Object.keys(i).filter(e=>i[e]!=="0").reduce((e,t)=>{let r=Xe(i[t]);return r!==void 0&&(e[`-${t}`]=r),e},{})},breakpoints(i){return Object.keys(i).filter(e=>typeof i[e]=="string").reduce((e,t)=>({...e,[`screen-${t}`]:i[t]}),{})}}});var bi=v((eT,Zu)=>{l();Zu.exports={content:[],presets:[],darkMode:"media",theme:{accentColor:({theme:i})=>({...i("colors"),auto:"auto"}),animation:{none:"none",spin:"spin 1s linear infinite",ping:"ping 1s cubic-bezier(0, 0, 0.2, 1) infinite",pulse:"pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite",bounce:"bounce 1s infinite"},aria:{busy:'busy="true"',checked:'checked="true"',disabled:'disabled="true"',expanded:'expanded="true"',hidden:'hidden="true"',pressed:'pressed="true"',readonly:'readonly="true"',required:'required="true"',selected:'selected="true"'},aspectRatio:{auto:"auto",square:"1 / 1",video:"16 / 9"},backdropBlur:({theme:i})=>i("blur"),backdropBrightness:({theme:i})=>i("brightness"),backdropContrast:({theme:i})=>i("contrast"),backdropGrayscale:({theme:i})=>i("grayscale"),backdropHueRotate:({theme:i})=>i("hueRotate"),backdropInvert:({theme:i})=>i("invert"),backdropOpacity:({theme:i})=>i("opacity"),backdropSaturate:({theme:i})=>i("saturate"),backdropSepia:({theme:i})=>i("sepia"),backgroundColor:({theme:i})=>i("colors"),backgroundImage:{none:"none","gradient-to-t":"linear-gradient(to top, var(--tw-gradient-stops))","gradient-to-tr":"linear-gradient(to top right, var(--tw-gradient-stops))","gradient-to-r":"linear-gradient(to right, var(--tw-gradient-stops))","gradient-to-br":"linear-gradient(to bottom right, var(--tw-gradient-stops))","gradient-to-b":"linear-gradient(to bottom, var(--tw-gradient-stops))","gradient-to-bl":"linear-gradient(to bottom left, var(--tw-gradient-stops))","gradient-to-l":"linear-gradient(to left, var(--tw-gradient-stops))","gradient-to-tl":"linear-gradient(to top left, var(--tw-gradient-stops))"},backgroundOpacity:({theme:i})=>i("opacity"),backgroundPosition:{bottom:"bottom",center:"center",left:"left","left-bottom":"left bottom","left-top":"left top",right:"right","right-bottom":"right bottom","right-top":"right top",top:"top"},backgroundSize:{auto:"auto",cover:"cover",contain:"contain"},blur:{0:"0",none:"0",sm:"4px",DEFAULT:"8px",md:"12px",lg:"16px",xl:"24px","2xl":"40px","3xl":"64px"},borderColor:({theme:i})=>({...i("colors"),DEFAULT:i("colors.gray.200","currentColor")}),borderOpacity:({theme:i})=>i("opacity"),borderRadius:{none:"0px",sm:"0.125rem",DEFAULT:"0.25rem",md:"0.375rem",lg:"0.5rem",xl:"0.75rem","2xl":"1rem","3xl":"1.5rem",full:"9999px"},borderSpacing:({theme:i})=>({...i("spacing")}),borderWidth:{DEFAULT:"1px",0:"0px",2:"2px",4:"4px",8:"8px"},boxShadow:{sm:"0 1px 2px 0 rgb(0 0 0 / 0.05)",DEFAULT:"0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",md:"0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",lg:"0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",xl:"0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)","2xl":"0 25px 50px -12px rgb(0 0 0 / 0.25)",inner:"inset 0 2px 4px 0 rgb(0 0 0 / 0.05)",none:"none"},boxShadowColor:({theme:i})=>i("colors"),brightness:{0:"0",50:".5",75:".75",90:".9",95:".95",100:"1",105:"1.05",110:"1.1",125:"1.25",150:"1.5",200:"2"},caretColor:({theme:i})=>i("colors"),colors:({colors:i})=>({inherit:i.inherit,current:i.current,transparent:i.transparent,black:i.black,white:i.white,slate:i.slate,gray:i.gray,zinc:i.zinc,neutral:i.neutral,stone:i.stone,red:i.red,orange:i.orange,amber:i.amber,yellow:i.yellow,lime:i.lime,green:i.green,emerald:i.emerald,teal:i.teal,cyan:i.cyan,sky:i.sky,blue:i.blue,indigo:i.indigo,violet:i.violet,purple:i.purple,fuchsia:i.fuchsia,pink:i.pink,rose:i.rose}),columns:{auto:"auto",1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",7:"7",8:"8",9:"9",10:"10",11:"11",12:"12","3xs":"16rem","2xs":"18rem",xs:"20rem",sm:"24rem",md:"28rem",lg:"32rem",xl:"36rem","2xl":"42rem","3xl":"48rem","4xl":"56rem","5xl":"64rem","6xl":"72rem","7xl":"80rem"},container:{},content:{none:"none"},contrast:{0:"0",50:".5",75:".75",100:"1",125:"1.25",150:"1.5",200:"2"},cursor:{auto:"auto",default:"default",pointer:"pointer",wait:"wait",text:"text",move:"move",help:"help","not-allowed":"not-allowed",none:"none","context-menu":"context-menu",progress:"progress",cell:"cell",crosshair:"crosshair","vertical-text":"vertical-text",alias:"alias",copy:"copy","no-drop":"no-drop",grab:"grab",grabbing:"grabbing","all-scroll":"all-scroll","col-resize":"col-resize","row-resize":"row-resize","n-resize":"n-resize","e-resize":"e-resize","s-resize":"s-resize","w-resize":"w-resize","ne-resize":"ne-resize","nw-resize":"nw-resize","se-resize":"se-resize","sw-resize":"sw-resize","ew-resize":"ew-resize","ns-resize":"ns-resize","nesw-resize":"nesw-resize","nwse-resize":"nwse-resize","zoom-in":"zoom-in","zoom-out":"zoom-out"},divideColor:({theme:i})=>i("borderColor"),divideOpacity:({theme:i})=>i("borderOpacity"),divideWidth:({theme:i})=>i("borderWidth"),dropShadow:{sm:"0 1px 1px rgb(0 0 0 / 0.05)",DEFAULT:["0 1px 2px rgb(0 0 0 / 0.1)","0 1px 1px rgb(0 0 0 / 0.06)"],md:["0 4px 3px rgb(0 0 0 / 0.07)","0 2px 2px rgb(0 0 0 / 0.06)"],lg:["0 10px 8px rgb(0 0 0 / 0.04)","0 4px 3px rgb(0 0 0 / 0.1)"],xl:["0 20px 13px rgb(0 0 0 / 0.03)","0 8px 5px rgb(0 0 0 / 0.08)"],"2xl":"0 25px 25px rgb(0 0 0 / 0.15)",none:"0 0 #0000"},fill:({theme:i})=>({none:"none",...i("colors")}),flex:{1:"1 1 0%",auto:"1 1 auto",initial:"0 1 auto",none:"none"},flexBasis:({theme:i})=>({auto:"auto",...i("spacing"),"1/2":"50%","1/3":"33.333333%","2/3":"66.666667%","1/4":"25%","2/4":"50%","3/4":"75%","1/5":"20%","2/5":"40%","3/5":"60%","4/5":"80%","1/6":"16.666667%","2/6":"33.333333%","3/6":"50%","4/6":"66.666667%","5/6":"83.333333%","1/12":"8.333333%","2/12":"16.666667%","3/12":"25%","4/12":"33.333333%","5/12":"41.666667%","6/12":"50%","7/12":"58.333333%","8/12":"66.666667%","9/12":"75%","10/12":"83.333333%","11/12":"91.666667%",full:"100%"}),flexGrow:{0:"0",DEFAULT:"1"},flexShrink:{0:"0",DEFAULT:"1"},fontFamily:{sans:["ui-sans-serif","system-ui","-apple-system","BlinkMacSystemFont",'"Segoe UI"',"Roboto",'"Helvetica Neue"',"Arial",'"Noto Sans"',"sans-serif",'"Apple Color Emoji"','"Segoe UI Emoji"','"Segoe UI Symbol"','"Noto Color Emoji"'],serif:["ui-serif","Georgia","Cambria",'"Times New Roman"',"Times","serif"],mono:["ui-monospace","SFMono-Regular","Menlo","Monaco","Consolas",'"Liberation Mono"','"Courier New"',"monospace"]},fontSize:{xs:["0.75rem",{lineHeight:"1rem"}],sm:["0.875rem",{lineHeight:"1.25rem"}],base:["1rem",{lineHeight:"1.5rem"}],lg:["1.125rem",{lineHeight:"1.75rem"}],xl:["1.25rem",{lineHeight:"1.75rem"}],"2xl":["1.5rem",{lineHeight:"2rem"}],"3xl":["1.875rem",{lineHeight:"2.25rem"}],"4xl":["2.25rem",{lineHeight:"2.5rem"}],"5xl":["3rem",{lineHeight:"1"}],"6xl":["3.75rem",{lineHeight:"1"}],"7xl":["4.5rem",{lineHeight:"1"}],"8xl":["6rem",{lineHeight:"1"}],"9xl":["8rem",{lineHeight:"1"}]},fontWeight:{thin:"100",extralight:"200",light:"300",normal:"400",medium:"500",semibold:"600",bold:"700",extrabold:"800",black:"900"},gap:({theme:i})=>i("spacing"),gradientColorStops:({theme:i})=>i("colors"),gradientColorStopPositions:{"0%":"0%","5%":"5%","10%":"10%","15%":"15%","20%":"20%","25%":"25%","30%":"30%","35%":"35%","40%":"40%","45%":"45%","50%":"50%","55%":"55%","60%":"60%","65%":"65%","70%":"70%","75%":"75%","80%":"80%","85%":"85%","90%":"90%","95%":"95%","100%":"100%"},grayscale:{0:"0",DEFAULT:"100%"},gridAutoColumns:{auto:"auto",min:"min-content",max:"max-content",fr:"minmax(0, 1fr)"},gridAutoRows:{auto:"auto",min:"min-content",max:"max-content",fr:"minmax(0, 1fr)"},gridColumn:{auto:"auto","span-1":"span 1 / span 1","span-2":"span 2 / span 2","span-3":"span 3 / span 3","span-4":"span 4 / span 4","span-5":"span 5 / span 5","span-6":"span 6 / span 6","span-7":"span 7 / span 7","span-8":"span 8 / span 8","span-9":"span 9 / span 9","span-10":"span 10 / span 10","span-11":"span 11 / span 11","span-12":"span 12 / span 12","span-full":"1 / -1"},gridColumnEnd:{auto:"auto",1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",7:"7",8:"8",9:"9",10:"10",11:"11",12:"12",13:"13"},gridColumnStart:{auto:"auto",1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",7:"7",8:"8",9:"9",10:"10",11:"11",12:"12",13:"13"},gridRow:{auto:"auto","span-1":"span 1 / span 1","span-2":"span 2 / span 2","span-3":"span 3 / span 3","span-4":"span 4 / span 4","span-5":"span 5 / span 5","span-6":"span 6 / span 6","span-full":"1 / -1"},gridRowEnd:{auto:"auto",1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",7:"7"},gridRowStart:{auto:"auto",1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",7:"7"},gridTemplateColumns:{none:"none",1:"repeat(1, minmax(0, 1fr))",2:"repeat(2, minmax(0, 1fr))",3:"repeat(3, minmax(0, 1fr))",4:"repeat(4, minmax(0, 1fr))",5:"repeat(5, minmax(0, 1fr))",6:"repeat(6, minmax(0, 1fr))",7:"repeat(7, minmax(0, 1fr))",8:"repeat(8, minmax(0, 1fr))",9:"repeat(9, minmax(0, 1fr))",10:"repeat(10, minmax(0, 1fr))",11:"repeat(11, minmax(0, 1fr))",12:"repeat(12, minmax(0, 1fr))"},gridTemplateRows:{none:"none",1:"repeat(1, minmax(0, 1fr))",2:"repeat(2, minmax(0, 1fr))",3:"repeat(3, minmax(0, 1fr))",4:"repeat(4, minmax(0, 1fr))",5:"repeat(5, minmax(0, 1fr))",6:"repeat(6, minmax(0, 1fr))"},height:({theme:i})=>({auto:"auto",...i("spacing"),"1/2":"50%","1/3":"33.333333%","2/3":"66.666667%","1/4":"25%","2/4":"50%","3/4":"75%","1/5":"20%","2/5":"40%","3/5":"60%","4/5":"80%","1/6":"16.666667%","2/6":"33.333333%","3/6":"50%","4/6":"66.666667%","5/6":"83.333333%",full:"100%",screen:"100vh",min:"min-content",max:"max-content",fit:"fit-content"}),hueRotate:{0:"0deg",15:"15deg",30:"30deg",60:"60deg",90:"90deg",180:"180deg"},inset:({theme:i})=>({auto:"auto",...i("spacing"),"1/2":"50%","1/3":"33.333333%","2/3":"66.666667%","1/4":"25%","2/4":"50%","3/4":"75%",full:"100%"}),invert:{0:"0",DEFAULT:"100%"},keyframes:{spin:{to:{transform:"rotate(360deg)"}},ping:{"75%, 100%":{transform:"scale(2)",opacity:"0"}},pulse:{"50%":{opacity:".5"}},bounce:{"0%, 100%":{transform:"translateY(-25%)",animationTimingFunction:"cubic-bezier(0.8,0,1,1)"},"50%":{transform:"none",animationTimingFunction:"cubic-bezier(0,0,0.2,1)"}}},letterSpacing:{tighter:"-0.05em",tight:"-0.025em",normal:"0em",wide:"0.025em",wider:"0.05em",widest:"0.1em"},lineHeight:{none:"1",tight:"1.25",snug:"1.375",normal:"1.5",relaxed:"1.625",loose:"2",3:".75rem",4:"1rem",5:"1.25rem",6:"1.5rem",7:"1.75rem",8:"2rem",9:"2.25rem",10:"2.5rem"},listStyleType:{none:"none",disc:"disc",decimal:"decimal"},listStyleImage:{none:"none"},margin:({theme:i})=>({auto:"auto",...i("spacing")}),lineClamp:{1:"1",2:"2",3:"3",4:"4",5:"5",6:"6"},maxHeight:({theme:i})=>({...i("spacing"),none:"none",full:"100%",screen:"100vh",min:"min-content",max:"max-content",fit:"fit-content"}),maxWidth:({theme:i,breakpoints:e})=>({none:"none",0:"0rem",xs:"20rem",sm:"24rem",md:"28rem",lg:"32rem",xl:"36rem","2xl":"42rem","3xl":"48rem","4xl":"56rem","5xl":"64rem","6xl":"72rem","7xl":"80rem",full:"100%",min:"min-content",max:"max-content",fit:"fit-content",prose:"65ch",...e(i("screens"))}),minHeight:{0:"0px",full:"100%",screen:"100vh",min:"min-content",max:"max-content",fit:"fit-content"},minWidth:{0:"0px",full:"100%",min:"min-content",max:"max-content",fit:"fit-content"},objectPosition:{bottom:"bottom",center:"center",left:"left","left-bottom":"left bottom","left-top":"left top",right:"right","right-bottom":"right bottom","right-top":"right top",top:"top"},opacity:{0:"0",5:"0.05",10:"0.1",20:"0.2",25:"0.25",30:"0.3",40:"0.4",50:"0.5",60:"0.6",70:"0.7",75:"0.75",80:"0.8",90:"0.9",95:"0.95",100:"1"},order:{first:"-9999",last:"9999",none:"0",1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",7:"7",8:"8",9:"9",10:"10",11:"11",12:"12"},outlineColor:({theme:i})=>i("colors"),outlineOffset:{0:"0px",1:"1px",2:"2px",4:"4px",8:"8px"},outlineWidth:{0:"0px",1:"1px",2:"2px",4:"4px",8:"8px"},padding:({theme:i})=>i("spacing"),placeholderColor:({theme:i})=>i("colors"),placeholderOpacity:({theme:i})=>i("opacity"),ringColor:({theme:i})=>({DEFAULT:i("colors.blue.500","#3b82f6"),...i("colors")}),ringOffsetColor:({theme:i})=>i("colors"),ringOffsetWidth:{0:"0px",1:"1px",2:"2px",4:"4px",8:"8px"},ringOpacity:({theme:i})=>({DEFAULT:"0.5",...i("opacity")}),ringWidth:{DEFAULT:"3px",0:"0px",1:"1px",2:"2px",4:"4px",8:"8px"},rotate:{0:"0deg",1:"1deg",2:"2deg",3:"3deg",6:"6deg",12:"12deg",45:"45deg",90:"90deg",180:"180deg"},saturate:{0:"0",50:".5",100:"1",150:"1.5",200:"2"},scale:{0:"0",50:".5",75:".75",90:".9",95:".95",100:"1",105:"1.05",110:"1.1",125:"1.25",150:"1.5"},screens:{sm:"640px",md:"768px",lg:"1024px",xl:"1280px","2xl":"1536px"},scrollMargin:({theme:i})=>({...i("spacing")}),scrollPadding:({theme:i})=>i("spacing"),sepia:{0:"0",DEFAULT:"100%"},skew:{0:"0deg",1:"1deg",2:"2deg",3:"3deg",6:"6deg",12:"12deg"},space:({theme:i})=>({...i("spacing")}),spacing:{px:"1px",0:"0px",.5:"0.125rem",1:"0.25rem",1.5:"0.375rem",2:"0.5rem",2.5:"0.625rem",3:"0.75rem",3.5:"0.875rem",4:"1rem",5:"1.25rem",6:"1.5rem",7:"1.75rem",8:"2rem",9:"2.25rem",10:"2.5rem",11:"2.75rem",12:"3rem",14:"3.5rem",16:"4rem",20:"5rem",24:"6rem",28:"7rem",32:"8rem",36:"9rem",40:"10rem",44:"11rem",48:"12rem",52:"13rem",56:"14rem",60:"15rem",64:"16rem",72:"18rem",80:"20rem",96:"24rem"},stroke:({theme:i})=>({none:"none",...i("colors")}),strokeWidth:{0:"0",1:"1",2:"2"},supports:{},data:{},textColor:({theme:i})=>i("colors"),textDecorationColor:({theme:i})=>i("colors"),textDecorationThickness:{auto:"auto","from-font":"from-font",0:"0px",1:"1px",2:"2px",4:"4px",8:"8px"},textIndent:({theme:i})=>({...i("spacing")}),textOpacity:({theme:i})=>i("opacity"),textUnderlineOffset:{auto:"auto",0:"0px",1:"1px",2:"2px",4:"4px",8:"8px"},transformOrigin:{center:"center",top:"top","top-right":"top right",right:"right","bottom-right":"bottom right",bottom:"bottom","bottom-left":"bottom left",left:"left","top-left":"top left"},transitionDelay:{0:"0s",75:"75ms",100:"100ms",150:"150ms",200:"200ms",300:"300ms",500:"500ms",700:"700ms",1e3:"1000ms"},transitionDuration:{DEFAULT:"150ms",0:"0s",75:"75ms",100:"100ms",150:"150ms",200:"200ms",300:"300ms",500:"500ms",700:"700ms",1e3:"1000ms"},transitionProperty:{none:"none",all:"all",DEFAULT:"color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter",colors:"color, background-color, border-color, text-decoration-color, fill, stroke",opacity:"opacity",shadow:"box-shadow",transform:"transform"},transitionTimingFunction:{DEFAULT:"cubic-bezier(0.4, 0, 0.2, 1)",linear:"linear",in:"cubic-bezier(0.4, 0, 1, 1)",out:"cubic-bezier(0, 0, 0.2, 1)","in-out":"cubic-bezier(0.4, 0, 0.2, 1)"},translate:({theme:i})=>({...i("spacing"),"1/2":"50%","1/3":"33.333333%","2/3":"66.666667%","1/4":"25%","2/4":"50%","3/4":"75%",full:"100%"}),width:({theme:i})=>({auto:"auto",...i("spacing"),"1/2":"50%","1/3":"33.333333%","2/3":"66.666667%","1/4":"25%","2/4":"50%","3/4":"75%","1/5":"20%","2/5":"40%","3/5":"60%","4/5":"80%","1/6":"16.666667%","2/6":"33.333333%","3/6":"50%","4/6":"66.666667%","5/6":"83.333333%","1/12":"8.333333%","2/12":"16.666667%","3/12":"25%","4/12":"33.333333%","5/12":"41.666667%","6/12":"50%","7/12":"58.333333%","8/12":"66.666667%","9/12":"75%","10/12":"83.333333%","11/12":"91.666667%",full:"100%",screen:"100vw",min:"min-content",max:"max-content",fit:"fit-content"}),willChange:{auto:"auto",scroll:"scroll-position",contents:"contents",transform:"transform"},zIndex:{auto:"auto",0:"0",10:"10",20:"20",30:"30",40:"40",50:"50"}},plugins:[]}});function vi(i){let e=(i?.presets??[ef.default]).slice().reverse().flatMap(n=>vi(n instanceof Function?n():n)),t={respectDefaultRingColorOpacity:{theme:{ringColor:({theme:n})=>({DEFAULT:"#3b82f67f",...n("colors")})}},disableColorOpacityUtilitiesByDefault:{corePlugins:{backgroundOpacity:!1,borderOpacity:!1,divideOpacity:!1,placeholderOpacity:!1,ringOpacity:!1,textOpacity:!1}}},r=Object.keys(t).filter(n=>J(i,n)).map(n=>t[n]);return[i,...r,...e]}var ef,tf=C(()=>{l();ef=K(bi());De()});var rf={};Ae(rf,{default:()=>dr});function dr(...i){let[,...e]=vi(i[0]);return ms([...i,...e])}var gs=C(()=>{l();Ku();tf()});var nf={};Ae(nf,{default:()=>Z});var Z,mt=C(()=>{l();Z={resolve:i=>i,extname:i=>"."+i.split(".").pop()}});function xi(i){return typeof i=="object"&&i!==null}function o0(i){return Object.keys(i).length===0}function sf(i){return typeof i=="string"||i instanceof String}function ys(i){return xi(i)&&i.config===void 0&&!o0(i)?null:xi(i)&&i.config!==void 0&&sf(i.config)?Z.resolve(i.config):xi(i)&&i.config!==void 0&&xi(i.config)?null:sf(i)?Z.resolve(i):l0()}function l0(){for(let i of a0)try{let e=Z.resolve(i);return te.accessSync(e),e}catch(e){}return null}var a0,af=C(()=>{l();ze();mt();a0=["./tailwind.config.js","./tailwind.config.cjs","./tailwind.config.mjs","./tailwind.config.ts"]});var of={};Ae(of,{default:()=>ws});var ws,bs=C(()=>{l();ws={parse:i=>({href:i})}});var vs=v(()=>{l()});var ki=v((fT,ff)=>{l();"use strict";var lf=(ci(),vu),uf=vs(),Ct=class extends Error{constructor(e,t,r,n,a,s){super(e);this.name="CssSyntaxError",this.reason=e,a&&(this.file=a),n&&(this.source=n),s&&(this.plugin=s),typeof t!="undefined"&&typeof r!="undefined"&&(typeof t=="number"?(this.line=t,this.column=r):(this.line=t.line,this.column=t.column,this.endLine=r.line,this.endColumn=r.column)),this.setMessage(),Error.captureStackTrace&&Error.captureStackTrace(this,Ct)}setMessage(){this.message=this.plugin?this.plugin+": ":"",this.message+=this.file?this.file:"",typeof this.line!="undefined"&&(this.message+=":"+this.line+":"+this.column),this.message+=": "+this.reason}showSourceCode(e){if(!this.source)return"";let t=this.source;e==null&&(e=lf.isColorSupported),uf&&e&&(t=uf(t));let r=t.split(/\r?\n/),n=Math.max(this.line-3,0),a=Math.min(this.line+2,r.length),s=String(a).length,o,u;if(e){let{bold:c,red:f,gray:p}=lf.createColors(!0);o=d=>c(f(d)),u=d=>p(d)}else o=u=c=>c;return r.slice(n,a).map((c,f)=>{let p=n+1+f,d=" "+(" "+p).slice(-s)+" | ";if(p===this.line){let h=u(d.replace(/\d/g," "))+c.slice(0,this.column-1).replace(/[^\t]/g," ");return o(">")+u(d)+c+` + `+h+o("^")}return" "+u(d)+c}).join(` +`)}toString(){let e=this.showSourceCode();return e&&(e=` + +`+e+` +`),this.name+": "+this.message+e}};ff.exports=Ct;Ct.default=Ct});var Si=v((cT,xs)=>{l();"use strict";xs.exports.isClean=Symbol("isClean");xs.exports.my=Symbol("my")});var ks=v((pT,pf)=>{l();"use strict";var cf={colon:": ",indent:" ",beforeDecl:` +`,beforeRule:` +`,beforeOpen:" ",beforeClose:` +`,beforeComment:` +`,after:` +`,emptyBody:"",commentLeft:" ",commentRight:" ",semicolon:!1};function u0(i){return i[0].toUpperCase()+i.slice(1)}var Ci=class{constructor(e){this.builder=e}stringify(e,t){if(!this[e.type])throw new Error("Unknown AST node type "+e.type+". Maybe you need to change PostCSS stringifier.");this[e.type](e,t)}document(e){this.body(e)}root(e){this.body(e),e.raws.after&&this.builder(e.raws.after)}comment(e){let t=this.raw(e,"left","commentLeft"),r=this.raw(e,"right","commentRight");this.builder("/*"+t+e.text+r+"*/",e)}decl(e,t){let r=this.raw(e,"between","colon"),n=e.prop+r+this.rawValue(e,"value");e.important&&(n+=e.raws.important||" !important"),t&&(n+=";"),this.builder(n,e)}rule(e){this.block(e,this.rawValue(e,"selector")),e.raws.ownSemicolon&&this.builder(e.raws.ownSemicolon,e,"end")}atrule(e,t){let r="@"+e.name,n=e.params?this.rawValue(e,"params"):"";if(typeof e.raws.afterName!="undefined"?r+=e.raws.afterName:n&&(r+=" "),e.nodes)this.block(e,r+n);else{let a=(e.raws.between||"")+(t?";":"");this.builder(r+n+a,e)}}body(e){let t=e.nodes.length-1;for(;t>0&&e.nodes[t].type==="comment";)t-=1;let r=this.raw(e,"semicolon");for(let n=0;n{if(n=u.raws[t],typeof n!="undefined")return!1})}return typeof n=="undefined"&&(n=cf[r]),s.rawCache[r]=n,n}rawSemicolon(e){let t;return e.walk(r=>{if(r.nodes&&r.nodes.length&&r.last.type==="decl"&&(t=r.raws.semicolon,typeof t!="undefined"))return!1}),t}rawEmptyBody(e){let t;return e.walk(r=>{if(r.nodes&&r.nodes.length===0&&(t=r.raws.after,typeof t!="undefined"))return!1}),t}rawIndent(e){if(e.raws.indent)return e.raws.indent;let t;return e.walk(r=>{let n=r.parent;if(n&&n!==e&&n.parent&&n.parent===e&&typeof r.raws.before!="undefined"){let a=r.raws.before.split(` +`);return t=a[a.length-1],t=t.replace(/\S/g,""),!1}}),t}rawBeforeComment(e,t){let r;return e.walkComments(n=>{if(typeof n.raws.before!="undefined")return r=n.raws.before,r.includes(` +`)&&(r=r.replace(/[^\n]+$/,"")),!1}),typeof r=="undefined"?r=this.raw(t,null,"beforeDecl"):r&&(r=r.replace(/\S/g,"")),r}rawBeforeDecl(e,t){let r;return e.walkDecls(n=>{if(typeof n.raws.before!="undefined")return r=n.raws.before,r.includes(` +`)&&(r=r.replace(/[^\n]+$/,"")),!1}),typeof r=="undefined"?r=this.raw(t,null,"beforeRule"):r&&(r=r.replace(/\S/g,"")),r}rawBeforeRule(e){let t;return e.walk(r=>{if(r.nodes&&(r.parent!==e||e.first!==r)&&typeof r.raws.before!="undefined")return t=r.raws.before,t.includes(` +`)&&(t=t.replace(/[^\n]+$/,"")),!1}),t&&(t=t.replace(/\S/g,"")),t}rawBeforeClose(e){let t;return e.walk(r=>{if(r.nodes&&r.nodes.length>0&&typeof r.raws.after!="undefined")return t=r.raws.after,t.includes(` +`)&&(t=t.replace(/[^\n]+$/,"")),!1}),t&&(t=t.replace(/\S/g,"")),t}rawBeforeOpen(e){let t;return e.walk(r=>{if(r.type!=="decl"&&(t=r.raws.between,typeof t!="undefined"))return!1}),t}rawColon(e){let t;return e.walkDecls(r=>{if(typeof r.raws.between!="undefined")return t=r.raws.between.replace(/[^\s:]/g,""),!1}),t}beforeAfter(e,t){let r;e.type==="decl"?r=this.raw(e,null,"beforeDecl"):e.type==="comment"?r=this.raw(e,null,"beforeComment"):t==="before"?r=this.raw(e,null,"beforeRule"):r=this.raw(e,null,"beforeClose");let n=e.parent,a=0;for(;n&&n.type!=="root";)a+=1,n=n.parent;if(r.includes(` +`)){let s=this.raw(e,null,"indent");if(s.length)for(let o=0;o{l();"use strict";var f0=ks();function Ss(i,e){new f0(e).stringify(i)}df.exports=Ss;Ss.default=Ss});var mr=v((hT,hf)=>{l();"use strict";var{isClean:Ai,my:c0}=Si(),p0=ki(),d0=ks(),h0=hr();function Cs(i,e){let t=new i.constructor;for(let r in i){if(!Object.prototype.hasOwnProperty.call(i,r)||r==="proxyCache")continue;let n=i[r],a=typeof n;r==="parent"&&a==="object"?e&&(t[r]=e):r==="source"?t[r]=n:Array.isArray(n)?t[r]=n.map(s=>Cs(s,t)):(a==="object"&&n!==null&&(n=Cs(n)),t[r]=n)}return t}var _i=class{constructor(e={}){this.raws={},this[Ai]=!1,this[c0]=!0;for(let t in e)if(t==="nodes"){this.nodes=[];for(let r of e[t])typeof r.clone=="function"?this.append(r.clone()):this.append(r)}else this[t]=e[t]}error(e,t={}){if(this.source){let{start:r,end:n}=this.rangeBy(t);return this.source.input.error(e,{line:r.line,column:r.column},{line:n.line,column:n.column},t)}return new p0(e)}warn(e,t,r){let n={node:this};for(let a in r)n[a]=r[a];return e.warn(t,n)}remove(){return this.parent&&this.parent.removeChild(this),this.parent=void 0,this}toString(e=h0){e.stringify&&(e=e.stringify);let t="";return e(this,r=>{t+=r}),t}assign(e={}){for(let t in e)this[t]=e[t];return this}clone(e={}){let t=Cs(this);for(let r in e)t[r]=e[r];return t}cloneBefore(e={}){let t=this.clone(e);return this.parent.insertBefore(this,t),t}cloneAfter(e={}){let t=this.clone(e);return this.parent.insertAfter(this,t),t}replaceWith(...e){if(this.parent){let t=this,r=!1;for(let n of e)n===this?r=!0:r?(this.parent.insertAfter(t,n),t=n):this.parent.insertBefore(t,n);r||this.remove()}return this}next(){if(!this.parent)return;let e=this.parent.index(this);return this.parent.nodes[e+1]}prev(){if(!this.parent)return;let e=this.parent.index(this);return this.parent.nodes[e-1]}before(e){return this.parent.insertBefore(this,e),this}after(e){return this.parent.insertAfter(this,e),this}root(){let e=this;for(;e.parent&&e.parent.type!=="document";)e=e.parent;return e}raw(e,t){return new d0().raw(this,e,t)}cleanRaws(e){delete this.raws.before,delete this.raws.after,e||delete this.raws.between}toJSON(e,t){let r={},n=t==null;t=t||new Map;let a=0;for(let s in this){if(!Object.prototype.hasOwnProperty.call(this,s)||s==="parent"||s==="proxyCache")continue;let o=this[s];if(Array.isArray(o))r[s]=o.map(u=>typeof u=="object"&&u.toJSON?u.toJSON(null,t):u);else if(typeof o=="object"&&o.toJSON)r[s]=o.toJSON(null,t);else if(s==="source"){let u=t.get(o.input);u==null&&(u=a,t.set(o.input,a),a++),r[s]={inputId:u,start:o.start,end:o.end}}else r[s]=o}return n&&(r.inputs=[...t.keys()].map(s=>s.toJSON())),r}positionInside(e){let t=this.toString(),r=this.source.start.column,n=this.source.start.line;for(let a=0;ae.root().toProxy():e[t]}}}toProxy(){return this.proxyCache||(this.proxyCache=new Proxy(this,this.getProxyProcessor())),this.proxyCache}addToError(e){if(e.postcssNode=this,e.stack&&this.source&&/\n\s{4}at /.test(e.stack)){let t=this.source;e.stack=e.stack.replace(/\n\s{4}at /,`$&${t.input.from}:${t.start.line}:${t.start.column}$&`)}return e}markDirty(){if(this[Ai]){this[Ai]=!1;let e=this;for(;e=e.parent;)e[Ai]=!1}}get proxyOf(){return this}};hf.exports=_i;_i.default=_i});var gr=v((mT,mf)=>{l();"use strict";var m0=mr(),Ei=class extends m0{constructor(e){e&&typeof e.value!="undefined"&&typeof e.value!="string"&&(e={...e,value:String(e.value)});super(e);this.type="decl"}get variable(){return this.prop.startsWith("--")||this.prop[0]==="$"}};mf.exports=Ei;Ei.default=Ei});var As=v((gT,gf)=>{l();gf.exports=function(i,e){return{generate:()=>{let t="";return i(e,r=>{t+=r}),[t]}}}});var yr=v((yT,yf)=>{l();"use strict";var g0=mr(),Oi=class extends g0{constructor(e){super(e);this.type="comment"}};yf.exports=Oi;Oi.default=Oi});var it=v((wT,_f)=>{l();"use strict";var{isClean:wf,my:bf}=Si(),vf=gr(),xf=yr(),y0=mr(),kf,_s,Es,Sf;function Cf(i){return i.map(e=>(e.nodes&&(e.nodes=Cf(e.nodes)),delete e.source,e))}function Af(i){if(i[wf]=!1,i.proxyOf.nodes)for(let e of i.proxyOf.nodes)Af(e)}var ye=class extends y0{push(e){return e.parent=this,this.proxyOf.nodes.push(e),this}each(e){if(!this.proxyOf.nodes)return;let t=this.getIterator(),r,n;for(;this.indexes[t]{let n;try{n=e(t,r)}catch(a){throw t.addToError(a)}return n!==!1&&t.walk&&(n=t.walk(e)),n})}walkDecls(e,t){return t?e instanceof RegExp?this.walk((r,n)=>{if(r.type==="decl"&&e.test(r.prop))return t(r,n)}):this.walk((r,n)=>{if(r.type==="decl"&&r.prop===e)return t(r,n)}):(t=e,this.walk((r,n)=>{if(r.type==="decl")return t(r,n)}))}walkRules(e,t){return t?e instanceof RegExp?this.walk((r,n)=>{if(r.type==="rule"&&e.test(r.selector))return t(r,n)}):this.walk((r,n)=>{if(r.type==="rule"&&r.selector===e)return t(r,n)}):(t=e,this.walk((r,n)=>{if(r.type==="rule")return t(r,n)}))}walkAtRules(e,t){return t?e instanceof RegExp?this.walk((r,n)=>{if(r.type==="atrule"&&e.test(r.name))return t(r,n)}):this.walk((r,n)=>{if(r.type==="atrule"&&r.name===e)return t(r,n)}):(t=e,this.walk((r,n)=>{if(r.type==="atrule")return t(r,n)}))}walkComments(e){return this.walk((t,r)=>{if(t.type==="comment")return e(t,r)})}append(...e){for(let t of e){let r=this.normalize(t,this.last);for(let n of r)this.proxyOf.nodes.push(n)}return this.markDirty(),this}prepend(...e){e=e.reverse();for(let t of e){let r=this.normalize(t,this.first,"prepend").reverse();for(let n of r)this.proxyOf.nodes.unshift(n);for(let n in this.indexes)this.indexes[n]=this.indexes[n]+r.length}return this.markDirty(),this}cleanRaws(e){if(super.cleanRaws(e),this.nodes)for(let t of this.nodes)t.cleanRaws(e)}insertBefore(e,t){let r=this.index(e),n=r===0?"prepend":!1,a=this.normalize(t,this.proxyOf.nodes[r],n).reverse();r=this.index(e);for(let o of a)this.proxyOf.nodes.splice(r,0,o);let s;for(let o in this.indexes)s=this.indexes[o],r<=s&&(this.indexes[o]=s+a.length);return this.markDirty(),this}insertAfter(e,t){let r=this.index(e),n=this.normalize(t,this.proxyOf.nodes[r]).reverse();r=this.index(e);for(let s of n)this.proxyOf.nodes.splice(r+1,0,s);let a;for(let s in this.indexes)a=this.indexes[s],r=e&&(this.indexes[r]=t-1);return this.markDirty(),this}removeAll(){for(let e of this.proxyOf.nodes)e.parent=void 0;return this.proxyOf.nodes=[],this.markDirty(),this}replaceValues(e,t,r){return r||(r=t,t={}),this.walkDecls(n=>{t.props&&!t.props.includes(n.prop)||t.fast&&!n.value.includes(t.fast)||(n.value=n.value.replace(e,r))}),this.markDirty(),this}every(e){return this.nodes.every(e)}some(e){return this.nodes.some(e)}index(e){return typeof e=="number"?e:(e.proxyOf&&(e=e.proxyOf),this.proxyOf.nodes.indexOf(e))}get first(){if(!!this.proxyOf.nodes)return this.proxyOf.nodes[0]}get last(){if(!!this.proxyOf.nodes)return this.proxyOf.nodes[this.proxyOf.nodes.length-1]}normalize(e,t){if(typeof e=="string")e=Cf(kf(e).nodes);else if(Array.isArray(e)){e=e.slice(0);for(let n of e)n.parent&&n.parent.removeChild(n,"ignore")}else if(e.type==="root"&&this.type!=="document"){e=e.nodes.slice(0);for(let n of e)n.parent&&n.parent.removeChild(n,"ignore")}else if(e.type)e=[e];else if(e.prop){if(typeof e.value=="undefined")throw new Error("Value field is missed in node creation");typeof e.value!="string"&&(e.value=String(e.value)),e=[new vf(e)]}else if(e.selector)e=[new _s(e)];else if(e.name)e=[new Es(e)];else if(e.text)e=[new xf(e)];else throw new Error("Unknown node type in node creation");return e.map(n=>(n[bf]||ye.rebuild(n),n=n.proxyOf,n.parent&&n.parent.removeChild(n),n[wf]&&Af(n),typeof n.raws.before=="undefined"&&t&&typeof t.raws.before!="undefined"&&(n.raws.before=t.raws.before.replace(/\S/g,"")),n.parent=this.proxyOf,n))}getProxyProcessor(){return{set(e,t,r){return e[t]===r||(e[t]=r,(t==="name"||t==="params"||t==="selector")&&e.markDirty()),!0},get(e,t){return t==="proxyOf"?e:e[t]?t==="each"||typeof t=="string"&&t.startsWith("walk")?(...r)=>e[t](...r.map(n=>typeof n=="function"?(a,s)=>n(a.toProxy(),s):n)):t==="every"||t==="some"?r=>e[t]((n,...a)=>r(n.toProxy(),...a)):t==="root"?()=>e.root().toProxy():t==="nodes"?e.nodes.map(r=>r.toProxy()):t==="first"||t==="last"?e[t].toProxy():e[t]:e[t]}}}getIterator(){this.lastEach||(this.lastEach=0),this.indexes||(this.indexes={}),this.lastEach+=1;let e=this.lastEach;return this.indexes[e]=0,e}};ye.registerParse=i=>{kf=i};ye.registerRule=i=>{_s=i};ye.registerAtRule=i=>{Es=i};ye.registerRoot=i=>{Sf=i};_f.exports=ye;ye.default=ye;ye.rebuild=i=>{i.type==="atrule"?Object.setPrototypeOf(i,Es.prototype):i.type==="rule"?Object.setPrototypeOf(i,_s.prototype):i.type==="decl"?Object.setPrototypeOf(i,vf.prototype):i.type==="comment"?Object.setPrototypeOf(i,xf.prototype):i.type==="root"&&Object.setPrototypeOf(i,Sf.prototype),i[bf]=!0,i.nodes&&i.nodes.forEach(e=>{ye.rebuild(e)})}});var Ti=v((bT,Tf)=>{l();"use strict";var w0=it(),Ef,Of,At=class extends w0{constructor(e){super({type:"document",...e});this.nodes||(this.nodes=[])}toResult(e={}){return new Ef(new Of,this,e).stringify()}};At.registerLazyResult=i=>{Ef=i};At.registerProcessor=i=>{Of=i};Tf.exports=At;At.default=At});var Os=v((vT,Df)=>{l();"use strict";var Pf={};Df.exports=function(e){Pf[e]||(Pf[e]=!0,typeof console!="undefined"&&console.warn&&console.warn(e))}});var Ts=v((xT,If)=>{l();"use strict";var Pi=class{constructor(e,t={}){if(this.type="warning",this.text=e,t.node&&t.node.source){let r=t.node.rangeBy(t);this.line=r.start.line,this.column=r.start.column,this.endLine=r.end.line,this.endColumn=r.end.column}for(let r in t)this[r]=t[r]}toString(){return this.node?this.node.error(this.text,{plugin:this.plugin,index:this.index,word:this.word}).message:this.plugin?this.plugin+": "+this.text:this.text}};If.exports=Pi;Pi.default=Pi});var Ii=v((kT,qf)=>{l();"use strict";var b0=Ts(),Di=class{constructor(e,t,r){this.processor=e,this.messages=[],this.root=t,this.opts=r,this.css=void 0,this.map=void 0}toString(){return this.css}warn(e,t={}){t.plugin||this.lastPlugin&&this.lastPlugin.postcssPlugin&&(t.plugin=this.lastPlugin.postcssPlugin);let r=new b0(e,t);return this.messages.push(r),r}warnings(){return this.messages.filter(e=>e.type==="warning")}get content(){return this.css}};qf.exports=Di;Di.default=Di});var Nf=v((ST,Ff)=>{l();"use strict";var Ps="'".charCodeAt(0),Rf='"'.charCodeAt(0),qi="\\".charCodeAt(0),Mf="/".charCodeAt(0),Ri=` +`.charCodeAt(0),wr=" ".charCodeAt(0),Mi="\f".charCodeAt(0),Bi=" ".charCodeAt(0),Fi="\r".charCodeAt(0),v0="[".charCodeAt(0),x0="]".charCodeAt(0),k0="(".charCodeAt(0),S0=")".charCodeAt(0),C0="{".charCodeAt(0),A0="}".charCodeAt(0),_0=";".charCodeAt(0),E0="*".charCodeAt(0),O0=":".charCodeAt(0),T0="@".charCodeAt(0),Ni=/[\t\n\f\r "#'()/;[\\\]{}]/g,Li=/[\t\n\f\r !"#'():;@[\\\]{}]|\/(?=\*)/g,P0=/.[\n"'(/\\]/,Bf=/[\da-f]/i;Ff.exports=function(e,t={}){let r=e.css.valueOf(),n=t.ignoreErrors,a,s,o,u,c,f,p,d,h,y,x=r.length,w=0,b=[],k=[];function S(){return w}function _(q){throw e.error("Unclosed "+q,w)}function E(){return k.length===0&&w>=x}function I(q){if(k.length)return k.pop();if(w>=x)return;let X=q?q.ignoreUnclosed:!1;switch(a=r.charCodeAt(w),a){case Ri:case wr:case Bi:case Fi:case Mi:{s=w;do s+=1,a=r.charCodeAt(s);while(a===wr||a===Ri||a===Bi||a===Fi||a===Mi);y=["space",r.slice(w,s)],w=s-1;break}case v0:case x0:case C0:case A0:case O0:case _0:case S0:{let ae=String.fromCharCode(a);y=[ae,ae,w];break}case k0:{if(d=b.length?b.pop()[1]:"",h=r.charCodeAt(w+1),d==="url"&&h!==Ps&&h!==Rf&&h!==wr&&h!==Ri&&h!==Bi&&h!==Mi&&h!==Fi){s=w;do{if(f=!1,s=r.indexOf(")",s+1),s===-1)if(n||X){s=w;break}else _("bracket");for(p=s;r.charCodeAt(p-1)===qi;)p-=1,f=!f}while(f);y=["brackets",r.slice(w,s+1),w,s],w=s}else s=r.indexOf(")",w+1),u=r.slice(w,s+1),s===-1||P0.test(u)?y=["(","(",w]:(y=["brackets",u,w,s],w=s);break}case Ps:case Rf:{o=a===Ps?"'":'"',s=w;do{if(f=!1,s=r.indexOf(o,s+1),s===-1)if(n||X){s=w+1;break}else _("string");for(p=s;r.charCodeAt(p-1)===qi;)p-=1,f=!f}while(f);y=["string",r.slice(w,s+1),w,s],w=s;break}case T0:{Ni.lastIndex=w+1,Ni.test(r),Ni.lastIndex===0?s=r.length-1:s=Ni.lastIndex-2,y=["at-word",r.slice(w,s+1),w,s],w=s;break}case qi:{for(s=w,c=!0;r.charCodeAt(s+1)===qi;)s+=1,c=!c;if(a=r.charCodeAt(s+1),c&&a!==Mf&&a!==wr&&a!==Ri&&a!==Bi&&a!==Fi&&a!==Mi&&(s+=1,Bf.test(r.charAt(s)))){for(;Bf.test(r.charAt(s+1));)s+=1;r.charCodeAt(s+1)===wr&&(s+=1)}y=["word",r.slice(w,s+1),w,s],w=s;break}default:{a===Mf&&r.charCodeAt(w+1)===E0?(s=r.indexOf("*/",w+2)+1,s===0&&(n||X?s=r.length:_("comment")),y=["comment",r.slice(w,s+1),w,s],w=s):(Li.lastIndex=w+1,Li.test(r),Li.lastIndex===0?s=r.length-1:s=Li.lastIndex-2,y=["word",r.slice(w,s+1),w,s],b.push(y),w=s);break}}return w++,y}function B(q){k.push(q)}return{back:B,nextToken:I,endOfFile:E,position:S}}});var $i=v((CT,$f)=>{l();"use strict";var Lf=it(),br=class extends Lf{constructor(e){super(e);this.type="atrule"}append(...e){return this.proxyOf.nodes||(this.nodes=[]),super.append(...e)}prepend(...e){return this.proxyOf.nodes||(this.nodes=[]),super.prepend(...e)}};$f.exports=br;br.default=br;Lf.registerAtRule(br)});var _t=v((AT,Uf)=>{l();"use strict";var jf=it(),zf,Vf,gt=class extends jf{constructor(e){super(e);this.type="root",this.nodes||(this.nodes=[])}removeChild(e,t){let r=this.index(e);return!t&&r===0&&this.nodes.length>1&&(this.nodes[1].raws.before=this.nodes[r].raws.before),super.removeChild(e)}normalize(e,t,r){let n=super.normalize(e);if(t){if(r==="prepend")this.nodes.length>1?t.raws.before=this.nodes[1].raws.before:delete t.raws.before;else if(this.first!==t)for(let a of n)a.raws.before=t.raws.before}return n}toResult(e={}){return new zf(new Vf,this,e).stringify()}};gt.registerLazyResult=i=>{zf=i};gt.registerProcessor=i=>{Vf=i};Uf.exports=gt;gt.default=gt;jf.registerRoot(gt)});var Ds=v((_T,Wf)=>{l();"use strict";var vr={split(i,e,t){let r=[],n="",a=!1,s=0,o=!1,u="",c=!1;for(let f of i)c?c=!1:f==="\\"?c=!0:o?f===u&&(o=!1):f==='"'||f==="'"?(o=!0,u=f):f==="("?s+=1:f===")"?s>0&&(s-=1):s===0&&e.includes(f)&&(a=!0),a?(n!==""&&r.push(n.trim()),n="",a=!1):n+=f;return(t||n!=="")&&r.push(n.trim()),r},space(i){let e=[" ",` +`," "];return vr.split(i,e)},comma(i){return vr.split(i,[","],!0)}};Wf.exports=vr;vr.default=vr});var ji=v((ET,Hf)=>{l();"use strict";var Gf=it(),D0=Ds(),xr=class extends Gf{constructor(e){super(e);this.type="rule",this.nodes||(this.nodes=[])}get selectors(){return D0.comma(this.selector)}set selectors(e){let t=this.selector?this.selector.match(/,\s*/):null,r=t?t[0]:","+this.raw("between","beforeOpen");this.selector=e.join(r)}};Hf.exports=xr;xr.default=xr;Gf.registerRule(xr)});var Kf=v((OT,Xf)=>{l();"use strict";var I0=gr(),q0=Nf(),R0=yr(),M0=$i(),B0=_t(),Yf=ji(),Qf={empty:!0,space:!0};function F0(i){for(let e=i.length-1;e>=0;e--){let t=i[e],r=t[3]||t[2];if(r)return r}}var Jf=class{constructor(e){this.input=e,this.root=new B0,this.current=this.root,this.spaces="",this.semicolon=!1,this.customProperty=!1,this.createTokenizer(),this.root.source={input:e,start:{offset:0,line:1,column:1}}}createTokenizer(){this.tokenizer=q0(this.input)}parse(){let e;for(;!this.tokenizer.endOfFile();)switch(e=this.tokenizer.nextToken(),e[0]){case"space":this.spaces+=e[1];break;case";":this.freeSemicolon(e);break;case"}":this.end(e);break;case"comment":this.comment(e);break;case"at-word":this.atrule(e);break;case"{":this.emptyRule(e);break;default:this.other(e);break}this.endFile()}comment(e){let t=new R0;this.init(t,e[2]),t.source.end=this.getPosition(e[3]||e[2]);let r=e[1].slice(2,-2);if(/^\s*$/.test(r))t.text="",t.raws.left=r,t.raws.right="";else{let n=r.match(/^(\s*)([^]*\S)(\s*)$/);t.text=n[2],t.raws.left=n[1],t.raws.right=n[3]}}emptyRule(e){let t=new Yf;this.init(t,e[2]),t.selector="",t.raws.between="",this.current=t}other(e){let t=!1,r=null,n=!1,a=null,s=[],o=e[1].startsWith("--"),u=[],c=e;for(;c;){if(r=c[0],u.push(c),r==="("||r==="[")a||(a=c),s.push(r==="("?")":"]");else if(o&&n&&r==="{")a||(a=c),s.push("}");else if(s.length===0)if(r===";")if(n){this.decl(u,o);return}else break;else if(r==="{"){this.rule(u);return}else if(r==="}"){this.tokenizer.back(u.pop()),t=!0;break}else r===":"&&(n=!0);else r===s[s.length-1]&&(s.pop(),s.length===0&&(a=null));c=this.tokenizer.nextToken()}if(this.tokenizer.endOfFile()&&(t=!0),s.length>0&&this.unclosedBracket(a),t&&n){if(!o)for(;u.length&&(c=u[u.length-1][0],!(c!=="space"&&c!=="comment"));)this.tokenizer.back(u.pop());this.decl(u,o)}else this.unknownWord(u)}rule(e){e.pop();let t=new Yf;this.init(t,e[0][2]),t.raws.between=this.spacesAndCommentsFromEnd(e),this.raw(t,"selector",e),this.current=t}decl(e,t){let r=new I0;this.init(r,e[0][2]);let n=e[e.length-1];for(n[0]===";"&&(this.semicolon=!0,e.pop()),r.source.end=this.getPosition(n[3]||n[2]||F0(e));e[0][0]!=="word";)e.length===1&&this.unknownWord(e),r.raws.before+=e.shift()[1];for(r.source.start=this.getPosition(e[0][2]),r.prop="";e.length;){let c=e[0][0];if(c===":"||c==="space"||c==="comment")break;r.prop+=e.shift()[1]}r.raws.between="";let a;for(;e.length;)if(a=e.shift(),a[0]===":"){r.raws.between+=a[1];break}else a[0]==="word"&&/\w/.test(a[1])&&this.unknownWord([a]),r.raws.between+=a[1];(r.prop[0]==="_"||r.prop[0]==="*")&&(r.raws.before+=r.prop[0],r.prop=r.prop.slice(1));let s=[],o;for(;e.length&&(o=e[0][0],!(o!=="space"&&o!=="comment"));)s.push(e.shift());this.precheckMissedSemicolon(e);for(let c=e.length-1;c>=0;c--){if(a=e[c],a[1].toLowerCase()==="!important"){r.important=!0;let f=this.stringFrom(e,c);f=this.spacesFromEnd(e)+f,f!==" !important"&&(r.raws.important=f);break}else if(a[1].toLowerCase()==="important"){let f=e.slice(0),p="";for(let d=c;d>0;d--){let h=f[d][0];if(p.trim().indexOf("!")===0&&h!=="space")break;p=f.pop()[1]+p}p.trim().indexOf("!")===0&&(r.important=!0,r.raws.important=p,e=f)}if(a[0]!=="space"&&a[0]!=="comment")break}e.some(c=>c[0]!=="space"&&c[0]!=="comment")&&(r.raws.between+=s.map(c=>c[1]).join(""),s=[]),this.raw(r,"value",s.concat(e),t),r.value.includes(":")&&!t&&this.checkMissedSemicolon(e)}atrule(e){let t=new M0;t.name=e[1].slice(1),t.name===""&&this.unnamedAtrule(t,e),this.init(t,e[2]);let r,n,a,s=!1,o=!1,u=[],c=[];for(;!this.tokenizer.endOfFile();){if(e=this.tokenizer.nextToken(),r=e[0],r==="("||r==="["?c.push(r==="("?")":"]"):r==="{"&&c.length>0?c.push("}"):r===c[c.length-1]&&c.pop(),c.length===0)if(r===";"){t.source.end=this.getPosition(e[2]),this.semicolon=!0;break}else if(r==="{"){o=!0;break}else if(r==="}"){if(u.length>0){for(a=u.length-1,n=u[a];n&&n[0]==="space";)n=u[--a];n&&(t.source.end=this.getPosition(n[3]||n[2]))}this.end(e);break}else u.push(e);else u.push(e);if(this.tokenizer.endOfFile()){s=!0;break}}t.raws.between=this.spacesAndCommentsFromEnd(u),u.length?(t.raws.afterName=this.spacesAndCommentsFromStart(u),this.raw(t,"params",u),s&&(e=u[u.length-1],t.source.end=this.getPosition(e[3]||e[2]),this.spaces=t.raws.between,t.raws.between="")):(t.raws.afterName="",t.params=""),o&&(t.nodes=[],this.current=t)}end(e){this.current.nodes&&this.current.nodes.length&&(this.current.raws.semicolon=this.semicolon),this.semicolon=!1,this.current.raws.after=(this.current.raws.after||"")+this.spaces,this.spaces="",this.current.parent?(this.current.source.end=this.getPosition(e[2]),this.current=this.current.parent):this.unexpectedClose(e)}endFile(){this.current.parent&&this.unclosedBlock(),this.current.nodes&&this.current.nodes.length&&(this.current.raws.semicolon=this.semicolon),this.current.raws.after=(this.current.raws.after||"")+this.spaces}freeSemicolon(e){if(this.spaces+=e[1],this.current.nodes){let t=this.current.nodes[this.current.nodes.length-1];t&&t.type==="rule"&&!t.raws.ownSemicolon&&(t.raws.ownSemicolon=this.spaces,this.spaces="")}}getPosition(e){let t=this.input.fromOffset(e);return{offset:e,line:t.line,column:t.col}}init(e,t){this.current.push(e),e.source={start:this.getPosition(t),input:this.input},e.raws.before=this.spaces,this.spaces="",e.type!=="comment"&&(this.semicolon=!1)}raw(e,t,r,n){let a,s,o=r.length,u="",c=!0,f,p;for(let d=0;dh+y[1],"");e.raws[t]={value:u,raw:d}}e[t]=u}spacesAndCommentsFromEnd(e){let t,r="";for(;e.length&&(t=e[e.length-1][0],!(t!=="space"&&t!=="comment"));)r=e.pop()[1]+r;return r}spacesAndCommentsFromStart(e){let t,r="";for(;e.length&&(t=e[0][0],!(t!=="space"&&t!=="comment"));)r+=e.shift()[1];return r}spacesFromEnd(e){let t,r="";for(;e.length&&(t=e[e.length-1][0],t==="space");)r=e.pop()[1]+r;return r}stringFrom(e,t){let r="";for(let n=t;n=0&&(n=e[a],!(n[0]!=="space"&&(r+=1,r===2)));a--);throw this.input.error("Missed semicolon",n[0]==="word"?n[3]+1:n[2])}};Xf.exports=Jf});var Zf=v(()=>{l()});var tc=v((DT,ec)=>{l();var N0="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict",L0=(i,e=21)=>(t=e)=>{let r="",n=t;for(;n--;)r+=i[Math.random()*i.length|0];return r},$0=(i=21)=>{let e="",t=i;for(;t--;)e+=N0[Math.random()*64|0];return e};ec.exports={nanoid:$0,customAlphabet:L0}});var Is=v((IT,rc)=>{l();rc.exports={}});var Vi=v((qT,ac)=>{l();"use strict";var{SourceMapConsumer:j0,SourceMapGenerator:z0}=Zf(),{fileURLToPath:ic,pathToFileURL:zi}=(bs(),of),{resolve:qs,isAbsolute:Rs}=(mt(),nf),{nanoid:V0}=tc(),Ms=vs(),nc=ki(),U0=Is(),Bs=Symbol("fromOffsetCache"),W0=Boolean(j0&&z0),sc=Boolean(qs&&Rs),kr=class{constructor(e,t={}){if(e===null||typeof e=="undefined"||typeof e=="object"&&!e.toString)throw new Error(`PostCSS received ${e} instead of CSS string`);if(this.css=e.toString(),this.css[0]==="\uFEFF"||this.css[0]==="\uFFFE"?(this.hasBOM=!0,this.css=this.css.slice(1)):this.hasBOM=!1,t.from&&(!sc||/^\w+:\/\//.test(t.from)||Rs(t.from)?this.file=t.from:this.file=qs(t.from)),sc&&W0){let r=new U0(this.css,t);if(r.text){this.map=r;let n=r.consumer().file;!this.file&&n&&(this.file=this.mapResolve(n))}}this.file||(this.id=""),this.map&&(this.map.file=this.from)}fromOffset(e){let t,r;if(this[Bs])r=this[Bs];else{let a=this.css.split(` +`);r=new Array(a.length);let s=0;for(let o=0,u=a.length;o=t)n=r.length-1;else{let a=r.length-2,s;for(;n>1),e=r[s+1])n=s+1;else{n=s;break}}return{line:n+1,col:e-r[n]+1}}error(e,t,r,n={}){let a,s,o;if(t&&typeof t=="object"){let c=t,f=r;if(typeof c.offset=="number"){let p=this.fromOffset(c.offset);t=p.line,r=p.col}else t=c.line,r=c.column;if(typeof f.offset=="number"){let p=this.fromOffset(f.offset);s=p.line,o=p.col}else s=f.line,o=f.column}else if(!r){let c=this.fromOffset(t);t=c.line,r=c.col}let u=this.origin(t,r,s,o);return u?a=new nc(e,u.endLine===void 0?u.line:{line:u.line,column:u.column},u.endLine===void 0?u.column:{line:u.endLine,column:u.endColumn},u.source,u.file,n.plugin):a=new nc(e,s===void 0?t:{line:t,column:r},s===void 0?r:{line:s,column:o},this.css,this.file,n.plugin),a.input={line:t,column:r,endLine:s,endColumn:o,source:this.css},this.file&&(zi&&(a.input.url=zi(this.file).toString()),a.input.file=this.file),a}origin(e,t,r,n){if(!this.map)return!1;let a=this.map.consumer(),s=a.originalPositionFor({line:e,column:t});if(!s.source)return!1;let o;typeof r=="number"&&(o=a.originalPositionFor({line:r,column:n}));let u;Rs(s.source)?u=zi(s.source):u=new URL(s.source,this.map.consumer().sourceRoot||zi(this.map.mapFile));let c={url:u.toString(),line:s.line,column:s.column,endLine:o&&o.line,endColumn:o&&o.column};if(u.protocol==="file:")if(ic)c.file=ic(u);else throw new Error("file: protocol is not available in this PostCSS build");let f=a.sourceContentFor(s.source);return f&&(c.source=f),c}mapResolve(e){return/^\w+:\/\//.test(e)?e:qs(this.map.consumer().sourceRoot||this.map.root||".",e)}get from(){return this.file||this.id}toJSON(){let e={};for(let t of["hasBOM","css","file","id"])this[t]!=null&&(e[t]=this[t]);return this.map&&(e.map={...this.map},e.map.consumerCache&&(e.map.consumerCache=void 0)),e}};ac.exports=kr;kr.default=kr;Ms&&Ms.registerInput&&Ms.registerInput(kr)});var Wi=v((RT,oc)=>{l();"use strict";var G0=it(),H0=Kf(),Y0=Vi();function Ui(i,e){let t=new Y0(i,e),r=new H0(t);try{r.parse()}catch(n){throw n}return r.root}oc.exports=Ui;Ui.default=Ui;G0.registerParse(Ui)});var Ls=v((BT,cc)=>{l();"use strict";var{isClean:qe,my:Q0}=Si(),J0=As(),X0=hr(),K0=it(),Z0=Ti(),MT=Os(),lc=Ii(),ev=Wi(),tv=_t(),rv={document:"Document",root:"Root",atrule:"AtRule",rule:"Rule",decl:"Declaration",comment:"Comment"},iv={postcssPlugin:!0,prepare:!0,Once:!0,Document:!0,Root:!0,Declaration:!0,Rule:!0,AtRule:!0,Comment:!0,DeclarationExit:!0,RuleExit:!0,AtRuleExit:!0,CommentExit:!0,RootExit:!0,DocumentExit:!0,OnceExit:!0},nv={postcssPlugin:!0,prepare:!0,Once:!0},Et=0;function Sr(i){return typeof i=="object"&&typeof i.then=="function"}function uc(i){let e=!1,t=rv[i.type];return i.type==="decl"?e=i.prop.toLowerCase():i.type==="atrule"&&(e=i.name.toLowerCase()),e&&i.append?[t,t+"-"+e,Et,t+"Exit",t+"Exit-"+e]:e?[t,t+"-"+e,t+"Exit",t+"Exit-"+e]:i.append?[t,Et,t+"Exit"]:[t,t+"Exit"]}function fc(i){let e;return i.type==="document"?e=["Document",Et,"DocumentExit"]:i.type==="root"?e=["Root",Et,"RootExit"]:e=uc(i),{node:i,events:e,eventIndex:0,visitors:[],visitorIndex:0,iterator:0}}function Fs(i){return i[qe]=!1,i.nodes&&i.nodes.forEach(e=>Fs(e)),i}var Ns={},Ve=class{constructor(e,t,r){this.stringified=!1,this.processed=!1;let n;if(typeof t=="object"&&t!==null&&(t.type==="root"||t.type==="document"))n=Fs(t);else if(t instanceof Ve||t instanceof lc)n=Fs(t.root),t.map&&(typeof r.map=="undefined"&&(r.map={}),r.map.inline||(r.map.inline=!1),r.map.prev=t.map);else{let a=ev;r.syntax&&(a=r.syntax.parse),r.parser&&(a=r.parser),a.parse&&(a=a.parse);try{n=a(t,r)}catch(s){this.processed=!0,this.error=s}n&&!n[Q0]&&K0.rebuild(n)}this.result=new lc(e,n,r),this.helpers={...Ns,result:this.result,postcss:Ns},this.plugins=this.processor.plugins.map(a=>typeof a=="object"&&a.prepare?{...a,...a.prepare(this.result)}:a)}get[Symbol.toStringTag](){return"LazyResult"}get processor(){return this.result.processor}get opts(){return this.result.opts}get css(){return this.stringify().css}get content(){return this.stringify().content}get map(){return this.stringify().map}get root(){return this.sync().root}get messages(){return this.sync().messages}warnings(){return this.sync().warnings()}toString(){return this.css}then(e,t){return this.async().then(e,t)}catch(e){return this.async().catch(e)}finally(e){return this.async().then(e,e)}async(){return this.error?Promise.reject(this.error):this.processed?Promise.resolve(this.result):(this.processing||(this.processing=this.runAsync()),this.processing)}sync(){if(this.error)throw this.error;if(this.processed)return this.result;if(this.processed=!0,this.processing)throw this.getAsyncError();for(let e of this.plugins){let t=this.runOnRoot(e);if(Sr(t))throw this.getAsyncError()}if(this.prepareVisitors(),this.hasListener){let e=this.result.root;for(;!e[qe];)e[qe]=!0,this.walkSync(e);if(this.listeners.OnceExit)if(e.type==="document")for(let t of e.nodes)this.visitSync(this.listeners.OnceExit,t);else this.visitSync(this.listeners.OnceExit,e)}return this.result}stringify(){if(this.error)throw this.error;if(this.stringified)return this.result;this.stringified=!0,this.sync();let e=this.result.opts,t=X0;e.syntax&&(t=e.syntax.stringify),e.stringifier&&(t=e.stringifier),t.stringify&&(t=t.stringify);let n=new J0(t,this.result.root,this.result.opts).generate();return this.result.css=n[0],this.result.map=n[1],this.result}walkSync(e){e[qe]=!0;let t=uc(e);for(let r of t)if(r===Et)e.nodes&&e.each(n=>{n[qe]||this.walkSync(n)});else{let n=this.listeners[r];if(n&&this.visitSync(n,e.toProxy()))return}}visitSync(e,t){for(let[r,n]of e){this.result.lastPlugin=r;let a;try{a=n(t,this.helpers)}catch(s){throw this.handleError(s,t.proxyOf)}if(t.type!=="root"&&t.type!=="document"&&!t.parent)return!0;if(Sr(a))throw this.getAsyncError()}}runOnRoot(e){this.result.lastPlugin=e;try{if(typeof e=="object"&&e.Once){if(this.result.root.type==="document"){let t=this.result.root.nodes.map(r=>e.Once(r,this.helpers));return Sr(t[0])?Promise.all(t):t}return e.Once(this.result.root,this.helpers)}else if(typeof e=="function")return e(this.result.root,this.result)}catch(t){throw this.handleError(t)}}getAsyncError(){throw new Error("Use process(css).then(cb) to work with async plugins")}handleError(e,t){let r=this.result.lastPlugin;try{t&&t.addToError(e),this.error=e,e.name==="CssSyntaxError"&&!e.plugin?(e.plugin=r.postcssPlugin,e.setMessage()):r.postcssVersion}catch(n){console&&console.error&&console.error(n)}return e}async runAsync(){this.plugin=0;for(let e=0;e0;){let r=this.visitTick(t);if(Sr(r))try{await r}catch(n){let a=t[t.length-1].node;throw this.handleError(n,a)}}}if(this.listeners.OnceExit)for(let[t,r]of this.listeners.OnceExit){this.result.lastPlugin=t;try{if(e.type==="document"){let n=e.nodes.map(a=>r(a,this.helpers));await Promise.all(n)}else await r(e,this.helpers)}catch(n){throw this.handleError(n)}}}return this.processed=!0,this.stringify()}prepareVisitors(){this.listeners={};let e=(t,r,n)=>{this.listeners[r]||(this.listeners[r]=[]),this.listeners[r].push([t,n])};for(let t of this.plugins)if(typeof t=="object")for(let r in t){if(!iv[r]&&/^[A-Z]/.test(r))throw new Error(`Unknown event ${r} in ${t.postcssPlugin}. Try to update PostCSS (${this.processor.version} now).`);if(!nv[r])if(typeof t[r]=="object")for(let n in t[r])n==="*"?e(t,r,t[r][n]):e(t,r+"-"+n.toLowerCase(),t[r][n]);else typeof t[r]=="function"&&e(t,r,t[r])}this.hasListener=Object.keys(this.listeners).length>0}visitTick(e){let t=e[e.length-1],{node:r,visitors:n}=t;if(r.type!=="root"&&r.type!=="document"&&!r.parent){e.pop();return}if(n.length>0&&t.visitorIndex{Ns=i};cc.exports=Ve;Ve.default=Ve;tv.registerLazyResult(Ve);Z0.registerLazyResult(Ve)});var dc=v((NT,pc)=>{l();"use strict";var sv=As(),av=hr(),FT=Os(),ov=Wi(),lv=Ii(),Gi=class{constructor(e,t,r){t=t.toString(),this.stringified=!1,this._processor=e,this._css=t,this._opts=r,this._map=void 0;let n,a=av;this.result=new lv(this._processor,n,this._opts),this.result.css=t;let s=this;Object.defineProperty(this.result,"root",{get(){return s.root}});let o=new sv(a,n,this._opts,t);if(o.isMap()){let[u,c]=o.generate();u&&(this.result.css=u),c&&(this.result.map=c)}}get[Symbol.toStringTag](){return"NoWorkResult"}get processor(){return this.result.processor}get opts(){return this.result.opts}get css(){return this.result.css}get content(){return this.result.css}get map(){return this.result.map}get root(){if(this._root)return this._root;let e,t=ov;try{e=t(this._css,this._opts)}catch(r){this.error=r}if(this.error)throw this.error;return this._root=e,e}get messages(){return[]}warnings(){return[]}toString(){return this._css}then(e,t){return this.async().then(e,t)}catch(e){return this.async().catch(e)}finally(e){return this.async().then(e,e)}async(){return this.error?Promise.reject(this.error):Promise.resolve(this.result)}sync(){if(this.error)throw this.error;return this.result}};pc.exports=Gi;Gi.default=Gi});var mc=v((LT,hc)=>{l();"use strict";var uv=dc(),fv=Ls(),cv=Ti(),pv=_t(),Ot=class{constructor(e=[]){this.version="8.4.24",this.plugins=this.normalize(e)}use(e){return this.plugins=this.plugins.concat(this.normalize([e])),this}process(e,t={}){return this.plugins.length===0&&typeof t.parser=="undefined"&&typeof t.stringifier=="undefined"&&typeof t.syntax=="undefined"?new uv(this,e,t):new fv(this,e,t)}normalize(e){let t=[];for(let r of e)if(r.postcss===!0?r=r():r.postcss&&(r=r.postcss),typeof r=="object"&&Array.isArray(r.plugins))t=t.concat(r.plugins);else if(typeof r=="object"&&r.postcssPlugin)t.push(r);else if(typeof r=="function")t.push(r);else if(!(typeof r=="object"&&(r.parse||r.stringify)))throw new Error(r+" is not a PostCSS plugin");return t}};hc.exports=Ot;Ot.default=Ot;pv.registerProcessor(Ot);cv.registerProcessor(Ot)});var yc=v(($T,gc)=>{l();"use strict";var dv=gr(),hv=Is(),mv=yr(),gv=$i(),yv=Vi(),wv=_t(),bv=ji();function Cr(i,e){if(Array.isArray(i))return i.map(n=>Cr(n));let{inputs:t,...r}=i;if(t){e=[];for(let n of t){let a={...n,__proto__:yv.prototype};a.map&&(a.map={...a.map,__proto__:hv.prototype}),e.push(a)}}if(r.nodes&&(r.nodes=i.nodes.map(n=>Cr(n,e))),r.source){let{inputId:n,...a}=r.source;r.source=a,n!=null&&(r.source.input=e[n])}if(r.type==="root")return new wv(r);if(r.type==="decl")return new dv(r);if(r.type==="rule")return new bv(r);if(r.type==="comment")return new mv(r);if(r.type==="atrule")return new gv(r);throw new Error("Unknown node type: "+i.type)}gc.exports=Cr;Cr.default=Cr});var me=v((jT,Cc)=>{l();"use strict";var vv=ki(),wc=gr(),xv=Ls(),kv=it(),$s=mc(),Sv=hr(),Cv=yc(),bc=Ti(),Av=Ts(),vc=yr(),xc=$i(),_v=Ii(),Ev=Vi(),Ov=Wi(),Tv=Ds(),kc=ji(),Sc=_t(),Pv=mr();function j(...i){return i.length===1&&Array.isArray(i[0])&&(i=i[0]),new $s(i)}j.plugin=function(e,t){let r=!1;function n(...s){console&&console.warn&&!r&&(r=!0,console.warn(e+`: postcss.plugin was deprecated. Migration guide: +https://evilmartians.com/chronicles/postcss-8-plugin-migration`),m.env.LANG&&m.env.LANG.startsWith("cn")&&console.warn(e+`: \u91CC\u9762 postcss.plugin \u88AB\u5F03\u7528. \u8FC1\u79FB\u6307\u5357: +https://www.w3ctech.com/topic/2226`));let o=t(...s);return o.postcssPlugin=e,o.postcssVersion=new $s().version,o}let a;return Object.defineProperty(n,"postcss",{get(){return a||(a=n()),a}}),n.process=function(s,o,u){return j([n(u)]).process(s,o)},n};j.stringify=Sv;j.parse=Ov;j.fromJSON=Cv;j.list=Tv;j.comment=i=>new vc(i);j.atRule=i=>new xc(i);j.decl=i=>new wc(i);j.rule=i=>new kc(i);j.root=i=>new Sc(i);j.document=i=>new bc(i);j.CssSyntaxError=vv;j.Declaration=wc;j.Container=kv;j.Processor=$s;j.Document=bc;j.Comment=vc;j.Warning=Av;j.AtRule=xc;j.Result=_v;j.Input=Ev;j.Rule=kc;j.Root=Sc;j.Node=Pv;xv.registerPostcss(j);Cc.exports=j;j.default=j});var W,z,zT,VT,UT,WT,GT,HT,YT,QT,JT,XT,KT,ZT,eP,tP,rP,iP,nP,sP,aP,oP,lP,uP,fP,cP,nt=C(()=>{l();W=K(me()),z=W.default,zT=W.default.stringify,VT=W.default.fromJSON,UT=W.default.plugin,WT=W.default.parse,GT=W.default.list,HT=W.default.document,YT=W.default.comment,QT=W.default.atRule,JT=W.default.rule,XT=W.default.decl,KT=W.default.root,ZT=W.default.CssSyntaxError,eP=W.default.Declaration,tP=W.default.Container,rP=W.default.Processor,iP=W.default.Document,nP=W.default.Comment,sP=W.default.Warning,aP=W.default.AtRule,oP=W.default.Result,lP=W.default.Input,uP=W.default.Rule,fP=W.default.Root,cP=W.default.Node});var js=v((dP,Ac)=>{l();Ac.exports=function(i,e,t,r,n){for(e=e.split?e.split("."):e,r=0;r{l();"use strict";Hi.__esModule=!0;Hi.default=qv;function Dv(i){for(var e=i.toLowerCase(),t="",r=!1,n=0;n<6&&e[n]!==void 0;n++){var a=e.charCodeAt(n),s=a>=97&&a<=102||a>=48&&a<=57;if(r=a===32,!s)break;t+=e[n]}if(t.length!==0){var o=parseInt(t,16),u=o>=55296&&o<=57343;return u||o===0||o>1114111?["\uFFFD",t.length+(r?1:0)]:[String.fromCodePoint(o),t.length+(r?1:0)]}}var Iv=/\\/;function qv(i){var e=Iv.test(i);if(!e)return i;for(var t="",r=0;r{l();"use strict";Qi.__esModule=!0;Qi.default=Rv;function Rv(i){for(var e=arguments.length,t=new Array(e>1?e-1:0),r=1;r0;){var n=t.shift();if(!i[n])return;i=i[n]}return i}Ec.exports=Qi.default});var Pc=v((Ji,Tc)=>{l();"use strict";Ji.__esModule=!0;Ji.default=Mv;function Mv(i){for(var e=arguments.length,t=new Array(e>1?e-1:0),r=1;r0;){var n=t.shift();i[n]||(i[n]={}),i=i[n]}}Tc.exports=Ji.default});var Ic=v((Xi,Dc)=>{l();"use strict";Xi.__esModule=!0;Xi.default=Bv;function Bv(i){for(var e="",t=i.indexOf("/*"),r=0;t>=0;){e=e+i.slice(r,t);var n=i.indexOf("*/",t+2);if(n<0)return e;r=n+2,t=i.indexOf("/*",r)}return e=e+i.slice(r),e}Dc.exports=Xi.default});var Ar=v(Re=>{l();"use strict";Re.__esModule=!0;Re.unesc=Re.stripComments=Re.getProp=Re.ensureObject=void 0;var Fv=Ki(Yi());Re.unesc=Fv.default;var Nv=Ki(Oc());Re.getProp=Nv.default;var Lv=Ki(Pc());Re.ensureObject=Lv.default;var $v=Ki(Ic());Re.stripComments=$v.default;function Ki(i){return i&&i.__esModule?i:{default:i}}});var Ue=v((_r,Mc)=>{l();"use strict";_r.__esModule=!0;_r.default=void 0;var qc=Ar();function Rc(i,e){for(var t=0;tr||this.source.end.linen||this.source.end.line===r&&this.source.end.column{l();"use strict";G.__esModule=!0;G.UNIVERSAL=G.TAG=G.STRING=G.SELECTOR=G.ROOT=G.PSEUDO=G.NESTING=G.ID=G.COMMENT=G.COMBINATOR=G.CLASS=G.ATTRIBUTE=void 0;var Uv="tag";G.TAG=Uv;var Wv="string";G.STRING=Wv;var Gv="selector";G.SELECTOR=Gv;var Hv="root";G.ROOT=Hv;var Yv="pseudo";G.PSEUDO=Yv;var Qv="nesting";G.NESTING=Qv;var Jv="id";G.ID=Jv;var Xv="comment";G.COMMENT=Xv;var Kv="combinator";G.COMBINATOR=Kv;var Zv="class";G.CLASS=Zv;var ex="attribute";G.ATTRIBUTE=ex;var tx="universal";G.UNIVERSAL=tx});var Zi=v((Er,Lc)=>{l();"use strict";Er.__esModule=!0;Er.default=void 0;var rx=nx(Ue()),We=ix(ne());function Bc(i){if(typeof WeakMap!="function")return null;var e=new WeakMap,t=new WeakMap;return(Bc=function(n){return n?t:e})(i)}function ix(i,e){if(!e&&i&&i.__esModule)return i;if(i===null||typeof i!="object"&&typeof i!="function")return{default:i};var t=Bc(e);if(t&&t.has(i))return t.get(i);var r={},n=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in i)if(a!=="default"&&Object.prototype.hasOwnProperty.call(i,a)){var s=n?Object.getOwnPropertyDescriptor(i,a):null;s&&(s.get||s.set)?Object.defineProperty(r,a,s):r[a]=i[a]}return r.default=i,t&&t.set(i,r),r}function nx(i){return i&&i.__esModule?i:{default:i}}function sx(i,e){var t=typeof Symbol!="undefined"&&i[Symbol.iterator]||i["@@iterator"];if(t)return(t=t.call(i)).next.bind(t);if(Array.isArray(i)||(t=ax(i))||e&&i&&typeof i.length=="number"){t&&(i=t);var r=0;return function(){return r>=i.length?{done:!0}:{done:!1,value:i[r++]}}}throw new TypeError(`Invalid attempt to iterate non-iterable instance. +In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function ax(i,e){if(!!i){if(typeof i=="string")return Fc(i,e);var t=Object.prototype.toString.call(i).slice(8,-1);if(t==="Object"&&i.constructor&&(t=i.constructor.name),t==="Map"||t==="Set")return Array.from(i);if(t==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t))return Fc(i,e)}}function Fc(i,e){(e==null||e>i.length)&&(e=i.length);for(var t=0,r=new Array(e);t=n&&(this.indexes[s]=a-1);return this},t.removeAll=function(){for(var n=sx(this.nodes),a;!(a=n()).done;){var s=a.value;s.parent=void 0}return this.nodes=[],this},t.empty=function(){return this.removeAll()},t.insertAfter=function(n,a){a.parent=this;var s=this.index(n);this.nodes.splice(s+1,0,a),a.parent=this;var o;for(var u in this.indexes)o=this.indexes[u],s<=o&&(this.indexes[u]=o+1);return this},t.insertBefore=function(n,a){a.parent=this;var s=this.index(n);this.nodes.splice(s,0,a),a.parent=this;var o;for(var u in this.indexes)o=this.indexes[u],o<=s&&(this.indexes[u]=o+1);return this},t._findChildAtPosition=function(n,a){var s=void 0;return this.each(function(o){if(o.atPosition){var u=o.atPosition(n,a);if(u)return s=u,!1}else if(o.isAtPosition(n,a))return s=o,!1}),s},t.atPosition=function(n,a){if(this.isAtPosition(n,a))return this._findChildAtPosition(n,a)||this},t._inferEndPosition=function(){this.last&&this.last.source&&this.last.source.end&&(this.source=this.source||{},this.source.end=this.source.end||{},Object.assign(this.source.end,this.last.source.end))},t.each=function(n){this.lastEach||(this.lastEach=0),this.indexes||(this.indexes={}),this.lastEach++;var a=this.lastEach;if(this.indexes[a]=0,!!this.length){for(var s,o;this.indexes[a]{l();"use strict";Or.__esModule=!0;Or.default=void 0;var fx=px(Zi()),cx=ne();function px(i){return i&&i.__esModule?i:{default:i}}function $c(i,e){for(var t=0;t{l();"use strict";Tr.__esModule=!0;Tr.default=void 0;var gx=wx(Zi()),yx=ne();function wx(i){return i&&i.__esModule?i:{default:i}}function bx(i,e){i.prototype=Object.create(e.prototype),i.prototype.constructor=i,Ws(i,e)}function Ws(i,e){return Ws=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(r,n){return r.__proto__=n,r},Ws(i,e)}var vx=function(i){bx(e,i);function e(t){var r;return r=i.call(this,t)||this,r.type=yx.SELECTOR,r}return e}(gx.default);Tr.default=vx;zc.exports=Tr.default});var en=v((gP,Vc)=>{l();"use strict";var xx={},kx=xx.hasOwnProperty,Sx=function(e,t){if(!e)return t;var r={};for(var n in t)r[n]=kx.call(e,n)?e[n]:t[n];return r},Cx=/[ -,\.\/:-@\[-\^`\{-~]/,Ax=/[ -,\.\/:-@\[\]\^`\{-~]/,_x=/(^|\\+)?(\\[A-F0-9]{1,6})\x20(?![a-fA-F0-9\x20])/g,Hs=function i(e,t){t=Sx(t,i.options),t.quotes!="single"&&t.quotes!="double"&&(t.quotes="single");for(var r=t.quotes=="double"?'"':"'",n=t.isIdentifier,a=e.charAt(0),s="",o=0,u=e.length;o126){if(f>=55296&&f<=56319&&o{l();"use strict";Pr.__esModule=!0;Pr.default=void 0;var Ex=Uc(en()),Ox=Ar(),Tx=Uc(Ue()),Px=ne();function Uc(i){return i&&i.__esModule?i:{default:i}}function Wc(i,e){for(var t=0;t{l();"use strict";Dr.__esModule=!0;Dr.default=void 0;var Rx=Bx(Ue()),Mx=ne();function Bx(i){return i&&i.__esModule?i:{default:i}}function Fx(i,e){i.prototype=Object.create(e.prototype),i.prototype.constructor=i,Js(i,e)}function Js(i,e){return Js=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(r,n){return r.__proto__=n,r},Js(i,e)}var Nx=function(i){Fx(e,i);function e(t){var r;return r=i.call(this,t)||this,r.type=Mx.COMMENT,r}return e}(Rx.default);Dr.default=Nx;Hc.exports=Dr.default});var Zs=v((Ir,Yc)=>{l();"use strict";Ir.__esModule=!0;Ir.default=void 0;var Lx=jx(Ue()),$x=ne();function jx(i){return i&&i.__esModule?i:{default:i}}function zx(i,e){i.prototype=Object.create(e.prototype),i.prototype.constructor=i,Ks(i,e)}function Ks(i,e){return Ks=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(r,n){return r.__proto__=n,r},Ks(i,e)}var Vx=function(i){zx(e,i);function e(r){var n;return n=i.call(this,r)||this,n.type=$x.ID,n}var t=e.prototype;return t.valueToString=function(){return"#"+i.prototype.valueToString.call(this)},e}(Lx.default);Ir.default=Vx;Yc.exports=Ir.default});var tn=v((qr,Xc)=>{l();"use strict";qr.__esModule=!0;qr.default=void 0;var Ux=Qc(en()),Wx=Ar(),Gx=Qc(Ue());function Qc(i){return i&&i.__esModule?i:{default:i}}function Jc(i,e){for(var t=0;t{l();"use strict";Rr.__esModule=!0;Rr.default=void 0;var Jx=Kx(tn()),Xx=ne();function Kx(i){return i&&i.__esModule?i:{default:i}}function Zx(i,e){i.prototype=Object.create(e.prototype),i.prototype.constructor=i,ta(i,e)}function ta(i,e){return ta=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(r,n){return r.__proto__=n,r},ta(i,e)}var e1=function(i){Zx(e,i);function e(t){var r;return r=i.call(this,t)||this,r.type=Xx.TAG,r}return e}(Jx.default);Rr.default=e1;Kc.exports=Rr.default});var na=v((Mr,Zc)=>{l();"use strict";Mr.__esModule=!0;Mr.default=void 0;var t1=i1(Ue()),r1=ne();function i1(i){return i&&i.__esModule?i:{default:i}}function n1(i,e){i.prototype=Object.create(e.prototype),i.prototype.constructor=i,ia(i,e)}function ia(i,e){return ia=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(r,n){return r.__proto__=n,r},ia(i,e)}var s1=function(i){n1(e,i);function e(t){var r;return r=i.call(this,t)||this,r.type=r1.STRING,r}return e}(t1.default);Mr.default=s1;Zc.exports=Mr.default});var aa=v((Br,ep)=>{l();"use strict";Br.__esModule=!0;Br.default=void 0;var a1=l1(Zi()),o1=ne();function l1(i){return i&&i.__esModule?i:{default:i}}function u1(i,e){i.prototype=Object.create(e.prototype),i.prototype.constructor=i,sa(i,e)}function sa(i,e){return sa=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(r,n){return r.__proto__=n,r},sa(i,e)}var f1=function(i){u1(e,i);function e(r){var n;return n=i.call(this,r)||this,n.type=o1.PSEUDO,n}var t=e.prototype;return t.toString=function(){var n=this.length?"("+this.map(String).join(",")+")":"";return[this.rawSpaceBefore,this.stringifyProperty("value"),n,this.rawSpaceAfter].join("")},e}(a1.default);Br.default=f1;ep.exports=Br.default});var tp={};Ae(tp,{deprecate:()=>c1});function c1(i){return i}var rp=C(()=>{l()});var np=v((yP,ip)=>{l();ip.exports=(rp(),tp).deprecate});var pa=v(Lr=>{l();"use strict";Lr.__esModule=!0;Lr.default=void 0;Lr.unescapeValue=fa;var Fr=la(en()),p1=la(Yi()),d1=la(tn()),h1=ne(),oa;function la(i){return i&&i.__esModule?i:{default:i}}function sp(i,e){for(var t=0;t0&&!n.quoted&&o.before.length===0&&!(n.spaces.value&&n.spaces.value.after)&&(o.before=" "),ap(s,o)}))),a.push("]"),a.push(this.rawSpaceAfter),a.join("")},m1(e,[{key:"quoted",get:function(){var n=this.quoteMark;return n==="'"||n==='"'},set:function(n){b1()}},{key:"quoteMark",get:function(){return this._quoteMark},set:function(n){if(!this._constructed){this._quoteMark=n;return}this._quoteMark!==n&&(this._quoteMark=n,this._syncRawValue())}},{key:"qualifiedAttribute",get:function(){return this.qualifiedName(this.raws.attribute||this.attribute)}},{key:"insensitiveFlag",get:function(){return this.insensitive?"i":""}},{key:"value",get:function(){return this._value},set:function(n){if(this._constructed){var a=fa(n),s=a.deprecatedUsage,o=a.unescaped,u=a.quoteMark;if(s&&w1(),o===this._value&&u===this._quoteMark)return;this._value=o,this._quoteMark=u,this._syncRawValue()}else this._value=n}},{key:"insensitive",get:function(){return this._insensitive},set:function(n){n||(this._insensitive=!1,this.raws&&(this.raws.insensitiveFlag==="I"||this.raws.insensitiveFlag==="i")&&(this.raws.insensitiveFlag=void 0)),this._insensitive=n}},{key:"attribute",get:function(){return this._attribute},set:function(n){this._handleEscapes("attribute",n),this._attribute=n}}]),e}(d1.default);Lr.default=rn;rn.NO_QUOTE=null;rn.SINGLE_QUOTE="'";rn.DOUBLE_QUOTE='"';var ca=(oa={"'":{quotes:"single",wrap:!0},'"':{quotes:"double",wrap:!0}},oa[null]={isIdentifier:!0},oa);function ap(i,e){return""+e.before+i+e.after}});var ha=v(($r,op)=>{l();"use strict";$r.__esModule=!0;$r.default=void 0;var k1=C1(tn()),S1=ne();function C1(i){return i&&i.__esModule?i:{default:i}}function A1(i,e){i.prototype=Object.create(e.prototype),i.prototype.constructor=i,da(i,e)}function da(i,e){return da=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(r,n){return r.__proto__=n,r},da(i,e)}var _1=function(i){A1(e,i);function e(t){var r;return r=i.call(this,t)||this,r.type=S1.UNIVERSAL,r.value="*",r}return e}(k1.default);$r.default=_1;op.exports=$r.default});var ga=v((jr,lp)=>{l();"use strict";jr.__esModule=!0;jr.default=void 0;var E1=T1(Ue()),O1=ne();function T1(i){return i&&i.__esModule?i:{default:i}}function P1(i,e){i.prototype=Object.create(e.prototype),i.prototype.constructor=i,ma(i,e)}function ma(i,e){return ma=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(r,n){return r.__proto__=n,r},ma(i,e)}var D1=function(i){P1(e,i);function e(t){var r;return r=i.call(this,t)||this,r.type=O1.COMBINATOR,r}return e}(E1.default);jr.default=D1;lp.exports=jr.default});var wa=v((zr,up)=>{l();"use strict";zr.__esModule=!0;zr.default=void 0;var I1=R1(Ue()),q1=ne();function R1(i){return i&&i.__esModule?i:{default:i}}function M1(i,e){i.prototype=Object.create(e.prototype),i.prototype.constructor=i,ya(i,e)}function ya(i,e){return ya=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(r,n){return r.__proto__=n,r},ya(i,e)}var B1=function(i){M1(e,i);function e(t){var r;return r=i.call(this,t)||this,r.type=q1.NESTING,r.value="&",r}return e}(I1.default);zr.default=B1;up.exports=zr.default});var cp=v((nn,fp)=>{l();"use strict";nn.__esModule=!0;nn.default=F1;function F1(i){return i.sort(function(e,t){return e-t})}fp.exports=nn.default});var ba=v(D=>{l();"use strict";D.__esModule=!0;D.word=D.tilde=D.tab=D.str=D.space=D.slash=D.singleQuote=D.semicolon=D.plus=D.pipe=D.openSquare=D.openParenthesis=D.newline=D.greaterThan=D.feed=D.equals=D.doubleQuote=D.dollar=D.cr=D.comment=D.comma=D.combinator=D.colon=D.closeSquare=D.closeParenthesis=D.caret=D.bang=D.backslash=D.at=D.asterisk=D.ampersand=void 0;var N1=38;D.ampersand=N1;var L1=42;D.asterisk=L1;var $1=64;D.at=$1;var j1=44;D.comma=j1;var z1=58;D.colon=z1;var V1=59;D.semicolon=V1;var U1=40;D.openParenthesis=U1;var W1=41;D.closeParenthesis=W1;var G1=91;D.openSquare=G1;var H1=93;D.closeSquare=H1;var Y1=36;D.dollar=Y1;var Q1=126;D.tilde=Q1;var J1=94;D.caret=J1;var X1=43;D.plus=X1;var K1=61;D.equals=K1;var Z1=124;D.pipe=Z1;var ek=62;D.greaterThan=ek;var tk=32;D.space=tk;var pp=39;D.singleQuote=pp;var rk=34;D.doubleQuote=rk;var ik=47;D.slash=ik;var nk=33;D.bang=nk;var sk=92;D.backslash=sk;var ak=13;D.cr=ak;var ok=12;D.feed=ok;var lk=10;D.newline=lk;var uk=9;D.tab=uk;var fk=pp;D.str=fk;var ck=-1;D.comment=ck;var pk=-2;D.word=pk;var dk=-3;D.combinator=dk});var mp=v(Vr=>{l();"use strict";Vr.__esModule=!0;Vr.FIELDS=void 0;Vr.default=vk;var O=hk(ba()),Tt,V;function dp(i){if(typeof WeakMap!="function")return null;var e=new WeakMap,t=new WeakMap;return(dp=function(n){return n?t:e})(i)}function hk(i,e){if(!e&&i&&i.__esModule)return i;if(i===null||typeof i!="object"&&typeof i!="function")return{default:i};var t=dp(e);if(t&&t.has(i))return t.get(i);var r={},n=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in i)if(a!=="default"&&Object.prototype.hasOwnProperty.call(i,a)){var s=n?Object.getOwnPropertyDescriptor(i,a):null;s&&(s.get||s.set)?Object.defineProperty(r,a,s):r[a]=i[a]}return r.default=i,t&&t.set(i,r),r}var mk=(Tt={},Tt[O.tab]=!0,Tt[O.newline]=!0,Tt[O.cr]=!0,Tt[O.feed]=!0,Tt),gk=(V={},V[O.space]=!0,V[O.tab]=!0,V[O.newline]=!0,V[O.cr]=!0,V[O.feed]=!0,V[O.ampersand]=!0,V[O.asterisk]=!0,V[O.bang]=!0,V[O.comma]=!0,V[O.colon]=!0,V[O.semicolon]=!0,V[O.openParenthesis]=!0,V[O.closeParenthesis]=!0,V[O.openSquare]=!0,V[O.closeSquare]=!0,V[O.singleQuote]=!0,V[O.doubleQuote]=!0,V[O.plus]=!0,V[O.pipe]=!0,V[O.tilde]=!0,V[O.greaterThan]=!0,V[O.equals]=!0,V[O.dollar]=!0,V[O.caret]=!0,V[O.slash]=!0,V),va={},hp="0123456789abcdefABCDEF";for(sn=0;sn0?(k=s+x,S=b-w[x].length):(k=s,S=a),E=O.comment,s=k,d=k,p=b-S):c===O.slash?(b=o,E=c,d=s,p=o-a,u=b+1):(b=yk(t,o),E=O.word,d=s,p=b-a),u=b+1;break}e.push([E,s,o-a,d,p,o,u]),S&&(a=S,S=null),o=u}return e}});var Sp=v((Ur,kp)=>{l();"use strict";Ur.__esModule=!0;Ur.default=void 0;var xk=we(Us()),xa=we(Gs()),kk=we(Qs()),gp=we(Xs()),Sk=we(Zs()),Ck=we(ra()),ka=we(na()),Ak=we(aa()),yp=an(pa()),_k=we(ha()),Sa=we(ga()),Ek=we(wa()),Ok=we(cp()),A=an(mp()),T=an(ba()),Tk=an(ne()),Y=Ar(),yt,Ca;function wp(i){if(typeof WeakMap!="function")return null;var e=new WeakMap,t=new WeakMap;return(wp=function(n){return n?t:e})(i)}function an(i,e){if(!e&&i&&i.__esModule)return i;if(i===null||typeof i!="object"&&typeof i!="function")return{default:i};var t=wp(e);if(t&&t.has(i))return t.get(i);var r={},n=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in i)if(a!=="default"&&Object.prototype.hasOwnProperty.call(i,a)){var s=n?Object.getOwnPropertyDescriptor(i,a):null;s&&(s.get||s.set)?Object.defineProperty(r,a,s):r[a]=i[a]}return r.default=i,t&&t.set(i,r),r}function we(i){return i&&i.__esModule?i:{default:i}}function bp(i,e){for(var t=0;t0){var s=this.current.last;if(s){var o=this.convertWhitespaceNodesToSpace(a),u=o.space,c=o.rawSpace;c!==void 0&&(s.rawSpaceAfter+=c),s.spaces.after+=u}else a.forEach(function(E){return r.newNode(E)})}return}var f=this.currToken,p=void 0;n>this.position&&(p=this.parseWhitespaceEquivalentTokens(n));var d;if(this.isNamedCombinator()?d=this.namedCombinator():this.currToken[A.FIELDS.TYPE]===T.combinator?(d=new Sa.default({value:this.content(),source:Pt(this.currToken),sourceIndex:this.currToken[A.FIELDS.START_POS]}),this.position++):Aa[this.currToken[A.FIELDS.TYPE]]||p||this.unexpected(),d){if(p){var h=this.convertWhitespaceNodesToSpace(p),y=h.space,x=h.rawSpace;d.spaces.before=y,d.rawSpaceBefore=x}}else{var w=this.convertWhitespaceNodesToSpace(p,!0),b=w.space,k=w.rawSpace;k||(k=b);var S={},_={spaces:{}};b.endsWith(" ")&&k.endsWith(" ")?(S.before=b.slice(0,b.length-1),_.spaces.before=k.slice(0,k.length-1)):b.startsWith(" ")&&k.startsWith(" ")?(S.after=b.slice(1),_.spaces.after=k.slice(1)):_.value=k,d=new Sa.default({value:" ",source:_a(f,this.tokens[this.position-1]),sourceIndex:f[A.FIELDS.START_POS],spaces:S,raws:_})}return this.currToken&&this.currToken[A.FIELDS.TYPE]===T.space&&(d.spaces.after=this.optionalSpace(this.content()),this.position++),this.newNode(d)},e.comma=function(){if(this.position===this.tokens.length-1){this.root.trailingComma=!0,this.position++;return}this.current._inferEndPosition();var r=new xa.default({source:{start:vp(this.tokens[this.position+1])}});this.current.parent.append(r),this.current=r,this.position++},e.comment=function(){var r=this.currToken;this.newNode(new gp.default({value:this.content(),source:Pt(r),sourceIndex:r[A.FIELDS.START_POS]})),this.position++},e.error=function(r,n){throw this.root.error(r,n)},e.missingBackslash=function(){return this.error("Expected a backslash preceding the semicolon.",{index:this.currToken[A.FIELDS.START_POS]})},e.missingParenthesis=function(){return this.expected("opening parenthesis",this.currToken[A.FIELDS.START_POS])},e.missingSquareBracket=function(){return this.expected("opening square bracket",this.currToken[A.FIELDS.START_POS])},e.unexpected=function(){return this.error("Unexpected '"+this.content()+"'. Escaping special characters with \\ may help.",this.currToken[A.FIELDS.START_POS])},e.unexpectedPipe=function(){return this.error("Unexpected '|'.",this.currToken[A.FIELDS.START_POS])},e.namespace=function(){var r=this.prevToken&&this.content(this.prevToken)||!0;if(this.nextToken[A.FIELDS.TYPE]===T.word)return this.position++,this.word(r);if(this.nextToken[A.FIELDS.TYPE]===T.asterisk)return this.position++,this.universal(r);this.unexpectedPipe()},e.nesting=function(){if(this.nextToken){var r=this.content(this.nextToken);if(r==="|"){this.position++;return}}var n=this.currToken;this.newNode(new Ek.default({value:this.content(),source:Pt(n),sourceIndex:n[A.FIELDS.START_POS]})),this.position++},e.parentheses=function(){var r=this.current.last,n=1;if(this.position++,r&&r.type===Tk.PSEUDO){var a=new xa.default({source:{start:vp(this.tokens[this.position-1])}}),s=this.current;for(r.append(a),this.current=a;this.position1&&r.nextToken&&r.nextToken[A.FIELDS.TYPE]===T.openParenthesis&&r.error("Misplaced parenthesis.",{index:r.nextToken[A.FIELDS.START_POS]})});else return this.expected(["pseudo-class","pseudo-element"],this.currToken[A.FIELDS.START_POS])},e.space=function(){var r=this.content();this.position===0||this.prevToken[A.FIELDS.TYPE]===T.comma||this.prevToken[A.FIELDS.TYPE]===T.openParenthesis||this.current.nodes.every(function(n){return n.type==="comment"})?(this.spaces=this.optionalSpace(r),this.position++):this.position===this.tokens.length-1||this.nextToken[A.FIELDS.TYPE]===T.comma||this.nextToken[A.FIELDS.TYPE]===T.closeParenthesis?(this.current.last.spaces.after=this.optionalSpace(r),this.position++):this.combinator()},e.string=function(){var r=this.currToken;this.newNode(new ka.default({value:this.content(),source:Pt(r),sourceIndex:r[A.FIELDS.START_POS]})),this.position++},e.universal=function(r){var n=this.nextToken;if(n&&this.content(n)==="|")return this.position++,this.namespace();var a=this.currToken;this.newNode(new _k.default({value:this.content(),source:Pt(a),sourceIndex:a[A.FIELDS.START_POS]}),r),this.position++},e.splitWord=function(r,n){for(var a=this,s=this.nextToken,o=this.content();s&&~[T.dollar,T.caret,T.equals,T.word].indexOf(s[A.FIELDS.TYPE]);){this.position++;var u=this.content();if(o+=u,u.lastIndexOf("\\")===u.length-1){var c=this.nextToken;c&&c[A.FIELDS.TYPE]===T.space&&(o+=this.requiredSpace(this.content(c)),this.position++)}s=this.nextToken}var f=Ea(o,".").filter(function(y){var x=o[y-1]==="\\",w=/^\d+\.\d+%$/.test(o);return!x&&!w}),p=Ea(o,"#").filter(function(y){return o[y-1]!=="\\"}),d=Ea(o,"#{");d.length&&(p=p.filter(function(y){return!~d.indexOf(y)}));var h=(0,Ok.default)(Ik([0].concat(f,p)));h.forEach(function(y,x){var w=h[x+1]||o.length,b=o.slice(y,w);if(x===0&&n)return n.call(a,b,h.length);var k,S=a.currToken,_=S[A.FIELDS.START_POS]+h[x],E=wt(S[1],S[2]+y,S[3],S[2]+(w-1));if(~f.indexOf(y)){var I={value:b.slice(1),source:E,sourceIndex:_};k=new kk.default(Dt(I,"value"))}else if(~p.indexOf(y)){var B={value:b.slice(1),source:E,sourceIndex:_};k=new Sk.default(Dt(B,"value"))}else{var q={value:b,source:E,sourceIndex:_};Dt(q,"value"),k=new Ck.default(q)}a.newNode(k,r),r=null}),this.position++},e.word=function(r){var n=this.nextToken;return n&&this.content(n)==="|"?(this.position++,this.namespace()):this.splitWord(r)},e.loop=function(){for(;this.position{l();"use strict";Wr.__esModule=!0;Wr.default=void 0;var Rk=Mk(Sp());function Mk(i){return i&&i.__esModule?i:{default:i}}var Bk=function(){function i(t,r){this.func=t||function(){},this.funcRes=null,this.options=r}var e=i.prototype;return e._shouldUpdateSelector=function(r,n){n===void 0&&(n={});var a=Object.assign({},this.options,n);return a.updateSelector===!1?!1:typeof r!="string"},e._isLossy=function(r){r===void 0&&(r={});var n=Object.assign({},this.options,r);return n.lossless===!1},e._root=function(r,n){n===void 0&&(n={});var a=new Rk.default(r,this._parseOptions(n));return a.root},e._parseOptions=function(r){return{lossy:this._isLossy(r)}},e._run=function(r,n){var a=this;return n===void 0&&(n={}),new Promise(function(s,o){try{var u=a._root(r,n);Promise.resolve(a.func(u)).then(function(c){var f=void 0;return a._shouldUpdateSelector(r,n)&&(f=u.toString(),r.selector=f),{transform:c,root:u,string:f}}).then(s,o)}catch(c){o(c);return}})},e._runSync=function(r,n){n===void 0&&(n={});var a=this._root(r,n),s=this.func(a);if(s&&typeof s.then=="function")throw new Error("Selector processor returned a promise to a synchronous call.");var o=void 0;return n.updateSelector&&typeof r!="string"&&(o=a.toString(),r.selector=o),{transform:s,root:a,string:o}},e.ast=function(r,n){return this._run(r,n).then(function(a){return a.root})},e.astSync=function(r,n){return this._runSync(r,n).root},e.transform=function(r,n){return this._run(r,n).then(function(a){return a.transform})},e.transformSync=function(r,n){return this._runSync(r,n).transform},e.process=function(r,n){return this._run(r,n).then(function(a){return a.string||a.root.toString()})},e.processSync=function(r,n){var a=this._runSync(r,n);return a.string||a.root.toString()},i}();Wr.default=Bk;Cp.exports=Wr.default});var _p=v(H=>{l();"use strict";H.__esModule=!0;H.universal=H.tag=H.string=H.selector=H.root=H.pseudo=H.nesting=H.id=H.comment=H.combinator=H.className=H.attribute=void 0;var Fk=be(pa()),Nk=be(Qs()),Lk=be(ga()),$k=be(Xs()),jk=be(Zs()),zk=be(wa()),Vk=be(aa()),Uk=be(Us()),Wk=be(Gs()),Gk=be(na()),Hk=be(ra()),Yk=be(ha());function be(i){return i&&i.__esModule?i:{default:i}}var Qk=function(e){return new Fk.default(e)};H.attribute=Qk;var Jk=function(e){return new Nk.default(e)};H.className=Jk;var Xk=function(e){return new Lk.default(e)};H.combinator=Xk;var Kk=function(e){return new $k.default(e)};H.comment=Kk;var Zk=function(e){return new jk.default(e)};H.id=Zk;var eS=function(e){return new zk.default(e)};H.nesting=eS;var tS=function(e){return new Vk.default(e)};H.pseudo=tS;var rS=function(e){return new Uk.default(e)};H.root=rS;var iS=function(e){return new Wk.default(e)};H.selector=iS;var nS=function(e){return new Gk.default(e)};H.string=nS;var sS=function(e){return new Hk.default(e)};H.tag=sS;var aS=function(e){return new Yk.default(e)};H.universal=aS});var Pp=v(L=>{l();"use strict";L.__esModule=!0;L.isComment=L.isCombinator=L.isClassName=L.isAttribute=void 0;L.isContainer=wS;L.isIdentifier=void 0;L.isNamespace=bS;L.isNesting=void 0;L.isNode=Oa;L.isPseudo=void 0;L.isPseudoClass=yS;L.isPseudoElement=Tp;L.isUniversal=L.isTag=L.isString=L.isSelector=L.isRoot=void 0;var Q=ne(),fe,oS=(fe={},fe[Q.ATTRIBUTE]=!0,fe[Q.CLASS]=!0,fe[Q.COMBINATOR]=!0,fe[Q.COMMENT]=!0,fe[Q.ID]=!0,fe[Q.NESTING]=!0,fe[Q.PSEUDO]=!0,fe[Q.ROOT]=!0,fe[Q.SELECTOR]=!0,fe[Q.STRING]=!0,fe[Q.TAG]=!0,fe[Q.UNIVERSAL]=!0,fe);function Oa(i){return typeof i=="object"&&oS[i.type]}function ve(i,e){return Oa(e)&&e.type===i}var Ep=ve.bind(null,Q.ATTRIBUTE);L.isAttribute=Ep;var lS=ve.bind(null,Q.CLASS);L.isClassName=lS;var uS=ve.bind(null,Q.COMBINATOR);L.isCombinator=uS;var fS=ve.bind(null,Q.COMMENT);L.isComment=fS;var cS=ve.bind(null,Q.ID);L.isIdentifier=cS;var pS=ve.bind(null,Q.NESTING);L.isNesting=pS;var Ta=ve.bind(null,Q.PSEUDO);L.isPseudo=Ta;var dS=ve.bind(null,Q.ROOT);L.isRoot=dS;var hS=ve.bind(null,Q.SELECTOR);L.isSelector=hS;var mS=ve.bind(null,Q.STRING);L.isString=mS;var Op=ve.bind(null,Q.TAG);L.isTag=Op;var gS=ve.bind(null,Q.UNIVERSAL);L.isUniversal=gS;function Tp(i){return Ta(i)&&i.value&&(i.value.startsWith("::")||i.value.toLowerCase()===":before"||i.value.toLowerCase()===":after"||i.value.toLowerCase()===":first-letter"||i.value.toLowerCase()===":first-line")}function yS(i){return Ta(i)&&!Tp(i)}function wS(i){return!!(Oa(i)&&i.walk)}function bS(i){return Ep(i)||Op(i)}});var Dp=v(Oe=>{l();"use strict";Oe.__esModule=!0;var Pa=ne();Object.keys(Pa).forEach(function(i){i==="default"||i==="__esModule"||i in Oe&&Oe[i]===Pa[i]||(Oe[i]=Pa[i])});var Da=_p();Object.keys(Da).forEach(function(i){i==="default"||i==="__esModule"||i in Oe&&Oe[i]===Da[i]||(Oe[i]=Da[i])});var Ia=Pp();Object.keys(Ia).forEach(function(i){i==="default"||i==="__esModule"||i in Oe&&Oe[i]===Ia[i]||(Oe[i]=Ia[i])})});var Me=v((Gr,qp)=>{l();"use strict";Gr.__esModule=!0;Gr.default=void 0;var vS=SS(Ap()),xS=kS(Dp());function Ip(i){if(typeof WeakMap!="function")return null;var e=new WeakMap,t=new WeakMap;return(Ip=function(n){return n?t:e})(i)}function kS(i,e){if(!e&&i&&i.__esModule)return i;if(i===null||typeof i!="object"&&typeof i!="function")return{default:i};var t=Ip(e);if(t&&t.has(i))return t.get(i);var r={},n=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in i)if(a!=="default"&&Object.prototype.hasOwnProperty.call(i,a)){var s=n?Object.getOwnPropertyDescriptor(i,a):null;s&&(s.get||s.set)?Object.defineProperty(r,a,s):r[a]=i[a]}return r.default=i,t&&t.set(i,r),r}function SS(i){return i&&i.__esModule?i:{default:i}}var qa=function(e){return new vS.default(e)};Object.assign(qa,xS);delete qa.__esModule;var CS=qa;Gr.default=CS;qp.exports=Gr.default});function Ge(i){return["fontSize","outline"].includes(i)?e=>(typeof e=="function"&&(e=e({})),Array.isArray(e)&&(e=e[0]),e):i==="fontFamily"?e=>{typeof e=="function"&&(e=e({}));let t=Array.isArray(e)&&ie(e[1])?e[0]:e;return Array.isArray(t)?t.join(", "):t}:["boxShadow","transitionProperty","transitionDuration","transitionDelay","transitionTimingFunction","backgroundImage","backgroundSize","backgroundColor","cursor","animation"].includes(i)?e=>(typeof e=="function"&&(e=e({})),Array.isArray(e)&&(e=e.join(", ")),e):["gridTemplateColumns","gridTemplateRows","objectPosition"].includes(i)?e=>(typeof e=="function"&&(e=e({})),typeof e=="string"&&(e=z.list.comma(e).join(" ")),e):(e,t={})=>(typeof e=="function"&&(e=e(t)),e)}var Hr=C(()=>{l();nt();xt()});var $p=v((EP,Na)=>{l();var{Rule:Rp,AtRule:AS}=me(),Mp=Me();function Ra(i,e){let t;try{Mp(r=>{t=r}).processSync(i)}catch(r){throw i.includes(":")?e?e.error("Missed semicolon"):r:e?e.error(r.message):r}return t.at(0)}function Bp(i,e){let t=!1;return i.each(r=>{if(r.type==="nesting"){let n=e.clone({});r.value!=="&"?r.replaceWith(Ra(r.value.replace("&",n.toString()))):r.replaceWith(n),t=!0}else"nodes"in r&&r.nodes&&Bp(r,e)&&(t=!0)}),t}function Fp(i,e){let t=[];return i.selectors.forEach(r=>{let n=Ra(r,i);e.selectors.forEach(a=>{if(!a)return;let s=Ra(a,e);Bp(s,n)||(s.prepend(Mp.combinator({value:" "})),s.prepend(n.clone({}))),t.push(s.toString())})}),t}function on(i,e){let t=i.prev();for(e.after(i);t&&t.type==="comment";){let r=t.prev();e.after(t),t=r}return i}function _S(i){return function e(t,r,n,a=n){let s=[];if(r.each(o=>{o.type==="rule"&&n?a&&(o.selectors=Fp(t,o)):o.type==="atrule"&&o.nodes?i[o.name]?e(t,o,a):r[Ba]!==!1&&s.push(o):s.push(o)}),n&&s.length){let o=t.clone({nodes:[]});for(let u of s)o.append(u);r.prepend(o)}}}function Ma(i,e,t){let r=new Rp({selector:i,nodes:[]});return r.append(e),t.after(r),r}function Np(i,e){let t={};for(let r of i)t[r]=!0;if(e)for(let r of e)t[r.replace(/^@/,"")]=!0;return t}function ES(i){i=i.trim();let e=i.match(/^\((.*)\)$/);if(!e)return{type:"basic",selector:i};let t=e[1].match(/^(with(?:out)?):(.+)$/);if(t){let r=t[1]==="with",n=Object.fromEntries(t[2].trim().split(/\s+/).map(s=>[s,!0]));if(r&&n.all)return{type:"noop"};let a=s=>!!n[s];return n.all?a=()=>!0:r&&(a=s=>s==="all"?!1:!n[s]),{type:"withrules",escapes:a}}return{type:"unknown"}}function OS(i){let e=[],t=i.parent;for(;t&&t instanceof AS;)e.push(t),t=t.parent;return e}function TS(i){let e=i[Lp];if(!e)i.after(i.nodes);else{let t=i.nodes,r,n=-1,a,s,o,u=OS(i);if(u.forEach((c,f)=>{if(e(c.name))r=c,n=f,s=o;else{let p=o;o=c.clone({nodes:[]}),p&&o.append(p),a=a||o}}),r?s?(a.append(t),r.after(s)):r.after(t):i.after(t),i.next()&&r){let c;u.slice(0,n+1).forEach((f,p,d)=>{let h=c;c=f.clone({nodes:[]}),h&&c.append(h);let y=[],w=(d[p-1]||i).next();for(;w;)y.push(w),w=w.next();c.append(y)}),c&&(s||t[t.length-1]).after(c)}}i.remove()}var Ba=Symbol("rootRuleMergeSel"),Lp=Symbol("rootRuleEscapes");function PS(i){let{params:e}=i,{type:t,selector:r,escapes:n}=ES(e);if(t==="unknown")throw i.error(`Unknown @${i.name} parameter ${JSON.stringify(e)}`);if(t==="basic"&&r){let a=new Rp({selector:r,nodes:i.nodes});i.removeAll(),i.append(a)}i[Lp]=n,i[Ba]=n?!n("all"):t==="noop"}var Fa=Symbol("hasRootRule");Na.exports=(i={})=>{let e=Np(["media","supports","layer","container"],i.bubble),t=_S(e),r=Np(["document","font-face","keyframes","-webkit-keyframes","-moz-keyframes"],i.unwrap),n=(i.rootRuleName||"at-root").replace(/^@/,""),a=i.preserveEmpty;return{postcssPlugin:"postcss-nested",Once(s){s.walkAtRules(n,o=>{PS(o),s[Fa]=!0})},Rule(s){let o=!1,u=s,c=!1,f=[];s.each(p=>{p.type==="rule"?(f.length&&(u=Ma(s.selector,f,u),f=[]),c=!0,o=!0,p.selectors=Fp(s,p),u=on(p,u)):p.type==="atrule"?(f.length&&(u=Ma(s.selector,f,u),f=[]),p.name===n?(o=!0,t(s,p,!0,p[Ba]),u=on(p,u)):e[p.name]?(c=!0,o=!0,t(s,p,!0),u=on(p,u)):r[p.name]?(c=!0,o=!0,t(s,p,!1),u=on(p,u)):c&&f.push(p)):p.type==="decl"&&c&&f.push(p)}),f.length&&(u=Ma(s.selector,f,u)),o&&a!==!0&&(s.raws.semicolon=!0,s.nodes.length===0&&s.remove())},RootExit(s){s[Fa]&&(s.walkAtRules(n,TS),s[Fa]=!1)}}};Na.exports.postcss=!0});var Up=v((OP,Vp)=>{l();"use strict";var jp=/-(\w|$)/g,zp=(i,e)=>e.toUpperCase(),DS=i=>(i=i.toLowerCase(),i==="float"?"cssFloat":i.startsWith("-ms-")?i.substr(1).replace(jp,zp):i.replace(jp,zp));Vp.exports=DS});var ja=v((TP,Wp)=>{l();var IS=Up(),qS={boxFlex:!0,boxFlexGroup:!0,columnCount:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,strokeDashoffset:!0,strokeOpacity:!0,strokeWidth:!0};function La(i){return typeof i.nodes=="undefined"?!0:$a(i)}function $a(i){let e,t={};return i.each(r=>{if(r.type==="atrule")e="@"+r.name,r.params&&(e+=" "+r.params),typeof t[e]=="undefined"?t[e]=La(r):Array.isArray(t[e])?t[e].push(La(r)):t[e]=[t[e],La(r)];else if(r.type==="rule"){let n=$a(r);if(t[r.selector])for(let a in n)t[r.selector][a]=n[a];else t[r.selector]=n}else if(r.type==="decl"){r.prop[0]==="-"&&r.prop[1]==="-"||r.parent&&r.parent.selector===":export"?e=r.prop:e=IS(r.prop);let n=r.value;!isNaN(r.value)&&qS[e]&&(n=parseFloat(r.value)),r.important&&(n+=" !important"),typeof t[e]=="undefined"?t[e]=n:Array.isArray(t[e])?t[e].push(n):t[e]=[t[e],n]}}),t}Wp.exports=$a});var ln=v((PP,Qp)=>{l();var Yr=me(),Gp=/\s*!important\s*$/i,RS={"box-flex":!0,"box-flex-group":!0,"column-count":!0,flex:!0,"flex-grow":!0,"flex-positive":!0,"flex-shrink":!0,"flex-negative":!0,"font-weight":!0,"line-clamp":!0,"line-height":!0,opacity:!0,order:!0,orphans:!0,"tab-size":!0,widows:!0,"z-index":!0,zoom:!0,"fill-opacity":!0,"stroke-dashoffset":!0,"stroke-opacity":!0,"stroke-width":!0};function MS(i){return i.replace(/([A-Z])/g,"-$1").replace(/^ms-/,"-ms-").toLowerCase()}function Hp(i,e,t){t===!1||t===null||(e.startsWith("--")||(e=MS(e)),typeof t=="number"&&(t===0||RS[e]?t=t.toString():t+="px"),e==="css-float"&&(e="float"),Gp.test(t)?(t=t.replace(Gp,""),i.push(Yr.decl({prop:e,value:t,important:!0}))):i.push(Yr.decl({prop:e,value:t})))}function Yp(i,e,t){let r=Yr.atRule({name:e[1],params:e[3]||""});typeof t=="object"&&(r.nodes=[],za(t,r)),i.push(r)}function za(i,e){let t,r,n;for(t in i)if(r=i[t],!(r===null||typeof r=="undefined"))if(t[0]==="@"){let a=t.match(/@(\S+)(\s+([\W\w]*)\s*)?/);if(Array.isArray(r))for(let s of r)Yp(e,a,s);else Yp(e,a,r)}else if(Array.isArray(r))for(let a of r)Hp(e,t,a);else typeof r=="object"?(n=Yr.rule({selector:t}),za(r,n),e.push(n)):Hp(e,t,r)}Qp.exports=function(i){let e=Yr.root();return za(i,e),e}});var Va=v((DP,Jp)=>{l();var BS=ja();Jp.exports=function(e){return console&&console.warn&&e.warnings().forEach(t=>{let r=t.plugin||"PostCSS";console.warn(r+": "+t.text)}),BS(e.root)}});var Kp=v((IP,Xp)=>{l();var FS=me(),NS=Va(),LS=ln();Xp.exports=function(e){let t=FS(e);return async r=>{let n=await t.process(r,{parser:LS,from:void 0});return NS(n)}}});var ed=v((qP,Zp)=>{l();var $S=me(),jS=Va(),zS=ln();Zp.exports=function(i){let e=$S(i);return t=>{let r=e.process(t,{parser:zS,from:void 0});return jS(r)}}});var rd=v((RP,td)=>{l();var VS=ja(),US=ln(),WS=Kp(),GS=ed();td.exports={objectify:VS,parse:US,async:WS,sync:GS}});var It,id,MP,BP,FP,NP,nd=C(()=>{l();It=K(rd()),id=It.default,MP=It.default.objectify,BP=It.default.parse,FP=It.default.async,NP=It.default.sync});function qt(i){return Array.isArray(i)?i.flatMap(e=>z([(0,sd.default)({bubble:["screen"]})]).process(e,{parser:id}).root.nodes):qt([i])}var sd,Ua=C(()=>{l();nt();sd=K($p());nd()});function Rt(i,e,t=!1){if(i==="")return e;let r=typeof e=="string"?(0,ad.default)().astSync(e):e;return r.walkClasses(n=>{let a=n.value,s=t&&a.startsWith("-");n.value=s?`-${i}${a.slice(1)}`:`${i}${a}`}),typeof e=="string"?r.toString():r}var ad,un=C(()=>{l();ad=K(Me())});function ce(i){let e=od.default.className();return e.value=i,ht(e?.raws?.value??e.value)}var od,Mt=C(()=>{l();od=K(Me());mi()});function Wa(i){return ht(`.${ce(i)}`)}function fn(i,e){return Wa(Qr(i,e))}function Qr(i,e){return e==="DEFAULT"?i:e==="-"||e==="-DEFAULT"?`-${i}`:e.startsWith("-")?`-${i}${e}`:e.startsWith("/")?`${i}${e}`:`${i}-${e}`}var Ga=C(()=>{l();Mt();mi()});function P(i,e=[[i,[i]]],{filterDefault:t=!1,...r}={}){let n=Ge(i);return function({matchUtilities:a,theme:s}){for(let o of e){let u=Array.isArray(o[0])?o:[o];a(u.reduce((c,[f,p])=>Object.assign(c,{[f]:d=>p.reduce((h,y)=>Array.isArray(y)?Object.assign(h,{[y[0]]:y[1]}):Object.assign(h,{[y]:n(d)}),{})}),{}),{...r,values:t?Object.fromEntries(Object.entries(s(i)??{}).filter(([c])=>c!=="DEFAULT")):s(i)})}}}var ld=C(()=>{l();Hr()});function st(i){return i=Array.isArray(i)?i:[i],i.map(e=>{let t=e.values.map(r=>r.raw!==void 0?r.raw:[r.min&&`(min-width: ${r.min})`,r.max&&`(max-width: ${r.max})`].filter(Boolean).join(" and "));return e.not?`not all and ${t}`:t}).join(", ")}var cn=C(()=>{l()});function Ha(i){return i.split(ZS).map(t=>{let r=t.trim(),n={value:r},a=r.split(eC),s=new Set;for(let o of a)!s.has("DIRECTIONS")&&HS.has(o)?(n.direction=o,s.add("DIRECTIONS")):!s.has("PLAY_STATES")&&YS.has(o)?(n.playState=o,s.add("PLAY_STATES")):!s.has("FILL_MODES")&&QS.has(o)?(n.fillMode=o,s.add("FILL_MODES")):!s.has("ITERATION_COUNTS")&&(JS.has(o)||tC.test(o))?(n.iterationCount=o,s.add("ITERATION_COUNTS")):!s.has("TIMING_FUNCTION")&&XS.has(o)||!s.has("TIMING_FUNCTION")&&KS.some(u=>o.startsWith(`${u}(`))?(n.timingFunction=o,s.add("TIMING_FUNCTION")):!s.has("DURATION")&&ud.test(o)?(n.duration=o,s.add("DURATION")):!s.has("DELAY")&&ud.test(o)?(n.delay=o,s.add("DELAY")):s.has("NAME")?(n.unknown||(n.unknown=[]),n.unknown.push(o)):(n.name=o,s.add("NAME"));return n})}var HS,YS,QS,JS,XS,KS,ZS,eC,ud,tC,fd=C(()=>{l();HS=new Set(["normal","reverse","alternate","alternate-reverse"]),YS=new Set(["running","paused"]),QS=new Set(["none","forwards","backwards","both"]),JS=new Set(["infinite"]),XS=new Set(["linear","ease","ease-in","ease-out","ease-in-out","step-start","step-end"]),KS=["cubic-bezier","steps"],ZS=/\,(?![^(]*\))/g,eC=/\ +(?![^(]*\))/g,ud=/^(-?[\d.]+m?s)$/,tC=/^(\d+)$/});var cd,re,pd=C(()=>{l();cd=i=>Object.assign({},...Object.entries(i??{}).flatMap(([e,t])=>typeof t=="object"?Object.entries(cd(t)).map(([r,n])=>({[e+(r==="DEFAULT"?"":`-${r}`)]:n})):[{[`${e}`]:t}])),re=cd});var rC,Qa,iC,nC,sC,aC,oC,lC,uC,fC,cC,pC,dC,hC,mC,gC,yC,wC,Ja,Ya=C(()=>{rC="tailwindcss",Qa="3.3.3",iC="A utility-first CSS framework for rapidly building custom user interfaces.",nC="MIT",sC="lib/index.js",aC="types/index.d.ts",oC="https://github.com/tailwindlabs/tailwindcss.git",lC="https://github.com/tailwindlabs/tailwindcss/issues",uC="https://tailwindcss.com",fC={tailwind:"lib/cli.js",tailwindcss:"lib/cli.js"},cC={engine:"stable"},pC={prebuild:"npm run generate && rimraf lib",build:`swc src --out-dir lib --copy-files --config jsc.transform.optimizer.globals.vars.__OXIDE__='"false"'`,postbuild:"esbuild lib/cli-peer-dependencies.js --bundle --platform=node --outfile=peers/index.js --define:process.env.CSS_TRANSFORMER_WASM=false","rebuild-fixtures":"npm run build && node -r @swc/register scripts/rebuildFixtures.js",style:"eslint .",pretest:"npm run generate",test:"jest","test:integrations":"npm run test --prefix ./integrations","install:integrations":"node scripts/install-integrations.js","generate:plugin-list":"node -r @swc/register scripts/create-plugin-list.js","generate:types":"node -r @swc/register scripts/generate-types.js",generate:"npm run generate:plugin-list && npm run generate:types","release-channel":"node ./scripts/release-channel.js","release-notes":"node ./scripts/release-notes.js",prepublishOnly:"npm install --force && npm run build"},dC=["src/*","cli/*","lib/*","peers/*","scripts/*.js","stubs/*","nesting/*","types/**/*","*.d.ts","*.css","*.js"],hC={"@swc/cli":"^0.1.62","@swc/core":"^1.3.55","@swc/jest":"^0.2.26","@swc/register":"^0.1.10",autoprefixer:"^10.4.14",browserslist:"^4.21.5",concurrently:"^8.0.1",cssnano:"^6.0.0",esbuild:"^0.17.18",eslint:"^8.39.0","eslint-config-prettier":"^8.8.0","eslint-plugin-prettier":"^4.2.1",jest:"^29.5.0","jest-diff":"^29.5.0",lightningcss:"1.18.0",prettier:"^2.8.8",rimraf:"^5.0.0","source-map-js":"^1.0.2",turbo:"^1.9.3"},mC={"@alloc/quick-lru":"^5.2.0",arg:"^5.0.2",chokidar:"^3.5.3",didyoumean:"^1.2.2",dlv:"^1.1.3","fast-glob":"^3.2.12","glob-parent":"^6.0.2","is-glob":"^4.0.3",jiti:"^1.18.2",lilconfig:"^2.1.0",micromatch:"^4.0.5","normalize-path":"^3.0.0","object-hash":"^3.0.0",picocolors:"^1.0.0",postcss:"^8.4.23","postcss-import":"^15.1.0","postcss-js":"^4.0.1","postcss-load-config":"^4.0.1","postcss-nested":"^6.0.1","postcss-selector-parser":"^6.0.11",resolve:"^1.22.2",sucrase:"^3.32.0"},gC=["> 1%","not edge <= 18","not ie 11","not op_mini all"],yC={testTimeout:3e4,setupFilesAfterEnv:["/jest/customMatchers.js"],testPathIgnorePatterns:["/node_modules/","/integrations/","/standalone-cli/","\\.test\\.skip\\.js$"],transformIgnorePatterns:["node_modules/(?!lightningcss)"],transform:{"\\.js$":"@swc/jest","\\.ts$":"@swc/jest"}},wC={node:">=14.0.0"},Ja={name:rC,version:Qa,description:iC,license:nC,main:sC,types:aC,repository:oC,bugs:lC,homepage:uC,bin:fC,tailwindcss:cC,scripts:pC,files:dC,devDependencies:hC,dependencies:mC,browserslist:gC,jest:yC,engines:wC}});function at(i,e=!0){return Array.isArray(i)?i.map(t=>{if(e&&Array.isArray(t))throw new Error("The tuple syntax is not supported for `screens`.");if(typeof t=="string")return{name:t.toString(),not:!1,values:[{min:t,max:void 0}]};let[r,n]=t;return r=r.toString(),typeof n=="string"?{name:r,not:!1,values:[{min:n,max:void 0}]}:Array.isArray(n)?{name:r,not:!1,values:n.map(a=>hd(a))}:{name:r,not:!1,values:[hd(n)]}}):at(Object.entries(i??{}),!1)}function pn(i){return i.values.length!==1?{result:!1,reason:"multiple-values"}:i.values[0].raw!==void 0?{result:!1,reason:"raw-values"}:i.values[0].min!==void 0&&i.values[0].max!==void 0?{result:!1,reason:"min-and-max"}:{result:!0,reason:null}}function dd(i,e,t){let r=dn(e,i),n=dn(t,i),a=pn(r),s=pn(n);if(a.reason==="multiple-values"||s.reason==="multiple-values")throw new Error("Attempted to sort a screen with multiple values. This should never happen. Please open a bug report.");if(a.reason==="raw-values"||s.reason==="raw-values")throw new Error("Attempted to sort a screen with raw values. This should never happen. Please open a bug report.");if(a.reason==="min-and-max"||s.reason==="min-and-max")throw new Error("Attempted to sort a screen with both min and max values. This should never happen. Please open a bug report.");let{min:o,max:u}=r.values[0],{min:c,max:f}=n.values[0];e.not&&([o,u]=[u,o]),t.not&&([c,f]=[f,c]),o=o===void 0?o:parseFloat(o),u=u===void 0?u:parseFloat(u),c=c===void 0?c:parseFloat(c),f=f===void 0?f:parseFloat(f);let[p,d]=i==="min"?[o,c]:[f,u];return p-d}function dn(i,e){return typeof i=="object"?i:{name:"arbitrary-screen",values:[{[e]:i}]}}function hd({"min-width":i,min:e=i,max:t,raw:r}={}){return{min:e,max:t,raw:r}}var hn=C(()=>{l()});function mn(i,e){i.walkDecls(t=>{if(e.includes(t.prop)){t.remove();return}for(let r of e)t.value.includes(`/ var(${r})`)&&(t.value=t.value.replace(`/ var(${r})`,""))})}var md=C(()=>{l()});var pe,Te,Be,Fe,gd,yd=C(()=>{l();ze();mt();nt();ld();cn();Mt();fd();pd();ar();ds();xt();Hr();Ya();Ee();hn();as();md();De();fr();Xr();pe={pseudoElementVariants:({addVariant:i})=>{i("first-letter","&::first-letter"),i("first-line","&::first-line"),i("marker",[({container:e})=>(mn(e,["--tw-text-opacity"]),"& *::marker"),({container:e})=>(mn(e,["--tw-text-opacity"]),"&::marker")]),i("selection",["& *::selection","&::selection"]),i("file","&::file-selector-button"),i("placeholder","&::placeholder"),i("backdrop","&::backdrop"),i("before",({container:e})=>(e.walkRules(t=>{let r=!1;t.walkDecls("content",()=>{r=!0}),r||t.prepend(z.decl({prop:"content",value:"var(--tw-content)"}))}),"&::before")),i("after",({container:e})=>(e.walkRules(t=>{let r=!1;t.walkDecls("content",()=>{r=!0}),r||t.prepend(z.decl({prop:"content",value:"var(--tw-content)"}))}),"&::after"))},pseudoClassVariants:({addVariant:i,matchVariant:e,config:t,prefix:r})=>{let n=[["first","&:first-child"],["last","&:last-child"],["only","&:only-child"],["odd","&:nth-child(odd)"],["even","&:nth-child(even)"],"first-of-type","last-of-type","only-of-type",["visited",({container:s})=>(mn(s,["--tw-text-opacity","--tw-border-opacity","--tw-bg-opacity"]),"&:visited")],"target",["open","&[open]"],"default","checked","indeterminate","placeholder-shown","autofill","optional","required","valid","invalid","in-range","out-of-range","read-only","empty","focus-within",["hover",J(t(),"hoverOnlyWhenSupported")?"@media (hover: hover) and (pointer: fine) { &:hover }":"&:hover"],"focus","focus-visible","active","enabled","disabled"].map(s=>Array.isArray(s)?s:[s,`&:${s}`]);for(let[s,o]of n)i(s,u=>typeof o=="function"?o(u):o);let a={group:(s,{modifier:o})=>o?[`:merge(${r(".group")}\\/${ce(o)})`," &"]:[`:merge(${r(".group")})`," &"],peer:(s,{modifier:o})=>o?[`:merge(${r(".peer")}\\/${ce(o)})`," ~ &"]:[`:merge(${r(".peer")})`," ~ &"]};for(let[s,o]of Object.entries(a))e(s,(u="",c)=>{let f=U(typeof u=="function"?u(c):u);f.includes("&")||(f="&"+f);let[p,d]=o("",c),h=null,y=null,x=0;for(let w=0;w{i("ltr",':is([dir="ltr"] &)'),i("rtl",':is([dir="rtl"] &)')},reducedMotionVariants:({addVariant:i})=>{i("motion-safe","@media (prefers-reduced-motion: no-preference)"),i("motion-reduce","@media (prefers-reduced-motion: reduce)")},darkVariants:({config:i,addVariant:e})=>{let[t,r=".dark"]=[].concat(i("darkMode","media"));t===!1&&(t="media",F.warn("darkmode-false",["The `darkMode` option in your Tailwind CSS configuration is set to `false`, which now behaves the same as `media`.","Change `darkMode` to `media` or remove it entirely.","https://tailwindcss.com/docs/upgrade-guide#remove-dark-mode-configuration"])),t==="class"?e("dark",`:is(${r} &)`):t==="media"&&e("dark","@media (prefers-color-scheme: dark)")},printVariant:({addVariant:i})=>{i("print","@media print")},screenVariants:({theme:i,addVariant:e,matchVariant:t})=>{let r=i("screens")??{},n=Object.values(r).every(b=>typeof b=="string"),a=at(i("screens")),s=new Set([]);function o(b){return b.match(/(\D+)$/)?.[1]??"(none)"}function u(b){b!==void 0&&s.add(o(b))}function c(b){return u(b),s.size===1}for(let b of a)for(let k of b.values)u(k.min),u(k.max);let f=s.size<=1;function p(b){return Object.fromEntries(a.filter(k=>pn(k).result).map(k=>{let{min:S,max:_}=k.values[0];if(b==="min"&&S!==void 0)return k;if(b==="min"&&_!==void 0)return{...k,not:!k.not};if(b==="max"&&_!==void 0)return k;if(b==="max"&&S!==void 0)return{...k,not:!k.not}}).map(k=>[k.name,k]))}function d(b){return(k,S)=>dd(b,k.value,S.value)}let h=d("max"),y=d("min");function x(b){return k=>{if(n)if(f){if(typeof k=="string"&&!c(k))return F.warn("minmax-have-mixed-units",["The `min-*` and `max-*` variants are not supported with a `screens` configuration containing mixed units."]),[]}else return F.warn("mixed-screen-units",["The `min-*` and `max-*` variants are not supported with a `screens` configuration containing mixed units."]),[];else return F.warn("complex-screen-config",["The `min-*` and `max-*` variants are not supported with a `screens` configuration containing objects."]),[];return[`@media ${st(dn(k,b))}`]}}t("max",x("max"),{sort:h,values:n?p("max"):{}});let w="min-screens";for(let b of a)e(b.name,`@media ${st(b)}`,{id:w,sort:n&&f?y:void 0,value:b});t("min",x("min"),{id:w,sort:y})},supportsVariants:({matchVariant:i,theme:e})=>{i("supports",(t="")=>{let r=U(t),n=/^\w*\s*\(/.test(r);return r=n?r.replace(/\b(and|or|not)\b/g," $1 "):r,n?`@supports ${r}`:(r.includes(":")||(r=`${r}: var(--tw)`),r.startsWith("(")&&r.endsWith(")")||(r=`(${r})`),`@supports ${r}`)},{values:e("supports")??{}})},ariaVariants:({matchVariant:i,theme:e})=>{i("aria",t=>`&[aria-${U(t)}]`,{values:e("aria")??{}}),i("group-aria",(t,{modifier:r})=>r?`:merge(.group\\/${r})[aria-${U(t)}] &`:`:merge(.group)[aria-${U(t)}] &`,{values:e("aria")??{}}),i("peer-aria",(t,{modifier:r})=>r?`:merge(.peer\\/${r})[aria-${U(t)}] ~ &`:`:merge(.peer)[aria-${U(t)}] ~ &`,{values:e("aria")??{}})},dataVariants:({matchVariant:i,theme:e})=>{i("data",t=>`&[data-${U(t)}]`,{values:e("data")??{}}),i("group-data",(t,{modifier:r})=>r?`:merge(.group\\/${r})[data-${U(t)}] &`:`:merge(.group)[data-${U(t)}] &`,{values:e("data")??{}}),i("peer-data",(t,{modifier:r})=>r?`:merge(.peer\\/${r})[data-${U(t)}] ~ &`:`:merge(.peer)[data-${U(t)}] ~ &`,{values:e("data")??{}})},orientationVariants:({addVariant:i})=>{i("portrait","@media (orientation: portrait)"),i("landscape","@media (orientation: landscape)")},prefersContrastVariants:({addVariant:i})=>{i("contrast-more","@media (prefers-contrast: more)"),i("contrast-less","@media (prefers-contrast: less)")}},Te=["translate(var(--tw-translate-x), var(--tw-translate-y))","rotate(var(--tw-rotate))","skewX(var(--tw-skew-x))","skewY(var(--tw-skew-y))","scaleX(var(--tw-scale-x))","scaleY(var(--tw-scale-y))"].join(" "),Be=["var(--tw-blur)","var(--tw-brightness)","var(--tw-contrast)","var(--tw-grayscale)","var(--tw-hue-rotate)","var(--tw-invert)","var(--tw-saturate)","var(--tw-sepia)","var(--tw-drop-shadow)"].join(" "),Fe=["var(--tw-backdrop-blur)","var(--tw-backdrop-brightness)","var(--tw-backdrop-contrast)","var(--tw-backdrop-grayscale)","var(--tw-backdrop-hue-rotate)","var(--tw-backdrop-invert)","var(--tw-backdrop-opacity)","var(--tw-backdrop-saturate)","var(--tw-backdrop-sepia)"].join(" "),gd={preflight:({addBase:i})=>{let e=z.parse(`*,::after,::before{box-sizing:border-box;border-width:0;border-style:solid;border-color:theme('borderColor.DEFAULT', currentColor)}::after,::before{--tw-content:''}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;font-family:theme('fontFamily.sans', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:theme('fontFamily.sans[1].fontFeatureSettings', normal);font-variation-settings:theme('fontFamily.sans[1].fontVariationSettings', normal)}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:theme('fontFamily.mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::placeholder,textarea::placeholder{opacity:1;color:theme('colors.gray.4', #9ca3af)}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}`);i([z.comment({text:`! tailwindcss v${Qa} | MIT License | https://tailwindcss.com`}),...e.nodes])},container:(()=>{function i(t=[]){return t.flatMap(r=>r.values.map(n=>n.min)).filter(r=>r!==void 0)}function e(t,r,n){if(typeof n=="undefined")return[];if(!(typeof n=="object"&&n!==null))return[{screen:"DEFAULT",minWidth:0,padding:n}];let a=[];n.DEFAULT&&a.push({screen:"DEFAULT",minWidth:0,padding:n.DEFAULT});for(let s of t)for(let o of r)for(let{min:u}of o.values)u===s&&a.push({minWidth:s,padding:n[o.name]});return a}return function({addComponents:t,theme:r}){let n=at(r("container.screens",r("screens"))),a=i(n),s=e(a,n,r("container.padding")),o=c=>{let f=s.find(p=>p.minWidth===c);return f?{paddingRight:f.padding,paddingLeft:f.padding}:{}},u=Array.from(new Set(a.slice().sort((c,f)=>parseInt(c)-parseInt(f)))).map(c=>({[`@media (min-width: ${c})`]:{".container":{"max-width":c,...o(c)}}}));t([{".container":Object.assign({width:"100%"},r("container.center",!1)?{marginRight:"auto",marginLeft:"auto"}:{},o(0))},...u])}})(),accessibility:({addUtilities:i})=>{i({".sr-only":{position:"absolute",width:"1px",height:"1px",padding:"0",margin:"-1px",overflow:"hidden",clip:"rect(0, 0, 0, 0)",whiteSpace:"nowrap",borderWidth:"0"},".not-sr-only":{position:"static",width:"auto",height:"auto",padding:"0",margin:"0",overflow:"visible",clip:"auto",whiteSpace:"normal"}})},pointerEvents:({addUtilities:i})=>{i({".pointer-events-none":{"pointer-events":"none"},".pointer-events-auto":{"pointer-events":"auto"}})},visibility:({addUtilities:i})=>{i({".visible":{visibility:"visible"},".invisible":{visibility:"hidden"},".collapse":{visibility:"collapse"}})},position:({addUtilities:i})=>{i({".static":{position:"static"},".fixed":{position:"fixed"},".absolute":{position:"absolute"},".relative":{position:"relative"},".sticky":{position:"sticky"}})},inset:P("inset",[["inset",["inset"]],[["inset-x",["left","right"]],["inset-y",["top","bottom"]]],[["start",["inset-inline-start"]],["end",["inset-inline-end"]],["top",["top"]],["right",["right"]],["bottom",["bottom"]],["left",["left"]]]],{supportsNegativeValues:!0}),isolation:({addUtilities:i})=>{i({".isolate":{isolation:"isolate"},".isolation-auto":{isolation:"auto"}})},zIndex:P("zIndex",[["z",["zIndex"]]],{supportsNegativeValues:!0}),order:P("order",void 0,{supportsNegativeValues:!0}),gridColumn:P("gridColumn",[["col",["gridColumn"]]]),gridColumnStart:P("gridColumnStart",[["col-start",["gridColumnStart"]]]),gridColumnEnd:P("gridColumnEnd",[["col-end",["gridColumnEnd"]]]),gridRow:P("gridRow",[["row",["gridRow"]]]),gridRowStart:P("gridRowStart",[["row-start",["gridRowStart"]]]),gridRowEnd:P("gridRowEnd",[["row-end",["gridRowEnd"]]]),float:({addUtilities:i})=>{i({".float-right":{float:"right"},".float-left":{float:"left"},".float-none":{float:"none"}})},clear:({addUtilities:i})=>{i({".clear-left":{clear:"left"},".clear-right":{clear:"right"},".clear-both":{clear:"both"},".clear-none":{clear:"none"}})},margin:P("margin",[["m",["margin"]],[["mx",["margin-left","margin-right"]],["my",["margin-top","margin-bottom"]]],[["ms",["margin-inline-start"]],["me",["margin-inline-end"]],["mt",["margin-top"]],["mr",["margin-right"]],["mb",["margin-bottom"]],["ml",["margin-left"]]]],{supportsNegativeValues:!0}),boxSizing:({addUtilities:i})=>{i({".box-border":{"box-sizing":"border-box"},".box-content":{"box-sizing":"content-box"}})},lineClamp:({matchUtilities:i,addUtilities:e,theme:t})=>{i({"line-clamp":r=>({overflow:"hidden",display:"-webkit-box","-webkit-box-orient":"vertical","-webkit-line-clamp":`${r}`})},{values:t("lineClamp")}),e({".line-clamp-none":{overflow:"visible",display:"block","-webkit-box-orient":"horizontal","-webkit-line-clamp":"none"}})},display:({addUtilities:i})=>{i({".block":{display:"block"},".inline-block":{display:"inline-block"},".inline":{display:"inline"},".flex":{display:"flex"},".inline-flex":{display:"inline-flex"},".table":{display:"table"},".inline-table":{display:"inline-table"},".table-caption":{display:"table-caption"},".table-cell":{display:"table-cell"},".table-column":{display:"table-column"},".table-column-group":{display:"table-column-group"},".table-footer-group":{display:"table-footer-group"},".table-header-group":{display:"table-header-group"},".table-row-group":{display:"table-row-group"},".table-row":{display:"table-row"},".flow-root":{display:"flow-root"},".grid":{display:"grid"},".inline-grid":{display:"inline-grid"},".contents":{display:"contents"},".list-item":{display:"list-item"},".hidden":{display:"none"}})},aspectRatio:P("aspectRatio",[["aspect",["aspect-ratio"]]]),height:P("height",[["h",["height"]]]),maxHeight:P("maxHeight",[["max-h",["maxHeight"]]]),minHeight:P("minHeight",[["min-h",["minHeight"]]]),width:P("width",[["w",["width"]]]),minWidth:P("minWidth",[["min-w",["minWidth"]]]),maxWidth:P("maxWidth",[["max-w",["maxWidth"]]]),flex:P("flex"),flexShrink:P("flexShrink",[["flex-shrink",["flex-shrink"]],["shrink",["flex-shrink"]]]),flexGrow:P("flexGrow",[["flex-grow",["flex-grow"]],["grow",["flex-grow"]]]),flexBasis:P("flexBasis",[["basis",["flex-basis"]]]),tableLayout:({addUtilities:i})=>{i({".table-auto":{"table-layout":"auto"},".table-fixed":{"table-layout":"fixed"}})},captionSide:({addUtilities:i})=>{i({".caption-top":{"caption-side":"top"},".caption-bottom":{"caption-side":"bottom"}})},borderCollapse:({addUtilities:i})=>{i({".border-collapse":{"border-collapse":"collapse"},".border-separate":{"border-collapse":"separate"}})},borderSpacing:({addDefaults:i,matchUtilities:e,theme:t})=>{i("border-spacing",{"--tw-border-spacing-x":0,"--tw-border-spacing-y":0}),e({"border-spacing":r=>({"--tw-border-spacing-x":r,"--tw-border-spacing-y":r,"@defaults border-spacing":{},"border-spacing":"var(--tw-border-spacing-x) var(--tw-border-spacing-y)"}),"border-spacing-x":r=>({"--tw-border-spacing-x":r,"@defaults border-spacing":{},"border-spacing":"var(--tw-border-spacing-x) var(--tw-border-spacing-y)"}),"border-spacing-y":r=>({"--tw-border-spacing-y":r,"@defaults border-spacing":{},"border-spacing":"var(--tw-border-spacing-x) var(--tw-border-spacing-y)"})},{values:t("borderSpacing")})},transformOrigin:P("transformOrigin",[["origin",["transformOrigin"]]]),translate:P("translate",[[["translate-x",[["@defaults transform",{}],"--tw-translate-x",["transform",Te]]],["translate-y",[["@defaults transform",{}],"--tw-translate-y",["transform",Te]]]]],{supportsNegativeValues:!0}),rotate:P("rotate",[["rotate",[["@defaults transform",{}],"--tw-rotate",["transform",Te]]]],{supportsNegativeValues:!0}),skew:P("skew",[[["skew-x",[["@defaults transform",{}],"--tw-skew-x",["transform",Te]]],["skew-y",[["@defaults transform",{}],"--tw-skew-y",["transform",Te]]]]],{supportsNegativeValues:!0}),scale:P("scale",[["scale",[["@defaults transform",{}],"--tw-scale-x","--tw-scale-y",["transform",Te]]],[["scale-x",[["@defaults transform",{}],"--tw-scale-x",["transform",Te]]],["scale-y",[["@defaults transform",{}],"--tw-scale-y",["transform",Te]]]]],{supportsNegativeValues:!0}),transform:({addDefaults:i,addUtilities:e})=>{i("transform",{"--tw-translate-x":"0","--tw-translate-y":"0","--tw-rotate":"0","--tw-skew-x":"0","--tw-skew-y":"0","--tw-scale-x":"1","--tw-scale-y":"1"}),e({".transform":{"@defaults transform":{},transform:Te},".transform-cpu":{transform:Te},".transform-gpu":{transform:Te.replace("translate(var(--tw-translate-x), var(--tw-translate-y))","translate3d(var(--tw-translate-x), var(--tw-translate-y), 0)")},".transform-none":{transform:"none"}})},animation:({matchUtilities:i,theme:e,config:t})=>{let r=a=>ce(t("prefix")+a),n=Object.fromEntries(Object.entries(e("keyframes")??{}).map(([a,s])=>[a,{[`@keyframes ${r(a)}`]:s}]));i({animate:a=>{let s=Ha(a);return[...s.flatMap(o=>n[o.name]),{animation:s.map(({name:o,value:u})=>o===void 0||n[o]===void 0?u:u.replace(o,r(o))).join(", ")}]}},{values:e("animation")})},cursor:P("cursor"),touchAction:({addDefaults:i,addUtilities:e})=>{i("touch-action",{"--tw-pan-x":" ","--tw-pan-y":" ","--tw-pinch-zoom":" "});let t="var(--tw-pan-x) var(--tw-pan-y) var(--tw-pinch-zoom)";e({".touch-auto":{"touch-action":"auto"},".touch-none":{"touch-action":"none"},".touch-pan-x":{"@defaults touch-action":{},"--tw-pan-x":"pan-x","touch-action":t},".touch-pan-left":{"@defaults touch-action":{},"--tw-pan-x":"pan-left","touch-action":t},".touch-pan-right":{"@defaults touch-action":{},"--tw-pan-x":"pan-right","touch-action":t},".touch-pan-y":{"@defaults touch-action":{},"--tw-pan-y":"pan-y","touch-action":t},".touch-pan-up":{"@defaults touch-action":{},"--tw-pan-y":"pan-up","touch-action":t},".touch-pan-down":{"@defaults touch-action":{},"--tw-pan-y":"pan-down","touch-action":t},".touch-pinch-zoom":{"@defaults touch-action":{},"--tw-pinch-zoom":"pinch-zoom","touch-action":t},".touch-manipulation":{"touch-action":"manipulation"}})},userSelect:({addUtilities:i})=>{i({".select-none":{"user-select":"none"},".select-text":{"user-select":"text"},".select-all":{"user-select":"all"},".select-auto":{"user-select":"auto"}})},resize:({addUtilities:i})=>{i({".resize-none":{resize:"none"},".resize-y":{resize:"vertical"},".resize-x":{resize:"horizontal"},".resize":{resize:"both"}})},scrollSnapType:({addDefaults:i,addUtilities:e})=>{i("scroll-snap-type",{"--tw-scroll-snap-strictness":"proximity"}),e({".snap-none":{"scroll-snap-type":"none"},".snap-x":{"@defaults scroll-snap-type":{},"scroll-snap-type":"x var(--tw-scroll-snap-strictness)"},".snap-y":{"@defaults scroll-snap-type":{},"scroll-snap-type":"y var(--tw-scroll-snap-strictness)"},".snap-both":{"@defaults scroll-snap-type":{},"scroll-snap-type":"both var(--tw-scroll-snap-strictness)"},".snap-mandatory":{"--tw-scroll-snap-strictness":"mandatory"},".snap-proximity":{"--tw-scroll-snap-strictness":"proximity"}})},scrollSnapAlign:({addUtilities:i})=>{i({".snap-start":{"scroll-snap-align":"start"},".snap-end":{"scroll-snap-align":"end"},".snap-center":{"scroll-snap-align":"center"},".snap-align-none":{"scroll-snap-align":"none"}})},scrollSnapStop:({addUtilities:i})=>{i({".snap-normal":{"scroll-snap-stop":"normal"},".snap-always":{"scroll-snap-stop":"always"}})},scrollMargin:P("scrollMargin",[["scroll-m",["scroll-margin"]],[["scroll-mx",["scroll-margin-left","scroll-margin-right"]],["scroll-my",["scroll-margin-top","scroll-margin-bottom"]]],[["scroll-ms",["scroll-margin-inline-start"]],["scroll-me",["scroll-margin-inline-end"]],["scroll-mt",["scroll-margin-top"]],["scroll-mr",["scroll-margin-right"]],["scroll-mb",["scroll-margin-bottom"]],["scroll-ml",["scroll-margin-left"]]]],{supportsNegativeValues:!0}),scrollPadding:P("scrollPadding",[["scroll-p",["scroll-padding"]],[["scroll-px",["scroll-padding-left","scroll-padding-right"]],["scroll-py",["scroll-padding-top","scroll-padding-bottom"]]],[["scroll-ps",["scroll-padding-inline-start"]],["scroll-pe",["scroll-padding-inline-end"]],["scroll-pt",["scroll-padding-top"]],["scroll-pr",["scroll-padding-right"]],["scroll-pb",["scroll-padding-bottom"]],["scroll-pl",["scroll-padding-left"]]]]),listStylePosition:({addUtilities:i})=>{i({".list-inside":{"list-style-position":"inside"},".list-outside":{"list-style-position":"outside"}})},listStyleType:P("listStyleType",[["list",["listStyleType"]]]),listStyleImage:P("listStyleImage",[["list-image",["listStyleImage"]]]),appearance:({addUtilities:i})=>{i({".appearance-none":{appearance:"none"}})},columns:P("columns",[["columns",["columns"]]]),breakBefore:({addUtilities:i})=>{i({".break-before-auto":{"break-before":"auto"},".break-before-avoid":{"break-before":"avoid"},".break-before-all":{"break-before":"all"},".break-before-avoid-page":{"break-before":"avoid-page"},".break-before-page":{"break-before":"page"},".break-before-left":{"break-before":"left"},".break-before-right":{"break-before":"right"},".break-before-column":{"break-before":"column"}})},breakInside:({addUtilities:i})=>{i({".break-inside-auto":{"break-inside":"auto"},".break-inside-avoid":{"break-inside":"avoid"},".break-inside-avoid-page":{"break-inside":"avoid-page"},".break-inside-avoid-column":{"break-inside":"avoid-column"}})},breakAfter:({addUtilities:i})=>{i({".break-after-auto":{"break-after":"auto"},".break-after-avoid":{"break-after":"avoid"},".break-after-all":{"break-after":"all"},".break-after-avoid-page":{"break-after":"avoid-page"},".break-after-page":{"break-after":"page"},".break-after-left":{"break-after":"left"},".break-after-right":{"break-after":"right"},".break-after-column":{"break-after":"column"}})},gridAutoColumns:P("gridAutoColumns",[["auto-cols",["gridAutoColumns"]]]),gridAutoFlow:({addUtilities:i})=>{i({".grid-flow-row":{gridAutoFlow:"row"},".grid-flow-col":{gridAutoFlow:"column"},".grid-flow-dense":{gridAutoFlow:"dense"},".grid-flow-row-dense":{gridAutoFlow:"row dense"},".grid-flow-col-dense":{gridAutoFlow:"column dense"}})},gridAutoRows:P("gridAutoRows",[["auto-rows",["gridAutoRows"]]]),gridTemplateColumns:P("gridTemplateColumns",[["grid-cols",["gridTemplateColumns"]]]),gridTemplateRows:P("gridTemplateRows",[["grid-rows",["gridTemplateRows"]]]),flexDirection:({addUtilities:i})=>{i({".flex-row":{"flex-direction":"row"},".flex-row-reverse":{"flex-direction":"row-reverse"},".flex-col":{"flex-direction":"column"},".flex-col-reverse":{"flex-direction":"column-reverse"}})},flexWrap:({addUtilities:i})=>{i({".flex-wrap":{"flex-wrap":"wrap"},".flex-wrap-reverse":{"flex-wrap":"wrap-reverse"},".flex-nowrap":{"flex-wrap":"nowrap"}})},placeContent:({addUtilities:i})=>{i({".place-content-center":{"place-content":"center"},".place-content-start":{"place-content":"start"},".place-content-end":{"place-content":"end"},".place-content-between":{"place-content":"space-between"},".place-content-around":{"place-content":"space-around"},".place-content-evenly":{"place-content":"space-evenly"},".place-content-baseline":{"place-content":"baseline"},".place-content-stretch":{"place-content":"stretch"}})},placeItems:({addUtilities:i})=>{i({".place-items-start":{"place-items":"start"},".place-items-end":{"place-items":"end"},".place-items-center":{"place-items":"center"},".place-items-baseline":{"place-items":"baseline"},".place-items-stretch":{"place-items":"stretch"}})},alignContent:({addUtilities:i})=>{i({".content-normal":{"align-content":"normal"},".content-center":{"align-content":"center"},".content-start":{"align-content":"flex-start"},".content-end":{"align-content":"flex-end"},".content-between":{"align-content":"space-between"},".content-around":{"align-content":"space-around"},".content-evenly":{"align-content":"space-evenly"},".content-baseline":{"align-content":"baseline"},".content-stretch":{"align-content":"stretch"}})},alignItems:({addUtilities:i})=>{i({".items-start":{"align-items":"flex-start"},".items-end":{"align-items":"flex-end"},".items-center":{"align-items":"center"},".items-baseline":{"align-items":"baseline"},".items-stretch":{"align-items":"stretch"}})},justifyContent:({addUtilities:i})=>{i({".justify-normal":{"justify-content":"normal"},".justify-start":{"justify-content":"flex-start"},".justify-end":{"justify-content":"flex-end"},".justify-center":{"justify-content":"center"},".justify-between":{"justify-content":"space-between"},".justify-around":{"justify-content":"space-around"},".justify-evenly":{"justify-content":"space-evenly"},".justify-stretch":{"justify-content":"stretch"}})},justifyItems:({addUtilities:i})=>{i({".justify-items-start":{"justify-items":"start"},".justify-items-end":{"justify-items":"end"},".justify-items-center":{"justify-items":"center"},".justify-items-stretch":{"justify-items":"stretch"}})},gap:P("gap",[["gap",["gap"]],[["gap-x",["columnGap"]],["gap-y",["rowGap"]]]]),space:({matchUtilities:i,addUtilities:e,theme:t})=>{i({"space-x":r=>(r=r==="0"?"0px":r,{"& > :not([hidden]) ~ :not([hidden])":{"--tw-space-x-reverse":"0","margin-right":`calc(${r} * var(--tw-space-x-reverse))`,"margin-left":`calc(${r} * calc(1 - var(--tw-space-x-reverse)))`}}),"space-y":r=>(r=r==="0"?"0px":r,{"& > :not([hidden]) ~ :not([hidden])":{"--tw-space-y-reverse":"0","margin-top":`calc(${r} * calc(1 - var(--tw-space-y-reverse)))`,"margin-bottom":`calc(${r} * var(--tw-space-y-reverse))`}})},{values:t("space"),supportsNegativeValues:!0}),e({".space-y-reverse > :not([hidden]) ~ :not([hidden])":{"--tw-space-y-reverse":"1"},".space-x-reverse > :not([hidden]) ~ :not([hidden])":{"--tw-space-x-reverse":"1"}})},divideWidth:({matchUtilities:i,addUtilities:e,theme:t})=>{i({"divide-x":r=>(r=r==="0"?"0px":r,{"& > :not([hidden]) ~ :not([hidden])":{"@defaults border-width":{},"--tw-divide-x-reverse":"0","border-right-width":`calc(${r} * var(--tw-divide-x-reverse))`,"border-left-width":`calc(${r} * calc(1 - var(--tw-divide-x-reverse)))`}}),"divide-y":r=>(r=r==="0"?"0px":r,{"& > :not([hidden]) ~ :not([hidden])":{"@defaults border-width":{},"--tw-divide-y-reverse":"0","border-top-width":`calc(${r} * calc(1 - var(--tw-divide-y-reverse)))`,"border-bottom-width":`calc(${r} * var(--tw-divide-y-reverse))`}})},{values:t("divideWidth"),type:["line-width","length","any"]}),e({".divide-y-reverse > :not([hidden]) ~ :not([hidden])":{"@defaults border-width":{},"--tw-divide-y-reverse":"1"},".divide-x-reverse > :not([hidden]) ~ :not([hidden])":{"@defaults border-width":{},"--tw-divide-x-reverse":"1"}})},divideStyle:({addUtilities:i})=>{i({".divide-solid > :not([hidden]) ~ :not([hidden])":{"border-style":"solid"},".divide-dashed > :not([hidden]) ~ :not([hidden])":{"border-style":"dashed"},".divide-dotted > :not([hidden]) ~ :not([hidden])":{"border-style":"dotted"},".divide-double > :not([hidden]) ~ :not([hidden])":{"border-style":"double"},".divide-none > :not([hidden]) ~ :not([hidden])":{"border-style":"none"}})},divideColor:({matchUtilities:i,theme:e,corePlugins:t})=>{i({divide:r=>t("divideOpacity")?{["& > :not([hidden]) ~ :not([hidden])"]:se({color:r,property:"border-color",variable:"--tw-divide-opacity"})}:{["& > :not([hidden]) ~ :not([hidden])"]:{"border-color":N(r)}}},{values:(({DEFAULT:r,...n})=>n)(re(e("divideColor"))),type:["color","any"]})},divideOpacity:({matchUtilities:i,theme:e})=>{i({"divide-opacity":t=>({["& > :not([hidden]) ~ :not([hidden])"]:{"--tw-divide-opacity":t}})},{values:e("divideOpacity")})},placeSelf:({addUtilities:i})=>{i({".place-self-auto":{"place-self":"auto"},".place-self-start":{"place-self":"start"},".place-self-end":{"place-self":"end"},".place-self-center":{"place-self":"center"},".place-self-stretch":{"place-self":"stretch"}})},alignSelf:({addUtilities:i})=>{i({".self-auto":{"align-self":"auto"},".self-start":{"align-self":"flex-start"},".self-end":{"align-self":"flex-end"},".self-center":{"align-self":"center"},".self-stretch":{"align-self":"stretch"},".self-baseline":{"align-self":"baseline"}})},justifySelf:({addUtilities:i})=>{i({".justify-self-auto":{"justify-self":"auto"},".justify-self-start":{"justify-self":"start"},".justify-self-end":{"justify-self":"end"},".justify-self-center":{"justify-self":"center"},".justify-self-stretch":{"justify-self":"stretch"}})},overflow:({addUtilities:i})=>{i({".overflow-auto":{overflow:"auto"},".overflow-hidden":{overflow:"hidden"},".overflow-clip":{overflow:"clip"},".overflow-visible":{overflow:"visible"},".overflow-scroll":{overflow:"scroll"},".overflow-x-auto":{"overflow-x":"auto"},".overflow-y-auto":{"overflow-y":"auto"},".overflow-x-hidden":{"overflow-x":"hidden"},".overflow-y-hidden":{"overflow-y":"hidden"},".overflow-x-clip":{"overflow-x":"clip"},".overflow-y-clip":{"overflow-y":"clip"},".overflow-x-visible":{"overflow-x":"visible"},".overflow-y-visible":{"overflow-y":"visible"},".overflow-x-scroll":{"overflow-x":"scroll"},".overflow-y-scroll":{"overflow-y":"scroll"}})},overscrollBehavior:({addUtilities:i})=>{i({".overscroll-auto":{"overscroll-behavior":"auto"},".overscroll-contain":{"overscroll-behavior":"contain"},".overscroll-none":{"overscroll-behavior":"none"},".overscroll-y-auto":{"overscroll-behavior-y":"auto"},".overscroll-y-contain":{"overscroll-behavior-y":"contain"},".overscroll-y-none":{"overscroll-behavior-y":"none"},".overscroll-x-auto":{"overscroll-behavior-x":"auto"},".overscroll-x-contain":{"overscroll-behavior-x":"contain"},".overscroll-x-none":{"overscroll-behavior-x":"none"}})},scrollBehavior:({addUtilities:i})=>{i({".scroll-auto":{"scroll-behavior":"auto"},".scroll-smooth":{"scroll-behavior":"smooth"}})},textOverflow:({addUtilities:i})=>{i({".truncate":{overflow:"hidden","text-overflow":"ellipsis","white-space":"nowrap"},".overflow-ellipsis":{"text-overflow":"ellipsis"},".text-ellipsis":{"text-overflow":"ellipsis"},".text-clip":{"text-overflow":"clip"}})},hyphens:({addUtilities:i})=>{i({".hyphens-none":{hyphens:"none"},".hyphens-manual":{hyphens:"manual"},".hyphens-auto":{hyphens:"auto"}})},whitespace:({addUtilities:i})=>{i({".whitespace-normal":{"white-space":"normal"},".whitespace-nowrap":{"white-space":"nowrap"},".whitespace-pre":{"white-space":"pre"},".whitespace-pre-line":{"white-space":"pre-line"},".whitespace-pre-wrap":{"white-space":"pre-wrap"},".whitespace-break-spaces":{"white-space":"break-spaces"}})},wordBreak:({addUtilities:i})=>{i({".break-normal":{"overflow-wrap":"normal","word-break":"normal"},".break-words":{"overflow-wrap":"break-word"},".break-all":{"word-break":"break-all"},".break-keep":{"word-break":"keep-all"}})},borderRadius:P("borderRadius",[["rounded",["border-radius"]],[["rounded-s",["border-start-start-radius","border-end-start-radius"]],["rounded-e",["border-start-end-radius","border-end-end-radius"]],["rounded-t",["border-top-left-radius","border-top-right-radius"]],["rounded-r",["border-top-right-radius","border-bottom-right-radius"]],["rounded-b",["border-bottom-right-radius","border-bottom-left-radius"]],["rounded-l",["border-top-left-radius","border-bottom-left-radius"]]],[["rounded-ss",["border-start-start-radius"]],["rounded-se",["border-start-end-radius"]],["rounded-ee",["border-end-end-radius"]],["rounded-es",["border-end-start-radius"]],["rounded-tl",["border-top-left-radius"]],["rounded-tr",["border-top-right-radius"]],["rounded-br",["border-bottom-right-radius"]],["rounded-bl",["border-bottom-left-radius"]]]]),borderWidth:P("borderWidth",[["border",[["@defaults border-width",{}],"border-width"]],[["border-x",[["@defaults border-width",{}],"border-left-width","border-right-width"]],["border-y",[["@defaults border-width",{}],"border-top-width","border-bottom-width"]]],[["border-s",[["@defaults border-width",{}],"border-inline-start-width"]],["border-e",[["@defaults border-width",{}],"border-inline-end-width"]],["border-t",[["@defaults border-width",{}],"border-top-width"]],["border-r",[["@defaults border-width",{}],"border-right-width"]],["border-b",[["@defaults border-width",{}],"border-bottom-width"]],["border-l",[["@defaults border-width",{}],"border-left-width"]]]],{type:["line-width","length"]}),borderStyle:({addUtilities:i})=>{i({".border-solid":{"border-style":"solid"},".border-dashed":{"border-style":"dashed"},".border-dotted":{"border-style":"dotted"},".border-double":{"border-style":"double"},".border-hidden":{"border-style":"hidden"},".border-none":{"border-style":"none"}})},borderColor:({matchUtilities:i,theme:e,corePlugins:t})=>{i({border:r=>t("borderOpacity")?se({color:r,property:"border-color",variable:"--tw-border-opacity"}):{"border-color":N(r)}},{values:(({DEFAULT:r,...n})=>n)(re(e("borderColor"))),type:["color","any"]}),i({"border-x":r=>t("borderOpacity")?se({color:r,property:["border-left-color","border-right-color"],variable:"--tw-border-opacity"}):{"border-left-color":N(r),"border-right-color":N(r)},"border-y":r=>t("borderOpacity")?se({color:r,property:["border-top-color","border-bottom-color"],variable:"--tw-border-opacity"}):{"border-top-color":N(r),"border-bottom-color":N(r)}},{values:(({DEFAULT:r,...n})=>n)(re(e("borderColor"))),type:["color","any"]}),i({"border-s":r=>t("borderOpacity")?se({color:r,property:"border-inline-start-color",variable:"--tw-border-opacity"}):{"border-inline-start-color":N(r)},"border-e":r=>t("borderOpacity")?se({color:r,property:"border-inline-end-color",variable:"--tw-border-opacity"}):{"border-inline-end-color":N(r)},"border-t":r=>t("borderOpacity")?se({color:r,property:"border-top-color",variable:"--tw-border-opacity"}):{"border-top-color":N(r)},"border-r":r=>t("borderOpacity")?se({color:r,property:"border-right-color",variable:"--tw-border-opacity"}):{"border-right-color":N(r)},"border-b":r=>t("borderOpacity")?se({color:r,property:"border-bottom-color",variable:"--tw-border-opacity"}):{"border-bottom-color":N(r)},"border-l":r=>t("borderOpacity")?se({color:r,property:"border-left-color",variable:"--tw-border-opacity"}):{"border-left-color":N(r)}},{values:(({DEFAULT:r,...n})=>n)(re(e("borderColor"))),type:["color","any"]})},borderOpacity:P("borderOpacity",[["border-opacity",["--tw-border-opacity"]]]),backgroundColor:({matchUtilities:i,theme:e,corePlugins:t})=>{i({bg:r=>t("backgroundOpacity")?se({color:r,property:"background-color",variable:"--tw-bg-opacity"}):{"background-color":N(r)}},{values:re(e("backgroundColor")),type:["color","any"]})},backgroundOpacity:P("backgroundOpacity",[["bg-opacity",["--tw-bg-opacity"]]]),backgroundImage:P("backgroundImage",[["bg",["background-image"]]],{type:["lookup","image","url"]}),gradientColorStops:(()=>{function i(e){return Ie(e,0,"rgb(255 255 255 / 0)")}return function({matchUtilities:e,theme:t,addDefaults:r}){r("gradient-color-stops",{"--tw-gradient-from-position":" ","--tw-gradient-via-position":" ","--tw-gradient-to-position":" "});let n={values:re(t("gradientColorStops")),type:["color","any"]},a={values:t("gradientColorStopPositions"),type:["length","percentage"]};e({from:s=>{let o=i(s);return{"@defaults gradient-color-stops":{},"--tw-gradient-from":`${N(s)} var(--tw-gradient-from-position)`,"--tw-gradient-to":`${o} var(--tw-gradient-to-position)`,"--tw-gradient-stops":"var(--tw-gradient-from), var(--tw-gradient-to)"}}},n),e({from:s=>({"--tw-gradient-from-position":s})},a),e({via:s=>{let o=i(s);return{"@defaults gradient-color-stops":{},"--tw-gradient-to":`${o} var(--tw-gradient-to-position)`,"--tw-gradient-stops":`var(--tw-gradient-from), ${N(s)} var(--tw-gradient-via-position), var(--tw-gradient-to)`}}},n),e({via:s=>({"--tw-gradient-via-position":s})},a),e({to:s=>({"@defaults gradient-color-stops":{},"--tw-gradient-to":`${N(s)} var(--tw-gradient-to-position)`})},n),e({to:s=>({"--tw-gradient-to-position":s})},a)}})(),boxDecorationBreak:({addUtilities:i})=>{i({".decoration-slice":{"box-decoration-break":"slice"},".decoration-clone":{"box-decoration-break":"clone"},".box-decoration-slice":{"box-decoration-break":"slice"},".box-decoration-clone":{"box-decoration-break":"clone"}})},backgroundSize:P("backgroundSize",[["bg",["background-size"]]],{type:["lookup","length","percentage","size"]}),backgroundAttachment:({addUtilities:i})=>{i({".bg-fixed":{"background-attachment":"fixed"},".bg-local":{"background-attachment":"local"},".bg-scroll":{"background-attachment":"scroll"}})},backgroundClip:({addUtilities:i})=>{i({".bg-clip-border":{"background-clip":"border-box"},".bg-clip-padding":{"background-clip":"padding-box"},".bg-clip-content":{"background-clip":"content-box"},".bg-clip-text":{"background-clip":"text"}})},backgroundPosition:P("backgroundPosition",[["bg",["background-position"]]],{type:["lookup",["position",{preferOnConflict:!0}]]}),backgroundRepeat:({addUtilities:i})=>{i({".bg-repeat":{"background-repeat":"repeat"},".bg-no-repeat":{"background-repeat":"no-repeat"},".bg-repeat-x":{"background-repeat":"repeat-x"},".bg-repeat-y":{"background-repeat":"repeat-y"},".bg-repeat-round":{"background-repeat":"round"},".bg-repeat-space":{"background-repeat":"space"}})},backgroundOrigin:({addUtilities:i})=>{i({".bg-origin-border":{"background-origin":"border-box"},".bg-origin-padding":{"background-origin":"padding-box"},".bg-origin-content":{"background-origin":"content-box"}})},fill:({matchUtilities:i,theme:e})=>{i({fill:t=>({fill:N(t)})},{values:re(e("fill")),type:["color","any"]})},stroke:({matchUtilities:i,theme:e})=>{i({stroke:t=>({stroke:N(t)})},{values:re(e("stroke")),type:["color","url","any"]})},strokeWidth:P("strokeWidth",[["stroke",["stroke-width"]]],{type:["length","number","percentage"]}),objectFit:({addUtilities:i})=>{i({".object-contain":{"object-fit":"contain"},".object-cover":{"object-fit":"cover"},".object-fill":{"object-fit":"fill"},".object-none":{"object-fit":"none"},".object-scale-down":{"object-fit":"scale-down"}})},objectPosition:P("objectPosition",[["object",["object-position"]]]),padding:P("padding",[["p",["padding"]],[["px",["padding-left","padding-right"]],["py",["padding-top","padding-bottom"]]],[["ps",["padding-inline-start"]],["pe",["padding-inline-end"]],["pt",["padding-top"]],["pr",["padding-right"]],["pb",["padding-bottom"]],["pl",["padding-left"]]]]),textAlign:({addUtilities:i})=>{i({".text-left":{"text-align":"left"},".text-center":{"text-align":"center"},".text-right":{"text-align":"right"},".text-justify":{"text-align":"justify"},".text-start":{"text-align":"start"},".text-end":{"text-align":"end"}})},textIndent:P("textIndent",[["indent",["text-indent"]]],{supportsNegativeValues:!0}),verticalAlign:({addUtilities:i,matchUtilities:e})=>{i({".align-baseline":{"vertical-align":"baseline"},".align-top":{"vertical-align":"top"},".align-middle":{"vertical-align":"middle"},".align-bottom":{"vertical-align":"bottom"},".align-text-top":{"vertical-align":"text-top"},".align-text-bottom":{"vertical-align":"text-bottom"},".align-sub":{"vertical-align":"sub"},".align-super":{"vertical-align":"super"}}),e({align:t=>({"vertical-align":t})})},fontFamily:({matchUtilities:i,theme:e})=>{i({font:t=>{let[r,n={}]=Array.isArray(t)&&ie(t[1])?t:[t],{fontFeatureSettings:a,fontVariationSettings:s}=n;return{"font-family":Array.isArray(r)?r.join(", "):r,...a===void 0?{}:{"font-feature-settings":a},...s===void 0?{}:{"font-variation-settings":s}}}},{values:e("fontFamily"),type:["lookup","generic-name","family-name"]})},fontSize:({matchUtilities:i,theme:e})=>{i({text:(t,{modifier:r})=>{let[n,a]=Array.isArray(t)?t:[t];if(r)return{"font-size":n,"line-height":r};let{lineHeight:s,letterSpacing:o,fontWeight:u}=ie(a)?a:{lineHeight:a};return{"font-size":n,...s===void 0?{}:{"line-height":s},...o===void 0?{}:{"letter-spacing":o},...u===void 0?{}:{"font-weight":u}}}},{values:e("fontSize"),modifiers:e("lineHeight"),type:["absolute-size","relative-size","length","percentage"]})},fontWeight:P("fontWeight",[["font",["fontWeight"]]],{type:["lookup","number","any"]}),textTransform:({addUtilities:i})=>{i({".uppercase":{"text-transform":"uppercase"},".lowercase":{"text-transform":"lowercase"},".capitalize":{"text-transform":"capitalize"},".normal-case":{"text-transform":"none"}})},fontStyle:({addUtilities:i})=>{i({".italic":{"font-style":"italic"},".not-italic":{"font-style":"normal"}})},fontVariantNumeric:({addDefaults:i,addUtilities:e})=>{let t="var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)";i("font-variant-numeric",{"--tw-ordinal":" ","--tw-slashed-zero":" ","--tw-numeric-figure":" ","--tw-numeric-spacing":" ","--tw-numeric-fraction":" "}),e({".normal-nums":{"font-variant-numeric":"normal"},".ordinal":{"@defaults font-variant-numeric":{},"--tw-ordinal":"ordinal","font-variant-numeric":t},".slashed-zero":{"@defaults font-variant-numeric":{},"--tw-slashed-zero":"slashed-zero","font-variant-numeric":t},".lining-nums":{"@defaults font-variant-numeric":{},"--tw-numeric-figure":"lining-nums","font-variant-numeric":t},".oldstyle-nums":{"@defaults font-variant-numeric":{},"--tw-numeric-figure":"oldstyle-nums","font-variant-numeric":t},".proportional-nums":{"@defaults font-variant-numeric":{},"--tw-numeric-spacing":"proportional-nums","font-variant-numeric":t},".tabular-nums":{"@defaults font-variant-numeric":{},"--tw-numeric-spacing":"tabular-nums","font-variant-numeric":t},".diagonal-fractions":{"@defaults font-variant-numeric":{},"--tw-numeric-fraction":"diagonal-fractions","font-variant-numeric":t},".stacked-fractions":{"@defaults font-variant-numeric":{},"--tw-numeric-fraction":"stacked-fractions","font-variant-numeric":t}})},lineHeight:P("lineHeight",[["leading",["lineHeight"]]]),letterSpacing:P("letterSpacing",[["tracking",["letterSpacing"]]],{supportsNegativeValues:!0}),textColor:({matchUtilities:i,theme:e,corePlugins:t})=>{i({text:r=>t("textOpacity")?se({color:r,property:"color",variable:"--tw-text-opacity"}):{color:N(r)}},{values:re(e("textColor")),type:["color","any"]})},textOpacity:P("textOpacity",[["text-opacity",["--tw-text-opacity"]]]),textDecoration:({addUtilities:i})=>{i({".underline":{"text-decoration-line":"underline"},".overline":{"text-decoration-line":"overline"},".line-through":{"text-decoration-line":"line-through"},".no-underline":{"text-decoration-line":"none"}})},textDecorationColor:({matchUtilities:i,theme:e})=>{i({decoration:t=>({"text-decoration-color":N(t)})},{values:re(e("textDecorationColor")),type:["color","any"]})},textDecorationStyle:({addUtilities:i})=>{i({".decoration-solid":{"text-decoration-style":"solid"},".decoration-double":{"text-decoration-style":"double"},".decoration-dotted":{"text-decoration-style":"dotted"},".decoration-dashed":{"text-decoration-style":"dashed"},".decoration-wavy":{"text-decoration-style":"wavy"}})},textDecorationThickness:P("textDecorationThickness",[["decoration",["text-decoration-thickness"]]],{type:["length","percentage"]}),textUnderlineOffset:P("textUnderlineOffset",[["underline-offset",["text-underline-offset"]]],{type:["length","percentage","any"]}),fontSmoothing:({addUtilities:i})=>{i({".antialiased":{"-webkit-font-smoothing":"antialiased","-moz-osx-font-smoothing":"grayscale"},".subpixel-antialiased":{"-webkit-font-smoothing":"auto","-moz-osx-font-smoothing":"auto"}})},placeholderColor:({matchUtilities:i,theme:e,corePlugins:t})=>{i({placeholder:r=>t("placeholderOpacity")?{"&::placeholder":se({color:r,property:"color",variable:"--tw-placeholder-opacity"})}:{"&::placeholder":{color:N(r)}}},{values:re(e("placeholderColor")),type:["color","any"]})},placeholderOpacity:({matchUtilities:i,theme:e})=>{i({"placeholder-opacity":t=>({["&::placeholder"]:{"--tw-placeholder-opacity":t}})},{values:e("placeholderOpacity")})},caretColor:({matchUtilities:i,theme:e})=>{i({caret:t=>({"caret-color":N(t)})},{values:re(e("caretColor")),type:["color","any"]})},accentColor:({matchUtilities:i,theme:e})=>{i({accent:t=>({"accent-color":N(t)})},{values:re(e("accentColor")),type:["color","any"]})},opacity:P("opacity",[["opacity",["opacity"]]]),backgroundBlendMode:({addUtilities:i})=>{i({".bg-blend-normal":{"background-blend-mode":"normal"},".bg-blend-multiply":{"background-blend-mode":"multiply"},".bg-blend-screen":{"background-blend-mode":"screen"},".bg-blend-overlay":{"background-blend-mode":"overlay"},".bg-blend-darken":{"background-blend-mode":"darken"},".bg-blend-lighten":{"background-blend-mode":"lighten"},".bg-blend-color-dodge":{"background-blend-mode":"color-dodge"},".bg-blend-color-burn":{"background-blend-mode":"color-burn"},".bg-blend-hard-light":{"background-blend-mode":"hard-light"},".bg-blend-soft-light":{"background-blend-mode":"soft-light"},".bg-blend-difference":{"background-blend-mode":"difference"},".bg-blend-exclusion":{"background-blend-mode":"exclusion"},".bg-blend-hue":{"background-blend-mode":"hue"},".bg-blend-saturation":{"background-blend-mode":"saturation"},".bg-blend-color":{"background-blend-mode":"color"},".bg-blend-luminosity":{"background-blend-mode":"luminosity"}})},mixBlendMode:({addUtilities:i})=>{i({".mix-blend-normal":{"mix-blend-mode":"normal"},".mix-blend-multiply":{"mix-blend-mode":"multiply"},".mix-blend-screen":{"mix-blend-mode":"screen"},".mix-blend-overlay":{"mix-blend-mode":"overlay"},".mix-blend-darken":{"mix-blend-mode":"darken"},".mix-blend-lighten":{"mix-blend-mode":"lighten"},".mix-blend-color-dodge":{"mix-blend-mode":"color-dodge"},".mix-blend-color-burn":{"mix-blend-mode":"color-burn"},".mix-blend-hard-light":{"mix-blend-mode":"hard-light"},".mix-blend-soft-light":{"mix-blend-mode":"soft-light"},".mix-blend-difference":{"mix-blend-mode":"difference"},".mix-blend-exclusion":{"mix-blend-mode":"exclusion"},".mix-blend-hue":{"mix-blend-mode":"hue"},".mix-blend-saturation":{"mix-blend-mode":"saturation"},".mix-blend-color":{"mix-blend-mode":"color"},".mix-blend-luminosity":{"mix-blend-mode":"luminosity"},".mix-blend-plus-lighter":{"mix-blend-mode":"plus-lighter"}})},boxShadow:(()=>{let i=Ge("boxShadow"),e=["var(--tw-ring-offset-shadow, 0 0 #0000)","var(--tw-ring-shadow, 0 0 #0000)","var(--tw-shadow)"].join(", ");return function({matchUtilities:t,addDefaults:r,theme:n}){r(" box-shadow",{"--tw-ring-offset-shadow":"0 0 #0000","--tw-ring-shadow":"0 0 #0000","--tw-shadow":"0 0 #0000","--tw-shadow-colored":"0 0 #0000"}),t({shadow:a=>{a=i(a);let s=yi(a);for(let o of s)!o.valid||(o.color="var(--tw-shadow-color)");return{"@defaults box-shadow":{},"--tw-shadow":a==="none"?"0 0 #0000":a,"--tw-shadow-colored":a==="none"?"0 0 #0000":Iu(s),"box-shadow":e}}},{values:n("boxShadow"),type:["shadow"]})}})(),boxShadowColor:({matchUtilities:i,theme:e})=>{i({shadow:t=>({"--tw-shadow-color":N(t),"--tw-shadow":"var(--tw-shadow-colored)"})},{values:re(e("boxShadowColor")),type:["color","any"]})},outlineStyle:({addUtilities:i})=>{i({".outline-none":{outline:"2px solid transparent","outline-offset":"2px"},".outline":{"outline-style":"solid"},".outline-dashed":{"outline-style":"dashed"},".outline-dotted":{"outline-style":"dotted"},".outline-double":{"outline-style":"double"}})},outlineWidth:P("outlineWidth",[["outline",["outline-width"]]],{type:["length","number","percentage"]}),outlineOffset:P("outlineOffset",[["outline-offset",["outline-offset"]]],{type:["length","number","percentage","any"],supportsNegativeValues:!0}),outlineColor:({matchUtilities:i,theme:e})=>{i({outline:t=>({"outline-color":N(t)})},{values:re(e("outlineColor")),type:["color","any"]})},ringWidth:({matchUtilities:i,addDefaults:e,addUtilities:t,theme:r,config:n})=>{let a=(()=>{if(J(n(),"respectDefaultRingColorOpacity"))return r("ringColor.DEFAULT");let s=r("ringOpacity.DEFAULT","0.5");return r("ringColor")?.DEFAULT?Ie(r("ringColor")?.DEFAULT,s,`rgb(147 197 253 / ${s})`):`rgb(147 197 253 / ${s})`})();e("ring-width",{"--tw-ring-inset":" ","--tw-ring-offset-width":r("ringOffsetWidth.DEFAULT","0px"),"--tw-ring-offset-color":r("ringOffsetColor.DEFAULT","#fff"),"--tw-ring-color":a,"--tw-ring-offset-shadow":"0 0 #0000","--tw-ring-shadow":"0 0 #0000","--tw-shadow":"0 0 #0000","--tw-shadow-colored":"0 0 #0000"}),i({ring:s=>({"@defaults ring-width":{},"--tw-ring-offset-shadow":"var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)","--tw-ring-shadow":`var(--tw-ring-inset) 0 0 0 calc(${s} + var(--tw-ring-offset-width)) var(--tw-ring-color)`,"box-shadow":["var(--tw-ring-offset-shadow)","var(--tw-ring-shadow)","var(--tw-shadow, 0 0 #0000)"].join(", ")})},{values:r("ringWidth"),type:"length"}),t({".ring-inset":{"@defaults ring-width":{},"--tw-ring-inset":"inset"}})},ringColor:({matchUtilities:i,theme:e,corePlugins:t})=>{i({ring:r=>t("ringOpacity")?se({color:r,property:"--tw-ring-color",variable:"--tw-ring-opacity"}):{"--tw-ring-color":N(r)}},{values:Object.fromEntries(Object.entries(re(e("ringColor"))).filter(([r])=>r!=="DEFAULT")),type:["color","any"]})},ringOpacity:i=>{let{config:e}=i;return P("ringOpacity",[["ring-opacity",["--tw-ring-opacity"]]],{filterDefault:!J(e(),"respectDefaultRingColorOpacity")})(i)},ringOffsetWidth:P("ringOffsetWidth",[["ring-offset",["--tw-ring-offset-width"]]],{type:"length"}),ringOffsetColor:({matchUtilities:i,theme:e})=>{i({"ring-offset":t=>({"--tw-ring-offset-color":N(t)})},{values:re(e("ringOffsetColor")),type:["color","any"]})},blur:({matchUtilities:i,theme:e})=>{i({blur:t=>({"--tw-blur":`blur(${t})`,"@defaults filter":{},filter:Be})},{values:e("blur")})},brightness:({matchUtilities:i,theme:e})=>{i({brightness:t=>({"--tw-brightness":`brightness(${t})`,"@defaults filter":{},filter:Be})},{values:e("brightness")})},contrast:({matchUtilities:i,theme:e})=>{i({contrast:t=>({"--tw-contrast":`contrast(${t})`,"@defaults filter":{},filter:Be})},{values:e("contrast")})},dropShadow:({matchUtilities:i,theme:e})=>{i({"drop-shadow":t=>({"--tw-drop-shadow":Array.isArray(t)?t.map(r=>`drop-shadow(${r})`).join(" "):`drop-shadow(${t})`,"@defaults filter":{},filter:Be})},{values:e("dropShadow")})},grayscale:({matchUtilities:i,theme:e})=>{i({grayscale:t=>({"--tw-grayscale":`grayscale(${t})`,"@defaults filter":{},filter:Be})},{values:e("grayscale")})},hueRotate:({matchUtilities:i,theme:e})=>{i({"hue-rotate":t=>({"--tw-hue-rotate":`hue-rotate(${t})`,"@defaults filter":{},filter:Be})},{values:e("hueRotate"),supportsNegativeValues:!0})},invert:({matchUtilities:i,theme:e})=>{i({invert:t=>({"--tw-invert":`invert(${t})`,"@defaults filter":{},filter:Be})},{values:e("invert")})},saturate:({matchUtilities:i,theme:e})=>{i({saturate:t=>({"--tw-saturate":`saturate(${t})`,"@defaults filter":{},filter:Be})},{values:e("saturate")})},sepia:({matchUtilities:i,theme:e})=>{i({sepia:t=>({"--tw-sepia":`sepia(${t})`,"@defaults filter":{},filter:Be})},{values:e("sepia")})},filter:({addDefaults:i,addUtilities:e})=>{i("filter",{"--tw-blur":" ","--tw-brightness":" ","--tw-contrast":" ","--tw-grayscale":" ","--tw-hue-rotate":" ","--tw-invert":" ","--tw-saturate":" ","--tw-sepia":" ","--tw-drop-shadow":" "}),e({".filter":{"@defaults filter":{},filter:Be},".filter-none":{filter:"none"}})},backdropBlur:({matchUtilities:i,theme:e})=>{i({"backdrop-blur":t=>({"--tw-backdrop-blur":`blur(${t})`,"@defaults backdrop-filter":{},"backdrop-filter":Fe})},{values:e("backdropBlur")})},backdropBrightness:({matchUtilities:i,theme:e})=>{i({"backdrop-brightness":t=>({"--tw-backdrop-brightness":`brightness(${t})`,"@defaults backdrop-filter":{},"backdrop-filter":Fe})},{values:e("backdropBrightness")})},backdropContrast:({matchUtilities:i,theme:e})=>{i({"backdrop-contrast":t=>({"--tw-backdrop-contrast":`contrast(${t})`,"@defaults backdrop-filter":{},"backdrop-filter":Fe})},{values:e("backdropContrast")})},backdropGrayscale:({matchUtilities:i,theme:e})=>{i({"backdrop-grayscale":t=>({"--tw-backdrop-grayscale":`grayscale(${t})`,"@defaults backdrop-filter":{},"backdrop-filter":Fe})},{values:e("backdropGrayscale")})},backdropHueRotate:({matchUtilities:i,theme:e})=>{i({"backdrop-hue-rotate":t=>({"--tw-backdrop-hue-rotate":`hue-rotate(${t})`,"@defaults backdrop-filter":{},"backdrop-filter":Fe})},{values:e("backdropHueRotate"),supportsNegativeValues:!0})},backdropInvert:({matchUtilities:i,theme:e})=>{i({"backdrop-invert":t=>({"--tw-backdrop-invert":`invert(${t})`,"@defaults backdrop-filter":{},"backdrop-filter":Fe})},{values:e("backdropInvert")})},backdropOpacity:({matchUtilities:i,theme:e})=>{i({"backdrop-opacity":t=>({"--tw-backdrop-opacity":`opacity(${t})`,"@defaults backdrop-filter":{},"backdrop-filter":Fe})},{values:e("backdropOpacity")})},backdropSaturate:({matchUtilities:i,theme:e})=>{i({"backdrop-saturate":t=>({"--tw-backdrop-saturate":`saturate(${t})`,"@defaults backdrop-filter":{},"backdrop-filter":Fe})},{values:e("backdropSaturate")})},backdropSepia:({matchUtilities:i,theme:e})=>{i({"backdrop-sepia":t=>({"--tw-backdrop-sepia":`sepia(${t})`,"@defaults backdrop-filter":{},"backdrop-filter":Fe})},{values:e("backdropSepia")})},backdropFilter:({addDefaults:i,addUtilities:e})=>{i("backdrop-filter",{"--tw-backdrop-blur":" ","--tw-backdrop-brightness":" ","--tw-backdrop-contrast":" ","--tw-backdrop-grayscale":" ","--tw-backdrop-hue-rotate":" ","--tw-backdrop-invert":" ","--tw-backdrop-opacity":" ","--tw-backdrop-saturate":" ","--tw-backdrop-sepia":" "}),e({".backdrop-filter":{"@defaults backdrop-filter":{},"backdrop-filter":Fe},".backdrop-filter-none":{"backdrop-filter":"none"}})},transitionProperty:({matchUtilities:i,theme:e})=>{let t=e("transitionTimingFunction.DEFAULT"),r=e("transitionDuration.DEFAULT");i({transition:n=>({"transition-property":n,...n==="none"?{}:{"transition-timing-function":t,"transition-duration":r}})},{values:e("transitionProperty")})},transitionDelay:P("transitionDelay",[["delay",["transitionDelay"]]]),transitionDuration:P("transitionDuration",[["duration",["transitionDuration"]]],{filterDefault:!0}),transitionTimingFunction:P("transitionTimingFunction",[["ease",["transitionTimingFunction"]]],{filterDefault:!0}),willChange:P("willChange",[["will-change",["will-change"]]]),content:P("content",[["content",["--tw-content",["content","var(--tw-content)"]]]])}});function bC(i){if(i===void 0)return!1;if(i==="true"||i==="1")return!0;if(i==="false"||i==="0")return!1;if(i==="*")return!0;let e=i.split(",").map(t=>t.split(":")[0]);return e.includes("-tailwindcss")?!1:!!e.includes("tailwindcss")}var Pe,wd,bd,gn,Xa,He,Kr,ot=C(()=>{l();Ya();Pe=typeof m!="undefined"?{NODE_ENV:"production",DEBUG:bC(m.env.DEBUG),ENGINE:Ja.tailwindcss.engine}:{NODE_ENV:"production",DEBUG:!1,ENGINE:Ja.tailwindcss.engine},wd=new Map,bd=new Map,gn=new Map,Xa=new Map,He=new String("*"),Kr=Symbol("__NONE__")});function Bt(i){let e=[],t=!1;for(let r=0;r0)}var vd,xd,vC,Ka=C(()=>{l();vd=new Map([["{","}"],["[","]"],["(",")"]]),xd=new Map(Array.from(vd.entries()).map(([i,e])=>[e,i])),vC=new Set(['"',"'","`"])});function Ft(i){let[e]=kd(i);return e.forEach(([t,r])=>t.removeChild(r)),i.nodes.push(...e.map(([,t])=>t)),i}function kd(i){let e=[],t=null;for(let r of i.nodes)if(r.type==="combinator")e=e.filter(([,n])=>eo(n).includes("jumpable")),t=null;else if(r.type==="pseudo"){xC(r)?(t=r,e.push([i,r,null])):t&&kC(r,t)?e.push([i,r,t]):t=null;for(let n of r.nodes??[]){let[a,s]=kd(n);t=s||t,e.push(...a)}}return[e,t]}function Sd(i){return i.value.startsWith("::")||Za[i.value]!==void 0}function xC(i){return Sd(i)&&eo(i).includes("terminal")}function kC(i,e){return i.type!=="pseudo"||Sd(i)?!1:eo(e).includes("actionable")}function eo(i){return Za[i.value]??Za.__default__}var Za,yn=C(()=>{l();Za={"::after":["terminal","jumpable"],"::backdrop":["terminal","jumpable"],"::before":["terminal","jumpable"],"::cue":["terminal"],"::cue-region":["terminal"],"::first-letter":["terminal","jumpable"],"::first-line":["terminal","jumpable"],"::grammar-error":["terminal"],"::marker":["terminal","jumpable"],"::part":["terminal","actionable"],"::placeholder":["terminal","jumpable"],"::selection":["terminal","jumpable"],"::slotted":["terminal"],"::spelling-error":["terminal"],"::target-text":["terminal"],"::file-selector-button":["terminal","actionable"],"::deep":["actionable"],"::v-deep":["actionable"],"::ng-deep":["actionable"],":after":["terminal","jumpable"],":before":["terminal","jumpable"],":first-letter":["terminal","jumpable"],":first-line":["terminal","jumpable"],__default__:["terminal","actionable"]}});function Nt(i,{context:e,candidate:t}){let r=e?.tailwindConfig.prefix??"",n=i.map(s=>{let o=(0,Ne.default)().astSync(s.format);return{...s,ast:s.respectPrefix?Rt(r,o):o}}),a=Ne.default.root({nodes:[Ne.default.selector({nodes:[Ne.default.className({value:ce(t)})]})]});for(let{ast:s}of n)[a,s]=CC(a,s),s.walkNesting(o=>o.replaceWith(...a.nodes[0].nodes)),a=s;return a}function Ad(i){let e=[];for(;i.prev()&&i.prev().type!=="combinator";)i=i.prev();for(;i&&i.type!=="combinator";)e.push(i),i=i.next();return e}function SC(i){return i.sort((e,t)=>e.type==="tag"&&t.type==="class"?-1:e.type==="class"&&t.type==="tag"?1:e.type==="class"&&t.type==="pseudo"&&t.value.startsWith("::")?-1:e.type==="pseudo"&&e.value.startsWith("::")&&t.type==="class"?1:i.index(e)-i.index(t)),i}function ro(i,e){let t=!1;i.walk(r=>{if(r.type==="class"&&r.value===e)return t=!0,!1}),t||i.remove()}function wn(i,e,{context:t,candidate:r,base:n}){let a=t?.tailwindConfig?.separator??":";n=n??r.split(new RegExp(`\\${a}(?![^[]*\\])`)).pop();let s=(0,Ne.default)().astSync(i);s.walkClasses(f=>{f.raws&&f.value.includes(n)&&(f.raws.value=ce((0,Cd.default)(f.raws.value)))}),s.each(f=>ro(f,n));let o=Array.isArray(e)?Nt(e,{context:t,candidate:r}):e;if(o===null)return s.toString();let u=Ne.default.comment({value:"/*__simple__*/"}),c=Ne.default.comment({value:"/*__simple__*/"});return s.walkClasses(f=>{if(f.value!==n)return;let p=f.parent,d=o.nodes[0].nodes;if(p.nodes.length===1){f.replaceWith(...d);return}let h=Ad(f);p.insertBefore(h[0],u),p.insertAfter(h[h.length-1],c);for(let x of d)p.insertBefore(h[0],x.clone());f.remove(),h=Ad(u);let y=p.index(u);p.nodes.splice(y,h.length,...SC(Ne.default.selector({nodes:h})).nodes),u.remove(),c.remove()}),s.walkPseudos(f=>{f.value===to&&f.replaceWith(f.nodes)}),s.each(f=>Ft(f)),s.toString()}function CC(i,e){let t=[];return i.walkPseudos(r=>{r.value===to&&t.push({pseudo:r,value:r.nodes[0].toString()})}),e.walkPseudos(r=>{if(r.value!==to)return;let n=r.nodes[0].toString(),a=t.find(c=>c.value===n);if(!a)return;let s=[],o=r.next();for(;o&&o.type!=="combinator";)s.push(o),o=o.next();let u=o;a.pseudo.parent.insertAfter(a.pseudo,Ne.default.selector({nodes:s.map(c=>c.clone())})),r.remove(),s.forEach(c=>c.remove()),u&&u.type==="combinator"&&u.remove()}),[i,e]}var Ne,Cd,to,io=C(()=>{l();Ne=K(Me()),Cd=K(Yi());Mt();un();yn();to=":merge"});function bn(i,e){let t=(0,no.default)().astSync(i);return t.each(r=>{r.nodes[0].type==="pseudo"&&r.nodes[0].value===":is"&&r.nodes.every(a=>a.type!=="combinator")||(r.nodes=[no.default.pseudo({value:":is",nodes:[r.clone()]})]),Ft(r)}),`${e} ${t.toString()}`}var no,so=C(()=>{l();no=K(Me());yn()});function ao(i){return AC.transformSync(i)}function*_C(i){let e=1/0;for(;e>=0;){let t,r=!1;if(e===1/0&&i.endsWith("]")){let s=i.indexOf("[");i[s-1]==="-"?t=s-1:i[s-1]==="/"?(t=s-1,r=!0):t=-1}else e===1/0&&i.includes("/")?(t=i.lastIndexOf("/"),r=!0):t=i.lastIndexOf("-",e);if(t<0)break;let n=i.slice(0,t),a=i.slice(r?t:t+1);e=t-1,!(n===""||a==="/")&&(yield[n,a])}}function EC(i,e){if(i.length===0||e.tailwindConfig.prefix==="")return i;for(let t of i){let[r]=t;if(r.options.respectPrefix){let n=z.root({nodes:[t[1].clone()]}),a=t[1].raws.tailwind.classCandidate;n.walkRules(s=>{let o=a.startsWith("-");s.selector=Rt(e.tailwindConfig.prefix,s.selector,o)}),t[1]=n.nodes[0]}}return i}function OC(i,e){if(i.length===0)return i;let t=[];for(let[r,n]of i){let a=z.root({nodes:[n.clone()]});a.walkRules(s=>{let o=(0,vn.default)().astSync(s.selector);o.each(u=>ro(u,e)),Wu(o,u=>u===e?`!${u}`:u),s.selector=o.toString(),s.walkDecls(u=>u.important=!0)}),t.push([{...r,important:!0},a.nodes[0]])}return t}function TC(i,e,t){if(e.length===0)return e;let r={modifier:null,value:Kr};{let[n,...a]=le(i,"/");if(a.length>1&&(n=n+"/"+a.slice(0,-1).join("/"),a=a.slice(-1)),a.length&&!t.variantMap.has(i)&&(i=n,r.modifier=a[0],!J(t.tailwindConfig,"generalizedModifiers")))return[]}if(i.endsWith("]")&&!i.startsWith("[")){let n=/(.)(-?)\[(.*)\]/g.exec(i);if(n){let[,a,s,o]=n;if(a==="@"&&s==="-")return[];if(a!=="@"&&s==="")return[];i=i.replace(`${s}[${o}]`,""),r.value=o}}if(lo(i)&&!t.variantMap.has(i)){let n=t.offsets.recordVariant(i),a=U(i.slice(1,-1)),s=le(a,",");if(s.length>1)return[];if(!s.every(An))return[];let o=s.map((u,c)=>[t.offsets.applyParallelOffset(n,c),Zr(u.trim())]);t.variantMap.set(i,o)}if(t.variantMap.has(i)){let n=lo(i),a=t.variantOptions.get(i)?.[Jr]??{},s=t.variantMap.get(i).slice(),o=[],u=(()=>!(n||a.respectPrefix===!1))();for(let[c,f]of e){if(c.layer==="user")continue;let p=z.root({nodes:[f.clone()]});for(let[d,h,y]of s){let b=function(){x.raws.neededBackup||(x.raws.neededBackup=!0,x.walkRules(E=>E.raws.originalSelector=E.selector))},k=function(E){return b(),x.each(I=>{I.type==="rule"&&(I.selectors=I.selectors.map(B=>E({get className(){return ao(B)},selector:B})))}),x},x=(y??p).clone(),w=[],S=h({get container(){return b(),x},separator:t.tailwindConfig.separator,modifySelectors:k,wrap(E){let I=x.nodes;x.removeAll(),E.append(I),x.append(E)},format(E){w.push({format:E,respectPrefix:u})},args:r});if(Array.isArray(S)){for(let[E,I]of S.entries())s.push([t.offsets.applyParallelOffset(d,E),I,x.clone()]);continue}if(typeof S=="string"&&w.push({format:S,respectPrefix:u}),S===null)continue;x.raws.neededBackup&&(delete x.raws.neededBackup,x.walkRules(E=>{let I=E.raws.originalSelector;if(!I||(delete E.raws.originalSelector,I===E.selector))return;let B=E.selector,q=(0,vn.default)(X=>{X.walkClasses(ae=>{ae.value=`${i}${t.tailwindConfig.separator}${ae.value}`})}).processSync(I);w.push({format:B.replace(q,"&"),respectPrefix:u}),E.selector=I})),x.nodes[0].raws.tailwind={...x.nodes[0].raws.tailwind,parentLayer:c.layer};let _=[{...c,sort:t.offsets.applyVariantOffset(c.sort,d,Object.assign(r,t.variantOptions.get(i))),collectedFormats:(c.collectedFormats??[]).concat(w)},x.nodes[0]];o.push(_)}}return o}return[]}function oo(i,e,t={}){return!ie(i)&&!Array.isArray(i)?[[i],t]:Array.isArray(i)?oo(i[0],e,i[1]):(e.has(i)||e.set(i,qt(i)),[e.get(i),t])}function DC(i){return PC.test(i)}function IC(i){if(!i.includes("://"))return!1;try{let e=new URL(i);return e.scheme!==""&&e.host!==""}catch(e){return!1}}function _d(i){let e=!0;return i.walkDecls(t=>{if(!Ed(t.prop,t.value))return e=!1,!1}),e}function Ed(i,e){if(IC(`${i}:${e}`))return!1;try{return z.parse(`a{${i}:${e}}`).toResult(),!0}catch(t){return!1}}function qC(i,e){let[,t,r]=i.match(/^\[([a-zA-Z0-9-_]+):(\S+)\]$/)??[];if(r===void 0||!DC(t)||!Bt(r))return null;let n=U(r);return Ed(t,n)?[[{sort:e.offsets.arbitraryProperty(),layer:"utilities"},()=>({[Wa(i)]:{[t]:n}})]]:null}function*RC(i,e){e.candidateRuleMap.has(i)&&(yield[e.candidateRuleMap.get(i),"DEFAULT"]),yield*function*(o){o!==null&&(yield[o,"DEFAULT"])}(qC(i,e));let t=i,r=!1,n=e.tailwindConfig.prefix,a=n.length,s=t.startsWith(n)||t.startsWith(`-${n}`);t[a]==="-"&&s&&(r=!0,t=n+t.slice(a+1)),r&&e.candidateRuleMap.has(t)&&(yield[e.candidateRuleMap.get(t),"-DEFAULT"]);for(let[o,u]of _C(t))e.candidateRuleMap.has(o)&&(yield[e.candidateRuleMap.get(o),r?`-${u}`:u])}function MC(i,e){return i===He?[He]:le(i,e)}function*BC(i,e){for(let t of i)t[1].raws.tailwind={...t[1].raws.tailwind,classCandidate:e,preserveSource:t[0].options?.preserveSource??!1},yield t}function*xn(i,e,t=i){let r=e.tailwindConfig.separator,[n,...a]=MC(i,r).reverse(),s=!1;if(n.startsWith("!")&&(s=!0,n=n.slice(1)),J(e.tailwindConfig,"variantGrouping")&&n.startsWith("(")&&n.endsWith(")")){let o=a.slice().reverse().join(r);for(let u of le(n.slice(1,-1),","))yield*xn(o+r+u,e,t)}for(let o of RC(n,e)){let u=[],c=new Map,[f,p]=o,d=f.length===1;for(let[h,y]of f){let x=[];if(typeof y=="function")for(let w of[].concat(y(p,{isOnlyPlugin:d}))){let[b,k]=oo(w,e.postCssNodeCache);for(let S of b)x.push([{...h,options:{...h.options,...k}},S])}else if(p==="DEFAULT"||p==="-DEFAULT"){let w=y,[b,k]=oo(w,e.postCssNodeCache);for(let S of b)x.push([{...h,options:{...h.options,...k}},S])}if(x.length>0){let w=Array.from(ps(h.options?.types??[],p,h.options??{},e.tailwindConfig)).map(([b,k])=>k);w.length>0&&c.set(x,w),u.push(x)}}if(lo(p)){if(u.length>1){let x=function(b){return b.length===1?b[0]:b.find(k=>{let S=c.get(k);return k.some(([{options:_},E])=>_d(E)?_.types.some(({type:I,preferOnConflict:B})=>S.includes(I)&&B):!1)})},[h,y]=u.reduce((b,k)=>(k.some(([{options:_}])=>_.types.some(({type:E})=>E==="any"))?b[0].push(k):b[1].push(k),b),[[],[]]),w=x(y)??x(h);if(w)u=[w];else{let b=u.map(S=>new Set([...c.get(S)??[]]));for(let S of b)for(let _ of S){let E=!1;for(let I of b)S!==I&&I.has(_)&&(I.delete(_),E=!0);E&&S.delete(_)}let k=[];for(let[S,_]of b.entries())for(let E of _){let I=u[S].map(([,B])=>B).flat().map(B=>B.toString().split(` +`).slice(1,-1).map(q=>q.trim()).map(q=>` ${q}`).join(` +`)).join(` + +`);k.push(` Use \`${i.replace("[",`[${E}:`)}\` for \`${I.trim()}\``);break}F.warn([`The class \`${i}\` is ambiguous and matches multiple utilities.`,...k,`If this is content and not a class, replace it with \`${i.replace("[","[").replace("]","]")}\` to silence this warning.`]);continue}}u=u.map(h=>h.filter(y=>_d(y[1])))}u=u.flat(),u=Array.from(BC(u,n)),u=EC(u,e),s&&(u=OC(u,n));for(let h of a)u=TC(h,u,e);for(let h of u)h[1].raws.tailwind={...h[1].raws.tailwind,candidate:i},h=FC(h,{context:e,candidate:i,original:t}),h!==null&&(yield h)}}function FC(i,{context:e,candidate:t,original:r}){if(!i[0].collectedFormats)return i;let n=!0,a;try{a=Nt(i[0].collectedFormats,{context:e,candidate:t})}catch{return null}let s=z.root({nodes:[i[1].clone()]});return s.walkRules(o=>{if(!kn(o))try{o.selector=wn(o.selector,a,{candidate:r,context:e})}catch{return n=!1,!1}}),n?(i[1]=s.nodes[0],i):null}function kn(i){return i.parent&&i.parent.type==="atrule"&&i.parent.name==="keyframes"}function NC(i){if(i===!0)return e=>{kn(e)||e.walkDecls(t=>{t.parent.type==="rule"&&!kn(t.parent)&&(t.important=!0)})};if(typeof i=="string")return e=>{kn(e)||(e.selectors=e.selectors.map(t=>bn(t,i)))}}function Sn(i,e){let t=[],r=NC(e.tailwindConfig.important);for(let n of i){if(e.notClassCache.has(n))continue;if(e.candidateRuleCache.has(n)){t=t.concat(Array.from(e.candidateRuleCache.get(n)));continue}let a=Array.from(xn(n,e));if(a.length===0){e.notClassCache.add(n);continue}e.classCache.set(n,a);let s=e.candidateRuleCache.get(n)??new Set;e.candidateRuleCache.set(n,s);for(let o of a){let[{sort:u,options:c},f]=o;if(c.respectImportant&&r){let d=z.root({nodes:[f.clone()]});d.walkRules(r),f=d.nodes[0]}let p=[u,f];s.add(p),e.ruleCache.add(p),t.push(p)}}return t}function lo(i){return i.startsWith("[")&&i.endsWith("]")}var vn,AC,PC,Cn=C(()=>{l();nt();vn=K(Me());Ua();xt();un();cr();Ee();ot();io();Ga();fr();Xr();Ka();or();De();so();AC=(0,vn.default)(i=>i.first.filter(({type:e})=>e==="class").pop().value);PC=/^[a-z_-]/});var Od,Td=C(()=>{l();Od={}});function LC(i){try{return Od.createHash("md5").update(i,"utf-8").digest("binary")}catch(e){return""}}function Pd(i,e){let t=e.toString();if(!t.includes("@tailwind"))return!1;let r=Xa.get(i),n=LC(t),a=r!==n;return Xa.set(i,n),a}var Dd=C(()=>{l();Td();ot()});function _n(i){return(i>0n)-(i<0n)}var Id=C(()=>{l()});function qd(i,e){let t=0n,r=0n;for(let[n,a]of e)i&n&&(t=t|n,r=r|a);return i&~t|r}var Rd=C(()=>{l()});function Md(i){let e=null;for(let t of i)e=e??t,e=e>t?e:t;return e}function $C(i,e){let t=i.length,r=e.length,n=t{l();Id();Rd();uo=class{constructor(){this.offsets={defaults:0n,base:0n,components:0n,utilities:0n,variants:0n,user:0n},this.layerPositions={defaults:0n,base:1n,components:2n,utilities:3n,user:4n,variants:5n},this.reservedVariantBits=0n,this.variantOffsets=new Map}create(e){return{layer:e,parentLayer:e,arbitrary:0n,variants:0n,parallelIndex:0n,index:this.offsets[e]++,options:[]}}arbitraryProperty(){return{...this.create("utilities"),arbitrary:1n}}forVariant(e,t=0){let r=this.variantOffsets.get(e);if(r===void 0)throw new Error(`Cannot find offset for unknown variant ${e}`);return{...this.create("variants"),variants:r<n.startsWith("[")).sort(([n],[a])=>$C(n,a)),t=e.map(([,n])=>n).sort((n,a)=>_n(n-a));return e.map(([,n],a)=>[n,t[a]]).filter(([n,a])=>n!==a)}remapArbitraryVariantOffsets(e){let t=this.recalculateVariantOffsets();return t.length===0?e:e.map(r=>{let[n,a]=r;return n={...n,variants:qd(n.variants,t)},[n,a]})}sort(e){return e=this.remapArbitraryVariantOffsets(e),e.sort(([t],[r])=>_n(this.compare(t,r)))}}});function ho(i,e){let t=i.tailwindConfig.prefix;return typeof t=="function"?t(e):t+e}function Nd({type:i="any",...e}){let t=[].concat(i);return{...e,types:t.map(r=>Array.isArray(r)?{type:r[0],...r[1]}:{type:r,preferOnConflict:!1})}}function jC(i){let e=[],t="",r=0;for(let n=0;n0&&e.push(t.trim()),e=e.filter(n=>n!==""),e}function zC(i,e,{before:t=[]}={}){if(t=[].concat(t),t.length<=0){i.push(e);return}let r=i.length-1;for(let n of t){let a=i.indexOf(n);a!==-1&&(r=Math.min(r,a))}i.splice(r,0,e)}function Ld(i){return Array.isArray(i)?i.flatMap(e=>!Array.isArray(e)&&!ie(e)?e:qt(e)):Ld([i])}function $d(i,e){return(0,fo.default)(r=>{let n=[];return e&&e(r),r.walkClasses(a=>{n.push(a.value)}),n}).transformSync(i)}function VC(i,e={containsNonOnDemandable:!1},t=0){let r=[];if(i.type==="rule"){let n=function(a){a.walkPseudos(s=>{s.value===":not"&&s.remove()})};for(let a of i.selectors){let s=$d(a,n);s.length===0&&(e.containsNonOnDemandable=!0);for(let o of s)r.push(o)}}else i.type==="atrule"&&i.walkRules(n=>{for(let a of n.selectors.flatMap(s=>$d(s)))r.push(a)});return t===0?[e.containsNonOnDemandable||r.length===0,r]:r}function En(i){return Ld(i).flatMap(e=>{let t=new Map,[r,n]=VC(e);return r&&n.unshift(He),n.map(a=>(t.has(e)||t.set(e,e),[a,t.get(e)]))})}function An(i){return i.startsWith("@")||i.includes("&")}function Zr(i){i=i.replace(/\n+/g,"").replace(/\s{1,}/g," ").trim();let e=jC(i).map(t=>{if(!t.startsWith("@"))return({format:a})=>a(t);let[,r,n]=/@(\S*)( .+|[({].*)?/g.exec(t);return({wrap:a})=>a(z.atRule({name:r,params:n?.trim()??""}))}).reverse();return t=>{for(let r of e)r(t)}}function UC(i,e,{variantList:t,variantMap:r,offsets:n,classList:a}){function s(d,h){return d?(0,Fd.default)(i,d,h):i}function o(d){return Rt(i.prefix,d)}function u(d,h){return d===He?He:h.respectPrefix?e.tailwindConfig.prefix+d:d}function c(d,h,y={}){let x=Ke(d),w=s(["theme",...x],h);return Ge(x[0])(w,y)}let f=0,p={postcss:z,prefix:o,e:ce,config:s,theme:c,corePlugins:d=>Array.isArray(i.corePlugins)?i.corePlugins.includes(d):s(["corePlugins",d],!0),variants:()=>[],addBase(d){for(let[h,y]of En(d)){let x=u(h,{}),w=n.create("base");e.candidateRuleMap.has(x)||e.candidateRuleMap.set(x,[]),e.candidateRuleMap.get(x).push([{sort:w,layer:"base"},y])}},addDefaults(d,h){let y={[`@defaults ${d}`]:h};for(let[x,w]of En(y)){let b=u(x,{});e.candidateRuleMap.has(b)||e.candidateRuleMap.set(b,[]),e.candidateRuleMap.get(b).push([{sort:n.create("defaults"),layer:"defaults"},w])}},addComponents(d,h){h=Object.assign({},{preserveSource:!1,respectPrefix:!0,respectImportant:!1},Array.isArray(h)?{}:h);for(let[x,w]of En(d)){let b=u(x,h);a.add(b),e.candidateRuleMap.has(b)||e.candidateRuleMap.set(b,[]),e.candidateRuleMap.get(b).push([{sort:n.create("components"),layer:"components",options:h},w])}},addUtilities(d,h){h=Object.assign({},{preserveSource:!1,respectPrefix:!0,respectImportant:!0},Array.isArray(h)?{}:h);for(let[x,w]of En(d)){let b=u(x,h);a.add(b),e.candidateRuleMap.has(b)||e.candidateRuleMap.set(b,[]),e.candidateRuleMap.get(b).push([{sort:n.create("utilities"),layer:"utilities",options:h},w])}},matchUtilities:function(d,h){h=Nd({...{respectPrefix:!0,respectImportant:!0,modifiers:!1},...h});let x=n.create("utilities");for(let w in d){let S=function(E,{isOnlyPlugin:I}){let[B,q,X]=cs(h.types,E,h,i);if(B===void 0)return[];if(!h.types.some(({type:$})=>$===q))if(I)F.warn([`Unnecessary typehint \`${q}\` in \`${w}-${E}\`.`,`You can safely update it to \`${w}-${E.replace(q+":","")}\`.`]);else return[];if(!Bt(B))return[];let ae={get modifier(){return h.modifiers||F.warn(`modifier-used-without-options-for-${w}`,["Your plugin must set `modifiers: true` in its options to support modifiers."]),X}},ge=J(i,"generalizedModifiers");return[].concat(ge?k(B,ae):k(B)).filter(Boolean).map($=>({[fn(w,E)]:$}))},b=u(w,h),k=d[w];a.add([b,h]);let _=[{sort:x,layer:"utilities",options:h},S];e.candidateRuleMap.has(b)||e.candidateRuleMap.set(b,[]),e.candidateRuleMap.get(b).push(_)}},matchComponents:function(d,h){h=Nd({...{respectPrefix:!0,respectImportant:!1,modifiers:!1},...h});let x=n.create("components");for(let w in d){let S=function(E,{isOnlyPlugin:I}){let[B,q,X]=cs(h.types,E,h,i);if(B===void 0)return[];if(!h.types.some(({type:$})=>$===q))if(I)F.warn([`Unnecessary typehint \`${q}\` in \`${w}-${E}\`.`,`You can safely update it to \`${w}-${E.replace(q+":","")}\`.`]);else return[];if(!Bt(B))return[];let ae={get modifier(){return h.modifiers||F.warn(`modifier-used-without-options-for-${w}`,["Your plugin must set `modifiers: true` in its options to support modifiers."]),X}},ge=J(i,"generalizedModifiers");return[].concat(ge?k(B,ae):k(B)).filter(Boolean).map($=>({[fn(w,E)]:$}))},b=u(w,h),k=d[w];a.add([b,h]);let _=[{sort:x,layer:"components",options:h},S];e.candidateRuleMap.has(b)||e.candidateRuleMap.set(b,[]),e.candidateRuleMap.get(b).push(_)}},addVariant(d,h,y={}){h=[].concat(h).map(x=>{if(typeof x!="string")return(w={})=>{let{args:b,modifySelectors:k,container:S,separator:_,wrap:E,format:I}=w,B=x(Object.assign({modifySelectors:k,container:S,separator:_},y.type===co.MatchVariant&&{args:b,wrap:E,format:I}));if(typeof B=="string"&&!An(B))throw new Error(`Your custom variant \`${d}\` has an invalid format string. Make sure it's an at-rule or contains a \`&\` placeholder.`);return Array.isArray(B)?B.filter(q=>typeof q=="string").map(q=>Zr(q)):B&&typeof B=="string"&&Zr(B)(w)};if(!An(x))throw new Error(`Your custom variant \`${d}\` has an invalid format string. Make sure it's an at-rule or contains a \`&\` placeholder.`);return Zr(x)}),zC(t,d,y),r.set(d,h),e.variantOptions.set(d,y)},matchVariant(d,h,y){let x=y?.id??++f,w=d==="@",b=J(i,"generalizedModifiers");for(let[S,_]of Object.entries(y?.values??{}))S!=="DEFAULT"&&p.addVariant(w?`${d}${S}`:`${d}-${S}`,({args:E,container:I})=>h(_,b?{modifier:E?.modifier,container:I}:{container:I}),{...y,value:_,id:x,type:co.MatchVariant,variantInfo:po.Base});let k="DEFAULT"in(y?.values??{});p.addVariant(d,({args:S,container:_})=>S?.value===Kr&&!k?null:h(S?.value===Kr?y.values.DEFAULT:S?.value??(typeof S=="string"?S:""),b?{modifier:S?.modifier,container:_}:{container:_}),{...y,id:x,type:co.MatchVariant,variantInfo:po.Dynamic})}};return p}function On(i){return mo.has(i)||mo.set(i,new Map),mo.get(i)}function jd(i,e){let t=!1,r=new Map;for(let n of i){if(!n)continue;let a=ws.parse(n),s=a.hash?a.href.replace(a.hash,""):a.href;s=a.search?s.replace(a.search,""):s;let o=te.statSync(decodeURIComponent(s),{throwIfNoEntry:!1})?.mtimeMs;!o||((!e.has(n)||o>e.get(n))&&(t=!0),r.set(n,o))}return[t,r]}function zd(i){i.walkAtRules(e=>{["responsive","variants"].includes(e.name)&&(zd(e),e.before(e.nodes),e.remove())})}function WC(i){let e=[];return i.each(t=>{t.type==="atrule"&&["responsive","variants"].includes(t.name)&&(t.name="layer",t.params="utilities")}),i.walkAtRules("layer",t=>{if(zd(t),t.params==="base"){for(let r of t.nodes)e.push(function({addBase:n}){n(r,{respectPrefix:!1})});t.remove()}else if(t.params==="components"){for(let r of t.nodes)e.push(function({addComponents:n}){n(r,{respectPrefix:!1,preserveSource:!0})});t.remove()}else if(t.params==="utilities"){for(let r of t.nodes)e.push(function({addUtilities:n}){n(r,{respectPrefix:!1,preserveSource:!0})});t.remove()}}),e}function GC(i,e){let t=Object.entries({...pe,...gd}).map(([o,u])=>i.tailwindConfig.corePlugins.includes(o)?u:null).filter(Boolean),r=i.tailwindConfig.plugins.map(o=>(o.__isOptionsFunction&&(o=o()),typeof o=="function"?o:o.handler)),n=WC(e),a=[pe.pseudoElementVariants,pe.pseudoClassVariants,pe.ariaVariants,pe.dataVariants],s=[pe.supportsVariants,pe.directionVariants,pe.reducedMotionVariants,pe.prefersContrastVariants,pe.darkVariants,pe.printVariant,pe.screenVariants,pe.orientationVariants];return[...t,...a,...r,...s,...n]}function HC(i,e){let t=[],r=new Map;e.variantMap=r;let n=new uo;e.offsets=n;let a=new Set,s=UC(e.tailwindConfig,e,{variantList:t,variantMap:r,offsets:n,classList:a});for(let f of i)if(Array.isArray(f))for(let p of f)p(s);else f?.(s);n.recordVariants(t,f=>r.get(f).length);for(let[f,p]of r.entries())e.variantMap.set(f,p.map((d,h)=>[n.forVariant(f,h),d]));let o=(e.tailwindConfig.safelist??[]).filter(Boolean);if(o.length>0){let f=[];for(let p of o){if(typeof p=="string"){e.changedContent.push({content:p,extension:"html"});continue}if(p instanceof RegExp){F.warn("root-regex",["Regular expressions in `safelist` work differently in Tailwind CSS v3.0.","Update your `safelist` configuration to eliminate this warning.","https://tailwindcss.com/docs/content-configuration#safelisting-classes"]);continue}f.push(p)}if(f.length>0){let p=new Map,d=e.tailwindConfig.prefix.length,h=f.some(y=>y.pattern.source.includes("!"));for(let y of a){let x=Array.isArray(y)?(()=>{let[w,b]=y,S=Object.keys(b?.values??{}).map(_=>Qr(w,_));return b?.supportsNegativeValues&&(S=[...S,...S.map(_=>"-"+_)],S=[...S,...S.map(_=>_.slice(0,d)+"-"+_.slice(d))]),b.types.some(({type:_})=>_==="color")&&(S=[...S,...S.flatMap(_=>Object.keys(e.tailwindConfig.theme.opacity).map(E=>`${_}/${E}`))]),h&&b?.respectImportant&&(S=[...S,...S.map(_=>"!"+_)]),S})():[y];for(let w of x)for(let{pattern:b,variants:k=[]}of f)if(b.lastIndex=0,p.has(b)||p.set(b,0),!!b.test(w)){p.set(b,p.get(b)+1),e.changedContent.push({content:w,extension:"html"});for(let S of k)e.changedContent.push({content:S+e.tailwindConfig.separator+w,extension:"html"})}}for(let[y,x]of p.entries())x===0&&F.warn([`The safelist pattern \`${y}\` doesn't match any Tailwind CSS classes.`,"Fix this pattern or remove it from your `safelist` configuration.","https://tailwindcss.com/docs/content-configuration#safelisting-classes"])}}let u=[].concat(e.tailwindConfig.darkMode??"media")[1]??"dark",c=[ho(e,u),ho(e,"group"),ho(e,"peer")];e.getClassOrder=function(p){let d=[...p].sort((w,b)=>w===b?0:w[w,null])),y=Sn(new Set(d),e);y=e.offsets.sort(y);let x=BigInt(c.length);for(let[,w]of y){let b=w.raws.tailwind.candidate;h.set(b,h.get(b)??x++)}return p.map(w=>{let b=h.get(w)??null,k=c.indexOf(w);return b===null&&k!==-1&&(b=BigInt(k)),[w,b]})},e.getClassList=function(p={}){let d=[];for(let h of a)if(Array.isArray(h)){let[y,x]=h,w=[],b=Object.keys(x?.modifiers??{});x?.types?.some(({type:_})=>_==="color")&&b.push(...Object.keys(e.tailwindConfig.theme.opacity??{}));let k={modifiers:b},S=p.includeMetadata&&b.length>0;for(let[_,E]of Object.entries(x?.values??{})){if(E==null)continue;let I=Qr(y,_);if(d.push(S?[I,k]:I),x?.supportsNegativeValues&&Xe(E)){let B=Qr(y,`-${_}`);w.push(S?[B,k]:B)}}d.push(...w)}else d.push(h);return d},e.getVariants=function(){let p=[];for(let[d,h]of e.variantOptions.entries())h.variantInfo!==po.Base&&p.push({name:d,isArbitrary:h.type===Symbol.for("MATCH_VARIANT"),values:Object.keys(h.values??{}),hasDash:d!=="@",selectors({modifier:y,value:x}={}){let w="__TAILWIND_PLACEHOLDER__",b=z.rule({selector:`.${w}`}),k=z.root({nodes:[b.clone()]}),S=k.toString(),_=(e.variantMap.get(d)??[]).flatMap(([$,oe])=>oe),E=[];for(let $ of _){let oe=[],ai={args:{modifier:y,value:h.values?.[x]??x},separator:e.tailwindConfig.separator,modifySelectors(Ce){return k.each(Jn=>{Jn.type==="rule"&&(Jn.selectors=Jn.selectors.map(lu=>Ce({get className(){return ao(lu)},selector:lu})))}),k},format(Ce){oe.push(Ce)},wrap(Ce){oe.push(`@${Ce.name} ${Ce.params} { & }`)},container:k},oi=$(ai);if(oe.length>0&&E.push(oe),Array.isArray(oi))for(let Ce of oi)oe=[],Ce(ai),E.push(oe)}let I=[],B=k.toString();S!==B&&(k.walkRules($=>{let oe=$.selector,ai=(0,fo.default)(oi=>{oi.walkClasses(Ce=>{Ce.value=`${d}${e.tailwindConfig.separator}${Ce.value}`})}).processSync(oe);I.push(oe.replace(ai,"&").replace(w,"&"))}),k.walkAtRules($=>{I.push(`@${$.name} (${$.params}) { & }`)}));let q=!(x in(h.values??{})),X=h[Jr]??{},ae=(()=>!(q||X.respectPrefix===!1))();E=E.map($=>$.map(oe=>({format:oe,respectPrefix:ae}))),I=I.map($=>({format:$,respectPrefix:ae}));let ge={candidate:w,context:e},je=E.map($=>wn(`.${w}`,Nt($,ge),ge).replace(`.${w}`,"&").replace("{ & }","").trim());return I.length>0&&je.push(Nt(I,ge).toString().replace(`.${w}`,"&")),je}});return p}}function Vd(i,e){!i.classCache.has(e)||(i.notClassCache.add(e),i.classCache.delete(e),i.applyClassCache.delete(e),i.candidateRuleMap.delete(e),i.candidateRuleCache.delete(e),i.stylesheetCache=null)}function YC(i,e){let t=e.raws.tailwind.candidate;if(!!t){for(let r of i.ruleCache)r[1].raws.tailwind.candidate===t&&i.ruleCache.delete(r);Vd(i,t)}}function go(i,e=[],t=z.root()){let r={disposables:[],ruleCache:new Set,candidateRuleCache:new Map,classCache:new Map,applyClassCache:new Map,notClassCache:new Set(i.blocklist??[]),postCssNodeCache:new Map,candidateRuleMap:new Map,tailwindConfig:i,changedContent:e,variantMap:new Map,stylesheetCache:null,variantOptions:new Map,markInvalidUtilityCandidate:a=>Vd(r,a),markInvalidUtilityNode:a=>YC(r,a)},n=GC(r,t);return HC(n,r),r}function Ud(i,e,t,r,n,a){let s=e.opts.from,o=r!==null;Pe.DEBUG&&console.log("Source path:",s);let u;if(o&&Lt.has(s))u=Lt.get(s);else if(ei.has(n)){let d=ei.get(n);lt.get(d).add(s),Lt.set(s,d),u=d}let c=Pd(s,i);if(u){let[d,h]=jd([...a],On(u));if(!d&&!c)return[u,!1,h]}if(Lt.has(s)){let d=Lt.get(s);if(lt.has(d)&&(lt.get(d).delete(s),lt.get(d).size===0)){lt.delete(d);for(let[h,y]of ei)y===d&&ei.delete(h);for(let h of d.disposables.splice(0))h(d)}}Pe.DEBUG&&console.log("Setting up new context...");let f=go(t,[],i);Object.assign(f,{userConfigPath:r});let[,p]=jd([...a],On(f));return ei.set(n,f),Lt.set(s,f),lt.has(f)||lt.set(f,new Set),lt.get(f).add(s),[f,!0,p]}var Fd,fo,Jr,co,po,mo,Lt,ei,lt,Xr=C(()=>{l();ze();bs();nt();Fd=K(js()),fo=K(Me());Hr();Ua();un();xt();Mt();Ga();cr();yd();ot();ot();pi();Ee();fi();Ka();Cn();Dd();Bd();De();io();Jr=Symbol(),co={AddVariant:Symbol.for("ADD_VARIANT"),MatchVariant:Symbol.for("MATCH_VARIANT")},po={Base:1<<0,Dynamic:1<<1};mo=new WeakMap;Lt=wd,ei=bd,lt=gn});function yo(i){return i.ignore?[]:i.glob?m.env.ROLLUP_WATCH==="true"?[{type:"dependency",file:i.base}]:[{type:"dir-dependency",dir:i.base,glob:i.glob}]:[{type:"dependency",file:i.base}]}var Wd=C(()=>{l()});function Gd(i,e){return{handler:i,config:e}}var Hd,Yd=C(()=>{l();Gd.withOptions=function(i,e=()=>({})){let t=function(r){return{__options:r,handler:i(r),config:e(r)}};return t.__isOptionsFunction=!0,t.__pluginFunction=i,t.__configFunction=e,t};Hd=Gd});var wo={};Ae(wo,{default:()=>QC});var QC,bo=C(()=>{l();Yd();QC=Hd});var Jd=v((ID,Qd)=>{l();var JC=(bo(),wo).default,XC={overflow:"hidden",display:"-webkit-box","-webkit-box-orient":"vertical"},KC=JC(function({matchUtilities:i,addUtilities:e,theme:t,variants:r}){let n=t("lineClamp");i({"line-clamp":a=>({...XC,"-webkit-line-clamp":`${a}`})},{values:n}),e([{".line-clamp-none":{"-webkit-line-clamp":"unset"}}],r("lineClamp"))},{theme:{lineClamp:{1:"1",2:"2",3:"3",4:"4",5:"5",6:"6"}},variants:{lineClamp:["responsive"]}});Qd.exports=KC});function vo(i){i.content.files.length===0&&F.warn("content-problems",["The `content` option in your Tailwind CSS configuration is missing or empty.","Configure your content sources or your generated CSS will be missing styles.","https://tailwindcss.com/docs/content-configuration"]);try{let e=Jd();i.plugins.includes(e)&&(F.warn("line-clamp-in-core",["As of Tailwind CSS v3.3, the `@tailwindcss/line-clamp` plugin is now included by default.","Remove it from the `plugins` array in your configuration to eliminate this warning."]),i.plugins=i.plugins.filter(t=>t!==e))}catch{}return i}var Xd=C(()=>{l();Ee()});var Kd,Zd=C(()=>{l();Kd=()=>!1});var Tn,eh=C(()=>{l();Tn={sync:i=>[].concat(i),generateTasks:i=>[{dynamic:!1,base:".",negative:[],positive:[].concat(i),patterns:[].concat(i)}],escapePath:i=>i}});var xo,th=C(()=>{l();xo=i=>i});var rh,ih=C(()=>{l();rh=()=>""});function nh(i){let e=i,t=rh(i);return t!=="."&&(e=i.substr(t.length),e.charAt(0)==="/"&&(e=e.substr(1))),e.substr(0,2)==="./"&&(e=e.substr(2)),e.charAt(0)==="/"&&(e=e.substr(1)),{base:t,glob:e}}var sh=C(()=>{l();ih()});function ah(i,e){let t=e.content.files;t=t.filter(o=>typeof o=="string"),t=t.map(xo);let r=Tn.generateTasks(t),n=[],a=[];for(let o of r)n.push(...o.positive.map(u=>oh(u,!1))),a.push(...o.negative.map(u=>oh(u,!0)));let s=[...n,...a];return s=e2(i,s),s=s.flatMap(t2),s=s.map(ZC),s}function oh(i,e){let t={original:i,base:i,ignore:e,pattern:i,glob:null};return Kd(i)&&Object.assign(t,nh(i)),t}function ZC(i){let e=xo(i.base);return e=Tn.escapePath(e),i.pattern=i.glob?`${e}/${i.glob}`:e,i.pattern=i.ignore?`!${i.pattern}`:i.pattern,i}function e2(i,e){let t=[];return i.userConfigPath&&i.tailwindConfig.content.relative&&(t=[Z.dirname(i.userConfigPath)]),e.map(r=>(r.base=Z.resolve(...t,r.base),r))}function t2(i){let e=[i];try{let t=te.realpathSync(i.base);t!==i.base&&e.push({...i,base:t})}catch{}return e}function lh(i,e,t){let r=i.tailwindConfig.content.files.filter(s=>typeof s.raw=="string").map(({raw:s,extension:o="html"})=>({content:s,extension:o})),[n,a]=r2(e,t);for(let s of n){let o=Z.extname(s).slice(1);r.push({file:s,extension:o})}return[r,a]}function r2(i,e){let t=i.map(s=>s.pattern),r=new Map,n=new Set;Pe.DEBUG&&console.time("Finding changed files");let a=Tn.sync(t,{absolute:!0});for(let s of a){let o=e.get(s)||-1/0,u=te.statSync(s).mtimeMs;u>o&&(n.add(s),r.set(s,u))}return Pe.DEBUG&&console.timeEnd("Finding changed files"),[n,r]}var uh=C(()=>{l();ze();mt();Zd();eh();th();sh();ot()});function fh(){}var ch=C(()=>{l()});function a2(i,e){for(let t of e){let r=`${i}${t}`;if(te.existsSync(r)&&te.statSync(r).isFile())return r}for(let t of e){let r=`${i}/index${t}`;if(te.existsSync(r))return r}return null}function*ph(i,e,t,r=Z.extname(i)){let n=a2(Z.resolve(e,i),i2.includes(r)?n2:s2);if(n===null||t.has(n))return;t.add(n),yield n,e=Z.dirname(n),r=Z.extname(n);let a=te.readFileSync(n,"utf-8");for(let s of[...a.matchAll(/import[\s\S]*?['"](.{3,}?)['"]/gi),...a.matchAll(/import[\s\S]*from[\s\S]*?['"](.{3,}?)['"]/gi),...a.matchAll(/require\(['"`](.+)['"`]\)/gi)])!s[1].startsWith(".")||(yield*ph(s[1],e,t,r))}function ko(i){return i===null?new Set:new Set(ph(i,Z.dirname(i),new Set))}var i2,n2,s2,dh=C(()=>{l();ze();mt();i2=[".js",".cjs",".mjs"],n2=["",".js",".cjs",".mjs",".ts",".cts",".mts",".jsx",".tsx"],s2=["",".ts",".cts",".mts",".tsx",".js",".cjs",".mjs",".jsx"]});function o2(i,e){if(So.has(i))return So.get(i);let t=ah(i,e);return So.set(i,t).get(i)}function l2(i){let e=ys(i);if(e!==null){let[r,n,a,s]=mh.get(e)||[],o=ko(e),u=!1,c=new Map;for(let d of o){let h=te.statSync(d).mtimeMs;c.set(d,h),(!s||!s.has(d)||h>s.get(d))&&(u=!0)}if(!u)return[r,e,n,a];for(let d of o)delete fu.cache[d];let f=vo(dr(fh(e))),p=ui(f);return mh.set(e,[f,p,o,c]),[f,e,p,o]}let t=dr(i?.config??i??{});return t=vo(t),[t,null,ui(t),[]]}function Co(i){return({tailwindDirectives:e,registerDependency:t})=>(r,n)=>{let[a,s,o,u]=l2(i),c=new Set(u);if(e.size>0){c.add(n.opts.from);for(let y of n.messages)y.type==="dependency"&&c.add(y.file)}let[f,,p]=Ud(r,n,a,s,o,c),d=On(f),h=o2(f,a);if(e.size>0){for(let w of h)for(let b of yo(w))t(b);let[y,x]=lh(f,h,d);for(let w of y)f.changedContent.push(w);for(let[w,b]of x.entries())p.set(w,b)}for(let y of u)t({type:"dependency",file:y});for(let[y,x]of p.entries())d.set(y,x);return f}}var hh,mh,So,gh=C(()=>{l();ze();hh=K(Xn());mu();gs();af();Xr();Wd();Xd();uh();ch();dh();mh=new hh.default({maxSize:100}),So=new WeakMap});function Ao(i){let e=new Set,t=new Set,r=new Set;if(i.walkAtRules(n=>{n.name==="apply"&&r.add(n),n.name==="import"&&(n.params==='"tailwindcss/base"'||n.params==="'tailwindcss/base'"?(n.name="tailwind",n.params="base"):n.params==='"tailwindcss/components"'||n.params==="'tailwindcss/components'"?(n.name="tailwind",n.params="components"):n.params==='"tailwindcss/utilities"'||n.params==="'tailwindcss/utilities'"?(n.name="tailwind",n.params="utilities"):(n.params==='"tailwindcss/screens"'||n.params==="'tailwindcss/screens'"||n.params==='"tailwindcss/variants"'||n.params==="'tailwindcss/variants'")&&(n.name="tailwind",n.params="variants")),n.name==="tailwind"&&(n.params==="screens"&&(n.params="variants"),e.add(n.params)),["layer","responsive","variants"].includes(n.name)&&(["responsive","variants"].includes(n.name)&&F.warn(`${n.name}-at-rule-deprecated`,[`The \`@${n.name}\` directive has been deprecated in Tailwind CSS v3.0.`,"Use `@layer utilities` or `@layer components` instead.","https://tailwindcss.com/docs/upgrade-guide#replace-variants-with-layer"]),t.add(n))}),!e.has("base")||!e.has("components")||!e.has("utilities")){for(let n of t)if(n.name==="layer"&&["base","components","utilities"].includes(n.params)){if(!e.has(n.params))throw n.error(`\`@layer ${n.params}\` is used but no matching \`@tailwind ${n.params}\` directive is present.`)}else if(n.name==="responsive"){if(!e.has("utilities"))throw n.error("`@responsive` is used but `@tailwind utilities` is missing.")}else if(n.name==="variants"&&!e.has("utilities"))throw n.error("`@variants` is used but `@tailwind utilities` is missing.")}return{tailwindDirectives:e,applyDirectives:r}}var yh=C(()=>{l();Ee()});function bt(i,e=void 0,t=void 0){return i.map(r=>{let n=r.clone(),a=r.raws.tailwind?.preserveSource!==!0||!n.source;return e!==void 0&&a&&(n.source=e,"walk"in n&&n.walk(s=>{s.source=e})),t!==void 0&&(n.raws.tailwind={...n.raws.tailwind,...t}),n})}var wh=C(()=>{l()});function Pn(i){return i=Array.isArray(i)?i:[i],i=i.map(e=>e instanceof RegExp?e.source:e),i.join("")}function xe(i){return new RegExp(Pn(i),"g")}function $t(i){return`(?:${i.map(Pn).join("|")})`}function _o(i){return`(?:${Pn(i)})?`}function vh(i){return`(?:${Pn(i)})*`}function xh(i){return i&&u2.test(i)?i.replace(bh,"\\$&"):i||""}var bh,u2,kh=C(()=>{l();bh=/[\\^$.*+?()[\]{}|]/g,u2=RegExp(bh.source)});function Sh(i){let e=Array.from(f2(i));return t=>{let r=[];for(let n of e)r=[...r,...t.match(n)??[]];return r.filter(n=>n!==void 0).map(d2)}}function*f2(i){let e=i.tailwindConfig.separator,t=J(i.tailwindConfig,"variantGrouping"),r=i.tailwindConfig.prefix!==""?_o(xe([/-?/,xh(i.tailwindConfig.prefix)])):"",n=$t([/\[[^\s:'"`]+:[^\s\[\]]+\]/,/\[[^\s:'"`]+:[^\s]+?\[[^\s]+\][^\s]+?\]/,xe([/-?(?:\w+)/,_o($t([xe([/-(?:\w+-)*\[[^\s:]+\]/,/(?![{([]])/,/(?:\/[^\s'"`\\><$]*)?/]),xe([/-(?:\w+-)*\[[^\s]+\]/,/(?![{([]])/,/(?:\/[^\s'"`\\$]*)?/]),/[-\/][^\s'"`\\$={><]*/]))])]),a=[$t([xe([/@\[[^\s"'`]+\](\/[^\s"'`]+)?/,e]),xe([/([^\s"'`\[\\]+-)?\[[^\s"'`]+\]/,e]),xe([/[^\s"'`\[\\]+/,e])]),$t([xe([/([^\s"'`\[\\]+-)?\[[^\s`]+\]/,e]),xe([/[^\s`\[\\]+/,e])])];for(let s of a)yield xe(["((?=((",s,")+))\\2)?",/!?/,r,t?$t([xe([/\(/,n,vh([/,/,n]),/\)/]),n]):n]);yield/[^<>"'`\s.(){}[\]#=%$]*[^<>"'`\s.(){}[\]#=%:$]/g}function d2(i){if(!i.includes("-["))return i;let e=0,t=[],r=i.matchAll(c2);r=Array.from(r).flatMap(n=>{let[,...a]=n;return a.map((s,o)=>Object.assign([],n,{index:n.index+o,0:s}))});for(let n of r){let a=n[0],s=t[t.length-1];if(a===s?t.pop():(a==="'"||a==='"'||a==="`")&&t.push(a),!s){if(a==="["){e++;continue}else if(a==="]"){e--;continue}if(e<0)return i.substring(0,n.index-1);if(e===0&&!p2.test(a))return i.substring(0,n.index)}}return i}var c2,p2,Ch=C(()=>{l();De();kh();c2=/([\[\]'"`])([^\[\]'"`])?/g,p2=/[^"'`\s<>\]]+/});function h2(i,e){let t=i.tailwindConfig.content.extract;return t[e]||t.DEFAULT||_h[e]||_h.DEFAULT(i)}function m2(i,e){let t=i.content.transform;return t[e]||t.DEFAULT||Eh[e]||Eh.DEFAULT}function g2(i,e,t,r){ti.has(e)||ti.set(e,new Ah.default({maxSize:25e3}));for(let n of i.split(` +`))if(n=n.trim(),!r.has(n))if(r.add(n),ti.get(e).has(n))for(let a of ti.get(e).get(n))t.add(a);else{let a=e(n).filter(o=>o!=="!*"),s=new Set(a);for(let o of s)t.add(o);ti.get(e).set(n,s)}}function y2(i,e){let t=e.offsets.sort(i),r={base:new Set,defaults:new Set,components:new Set,utilities:new Set,variants:new Set};for(let[n,a]of t)r[n.layer].add(a);return r}function Eo(i){return async e=>{let t={base:null,components:null,utilities:null,variants:null};if(e.walkAtRules(y=>{y.name==="tailwind"&&Object.keys(t).includes(y.params)&&(t[y.params]=y)}),Object.values(t).every(y=>y===null))return e;let r=new Set([...i.candidates??[],He]),n=new Set;Ye.DEBUG&&console.time("Reading changed files"),await Promise.all(i.changedContent.map(async({file:y,content:x,extension:w})=>{let b=m2(i.tailwindConfig,w),k=h2(i,w);x=y?await te.promises.readFile(y,"utf8"):x,g2(b(x),k,r,n)})),Ye.DEBUG&&console.timeEnd("Reading changed files");let a=i.classCache.size;Ye.DEBUG&&console.time("Generate rules"),Ye.DEBUG&&console.time("Sorting candidates");let s=new Set([...r].sort((y,x)=>y===x?0:y{let x=y.raws.tailwind?.parentLayer;return x==="components"?t.components!==null:x==="utilities"?t.utilities!==null:!0});t.variants?(t.variants.before(bt(d,t.variants.source,{layer:"variants"})),t.variants.remove()):d.length>0&&e.append(bt(d,e.source,{layer:"variants"}));let h=d.some(y=>y.raws.tailwind?.parentLayer==="utilities");t.utilities&&f.size===0&&!h&&F.warn("content-problems",["No utility classes were detected in your source files. If this is unexpected, double-check the `content` option in your Tailwind CSS configuration.","https://tailwindcss.com/docs/content-configuration"]),Ye.DEBUG&&(console.log("Potential classes: ",r.size),console.log("Active contexts: ",gn.size)),i.changedContent=[],e.walkAtRules("layer",y=>{Object.keys(t).includes(y.params)&&y.remove()})}}var Ah,Ye,_h,Eh,ti,Oh=C(()=>{l();ze();Ah=K(Xn());ot();Cn();Ee();wh();Ch();Ye=Pe,_h={DEFAULT:Sh},Eh={DEFAULT:i=>i,svelte:i=>i.replace(/(?:^|\s)class:/g," ")};ti=new WeakMap});function In(i){let e=new Map;z.root({nodes:[i.clone()]}).walkRules(a=>{(0,Dn.default)(s=>{s.walkClasses(o=>{let u=o.parent.toString(),c=e.get(u);c||e.set(u,c=new Set),c.add(o.value)})}).processSync(a.selector)});let r=Array.from(e.values(),a=>Array.from(a)),n=r.flat();return Object.assign(n,{groups:r})}function Oo(i){return w2.astSync(i)}function Th(i,e){let t=new Set;for(let r of i)t.add(r.split(e).pop());return Array.from(t)}function Ph(i,e){let t=i.tailwindConfig.prefix;return typeof t=="function"?t(e):t+e}function*Dh(i){for(yield i;i.parent;)yield i.parent,i=i.parent}function b2(i,e={}){let t=i.nodes;i.nodes=[];let r=i.clone(e);return i.nodes=t,r}function v2(i){for(let e of Dh(i))if(i!==e){if(e.type==="root")break;i=b2(e,{nodes:[i]})}return i}function x2(i,e){let t=new Map;return i.walkRules(r=>{for(let s of Dh(r))if(s.raws.tailwind?.layer!==void 0)return;let n=v2(r),a=e.offsets.create("user");for(let s of In(r)){let o=t.get(s)||[];t.set(s,o),o.push([{layer:"user",sort:a,important:!1},n])}}),t}function k2(i,e){for(let t of i){if(e.notClassCache.has(t)||e.applyClassCache.has(t))continue;if(e.classCache.has(t)){e.applyClassCache.set(t,e.classCache.get(t).map(([n,a])=>[n,a.clone()]));continue}let r=Array.from(xn(t,e));if(r.length===0){e.notClassCache.add(t);continue}e.applyClassCache.set(t,r)}return e.applyClassCache}function S2(i){let e=null;return{get:t=>(e=e||i(),e.get(t)),has:t=>(e=e||i(),e.has(t))}}function C2(i){return{get:e=>i.flatMap(t=>t.get(e)||[]),has:e=>i.some(t=>t.has(e))}}function Ih(i){let e=i.split(/[\s\t\n]+/g);return e[e.length-1]==="!important"?[e.slice(0,-1),!0]:[e,!1]}function qh(i,e,t){let r=new Set,n=[];if(i.walkAtRules("apply",u=>{let[c]=Ih(u.params);for(let f of c)r.add(f);n.push(u)}),n.length===0)return;let a=C2([t,k2(r,e)]);function s(u,c,f){let p=Oo(u),d=Oo(c),y=Oo(`.${ce(f)}`).nodes[0].nodes[0];return p.each(x=>{let w=new Set;d.each(b=>{let k=!1;b=b.clone(),b.walkClasses(S=>{S.value===y.value&&(k||(S.replaceWith(...x.nodes.map(_=>_.clone())),w.add(b),k=!0))})});for(let b of w){let k=[[]];for(let S of b.nodes)S.type==="combinator"?(k.push(S),k.push([])):k[k.length-1].push(S);b.nodes=[];for(let S of k)Array.isArray(S)&&S.sort((_,E)=>_.type==="tag"&&E.type==="class"?-1:_.type==="class"&&E.type==="tag"?1:_.type==="class"&&E.type==="pseudo"&&E.value.startsWith("::")?-1:_.type==="pseudo"&&_.value.startsWith("::")&&E.type==="class"?1:0),b.nodes=b.nodes.concat(S)}x.replaceWith(...w)}),p.toString()}let o=new Map;for(let u of n){let[c]=o.get(u.parent)||[[],u.source];o.set(u.parent,[c,u.source]);let[f,p]=Ih(u.params);if(u.parent.type==="atrule"){if(u.parent.name==="screen"){let d=u.parent.params;throw u.error(`@apply is not supported within nested at-rules like @screen. We suggest you write this as @apply ${f.map(h=>`${d}:${h}`).join(" ")} instead.`)}throw u.error(`@apply is not supported within nested at-rules like @${u.parent.name}. You can fix this by un-nesting @${u.parent.name}.`)}for(let d of f){if([Ph(e,"group"),Ph(e,"peer")].includes(d))throw u.error(`@apply should not be used with the '${d}' utility`);if(!a.has(d))throw u.error(`The \`${d}\` class does not exist. If \`${d}\` is a custom class, make sure it is defined within a \`@layer\` directive.`);let h=a.get(d);c.push([d,p,h])}}for(let[u,[c,f]]of o){let p=[];for(let[h,y,x]of c){let w=[h,...Th([h],e.tailwindConfig.separator)];for(let[b,k]of x){let S=In(u),_=In(k);if(_=_.groups.filter(q=>q.some(X=>w.includes(X))).flat(),_=_.concat(Th(_,e.tailwindConfig.separator)),S.some(q=>_.includes(q)))throw k.error(`You cannot \`@apply\` the \`${h}\` utility here because it creates a circular dependency.`);let I=z.root({nodes:[k.clone()]});I.walk(q=>{q.source=f}),(k.type!=="atrule"||k.type==="atrule"&&k.name!=="keyframes")&&I.walkRules(q=>{if(!In(q).some($=>$===h)){q.remove();return}let X=typeof e.tailwindConfig.important=="string"?e.tailwindConfig.important:null,ge=u.raws.tailwind!==void 0&&X&&u.selector.indexOf(X)===0?u.selector.slice(X.length):u.selector;q.selector=s(ge,q.selector,h),X&&ge!==u.selector&&(q.selector=bn(q.selector,X)),q.walkDecls($=>{$.important=b.important||y});let je=(0,Dn.default)().astSync(q.selector);je.each($=>Ft($)),q.selector=je.toString()}),!!I.nodes[0]&&p.push([b.sort,I.nodes[0]])}}let d=e.offsets.sort(p).map(h=>h[1]);u.after(d)}for(let u of n)u.parent.nodes.length>1?u.remove():u.parent.remove();qh(i,e,t)}function To(i){return e=>{let t=S2(()=>x2(e,i));qh(e,i,t)}}var Dn,w2,Rh=C(()=>{l();nt();Dn=K(Me());Cn();Mt();so();yn();w2=(0,Dn.default)()});var Mh=v((PI,qn)=>{l();(function(){"use strict";function i(r,n,a){if(!r)return null;i.caseSensitive||(r=r.toLowerCase());var s=i.threshold===null?null:i.threshold*r.length,o=i.thresholdAbsolute,u;s!==null&&o!==null?u=Math.min(s,o):s!==null?u=s:o!==null?u=o:u=null;var c,f,p,d,h,y=n.length;for(h=0;ha)return a+1;var u=[],c,f,p,d,h;for(c=0;c<=o;c++)u[c]=[c];for(f=0;f<=s;f++)u[0][f]=f;for(c=1;c<=o;c++){for(p=e,d=1,c>a&&(d=c-a),h=o+1,h>a+c&&(h=a+c),f=1;f<=s;f++)fh?u[c][f]=a+1:n.charAt(c-1)===r.charAt(f-1)?u[c][f]=u[c-1][f-1]:u[c][f]=Math.min(u[c-1][f-1]+1,Math.min(u[c][f-1]+1,u[c-1][f]+1)),u[c][f]a)return a+1}return u[o][s]}})()});var Fh=v((DI,Bh)=>{l();var Po="(".charCodeAt(0),Do=")".charCodeAt(0),Rn="'".charCodeAt(0),Io='"'.charCodeAt(0),qo="\\".charCodeAt(0),jt="/".charCodeAt(0),Ro=",".charCodeAt(0),Mo=":".charCodeAt(0),Mn="*".charCodeAt(0),A2="u".charCodeAt(0),_2="U".charCodeAt(0),E2="+".charCodeAt(0),O2=/^[a-f0-9?-]+$/i;Bh.exports=function(i){for(var e=[],t=i,r,n,a,s,o,u,c,f,p=0,d=t.charCodeAt(p),h=t.length,y=[{nodes:e}],x=0,w,b="",k="",S="";p{l();Nh.exports=function i(e,t,r){var n,a,s,o;for(n=0,a=e.length;n{l();function $h(i,e){var t=i.type,r=i.value,n,a;return e&&(a=e(i))!==void 0?a:t==="word"||t==="space"?r:t==="string"?(n=i.quote||"",n+r+(i.unclosed?"":n)):t==="comment"?"/*"+r+(i.unclosed?"":"*/"):t==="div"?(i.before||"")+r+(i.after||""):Array.isArray(i.nodes)?(n=jh(i.nodes,e),t!=="function"?n:r+"("+(i.before||"")+n+(i.after||"")+(i.unclosed?"":")")):r}function jh(i,e){var t,r;if(Array.isArray(i)){for(t="",r=i.length-1;~r;r-=1)t=$h(i[r],e)+t;return t}return $h(i,e)}zh.exports=jh});var Wh=v((RI,Uh)=>{l();var Bn="-".charCodeAt(0),Fn="+".charCodeAt(0),Bo=".".charCodeAt(0),T2="e".charCodeAt(0),P2="E".charCodeAt(0);function D2(i){var e=i.charCodeAt(0),t;if(e===Fn||e===Bn){if(t=i.charCodeAt(1),t>=48&&t<=57)return!0;var r=i.charCodeAt(2);return t===Bo&&r>=48&&r<=57}return e===Bo?(t=i.charCodeAt(1),t>=48&&t<=57):e>=48&&e<=57}Uh.exports=function(i){var e=0,t=i.length,r,n,a;if(t===0||!D2(i))return!1;for(r=i.charCodeAt(e),(r===Fn||r===Bn)&&e++;e57));)e+=1;if(r=i.charCodeAt(e),n=i.charCodeAt(e+1),r===Bo&&n>=48&&n<=57)for(e+=2;e57));)e+=1;if(r=i.charCodeAt(e),n=i.charCodeAt(e+1),a=i.charCodeAt(e+2),(r===T2||r===P2)&&(n>=48&&n<=57||(n===Fn||n===Bn)&&a>=48&&a<=57))for(e+=n===Fn||n===Bn?3:2;e57));)e+=1;return{number:i.slice(0,e),unit:i.slice(e)}}});var Qh=v((MI,Yh)=>{l();var I2=Fh(),Gh=Lh(),Hh=Vh();function ut(i){return this instanceof ut?(this.nodes=I2(i),this):new ut(i)}ut.prototype.toString=function(){return Array.isArray(this.nodes)?Hh(this.nodes):""};ut.prototype.walk=function(i,e){return Gh(this.nodes,i,e),this};ut.unit=Wh();ut.walk=Gh;ut.stringify=Hh;Yh.exports=ut});function No(i){return typeof i=="object"&&i!==null}function q2(i,e){let t=Ke(e);do if(t.pop(),(0,ri.default)(i,t)!==void 0)break;while(t.length);return t.length?t:void 0}function zt(i){return typeof i=="string"?i:i.reduce((e,t,r)=>t.includes(".")?`${e}[${t}]`:r===0?t:`${e}.${t}`,"")}function Xh(i){return i.map(e=>`'${e}'`).join(", ")}function Kh(i){return Xh(Object.keys(i))}function Lo(i,e,t,r={}){let n=Array.isArray(e)?zt(e):e.replace(/^['"]+|['"]+$/g,""),a=Array.isArray(e)?e:Ke(n),s=(0,ri.default)(i.theme,a,t);if(s===void 0){let u=`'${n}' does not exist in your theme config.`,c=a.slice(0,-1),f=(0,ri.default)(i.theme,c);if(No(f)){let p=Object.keys(f).filter(h=>Lo(i,[...c,h]).isValid),d=(0,Jh.default)(a[a.length-1],p);d?u+=` Did you mean '${zt([...c,d])}'?`:p.length>0&&(u+=` '${zt(c)}' has the following valid keys: ${Xh(p)}`)}else{let p=q2(i.theme,n);if(p){let d=(0,ri.default)(i.theme,p);No(d)?u+=` '${zt(p)}' has the following keys: ${Kh(d)}`:u+=` '${zt(p)}' is not an object.`}else u+=` Your theme has the following top-level keys: ${Kh(i.theme)}`}return{isValid:!1,error:u}}if(!(typeof s=="string"||typeof s=="number"||typeof s=="function"||s instanceof String||s instanceof Number||Array.isArray(s))){let u=`'${n}' was found but does not resolve to a string.`;if(No(s)){let c=Object.keys(s).filter(f=>Lo(i,[...a,f]).isValid);c.length&&(u+=` Did you mean something like '${zt([...a,c[0]])}'?`)}return{isValid:!1,error:u}}let[o]=a;return{isValid:!0,value:Ge(o)(s,r)}}function R2(i,e,t){e=e.map(n=>Zh(i,n,t));let r=[""];for(let n of e)n.type==="div"&&n.value===","?r.push(""):r[r.length-1]+=Fo.default.stringify(n);return r}function Zh(i,e,t){if(e.type==="function"&&t[e.value]!==void 0){let r=R2(i,e.nodes,t);e.type="word",e.value=t[e.value](i,...r)}return e}function M2(i,e,t){return Object.keys(t).some(n=>e.includes(`${n}(`))?(0,Fo.default)(e).walk(n=>{Zh(i,n,t)}).toString():e}function*F2(i){i=i.replace(/^['"]+|['"]+$/g,"");let e=i.match(/^([^\s]+)(?![^\[]*\])(?:\s*\/\s*([^\/\s]+))$/),t;yield[i,void 0],e&&(i=e[1],t=e[2],yield[i,t])}function N2(i,e,t){let r=Array.from(F2(e)).map(([n,a])=>Object.assign(Lo(i,n,t,{opacityValue:a}),{resolvedPath:n,alpha:a}));return r.find(n=>n.isValid)??r[0]}function em(i){let e=i.tailwindConfig,t={theme:(r,n,...a)=>{let{isValid:s,value:o,error:u,alpha:c}=N2(e,n,a.length?a:void 0);if(!s){let d=r.parent,h=d?.raws.tailwind?.candidate;if(d&&h!==void 0){i.markInvalidUtilityNode(d),d.remove(),F.warn("invalid-theme-key-in-class",[`The utility \`${h}\` contains an invalid theme value and was not generated.`]);return}throw r.error(u)}let f=kt(o),p=f!==void 0&&typeof f=="function";return(c!==void 0||p)&&(c===void 0&&(c=1),o=Ie(f,c,f)),o},screen:(r,n)=>{n=n.replace(/^['"]+/g,"").replace(/['"]+$/g,"");let s=at(e.theme.screens).find(({name:o})=>o===n);if(!s)throw r.error(`The '${n}' screen does not exist in your theme.`);return st(s)}};return r=>{r.walk(n=>{let a=B2[n.type];a!==void 0&&(n[a]=M2(n,n[a],t))})}}var ri,Jh,Fo,B2,tm=C(()=>{l();ri=K(js()),Jh=K(Mh());Hr();Fo=K(Qh());hn();cn();pi();ar();cr();Ee();B2={atrule:"params",decl:"value"}});function rm({tailwindConfig:{theme:i}}){return function(e){e.walkAtRules("screen",t=>{let r=t.params,a=at(i.screens).find(({name:s})=>s===r);if(!a)throw t.error(`No \`${r}\` screen found.`);t.name="media",t.params=st(a)})}}var im=C(()=>{l();hn();cn()});function L2(i){let e=i.filter(o=>o.type!=="pseudo"||o.nodes.length>0?!0:o.value.startsWith("::")||[":before",":after",":first-line",":first-letter"].includes(o.value)).reverse(),t=new Set(["tag","class","id","attribute"]),r=e.findIndex(o=>t.has(o.type));if(r===-1)return e.reverse().join("").trim();let n=e[r],a=nm[n.type]?nm[n.type](n):n;e=e.slice(0,r);let s=e.findIndex(o=>o.type==="combinator"&&o.value===">");return s!==-1&&(e.splice(0,s),e.unshift(Nn.default.universal())),[a,...e.reverse()].join("").trim()}function j2(i){return $o.has(i)||$o.set(i,$2.transformSync(i)),$o.get(i)}function jo({tailwindConfig:i}){return e=>{let t=new Map,r=new Set;if(e.walkAtRules("defaults",n=>{if(n.nodes&&n.nodes.length>0){r.add(n);return}let a=n.params;t.has(a)||t.set(a,new Set),t.get(a).add(n.parent),n.remove()}),J(i,"optimizeUniversalDefaults"))for(let n of r){let a=new Map,s=t.get(n.params)??[];for(let o of s)for(let u of j2(o.selector)){let c=u.includes(":-")||u.includes("::-")?u:"__DEFAULT__",f=a.get(c)??new Set;a.set(c,f),f.add(u)}if(J(i,"optimizeUniversalDefaults")){if(a.size===0){n.remove();continue}for(let[,o]of a){let u=z.rule({source:n.source});u.selectors=[...o],u.append(n.nodes.map(c=>c.clone())),n.before(u)}}n.remove()}else if(r.size){let n=z.rule({selectors:["*","::before","::after"]});for(let s of r)n.append(s.nodes),n.parent||s.before(n),n.source||(n.source=s.source),s.remove();let a=n.clone({selectors:["::backdrop"]});n.after(a)}}}var Nn,nm,$2,$o,sm=C(()=>{l();nt();Nn=K(Me());De();nm={id(i){return Nn.default.attribute({attribute:"id",operator:"=",value:i.value,quoteMark:'"'})}};$2=(0,Nn.default)(i=>i.map(e=>{let t=e.split(r=>r.type==="combinator"&&r.value===" ").pop();return L2(t)})),$o=new Map});function zo(){function i(e){let t=null;e.each(r=>{if(!z2.has(r.type)){t=null;return}if(t===null){t=r;return}let n=am[r.type];r.type==="atrule"&&r.name==="font-face"?t=r:n.every(a=>(r[a]??"").replace(/\s+/g," ")===(t[a]??"").replace(/\s+/g," "))?(r.nodes&&t.append(r.nodes),r.remove()):t=r}),e.each(r=>{r.type==="atrule"&&i(r)})}return e=>{i(e)}}var am,z2,om=C(()=>{l();am={atrule:["name","params"],rule:["selector"]},z2=new Set(Object.keys(am))});function Vo(){return i=>{i.walkRules(e=>{let t=new Map,r=new Set([]),n=new Map;e.walkDecls(a=>{if(a.parent===e){if(t.has(a.prop)){if(t.get(a.prop).value===a.value){r.add(t.get(a.prop)),t.set(a.prop,a);return}n.has(a.prop)||n.set(a.prop,new Set),n.get(a.prop).add(t.get(a.prop)),n.get(a.prop).add(a)}t.set(a.prop,a)}});for(let a of r)a.remove();for(let a of n.values()){let s=new Map;for(let o of a){let u=U2(o.value);u!==null&&(s.has(u)||s.set(u,new Set),s.get(u).add(o))}for(let o of s.values()){let u=Array.from(o).slice(0,-1);for(let c of u)c.remove()}}})}}function U2(i){let e=/^-?\d*.?\d+([\w%]+)?$/g.exec(i);return e?e[1]??V2:null}var V2,lm=C(()=>{l();V2=Symbol("unitless-number")});function W2(i){if(!i.walkAtRules)return;let e=new Set;if(i.walkAtRules("apply",t=>{e.add(t.parent)}),e.size!==0)for(let t of e){let r=[],n=[];for(let a of t.nodes)a.type==="atrule"&&a.name==="apply"?(n.length>0&&(r.push(n),n=[]),r.push([a])):n.push(a);if(n.length>0&&r.push(n),r.length!==1){for(let a of[...r].reverse()){let s=t.clone({nodes:[]});s.append(a),t.after(s)}t.remove()}}}function Ln(){return i=>{W2(i)}}var um=C(()=>{l()});function G2(i){return i.type==="root"}function H2(i){return i.type==="atrule"&&i.name==="layer"}function fm(i){return(e,t)=>{let r=!1;e.walkAtRules("tailwind",n=>{if(r)return!1;if(n.parent&&!(G2(n.parent)||H2(n.parent)))return r=!0,n.warn(t,["Nested @tailwind rules were detected, but are not supported.","Consider using a prefix to scope Tailwind's classes: https://tailwindcss.com/docs/configuration#prefix","Alternatively, use the important selector strategy: https://tailwindcss.com/docs/configuration#selector-strategy"].join(` +`)),!1}),e.walkRules(n=>{if(r)return!1;n.walkRules(a=>(r=!0,a.warn(t,["Nested CSS was detected, but CSS nesting has not been configured correctly.","Please enable a CSS nesting plugin *before* Tailwind in your configuration.","See how here: https://tailwindcss.com/docs/using-with-preprocessors#nesting"].join(` +`)),!1))})}}var cm=C(()=>{l()});function $n(i){return async function(e,t){let{tailwindDirectives:r,applyDirectives:n}=Ao(e);fm()(e,t),Ln()(e,t);let a=i({tailwindDirectives:r,applyDirectives:n,registerDependency(s){t.messages.push({plugin:"tailwindcss",parent:t.opts.from,...s})},createContext(s,o){return go(s,o,e)}})(e,t);if(a.tailwindConfig.separator==="-")throw new Error("The '-' character cannot be used as a custom separator in JIT mode due to parsing ambiguity. Please use another character like '_' instead.");_u(a.tailwindConfig),await Eo(a)(e,t),Ln()(e,t),To(a)(e,t),em(a)(e,t),rm(a)(e,t),jo(a)(e,t),zo(a)(e,t),Vo(a)(e,t)}}var pm=C(()=>{l();yh();Oh();Rh();tm();im();sm();om();lm();um();cm();Xr();De()});function dm(i,e){let t=null,r=null;return i.walkAtRules("config",n=>{if(r=n.source?.input.file??e.opts.from??null,r===null)throw n.error("The `@config` directive cannot be used without setting `from` in your PostCSS config.");if(t)throw n.error("Only one `@config` directive is allowed per file.");let a=n.params.match(/(['"])(.*?)\1/);if(!a)throw n.error("A path is required when using the `@config` directive.");let s=a[2];if(Z.isAbsolute(s))throw n.error("The `@config` directive cannot be used with an absolute path.");if(t=Z.resolve(Z.dirname(r),s),!te.existsSync(t))throw n.error(`The config file at "${s}" does not exist. Make sure the path is correct and the file exists.`);n.remove()}),t||null}var hm=C(()=>{l();ze();mt()});var mm=v((v4,Uo)=>{l();gh();pm();ot();hm();Uo.exports=function(e){return{postcssPlugin:"tailwindcss",plugins:[Pe.DEBUG&&function(t){return console.log(` +`),console.time("JIT TOTAL"),t},async function(t,r){e=dm(t,r)??e;let n=Co(e);if(t.type==="document"){let a=t.nodes.filter(s=>s.type==="root");for(let s of a)s.type==="root"&&await $n(n)(s,r);return}await $n(n)(t,r)},!1,Pe.DEBUG&&function(t){return console.timeEnd("JIT TOTAL"),console.log(` +`),t}].filter(Boolean)}};Uo.exports.postcss=!0});var ym=v((x4,gm)=>{l();gm.exports=mm()});var Wo=v((k4,wm)=>{l();wm.exports=()=>["and_chr 114","and_uc 15.5","chrome 114","chrome 113","chrome 109","edge 114","firefox 114","ios_saf 16.5","ios_saf 16.4","ios_saf 16.3","ios_saf 16.1","opera 99","safari 16.5","samsung 21"]});var jn={};Ae(jn,{agents:()=>Y2,feature:()=>Q2});function Q2(){return{status:"cr",title:"CSS Feature Queries",stats:{ie:{"6":"n","7":"n","8":"n","9":"n","10":"n","11":"n","5.5":"n"},edge:{"12":"y","13":"y","14":"y","15":"y","16":"y","17":"y","18":"y","79":"y","80":"y","81":"y","83":"y","84":"y","85":"y","86":"y","87":"y","88":"y","89":"y","90":"y","91":"y","92":"y","93":"y","94":"y","95":"y","96":"y","97":"y","98":"y","99":"y","100":"y","101":"y","102":"y","103":"y","104":"y","105":"y","106":"y","107":"y","108":"y","109":"y","110":"y","111":"y","112":"y","113":"y","114":"y"},firefox:{"2":"n","3":"n","4":"n","5":"n","6":"n","7":"n","8":"n","9":"n","10":"n","11":"n","12":"n","13":"n","14":"n","15":"n","16":"n","17":"n","18":"n","19":"n","20":"n","21":"n","22":"y","23":"y","24":"y","25":"y","26":"y","27":"y","28":"y","29":"y","30":"y","31":"y","32":"y","33":"y","34":"y","35":"y","36":"y","37":"y","38":"y","39":"y","40":"y","41":"y","42":"y","43":"y","44":"y","45":"y","46":"y","47":"y","48":"y","49":"y","50":"y","51":"y","52":"y","53":"y","54":"y","55":"y","56":"y","57":"y","58":"y","59":"y","60":"y","61":"y","62":"y","63":"y","64":"y","65":"y","66":"y","67":"y","68":"y","69":"y","70":"y","71":"y","72":"y","73":"y","74":"y","75":"y","76":"y","77":"y","78":"y","79":"y","80":"y","81":"y","82":"y","83":"y","84":"y","85":"y","86":"y","87":"y","88":"y","89":"y","90":"y","91":"y","92":"y","93":"y","94":"y","95":"y","96":"y","97":"y","98":"y","99":"y","100":"y","101":"y","102":"y","103":"y","104":"y","105":"y","106":"y","107":"y","108":"y","109":"y","110":"y","111":"y","112":"y","113":"y","114":"y","115":"y","116":"y","117":"y","3.5":"n","3.6":"n"},chrome:{"4":"n","5":"n","6":"n","7":"n","8":"n","9":"n","10":"n","11":"n","12":"n","13":"n","14":"n","15":"n","16":"n","17":"n","18":"n","19":"n","20":"n","21":"n","22":"n","23":"n","24":"n","25":"n","26":"n","27":"n","28":"y","29":"y","30":"y","31":"y","32":"y","33":"y","34":"y","35":"y","36":"y","37":"y","38":"y","39":"y","40":"y","41":"y","42":"y","43":"y","44":"y","45":"y","46":"y","47":"y","48":"y","49":"y","50":"y","51":"y","52":"y","53":"y","54":"y","55":"y","56":"y","57":"y","58":"y","59":"y","60":"y","61":"y","62":"y","63":"y","64":"y","65":"y","66":"y","67":"y","68":"y","69":"y","70":"y","71":"y","72":"y","73":"y","74":"y","75":"y","76":"y","77":"y","78":"y","79":"y","80":"y","81":"y","83":"y","84":"y","85":"y","86":"y","87":"y","88":"y","89":"y","90":"y","91":"y","92":"y","93":"y","94":"y","95":"y","96":"y","97":"y","98":"y","99":"y","100":"y","101":"y","102":"y","103":"y","104":"y","105":"y","106":"y","107":"y","108":"y","109":"y","110":"y","111":"y","112":"y","113":"y","114":"y","115":"y","116":"y","117":"y"},safari:{"4":"n","5":"n","6":"n","7":"n","8":"n","9":"y","10":"y","11":"y","12":"y","13":"y","14":"y","15":"y","17":"y","9.1":"y","10.1":"y","11.1":"y","12.1":"y","13.1":"y","14.1":"y","15.1":"y","15.2-15.3":"y","15.4":"y","15.5":"y","15.6":"y","16.0":"y","16.1":"y","16.2":"y","16.3":"y","16.4":"y","16.5":"y","16.6":"y",TP:"y","3.1":"n","3.2":"n","5.1":"n","6.1":"n","7.1":"n"},opera:{"9":"n","11":"n","12":"n","15":"y","16":"y","17":"y","18":"y","19":"y","20":"y","21":"y","22":"y","23":"y","24":"y","25":"y","26":"y","27":"y","28":"y","29":"y","30":"y","31":"y","32":"y","33":"y","34":"y","35":"y","36":"y","37":"y","38":"y","39":"y","40":"y","41":"y","42":"y","43":"y","44":"y","45":"y","46":"y","47":"y","48":"y","49":"y","50":"y","51":"y","52":"y","53":"y","54":"y","55":"y","56":"y","57":"y","58":"y","60":"y","62":"y","63":"y","64":"y","65":"y","66":"y","67":"y","68":"y","69":"y","70":"y","71":"y","72":"y","73":"y","74":"y","75":"y","76":"y","77":"y","78":"y","79":"y","80":"y","81":"y","82":"y","83":"y","84":"y","85":"y","86":"y","87":"y","88":"y","89":"y","90":"y","91":"y","92":"y","93":"y","94":"y","95":"y","96":"y","97":"y","98":"y","99":"y","100":"y","12.1":"y","9.5-9.6":"n","10.0-10.1":"n","10.5":"n","10.6":"n","11.1":"n","11.5":"n","11.6":"n"},ios_saf:{"8":"n","17":"y","9.0-9.2":"y","9.3":"y","10.0-10.2":"y","10.3":"y","11.0-11.2":"y","11.3-11.4":"y","12.0-12.1":"y","12.2-12.5":"y","13.0-13.1":"y","13.2":"y","13.3":"y","13.4-13.7":"y","14.0-14.4":"y","14.5-14.8":"y","15.0-15.1":"y","15.2-15.3":"y","15.4":"y","15.5":"y","15.6":"y","16.0":"y","16.1":"y","16.2":"y","16.3":"y","16.4":"y","16.5":"y","16.6":"y","3.2":"n","4.0-4.1":"n","4.2-4.3":"n","5.0-5.1":"n","6.0-6.1":"n","7.0-7.1":"n","8.1-8.4":"n"},op_mini:{all:"y"},android:{"3":"n","4":"n","114":"y","4.4":"y","4.4.3-4.4.4":"y","2.1":"n","2.2":"n","2.3":"n","4.1":"n","4.2-4.3":"n"},bb:{"7":"n","10":"n"},op_mob:{"10":"n","11":"n","12":"n","73":"y","11.1":"n","11.5":"n","12.1":"n"},and_chr:{"114":"y"},and_ff:{"115":"y"},ie_mob:{"10":"n","11":"n"},and_uc:{"15.5":"y"},samsung:{"4":"y","20":"y","21":"y","5.0-5.4":"y","6.2-6.4":"y","7.2-7.4":"y","8.2":"y","9.2":"y","10.1":"y","11.1-11.2":"y","12.0":"y","13.0":"y","14.0":"y","15.0":"y","16.0":"y","17.0":"y","18.0":"y","19.0":"y"},and_qq:{"13.1":"y"},baidu:{"13.18":"y"},kaios:{"2.5":"y","3.0-3.1":"y"}}}}var Y2,zn=C(()=>{l();Y2={ie:{prefix:"ms"},edge:{prefix:"webkit",prefix_exceptions:{"12":"ms","13":"ms","14":"ms","15":"ms","16":"ms","17":"ms","18":"ms"}},firefox:{prefix:"moz"},chrome:{prefix:"webkit"},safari:{prefix:"webkit"},opera:{prefix:"webkit",prefix_exceptions:{"9":"o","11":"o","12":"o","9.5-9.6":"o","10.0-10.1":"o","10.5":"o","10.6":"o","11.1":"o","11.5":"o","11.6":"o","12.1":"o"}},ios_saf:{prefix:"webkit"},op_mini:{prefix:"o"},android:{prefix:"webkit"},bb:{prefix:"webkit"},op_mob:{prefix:"o",prefix_exceptions:{"73":"webkit"}},and_chr:{prefix:"webkit"},and_ff:{prefix:"moz"},ie_mob:{prefix:"ms"},and_uc:{prefix:"webkit",prefix_exceptions:{"15.5":"webkit"}},samsung:{prefix:"webkit"},and_qq:{prefix:"webkit"},baidu:{prefix:"webkit"},kaios:{prefix:"moz"}}});var bm=v(()=>{l()});var ue=v((A4,ft)=>{l();var{list:Go}=me();ft.exports.error=function(i){let e=new Error(i);throw e.autoprefixer=!0,e};ft.exports.uniq=function(i){return[...new Set(i)]};ft.exports.removeNote=function(i){return i.includes(" ")?i.split(" ")[0]:i};ft.exports.escapeRegexp=function(i){return i.replace(/[$()*+-.?[\\\]^{|}]/g,"\\$&")};ft.exports.regexp=function(i,e=!0){return e&&(i=this.escapeRegexp(i)),new RegExp(`(^|[\\s,(])(${i}($|[\\s(,]))`,"gi")};ft.exports.editList=function(i,e){let t=Go.comma(i),r=e(t,[]);if(t===r)return i;let n=i.match(/,\s*/);return n=n?n[0]:", ",r.join(n)};ft.exports.splitSelector=function(i){return Go.comma(i).map(e=>Go.space(e).map(t=>t.split(/(?=\.|#)/g)))}});var ct=v((_4,km)=>{l();var J2=Wo(),vm=(zn(),jn).agents,X2=ue(),xm=class{static prefixes(){if(this.prefixesCache)return this.prefixesCache;this.prefixesCache=[];for(let e in vm)this.prefixesCache.push(`-${vm[e].prefix}-`);return this.prefixesCache=X2.uniq(this.prefixesCache).sort((e,t)=>t.length-e.length),this.prefixesCache}static withPrefix(e){return this.prefixesRegexp||(this.prefixesRegexp=new RegExp(this.prefixes().join("|"))),this.prefixesRegexp.test(e)}constructor(e,t,r,n){this.data=e,this.options=r||{},this.browserslistOpts=n||{},this.selected=this.parse(t)}parse(e){let t={};for(let r in this.browserslistOpts)t[r]=this.browserslistOpts[r];return t.path=this.options.from,J2(e,t)}prefix(e){let[t,r]=e.split(" "),n=this.data[t],a=n.prefix_exceptions&&n.prefix_exceptions[r];return a||(a=n.prefix),`-${a}-`}isSelected(e){return this.selected.includes(e)}};km.exports=xm});var ii=v((E4,Sm)=>{l();Sm.exports={prefix(i){let e=i.match(/^(-\w+-)/);return e?e[0]:""},unprefixed(i){return i.replace(/^-\w+-/,"")}}});var Vt=v((O4,Am)=>{l();var K2=ct(),Cm=ii(),Z2=ue();function Ho(i,e){let t=new i.constructor;for(let r of Object.keys(i||{})){let n=i[r];r==="parent"&&typeof n=="object"?e&&(t[r]=e):r==="source"||r===null?t[r]=n:Array.isArray(n)?t[r]=n.map(a=>Ho(a,t)):r!=="_autoprefixerPrefix"&&r!=="_autoprefixerValues"&&r!=="proxyCache"&&(typeof n=="object"&&n!==null&&(n=Ho(n,t)),t[r]=n)}return t}var Vn=class{static hack(e){return this.hacks||(this.hacks={}),e.names.map(t=>(this.hacks[t]=e,this.hacks[t]))}static load(e,t,r){let n=this.hacks&&this.hacks[e];return n?new n(e,t,r):new this(e,t,r)}static clone(e,t){let r=Ho(e);for(let n in t)r[n]=t[n];return r}constructor(e,t,r){this.prefixes=t,this.name=e,this.all=r}parentPrefix(e){let t;return typeof e._autoprefixerPrefix!="undefined"?t=e._autoprefixerPrefix:e.type==="decl"&&e.prop[0]==="-"?t=Cm.prefix(e.prop):e.type==="root"?t=!1:e.type==="rule"&&e.selector.includes(":-")&&/:(-\w+-)/.test(e.selector)?t=e.selector.match(/:(-\w+-)/)[1]:e.type==="atrule"&&e.name[0]==="-"?t=Cm.prefix(e.name):t=this.parentPrefix(e.parent),K2.prefixes().includes(t)||(t=!1),e._autoprefixerPrefix=t,e._autoprefixerPrefix}process(e,t){if(!this.check(e))return;let r=this.parentPrefix(e),n=this.prefixes.filter(s=>!r||r===Z2.removeNote(s)),a=[];for(let s of n)this.add(e,s,a.concat([s]),t)&&a.push(s);return a}clone(e,t){return Vn.clone(e,t)}};Am.exports=Vn});var R=v((T4,Om)=>{l();var eA=Vt(),tA=ct(),_m=ue(),Em=class extends eA{check(){return!0}prefixed(e,t){return t+e}normalize(e){return e}otherPrefixes(e,t){for(let r of tA.prefixes())if(r!==t&&e.includes(r))return!0;return!1}set(e,t){return e.prop=this.prefixed(e.prop,t),e}needCascade(e){return e._autoprefixerCascade||(e._autoprefixerCascade=this.all.options.cascade!==!1&&e.raw("before").includes(` +`)),e._autoprefixerCascade}maxPrefixed(e,t){if(t._autoprefixerMax)return t._autoprefixerMax;let r=0;for(let n of e)n=_m.removeNote(n),n.length>r&&(r=n.length);return t._autoprefixerMax=r,t._autoprefixerMax}calcBefore(e,t,r=""){let a=this.maxPrefixed(e,t)-_m.removeNote(r).length,s=t.raw("before");return a>0&&(s+=Array(a).fill(" ").join("")),s}restoreBefore(e){let t=e.raw("before").split(` +`),r=t[t.length-1];this.all.group(e).up(n=>{let a=n.raw("before").split(` +`),s=a[a.length-1];s.lengths.prop===n.prop&&s.value===n.value)))return this.needCascade(e)&&(n.raws.before=this.calcBefore(r,e,t)),e.parent.insertBefore(e,n)}isAlready(e,t){let r=this.all.group(e).up(n=>n.prop===t);return r||(r=this.all.group(e).down(n=>n.prop===t)),r}add(e,t,r,n){let a=this.prefixed(e.prop,t);if(!(this.isAlready(e,a)||this.otherPrefixes(e.value,t)))return this.insert(e,t,r,n)}process(e,t){if(!this.needCascade(e)){super.process(e,t);return}let r=super.process(e,t);!r||!r.length||(this.restoreBefore(e),e.raws.before=this.calcBefore(r,e))}old(e,t){return[this.prefixed(e,t)]}};Om.exports=Em});var Pm=v((P4,Tm)=>{l();Tm.exports=function i(e){return{mul:t=>new i(e*t),div:t=>new i(e/t),simplify:()=>new i(e),toString:()=>e.toString()}}});var qm=v((D4,Im)=>{l();var rA=Pm(),iA=Vt(),Yo=ue(),nA=/(min|max)-resolution\s*:\s*\d*\.?\d+(dppx|dpcm|dpi|x)/gi,sA=/(min|max)-resolution(\s*:\s*)(\d*\.?\d+)(dppx|dpcm|dpi|x)/i,Dm=class extends iA{prefixName(e,t){return e==="-moz-"?t+"--moz-device-pixel-ratio":e+t+"-device-pixel-ratio"}prefixQuery(e,t,r,n,a){return n=new rA(n),a==="dpi"?n=n.div(96):a==="dpcm"&&(n=n.mul(2.54).div(96)),n=n.simplify(),e==="-o-"&&(n=n.n+"/"+n.d),this.prefixName(e,t)+r+n}clean(e){if(!this.bad){this.bad=[];for(let t of this.prefixes)this.bad.push(this.prefixName(t,"min")),this.bad.push(this.prefixName(t,"max"))}e.params=Yo.editList(e.params,t=>t.filter(r=>this.bad.every(n=>!r.includes(n))))}process(e){let t=this.parentPrefix(e),r=t?[t]:this.prefixes;e.params=Yo.editList(e.params,(n,a)=>{for(let s of n){if(!s.includes("min-resolution")&&!s.includes("max-resolution")){a.push(s);continue}for(let o of r){let u=s.replace(nA,c=>{let f=c.match(sA);return this.prefixQuery(o,f[1],f[2],f[3],f[4])});a.push(u)}a.push(s)}return Yo.uniq(a)})}};Im.exports=Dm});var Mm=v((I4,Rm)=>{l();var Qo="(".charCodeAt(0),Jo=")".charCodeAt(0),Un="'".charCodeAt(0),Xo='"'.charCodeAt(0),Ko="\\".charCodeAt(0),Ut="/".charCodeAt(0),Zo=",".charCodeAt(0),el=":".charCodeAt(0),Wn="*".charCodeAt(0),aA="u".charCodeAt(0),oA="U".charCodeAt(0),lA="+".charCodeAt(0),uA=/^[a-f0-9?-]+$/i;Rm.exports=function(i){for(var e=[],t=i,r,n,a,s,o,u,c,f,p=0,d=t.charCodeAt(p),h=t.length,y=[{nodes:e}],x=0,w,b="",k="",S="";p{l();Bm.exports=function i(e,t,r){var n,a,s,o;for(n=0,a=e.length;n{l();function Nm(i,e){var t=i.type,r=i.value,n,a;return e&&(a=e(i))!==void 0?a:t==="word"||t==="space"?r:t==="string"?(n=i.quote||"",n+r+(i.unclosed?"":n)):t==="comment"?"/*"+r+(i.unclosed?"":"*/"):t==="div"?(i.before||"")+r+(i.after||""):Array.isArray(i.nodes)?(n=Lm(i.nodes,e),t!=="function"?n:r+"("+(i.before||"")+n+(i.after||"")+(i.unclosed?"":")")):r}function Lm(i,e){var t,r;if(Array.isArray(i)){for(t="",r=i.length-1;~r;r-=1)t=Nm(i[r],e)+t;return t}return Nm(i,e)}$m.exports=Lm});var Vm=v((M4,zm)=>{l();var Gn="-".charCodeAt(0),Hn="+".charCodeAt(0),tl=".".charCodeAt(0),fA="e".charCodeAt(0),cA="E".charCodeAt(0);function pA(i){var e=i.charCodeAt(0),t;if(e===Hn||e===Gn){if(t=i.charCodeAt(1),t>=48&&t<=57)return!0;var r=i.charCodeAt(2);return t===tl&&r>=48&&r<=57}return e===tl?(t=i.charCodeAt(1),t>=48&&t<=57):e>=48&&e<=57}zm.exports=function(i){var e=0,t=i.length,r,n,a;if(t===0||!pA(i))return!1;for(r=i.charCodeAt(e),(r===Hn||r===Gn)&&e++;e57));)e+=1;if(r=i.charCodeAt(e),n=i.charCodeAt(e+1),r===tl&&n>=48&&n<=57)for(e+=2;e57));)e+=1;if(r=i.charCodeAt(e),n=i.charCodeAt(e+1),a=i.charCodeAt(e+2),(r===fA||r===cA)&&(n>=48&&n<=57||(n===Hn||n===Gn)&&a>=48&&a<=57))for(e+=n===Hn||n===Gn?3:2;e57));)e+=1;return{number:i.slice(0,e),unit:i.slice(e)}}});var Yn=v((B4,Gm)=>{l();var dA=Mm(),Um=Fm(),Wm=jm();function pt(i){return this instanceof pt?(this.nodes=dA(i),this):new pt(i)}pt.prototype.toString=function(){return Array.isArray(this.nodes)?Wm(this.nodes):""};pt.prototype.walk=function(i,e){return Um(this.nodes,i,e),this};pt.unit=Vm();pt.walk=Um;pt.stringify=Wm;Gm.exports=pt});var Xm=v((F4,Jm)=>{l();var{list:hA}=me(),Hm=Yn(),mA=ct(),Ym=ii(),Qm=class{constructor(e){this.props=["transition","transition-property"],this.prefixes=e}add(e,t){let r,n,a=this.prefixes.add[e.prop],s=this.ruleVendorPrefixes(e),o=s||a&&a.prefixes||[],u=this.parse(e.value),c=u.map(h=>this.findProp(h)),f=[];if(c.some(h=>h[0]==="-"))return;for(let h of u){if(n=this.findProp(h),n[0]==="-")continue;let y=this.prefixes.add[n];if(!(!y||!y.prefixes))for(r of y.prefixes){if(s&&!s.some(w=>r.includes(w)))continue;let x=this.prefixes.prefixed(n,r);x!=="-ms-transform"&&!c.includes(x)&&(this.disabled(n,r)||f.push(this.clone(n,x,h)))}}u=u.concat(f);let p=this.stringify(u),d=this.stringify(this.cleanFromUnprefixed(u,"-webkit-"));if(o.includes("-webkit-")&&this.cloneBefore(e,`-webkit-${e.prop}`,d),this.cloneBefore(e,e.prop,d),o.includes("-o-")){let h=this.stringify(this.cleanFromUnprefixed(u,"-o-"));this.cloneBefore(e,`-o-${e.prop}`,h)}for(r of o)if(r!=="-webkit-"&&r!=="-o-"){let h=this.stringify(this.cleanOtherPrefixes(u,r));this.cloneBefore(e,r+e.prop,h)}p!==e.value&&!this.already(e,e.prop,p)&&(this.checkForWarning(t,e),e.cloneBefore(),e.value=p)}findProp(e){let t=e[0].value;if(/^\d/.test(t)){for(let[r,n]of e.entries())if(r!==0&&n.type==="word")return n.value}return t}already(e,t,r){return e.parent.some(n=>n.prop===t&&n.value===r)}cloneBefore(e,t,r){this.already(e,t,r)||e.cloneBefore({prop:t,value:r})}checkForWarning(e,t){if(t.prop!=="transition-property")return;let r=!1,n=!1;t.parent.each(a=>{if(a.type!=="decl"||a.prop.indexOf("transition-")!==0)return;let s=hA.comma(a.value);if(a.prop==="transition-property"){s.forEach(o=>{let u=this.prefixes.add[o];u&&u.prefixes&&u.prefixes.length>0&&(r=!0)});return}return n=n||s.length>1,!1}),r&&n&&t.warn(e,"Replace transition-property to transition, because Autoprefixer could not support any cases of transition-property and other transition-*")}remove(e){let t=this.parse(e.value);t=t.filter(s=>{let o=this.prefixes.remove[this.findProp(s)];return!o||!o.remove});let r=this.stringify(t);if(e.value===r)return;if(t.length===0){e.remove();return}let n=e.parent.some(s=>s.prop===e.prop&&s.value===r),a=e.parent.some(s=>s!==e&&s.prop===e.prop&&s.value.length>r.length);if(n||a){e.remove();return}e.value=r}parse(e){let t=Hm(e),r=[],n=[];for(let a of t.nodes)n.push(a),a.type==="div"&&a.value===","&&(r.push(n),n=[]);return r.push(n),r.filter(a=>a.length>0)}stringify(e){if(e.length===0)return"";let t=[];for(let r of e)r[r.length-1].type!=="div"&&r.push(this.div(e)),t=t.concat(r);return t[0].type==="div"&&(t=t.slice(1)),t[t.length-1].type==="div"&&(t=t.slice(0,-2+1||void 0)),Hm.stringify({nodes:t})}clone(e,t,r){let n=[],a=!1;for(let s of r)!a&&s.type==="word"&&s.value===e?(n.push({type:"word",value:t}),a=!0):n.push(s);return n}div(e){for(let t of e)for(let r of t)if(r.type==="div"&&r.value===",")return r;return{type:"div",value:",",after:" "}}cleanOtherPrefixes(e,t){return e.filter(r=>{let n=Ym.prefix(this.findProp(r));return n===""||n===t})}cleanFromUnprefixed(e,t){let r=e.map(a=>this.findProp(a)).filter(a=>a.slice(0,t.length)===t).map(a=>this.prefixes.unprefixed(a)),n=[];for(let a of e){let s=this.findProp(a),o=Ym.prefix(s);!r.includes(s)&&(o===t||o==="")&&n.push(a)}return n}disabled(e,t){let r=["order","justify-content","align-self","align-content"];if(e.includes("flex")||r.includes(e)){if(this.prefixes.options.flexbox===!1)return!0;if(this.prefixes.options.flexbox==="no-2009")return t.includes("2009")}}ruleVendorPrefixes(e){let{parent:t}=e;if(t.type!=="rule")return!1;if(!t.selector.includes(":-"))return!1;let r=mA.prefixes().filter(n=>t.selector.includes(":"+n));return r.length>0?r:!1}};Jm.exports=Qm});var Wt=v((N4,Zm)=>{l();var gA=ue(),Km=class{constructor(e,t,r,n){this.unprefixed=e,this.prefixed=t,this.string=r||t,this.regexp=n||gA.regexp(t)}check(e){return e.includes(this.string)?!!e.match(this.regexp):!1}};Zm.exports=Km});var ke=v((L4,tg)=>{l();var yA=Vt(),wA=Wt(),bA=ii(),vA=ue(),eg=class extends yA{static save(e,t){let r=t.prop,n=[];for(let a in t._autoprefixerValues){let s=t._autoprefixerValues[a];if(s===t.value)continue;let o,u=bA.prefix(r);if(u==="-pie-")continue;if(u===a){o=t.value=s,n.push(o);continue}let c=e.prefixed(r,a),f=t.parent;if(!f.every(y=>y.prop!==c)){n.push(o);continue}let p=s.replace(/\s+/," ");if(f.some(y=>y.prop===t.prop&&y.value.replace(/\s+/," ")===p)){n.push(o);continue}let h=this.clone(t,{value:s});o=t.parent.insertBefore(t,h),n.push(o)}return n}check(e){let t=e.value;return t.includes(this.name)?!!t.match(this.regexp()):!1}regexp(){return this.regexpCache||(this.regexpCache=vA.regexp(this.name))}replace(e,t){return e.replace(this.regexp(),`$1${t}$2`)}value(e){return e.raws.value&&e.raws.value.value===e.value?e.raws.value.raw:e.value}add(e,t){e._autoprefixerValues||(e._autoprefixerValues={});let r=e._autoprefixerValues[t]||this.value(e),n;do if(n=r,r=this.replace(r,t),r===!1)return;while(r!==n);e._autoprefixerValues[t]=r}old(e){return new wA(this.name,e+this.name)}};tg.exports=eg});var dt=v(($4,rg)=>{l();rg.exports={}});var il=v((j4,sg)=>{l();var ig=Yn(),xA=ke(),kA=dt().insertAreas,SA=/(^|[^-])linear-gradient\(\s*(top|left|right|bottom)/i,CA=/(^|[^-])radial-gradient\(\s*\d+(\w*|%)\s+\d+(\w*|%)\s*,/i,AA=/(!\s*)?autoprefixer:\s*ignore\s+next/i,_A=/(!\s*)?autoprefixer\s*grid:\s*(on|off|(no-)?autoplace)/i,EA=["width","height","min-width","max-width","min-height","max-height","inline-size","min-inline-size","max-inline-size","block-size","min-block-size","max-block-size"];function rl(i){return i.parent.some(e=>e.prop==="grid-template"||e.prop==="grid-template-areas")}function OA(i){let e=i.parent.some(r=>r.prop==="grid-template-rows"),t=i.parent.some(r=>r.prop==="grid-template-columns");return e&&t}var ng=class{constructor(e){this.prefixes=e}add(e,t){let r=this.prefixes.add["@resolution"],n=this.prefixes.add["@keyframes"],a=this.prefixes.add["@viewport"],s=this.prefixes.add["@supports"];e.walkAtRules(f=>{if(f.name==="keyframes"){if(!this.disabled(f,t))return n&&n.process(f)}else if(f.name==="viewport"){if(!this.disabled(f,t))return a&&a.process(f)}else if(f.name==="supports"){if(this.prefixes.options.supports!==!1&&!this.disabled(f,t))return s.process(f)}else if(f.name==="media"&&f.params.includes("-resolution")&&!this.disabled(f,t))return r&&r.process(f)}),e.walkRules(f=>{if(!this.disabled(f,t))return this.prefixes.add.selectors.map(p=>p.process(f,t))});function o(f){return f.parent.nodes.some(p=>{if(p.type!=="decl")return!1;let d=p.prop==="display"&&/(inline-)?grid/.test(p.value),h=p.prop.startsWith("grid-template"),y=/^grid-([A-z]+-)?gap/.test(p.prop);return d||h||y})}function u(f){return f.parent.some(p=>p.prop==="display"&&/(inline-)?flex/.test(p.value))}let c=this.gridStatus(e,t)&&this.prefixes.add["grid-area"]&&this.prefixes.add["grid-area"].prefixes;return e.walkDecls(f=>{if(this.disabledDecl(f,t))return;let p=f.parent,d=f.prop,h=f.value;if(d==="grid-row-span"){t.warn("grid-row-span is not part of final Grid Layout. Use grid-row.",{node:f});return}else if(d==="grid-column-span"){t.warn("grid-column-span is not part of final Grid Layout. Use grid-column.",{node:f});return}else if(d==="display"&&h==="box"){t.warn("You should write display: flex by final spec instead of display: box",{node:f});return}else if(d==="text-emphasis-position")(h==="under"||h==="over")&&t.warn("You should use 2 values for text-emphasis-position For example, `under left` instead of just `under`.",{node:f});else if(/^(align|justify|place)-(items|content)$/.test(d)&&u(f))(h==="start"||h==="end")&&t.warn(`${h} value has mixed support, consider using flex-${h} instead`,{node:f});else if(d==="text-decoration-skip"&&h==="ink")t.warn("Replace text-decoration-skip: ink to text-decoration-skip-ink: auto, because spec had been changed",{node:f});else{if(c&&this.gridStatus(f,t))if(f.value==="subgrid"&&t.warn("IE does not support subgrid",{node:f}),/^(align|justify|place)-items$/.test(d)&&o(f)){let x=d.replace("-items","-self");t.warn(`IE does not support ${d} on grid containers. Try using ${x} on child elements instead: ${f.parent.selector} > * { ${x}: ${f.value} }`,{node:f})}else if(/^(align|justify|place)-content$/.test(d)&&o(f))t.warn(`IE does not support ${f.prop} on grid containers`,{node:f});else if(d==="display"&&f.value==="contents"){t.warn("Please do not use display: contents; if you have grid setting enabled",{node:f});return}else if(f.prop==="grid-gap"){let x=this.gridStatus(f,t);x==="autoplace"&&!OA(f)&&!rl(f)?t.warn("grid-gap only works if grid-template(-areas) is being used or both rows and columns have been declared and cells have not been manually placed inside the explicit grid",{node:f}):(x===!0||x==="no-autoplace")&&!rl(f)&&t.warn("grid-gap only works if grid-template(-areas) is being used",{node:f})}else if(d==="grid-auto-columns"){t.warn("grid-auto-columns is not supported by IE",{node:f});return}else if(d==="grid-auto-rows"){t.warn("grid-auto-rows is not supported by IE",{node:f});return}else if(d==="grid-auto-flow"){let x=p.some(b=>b.prop==="grid-template-rows"),w=p.some(b=>b.prop==="grid-template-columns");rl(f)?t.warn("grid-auto-flow is not supported by IE",{node:f}):h.includes("dense")?t.warn("grid-auto-flow: dense is not supported by IE",{node:f}):!x&&!w&&t.warn("grid-auto-flow works only if grid-template-rows and grid-template-columns are present in the same rule",{node:f});return}else if(h.includes("auto-fit")){t.warn("auto-fit value is not supported by IE",{node:f,word:"auto-fit"});return}else if(h.includes("auto-fill")){t.warn("auto-fill value is not supported by IE",{node:f,word:"auto-fill"});return}else d.startsWith("grid-template")&&h.includes("[")&&t.warn("Autoprefixer currently does not support line names. Try using grid-template-areas instead.",{node:f,word:"["});if(h.includes("radial-gradient"))if(CA.test(f.value))t.warn("Gradient has outdated direction syntax. New syntax is like `closest-side at 0 0` instead of `0 0, closest-side`.",{node:f});else{let x=ig(h);for(let w of x.nodes)if(w.type==="function"&&w.value==="radial-gradient")for(let b of w.nodes)b.type==="word"&&(b.value==="cover"?t.warn("Gradient has outdated direction syntax. Replace `cover` to `farthest-corner`.",{node:f}):b.value==="contain"&&t.warn("Gradient has outdated direction syntax. Replace `contain` to `closest-side`.",{node:f}))}h.includes("linear-gradient")&&SA.test(h)&&t.warn("Gradient has outdated direction syntax. New syntax is like `to left` instead of `right`.",{node:f})}EA.includes(f.prop)&&(f.value.includes("-fill-available")||(f.value.includes("fill-available")?t.warn("Replace fill-available to stretch, because spec had been changed",{node:f}):f.value.includes("fill")&&ig(h).nodes.some(w=>w.type==="word"&&w.value==="fill")&&t.warn("Replace fill to stretch, because spec had been changed",{node:f})));let y;if(f.prop==="transition"||f.prop==="transition-property")return this.prefixes.transition.add(f,t);if(f.prop==="align-self"){if(this.displayType(f)!=="grid"&&this.prefixes.options.flexbox!==!1&&(y=this.prefixes.add["align-self"],y&&y.prefixes&&y.process(f)),this.gridStatus(f,t)!==!1&&(y=this.prefixes.add["grid-row-align"],y&&y.prefixes))return y.process(f,t)}else if(f.prop==="justify-self"){if(this.gridStatus(f,t)!==!1&&(y=this.prefixes.add["grid-column-align"],y&&y.prefixes))return y.process(f,t)}else if(f.prop==="place-self"){if(y=this.prefixes.add["place-self"],y&&y.prefixes&&this.gridStatus(f,t)!==!1)return y.process(f,t)}else if(y=this.prefixes.add[f.prop],y&&y.prefixes)return y.process(f,t)}),this.gridStatus(e,t)&&kA(e,this.disabled),e.walkDecls(f=>{if(this.disabledValue(f,t))return;let p=this.prefixes.unprefixed(f.prop),d=this.prefixes.values("add",p);if(Array.isArray(d))for(let h of d)h.process&&h.process(f,t);xA.save(this.prefixes,f)})}remove(e,t){let r=this.prefixes.remove["@resolution"];e.walkAtRules((n,a)=>{this.prefixes.remove[`@${n.name}`]?this.disabled(n,t)||n.parent.removeChild(a):n.name==="media"&&n.params.includes("-resolution")&&r&&r.clean(n)});for(let n of this.prefixes.remove.selectors)e.walkRules((a,s)=>{n.check(a)&&(this.disabled(a,t)||a.parent.removeChild(s))});return e.walkDecls((n,a)=>{if(this.disabled(n,t))return;let s=n.parent,o=this.prefixes.unprefixed(n.prop);if((n.prop==="transition"||n.prop==="transition-property")&&this.prefixes.transition.remove(n),this.prefixes.remove[n.prop]&&this.prefixes.remove[n.prop].remove){let u=this.prefixes.group(n).down(c=>this.prefixes.normalize(c.prop)===o);if(o==="flex-flow"&&(u=!0),n.prop==="-webkit-box-orient"){let c={"flex-direction":!0,"flex-flow":!0};if(!n.parent.some(f=>c[f.prop]))return}if(u&&!this.withHackValue(n)){n.raw("before").includes(` +`)&&this.reduceSpaces(n),s.removeChild(a);return}}for(let u of this.prefixes.values("remove",o)){if(!u.check||!u.check(n.value))continue;if(o=u.unprefixed,this.prefixes.group(n).down(f=>f.value.includes(o))){s.removeChild(a);return}}})}withHackValue(e){return e.prop==="-webkit-background-clip"&&e.value==="text"}disabledValue(e,t){return this.gridStatus(e,t)===!1&&e.type==="decl"&&e.prop==="display"&&e.value.includes("grid")||this.prefixes.options.flexbox===!1&&e.type==="decl"&&e.prop==="display"&&e.value.includes("flex")||e.type==="decl"&&e.prop==="content"?!0:this.disabled(e,t)}disabledDecl(e,t){if(this.gridStatus(e,t)===!1&&e.type==="decl"&&(e.prop.includes("grid")||e.prop==="justify-items"))return!0;if(this.prefixes.options.flexbox===!1&&e.type==="decl"){let r=["order","justify-content","align-items","align-content"];if(e.prop.includes("flex")||r.includes(e.prop))return!0}return this.disabled(e,t)}disabled(e,t){if(!e)return!1;if(e._autoprefixerDisabled!==void 0)return e._autoprefixerDisabled;if(e.parent){let n=e.prev();if(n&&n.type==="comment"&&AA.test(n.text))return e._autoprefixerDisabled=!0,e._autoprefixerSelfDisabled=!0,!0}let r=null;if(e.nodes){let n;e.each(a=>{a.type==="comment"&&/(!\s*)?autoprefixer:\s*(off|on)/i.test(a.text)&&(typeof n!="undefined"?t.warn("Second Autoprefixer control comment was ignored. Autoprefixer applies control comment to whole block, not to next rules.",{node:a}):n=/on/i.test(a.text))}),n!==void 0&&(r=!n)}if(!e.nodes||r===null)if(e.parent){let n=this.disabled(e.parent,t);e.parent._autoprefixerSelfDisabled===!0?r=!1:r=n}else r=!1;return e._autoprefixerDisabled=r,r}reduceSpaces(e){let t=!1;if(this.prefixes.group(e).up(()=>(t=!0,!0)),t)return;let r=e.raw("before").split(` +`),n=r[r.length-1].length,a=!1;this.prefixes.group(e).down(s=>{r=s.raw("before").split(` +`);let o=r.length-1;r[o].length>n&&(a===!1&&(a=r[o].length-n),r[o]=r[o].slice(0,-a),s.raws.before=r.join(` +`))})}displayType(e){for(let t of e.parent.nodes)if(t.prop==="display"){if(t.value.includes("flex"))return"flex";if(t.value.includes("grid"))return"grid"}return!1}gridStatus(e,t){if(!e)return!1;if(e._autoprefixerGridStatus!==void 0)return e._autoprefixerGridStatus;let r=null;if(e.nodes){let n;e.each(a=>{if(a.type==="comment"&&_A.test(a.text)){let s=/:\s*autoplace/i.test(a.text),o=/no-autoplace/i.test(a.text);typeof n!="undefined"?t.warn("Second Autoprefixer grid control comment was ignored. Autoprefixer applies control comments to the whole block, not to the next rules.",{node:a}):s?n="autoplace":o?n=!0:n=/on/i.test(a.text)}}),n!==void 0&&(r=n)}if(e.type==="atrule"&&e.name==="supports"){let n=e.params;n.includes("grid")&&n.includes("auto")&&(r=!1)}if(!e.nodes||r===null)if(e.parent){let n=this.gridStatus(e.parent,t);e.parent._autoprefixerSelfDisabled===!0?r=!1:r=n}else typeof this.prefixes.options.grid!="undefined"?r=this.prefixes.options.grid:typeof m.env.AUTOPREFIXER_GRID!="undefined"?m.env.AUTOPREFIXER_GRID==="autoplace"?r="autoplace":r=!0:r=!1;return e._autoprefixerGridStatus=r,r}};sg.exports=ng});var og=v((z4,ag)=>{l();ag.exports={A:{A:{"2":"K E F G A B JC"},B:{"1":"C L M H N D O P Q R S T U V W X Y Z a b c d e f g h i j n o p q r s t u v w x y z I"},C:{"1":"2 3 4 5 6 7 8 9 AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB YB ZB aB bB cB 0B dB 1B eB fB gB hB iB jB kB lB mB nB oB m pB qB rB sB tB P Q R 2B S T U V W X Y Z a b c d e f g h i j n o p q r s t u v w x y z I uB 3B 4B","2":"0 1 KC zB J K E F G A B C L M H N D O k l LC MC"},D:{"1":"8 9 AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB YB ZB aB bB cB 0B dB 1B eB fB gB hB iB jB kB lB mB nB oB m pB qB rB sB tB P Q R S T U V W X Y Z a b c d e f g h i j n o p q r s t u v w x y z I uB 3B 4B","2":"0 1 2 3 4 5 6 7 J K E F G A B C L M H N D O k l"},E:{"1":"G A B C L M H D RC 6B vB wB 7B SC TC 8B 9B xB AC yB BC CC DC EC FC GC UC","2":"0 J K E F NC 5B OC PC QC"},F:{"1":"1 2 3 4 5 6 7 8 9 H N D O k l AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB YB ZB aB bB cB dB eB fB gB hB iB jB kB lB mB nB oB m pB qB rB sB tB P Q R 2B S T U V W X Y Z a b c d e f g h i j wB","2":"G B C VC WC XC YC vB HC ZC"},G:{"1":"D fC gC hC iC jC kC lC mC nC oC pC qC rC sC tC 8B 9B xB AC yB BC CC DC EC FC GC","2":"F 5B aC IC bC cC dC eC"},H:{"1":"uC"},I:{"1":"I zC 0C","2":"zB J vC wC xC yC IC"},J:{"2":"E A"},K:{"1":"m","2":"A B C vB HC wB"},L:{"1":"I"},M:{"1":"uB"},N:{"2":"A B"},O:{"1":"xB"},P:{"1":"J k l 1C 2C 3C 4C 5C 6B 6C 7C 8C 9C AD yB BD CD DD"},Q:{"1":"7B"},R:{"1":"ED"},S:{"1":"FD GD"}},B:4,C:"CSS Feature Queries"}});var cg=v((V4,fg)=>{l();function lg(i){return i[i.length-1]}var ug={parse(i){let e=[""],t=[e];for(let r of i){if(r==="("){e=[""],lg(t).push(e),t.push(e);continue}if(r===")"){t.pop(),e=lg(t),e.push("");continue}e[e.length-1]+=r}return t[0]},stringify(i){let e="";for(let t of i){if(typeof t=="object"){e+=`(${ug.stringify(t)})`;continue}e+=t}return e}};fg.exports=ug});var gg=v((U4,mg)=>{l();var TA=og(),{feature:PA}=(zn(),jn),{parse:DA}=me(),IA=ct(),nl=cg(),qA=ke(),RA=ue(),pg=PA(TA),dg=[];for(let i in pg.stats){let e=pg.stats[i];for(let t in e){let r=e[t];/y/.test(r)&&dg.push(i+" "+t)}}var hg=class{constructor(e,t){this.Prefixes=e,this.all=t}prefixer(){if(this.prefixerCache)return this.prefixerCache;let e=this.all.browsers.selected.filter(r=>dg.includes(r)),t=new IA(this.all.browsers.data,e,this.all.options);return this.prefixerCache=new this.Prefixes(this.all.data,t,this.all.options),this.prefixerCache}parse(e){let t=e.split(":"),r=t[0],n=t[1];return n||(n=""),[r.trim(),n.trim()]}virtual(e){let[t,r]=this.parse(e),n=DA("a{}").first;return n.append({prop:t,value:r,raws:{before:""}}),n}prefixed(e){let t=this.virtual(e);if(this.disabled(t.first))return t.nodes;let r={warn:()=>null},n=this.prefixer().add[t.first.prop];n&&n.process&&n.process(t.first,r);for(let a of t.nodes){for(let s of this.prefixer().values("add",t.first.prop))s.process(a);qA.save(this.all,a)}return t.nodes}isNot(e){return typeof e=="string"&&/not\s*/i.test(e)}isOr(e){return typeof e=="string"&&/\s*or\s*/i.test(e)}isProp(e){return typeof e=="object"&&e.length===1&&typeof e[0]=="string"}isHack(e,t){return!new RegExp(`(\\(|\\s)${RA.escapeRegexp(t)}:`).test(e)}toRemove(e,t){let[r,n]=this.parse(e),a=this.all.unprefixed(r),s=this.all.cleaner();if(s.remove[r]&&s.remove[r].remove&&!this.isHack(t,a))return!0;for(let o of s.values("remove",a))if(o.check(n))return!0;return!1}remove(e,t){let r=0;for(;rtypeof t!="object"?t:t.length===1&&typeof t[0]=="object"?this.cleanBrackets(t[0]):this.cleanBrackets(t))}convert(e){let t=[""];for(let r of e)t.push([`${r.prop}: ${r.value}`]),t.push(" or ");return t[t.length-1]="",t}normalize(e){if(typeof e!="object")return e;if(e=e.filter(t=>t!==""),typeof e[0]=="string"){let t=e[0].trim();if(t.includes(":")||t==="selector"||t==="not selector")return[nl.stringify(e)]}return e.map(t=>this.normalize(t))}add(e,t){return e.map(r=>{if(this.isProp(r)){let n=this.prefixed(r[0]);return n.length>1?this.convert(n):r}return typeof r=="object"?this.add(r,t):r})}process(e){let t=nl.parse(e.params);t=this.normalize(t),t=this.remove(t,e.params),t=this.add(t,e.params),t=this.cleanBrackets(t),e.params=nl.stringify(t)}disabled(e){if(!this.all.options.grid&&(e.prop==="display"&&e.value.includes("grid")||e.prop.includes("grid")||e.prop==="justify-items"))return!0;if(this.all.options.flexbox===!1){if(e.prop==="display"&&e.value.includes("flex"))return!0;let t=["order","justify-content","align-items","align-content"];if(e.prop.includes("flex")||t.includes(e.prop))return!0}return!1}};mg.exports=hg});var bg=v((W4,wg)=>{l();var yg=class{constructor(e,t){this.prefix=t,this.prefixed=e.prefixed(this.prefix),this.regexp=e.regexp(this.prefix),this.prefixeds=e.possible().map(r=>[e.prefixed(r),e.regexp(r)]),this.unprefixed=e.name,this.nameRegexp=e.regexp()}isHack(e){let t=e.parent.index(e)+1,r=e.parent.nodes;for(;t{l();var{list:MA}=me(),BA=bg(),FA=Vt(),NA=ct(),LA=ue(),vg=class extends FA{constructor(e,t,r){super(e,t,r);this.regexpCache=new Map}check(e){return e.selector.includes(this.name)?!!e.selector.match(this.regexp()):!1}prefixed(e){return this.name.replace(/^(\W*)/,`$1${e}`)}regexp(e){if(!this.regexpCache.has(e)){let t=e?this.prefixed(e):this.name;this.regexpCache.set(e,new RegExp(`(^|[^:"'=])${LA.escapeRegexp(t)}`,"gi"))}return this.regexpCache.get(e)}possible(){return NA.prefixes()}prefixeds(e){if(e._autoprefixerPrefixeds){if(e._autoprefixerPrefixeds[this.name])return e._autoprefixerPrefixeds}else e._autoprefixerPrefixeds={};let t={};if(e.selector.includes(",")){let n=MA.comma(e.selector).filter(a=>a.includes(this.name));for(let a of this.possible())t[a]=n.map(s=>this.replace(s,a)).join(", ")}else for(let r of this.possible())t[r]=this.replace(e.selector,r);return e._autoprefixerPrefixeds[this.name]=t,e._autoprefixerPrefixeds}already(e,t,r){let n=e.parent.index(e)-1;for(;n>=0;){let a=e.parent.nodes[n];if(a.type!=="rule")return!1;let s=!1;for(let o in t[this.name]){let u=t[this.name][o];if(a.selector===u){if(r===o)return!0;s=!0;break}}if(!s)return!1;n-=1}return!1}replace(e,t){return e.replace(this.regexp(),`$1${this.prefixed(t)}`)}add(e,t){let r=this.prefixeds(e);if(this.already(e,r,t))return;let n=this.clone(e,{selector:r[this.name][t]});e.parent.insertBefore(e,n)}old(e){return new BA(this,e)}};xg.exports=vg});var Cg=v((H4,Sg)=>{l();var $A=Vt(),kg=class extends $A{add(e,t){let r=t+e.name;if(e.parent.some(s=>s.name===r&&s.params===e.params))return;let a=this.clone(e,{name:r});return e.parent.insertBefore(e,a)}process(e){let t=this.parentPrefix(e);for(let r of this.prefixes)(!t||t===r)&&this.add(e,r)}};Sg.exports=kg});var _g=v((Y4,Ag)=>{l();var jA=Gt(),sl=class extends jA{prefixed(e){return e==="-webkit-"?":-webkit-full-screen":e==="-moz-"?":-moz-full-screen":`:${e}fullscreen`}};sl.names=[":fullscreen"];Ag.exports=sl});var Og=v((Q4,Eg)=>{l();var zA=Gt(),al=class extends zA{possible(){return super.possible().concat(["-moz- old","-ms- old"])}prefixed(e){return e==="-webkit-"?"::-webkit-input-placeholder":e==="-ms-"?"::-ms-input-placeholder":e==="-ms- old"?":-ms-input-placeholder":e==="-moz- old"?":-moz-placeholder":`::${e}placeholder`}};al.names=["::placeholder"];Eg.exports=al});var Pg=v((J4,Tg)=>{l();var VA=Gt(),ol=class extends VA{prefixed(e){return e==="-ms-"?":-ms-input-placeholder":`:${e}placeholder-shown`}};ol.names=[":placeholder-shown"];Tg.exports=ol});var Ig=v((X4,Dg)=>{l();var UA=Gt(),WA=ue(),ll=class extends UA{constructor(e,t,r){super(e,t,r);this.prefixes&&(this.prefixes=WA.uniq(this.prefixes.map(n=>"-webkit-")))}prefixed(e){return e==="-webkit-"?"::-webkit-file-upload-button":`::${e}file-selector-button`}};ll.names=["::file-selector-button"];Dg.exports=ll});var de=v((K4,qg)=>{l();qg.exports=function(i){let e;return i==="-webkit- 2009"||i==="-moz-"?e=2009:i==="-ms-"?e=2012:i==="-webkit-"&&(e="final"),i==="-webkit- 2009"&&(i="-webkit-"),[e,i]}});var Fg=v((Z4,Bg)=>{l();var Rg=me().list,Mg=de(),GA=R(),Ht=class extends GA{prefixed(e,t){let r;return[r,t]=Mg(t),r===2009?t+"box-flex":super.prefixed(e,t)}normalize(){return"flex"}set(e,t){let r=Mg(t)[0];if(r===2009)return e.value=Rg.space(e.value)[0],e.value=Ht.oldValues[e.value]||e.value,super.set(e,t);if(r===2012){let n=Rg.space(e.value);n.length===3&&n[2]==="0"&&(e.value=n.slice(0,2).concat("0px").join(" "))}return super.set(e,t)}};Ht.names=["flex","box-flex"];Ht.oldValues={auto:"1",none:"0"};Bg.exports=Ht});var $g=v((eq,Lg)=>{l();var Ng=de(),HA=R(),ul=class extends HA{prefixed(e,t){let r;return[r,t]=Ng(t),r===2009?t+"box-ordinal-group":r===2012?t+"flex-order":super.prefixed(e,t)}normalize(){return"order"}set(e,t){return Ng(t)[0]===2009&&/\d/.test(e.value)?(e.value=(parseInt(e.value)+1).toString(),super.set(e,t)):super.set(e,t)}};ul.names=["order","flex-order","box-ordinal-group"];Lg.exports=ul});var zg=v((tq,jg)=>{l();var YA=R(),fl=class extends YA{check(e){let t=e.value;return!t.toLowerCase().includes("alpha(")&&!t.includes("DXImageTransform.Microsoft")&&!t.includes("data:image/svg+xml")}};fl.names=["filter"];jg.exports=fl});var Ug=v((rq,Vg)=>{l();var QA=R(),cl=class extends QA{insert(e,t,r,n){if(t!=="-ms-")return super.insert(e,t,r);let a=this.clone(e),s=e.prop.replace(/end$/,"start"),o=t+e.prop.replace(/end$/,"span");if(!e.parent.some(u=>u.prop===o)){if(a.prop=o,e.value.includes("span"))a.value=e.value.replace(/span\s/i,"");else{let u;if(e.parent.walkDecls(s,c=>{u=c}),u){let c=Number(e.value)-Number(u.value)+"";a.value=c}else e.warn(n,`Can not prefix ${e.prop} (${s} is not found)`)}e.cloneBefore(a)}}};cl.names=["grid-row-end","grid-column-end"];Vg.exports=cl});var Gg=v((iq,Wg)=>{l();var JA=R(),pl=class extends JA{check(e){return!e.value.split(/\s+/).some(t=>{let r=t.toLowerCase();return r==="reverse"||r==="alternate-reverse"})}};pl.names=["animation","animation-direction"];Wg.exports=pl});var Yg=v((nq,Hg)=>{l();var XA=de(),KA=R(),dl=class extends KA{insert(e,t,r){let n;if([n,t]=XA(t),n!==2009)return super.insert(e,t,r);let a=e.value.split(/\s+/).filter(p=>p!=="wrap"&&p!=="nowrap"&&"wrap-reverse");if(a.length===0||e.parent.some(p=>p.prop===t+"box-orient"||p.prop===t+"box-direction"))return;let o=a[0],u=o.includes("row")?"horizontal":"vertical",c=o.includes("reverse")?"reverse":"normal",f=this.clone(e);return f.prop=t+"box-orient",f.value=u,this.needCascade(e)&&(f.raws.before=this.calcBefore(r,e,t)),e.parent.insertBefore(e,f),f=this.clone(e),f.prop=t+"box-direction",f.value=c,this.needCascade(e)&&(f.raws.before=this.calcBefore(r,e,t)),e.parent.insertBefore(e,f)}};dl.names=["flex-flow","box-direction","box-orient"];Hg.exports=dl});var Jg=v((sq,Qg)=>{l();var ZA=de(),e_=R(),hl=class extends e_{normalize(){return"flex"}prefixed(e,t){let r;return[r,t]=ZA(t),r===2009?t+"box-flex":r===2012?t+"flex-positive":super.prefixed(e,t)}};hl.names=["flex-grow","flex-positive"];Qg.exports=hl});var Kg=v((aq,Xg)=>{l();var t_=de(),r_=R(),ml=class extends r_{set(e,t){if(t_(t)[0]!==2009)return super.set(e,t)}};ml.names=["flex-wrap"];Xg.exports=ml});var ey=v((oq,Zg)=>{l();var i_=R(),Yt=dt(),gl=class extends i_{insert(e,t,r,n){if(t!=="-ms-")return super.insert(e,t,r);let a=Yt.parse(e),[s,o]=Yt.translate(a,0,2),[u,c]=Yt.translate(a,1,3);[["grid-row",s],["grid-row-span",o],["grid-column",u],["grid-column-span",c]].forEach(([f,p])=>{Yt.insertDecl(e,f,p)}),Yt.warnTemplateSelectorNotFound(e,n),Yt.warnIfGridRowColumnExists(e,n)}};gl.names=["grid-area"];Zg.exports=gl});var ry=v((lq,ty)=>{l();var n_=R(),ni=dt(),yl=class extends n_{insert(e,t,r){if(t!=="-ms-")return super.insert(e,t,r);if(e.parent.some(s=>s.prop==="-ms-grid-row-align"))return;let[[n,a]]=ni.parse(e);a?(ni.insertDecl(e,"grid-row-align",n),ni.insertDecl(e,"grid-column-align",a)):(ni.insertDecl(e,"grid-row-align",n),ni.insertDecl(e,"grid-column-align",n))}};yl.names=["place-self"];ty.exports=yl});var ny=v((uq,iy)=>{l();var s_=R(),wl=class extends s_{check(e){let t=e.value;return!t.includes("/")||t.includes("span")}normalize(e){return e.replace("-start","")}prefixed(e,t){let r=super.prefixed(e,t);return t==="-ms-"&&(r=r.replace("-start","")),r}};wl.names=["grid-row-start","grid-column-start"];iy.exports=wl});var oy=v((fq,ay)=>{l();var sy=de(),a_=R(),Qt=class extends a_{check(e){return e.parent&&!e.parent.some(t=>t.prop&&t.prop.startsWith("grid-"))}prefixed(e,t){let r;return[r,t]=sy(t),r===2012?t+"flex-item-align":super.prefixed(e,t)}normalize(){return"align-self"}set(e,t){let r=sy(t)[0];if(r===2012)return e.value=Qt.oldValues[e.value]||e.value,super.set(e,t);if(r==="final")return super.set(e,t)}};Qt.names=["align-self","flex-item-align"];Qt.oldValues={"flex-end":"end","flex-start":"start"};ay.exports=Qt});var uy=v((cq,ly)=>{l();var o_=R(),l_=ue(),bl=class extends o_{constructor(e,t,r){super(e,t,r);this.prefixes&&(this.prefixes=l_.uniq(this.prefixes.map(n=>n==="-ms-"?"-webkit-":n)))}};bl.names=["appearance"];ly.exports=bl});var py=v((pq,cy)=>{l();var fy=de(),u_=R(),vl=class extends u_{normalize(){return"flex-basis"}prefixed(e,t){let r;return[r,t]=fy(t),r===2012?t+"flex-preferred-size":super.prefixed(e,t)}set(e,t){let r;if([r,t]=fy(t),r===2012||r==="final")return super.set(e,t)}};vl.names=["flex-basis","flex-preferred-size"];cy.exports=vl});var hy=v((dq,dy)=>{l();var f_=R(),xl=class extends f_{normalize(){return this.name.replace("box-image","border")}prefixed(e,t){let r=super.prefixed(e,t);return t==="-webkit-"&&(r=r.replace("border","box-image")),r}};xl.names=["mask-border","mask-border-source","mask-border-slice","mask-border-width","mask-border-outset","mask-border-repeat","mask-box-image","mask-box-image-source","mask-box-image-slice","mask-box-image-width","mask-box-image-outset","mask-box-image-repeat"];dy.exports=xl});var gy=v((hq,my)=>{l();var c_=R(),Le=class extends c_{insert(e,t,r){let n=e.prop==="mask-composite",a;n?a=e.value.split(","):a=e.value.match(Le.regexp)||[],a=a.map(c=>c.trim()).filter(c=>c);let s=a.length,o;if(s&&(o=this.clone(e),o.value=a.map(c=>Le.oldValues[c]||c).join(", "),a.includes("intersect")&&(o.value+=", xor"),o.prop=t+"mask-composite"),n)return s?(this.needCascade(e)&&(o.raws.before=this.calcBefore(r,e,t)),e.parent.insertBefore(e,o)):void 0;let u=this.clone(e);return u.prop=t+u.prop,s&&(u.value=u.value.replace(Le.regexp,"")),this.needCascade(e)&&(u.raws.before=this.calcBefore(r,e,t)),e.parent.insertBefore(e,u),s?(this.needCascade(e)&&(o.raws.before=this.calcBefore(r,e,t)),e.parent.insertBefore(e,o)):e}};Le.names=["mask","mask-composite"];Le.oldValues={add:"source-over",subtract:"source-out",intersect:"source-in",exclude:"xor"};Le.regexp=new RegExp(`\\s+(${Object.keys(Le.oldValues).join("|")})\\b(?!\\))\\s*(?=[,])`,"ig");my.exports=Le});var by=v((mq,wy)=>{l();var yy=de(),p_=R(),Jt=class extends p_{prefixed(e,t){let r;return[r,t]=yy(t),r===2009?t+"box-align":r===2012?t+"flex-align":super.prefixed(e,t)}normalize(){return"align-items"}set(e,t){let r=yy(t)[0];return(r===2009||r===2012)&&(e.value=Jt.oldValues[e.value]||e.value),super.set(e,t)}};Jt.names=["align-items","flex-align","box-align"];Jt.oldValues={"flex-end":"end","flex-start":"start"};wy.exports=Jt});var xy=v((gq,vy)=>{l();var d_=R(),kl=class extends d_{set(e,t){return t==="-ms-"&&e.value==="contain"&&(e.value="element"),super.set(e,t)}insert(e,t,r){if(!(e.value==="all"&&t==="-ms-"))return super.insert(e,t,r)}};kl.names=["user-select"];vy.exports=kl});var Cy=v((yq,Sy)=>{l();var ky=de(),h_=R(),Sl=class extends h_{normalize(){return"flex-shrink"}prefixed(e,t){let r;return[r,t]=ky(t),r===2012?t+"flex-negative":super.prefixed(e,t)}set(e,t){let r;if([r,t]=ky(t),r===2012||r==="final")return super.set(e,t)}};Sl.names=["flex-shrink","flex-negative"];Sy.exports=Sl});var _y=v((wq,Ay)=>{l();var m_=R(),Cl=class extends m_{prefixed(e,t){return`${t}column-${e}`}normalize(e){return e.includes("inside")?"break-inside":e.includes("before")?"break-before":"break-after"}set(e,t){return(e.prop==="break-inside"&&e.value==="avoid-column"||e.value==="avoid-page")&&(e.value="avoid"),super.set(e,t)}insert(e,t,r){if(e.prop!=="break-inside")return super.insert(e,t,r);if(!(/region/i.test(e.value)||/page/i.test(e.value)))return super.insert(e,t,r)}};Cl.names=["break-inside","page-break-inside","column-break-inside","break-before","page-break-before","column-break-before","break-after","page-break-after","column-break-after"];Ay.exports=Cl});var Oy=v((bq,Ey)=>{l();var g_=R(),Al=class extends g_{prefixed(e,t){return t+"print-color-adjust"}normalize(){return"color-adjust"}};Al.names=["color-adjust","print-color-adjust"];Ey.exports=Al});var Py=v((vq,Ty)=>{l();var y_=R(),Xt=class extends y_{insert(e,t,r){if(t==="-ms-"){let n=this.set(this.clone(e),t);this.needCascade(e)&&(n.raws.before=this.calcBefore(r,e,t));let a="ltr";return e.parent.nodes.forEach(s=>{s.prop==="direction"&&(s.value==="rtl"||s.value==="ltr")&&(a=s.value)}),n.value=Xt.msValues[a][e.value]||e.value,e.parent.insertBefore(e,n)}return super.insert(e,t,r)}};Xt.names=["writing-mode"];Xt.msValues={ltr:{"horizontal-tb":"lr-tb","vertical-rl":"tb-rl","vertical-lr":"tb-lr"},rtl:{"horizontal-tb":"rl-tb","vertical-rl":"bt-rl","vertical-lr":"bt-lr"}};Ty.exports=Xt});var Iy=v((xq,Dy)=>{l();var w_=R(),_l=class extends w_{set(e,t){return e.value=e.value.replace(/\s+fill(\s)/,"$1"),super.set(e,t)}};_l.names=["border-image"];Dy.exports=_l});var My=v((kq,Ry)=>{l();var qy=de(),b_=R(),Kt=class extends b_{prefixed(e,t){let r;return[r,t]=qy(t),r===2012?t+"flex-line-pack":super.prefixed(e,t)}normalize(){return"align-content"}set(e,t){let r=qy(t)[0];if(r===2012)return e.value=Kt.oldValues[e.value]||e.value,super.set(e,t);if(r==="final")return super.set(e,t)}};Kt.names=["align-content","flex-line-pack"];Kt.oldValues={"flex-end":"end","flex-start":"start","space-between":"justify","space-around":"distribute"};Ry.exports=Kt});var Fy=v((Sq,By)=>{l();var v_=R(),Se=class extends v_{prefixed(e,t){return t==="-moz-"?t+(Se.toMozilla[e]||e):super.prefixed(e,t)}normalize(e){return Se.toNormal[e]||e}};Se.names=["border-radius"];Se.toMozilla={};Se.toNormal={};for(let i of["top","bottom"])for(let e of["left","right"]){let t=`border-${i}-${e}-radius`,r=`border-radius-${i}${e}`;Se.names.push(t),Se.names.push(r),Se.toMozilla[t]=r,Se.toNormal[r]=t}By.exports=Se});var Ly=v((Cq,Ny)=>{l();var x_=R(),El=class extends x_{prefixed(e,t){return e.includes("-start")?t+e.replace("-block-start","-before"):t+e.replace("-block-end","-after")}normalize(e){return e.includes("-before")?e.replace("-before","-block-start"):e.replace("-after","-block-end")}};El.names=["border-block-start","border-block-end","margin-block-start","margin-block-end","padding-block-start","padding-block-end","border-before","border-after","margin-before","margin-after","padding-before","padding-after"];Ny.exports=El});var jy=v((Aq,$y)=>{l();var k_=R(),{parseTemplate:S_,warnMissedAreas:C_,getGridGap:A_,warnGridGap:__,inheritGridGap:E_}=dt(),Ol=class extends k_{insert(e,t,r,n){if(t!=="-ms-")return super.insert(e,t,r);if(e.parent.some(h=>h.prop==="-ms-grid-rows"))return;let a=A_(e),s=E_(e,a),{rows:o,columns:u,areas:c}=S_({decl:e,gap:s||a}),f=Object.keys(c).length>0,p=Boolean(o),d=Boolean(u);return __({gap:a,hasColumns:d,decl:e,result:n}),C_(c,e,n),(p&&d||f)&&e.cloneBefore({prop:"-ms-grid-rows",value:o,raws:{}}),d&&e.cloneBefore({prop:"-ms-grid-columns",value:u,raws:{}}),e}};Ol.names=["grid-template"];$y.exports=Ol});var Vy=v((_q,zy)=>{l();var O_=R(),Tl=class extends O_{prefixed(e,t){return t+e.replace("-inline","")}normalize(e){return e.replace(/(margin|padding|border)-(start|end)/,"$1-inline-$2")}};Tl.names=["border-inline-start","border-inline-end","margin-inline-start","margin-inline-end","padding-inline-start","padding-inline-end","border-start","border-end","margin-start","margin-end","padding-start","padding-end"];zy.exports=Tl});var Wy=v((Eq,Uy)=>{l();var T_=R(),Pl=class extends T_{check(e){return!e.value.includes("flex-")&&e.value!=="baseline"}prefixed(e,t){return t+"grid-row-align"}normalize(){return"align-self"}};Pl.names=["grid-row-align"];Uy.exports=Pl});var Hy=v((Oq,Gy)=>{l();var P_=R(),Zt=class extends P_{keyframeParents(e){let{parent:t}=e;for(;t;){if(t.type==="atrule"&&t.name==="keyframes")return!0;({parent:t}=t)}return!1}contain3d(e){if(e.prop==="transform-origin")return!1;for(let t of Zt.functions3d)if(e.value.includes(`${t}(`))return!0;return!1}set(e,t){return e=super.set(e,t),t==="-ms-"&&(e.value=e.value.replace(/rotatez/gi,"rotate")),e}insert(e,t,r){if(t==="-ms-"){if(!this.contain3d(e)&&!this.keyframeParents(e))return super.insert(e,t,r)}else if(t==="-o-"){if(!this.contain3d(e))return super.insert(e,t,r)}else return super.insert(e,t,r)}};Zt.names=["transform","transform-origin"];Zt.functions3d=["matrix3d","translate3d","translateZ","scale3d","scaleZ","rotate3d","rotateX","rotateY","perspective"];Gy.exports=Zt});var Jy=v((Tq,Qy)=>{l();var Yy=de(),D_=R(),Dl=class extends D_{normalize(){return"flex-direction"}insert(e,t,r){let n;if([n,t]=Yy(t),n!==2009)return super.insert(e,t,r);if(e.parent.some(f=>f.prop===t+"box-orient"||f.prop===t+"box-direction"))return;let s=e.value,o,u;s==="inherit"||s==="initial"||s==="unset"?(o=s,u=s):(o=s.includes("row")?"horizontal":"vertical",u=s.includes("reverse")?"reverse":"normal");let c=this.clone(e);return c.prop=t+"box-orient",c.value=o,this.needCascade(e)&&(c.raws.before=this.calcBefore(r,e,t)),e.parent.insertBefore(e,c),c=this.clone(e),c.prop=t+"box-direction",c.value=u,this.needCascade(e)&&(c.raws.before=this.calcBefore(r,e,t)),e.parent.insertBefore(e,c)}old(e,t){let r;return[r,t]=Yy(t),r===2009?[t+"box-orient",t+"box-direction"]:super.old(e,t)}};Dl.names=["flex-direction","box-direction","box-orient"];Qy.exports=Dl});var Ky=v((Pq,Xy)=>{l();var I_=R(),Il=class extends I_{check(e){return e.value==="pixelated"}prefixed(e,t){return t==="-ms-"?"-ms-interpolation-mode":super.prefixed(e,t)}set(e,t){return t!=="-ms-"?super.set(e,t):(e.prop="-ms-interpolation-mode",e.value="nearest-neighbor",e)}normalize(){return"image-rendering"}process(e,t){return super.process(e,t)}};Il.names=["image-rendering","interpolation-mode"];Xy.exports=Il});var ew=v((Dq,Zy)=>{l();var q_=R(),R_=ue(),ql=class extends q_{constructor(e,t,r){super(e,t,r);this.prefixes&&(this.prefixes=R_.uniq(this.prefixes.map(n=>n==="-ms-"?"-webkit-":n)))}};ql.names=["backdrop-filter"];Zy.exports=ql});var rw=v((Iq,tw)=>{l();var M_=R(),B_=ue(),Rl=class extends M_{constructor(e,t,r){super(e,t,r);this.prefixes&&(this.prefixes=B_.uniq(this.prefixes.map(n=>n==="-ms-"?"-webkit-":n)))}check(e){return e.value.toLowerCase()==="text"}};Rl.names=["background-clip"];tw.exports=Rl});var nw=v((qq,iw)=>{l();var F_=R(),N_=["none","underline","overline","line-through","blink","inherit","initial","unset"],Ml=class extends F_{check(e){return e.value.split(/\s+/).some(t=>!N_.includes(t))}};Ml.names=["text-decoration"];iw.exports=Ml});var ow=v((Rq,aw)=>{l();var sw=de(),L_=R(),er=class extends L_{prefixed(e,t){let r;return[r,t]=sw(t),r===2009?t+"box-pack":r===2012?t+"flex-pack":super.prefixed(e,t)}normalize(){return"justify-content"}set(e,t){let r=sw(t)[0];if(r===2009||r===2012){let n=er.oldValues[e.value]||e.value;if(e.value=n,r!==2009||n!=="distribute")return super.set(e,t)}else if(r==="final")return super.set(e,t)}};er.names=["justify-content","flex-pack","box-pack"];er.oldValues={"flex-end":"end","flex-start":"start","space-between":"justify","space-around":"distribute"};aw.exports=er});var uw=v((Mq,lw)=>{l();var $_=R(),Bl=class extends $_{set(e,t){let r=e.value.toLowerCase();return t==="-webkit-"&&!r.includes(" ")&&r!=="contain"&&r!=="cover"&&(e.value=e.value+" "+e.value),super.set(e,t)}};Bl.names=["background-size"];lw.exports=Bl});var cw=v((Bq,fw)=>{l();var j_=R(),Fl=dt(),Nl=class extends j_{insert(e,t,r){if(t!=="-ms-")return super.insert(e,t,r);let n=Fl.parse(e),[a,s]=Fl.translate(n,0,1);n[0]&&n[0].includes("span")&&(s=n[0].join("").replace(/\D/g,"")),[[e.prop,a],[`${e.prop}-span`,s]].forEach(([u,c])=>{Fl.insertDecl(e,u,c)})}};Nl.names=["grid-row","grid-column"];fw.exports=Nl});var hw=v((Fq,dw)=>{l();var z_=R(),{prefixTrackProp:pw,prefixTrackValue:V_,autoplaceGridItems:U_,getGridGap:W_,inheritGridGap:G_}=dt(),H_=il(),Ll=class extends z_{prefixed(e,t){return t==="-ms-"?pw({prop:e,prefix:t}):super.prefixed(e,t)}normalize(e){return e.replace(/^grid-(rows|columns)/,"grid-template-$1")}insert(e,t,r,n){if(t!=="-ms-")return super.insert(e,t,r);let{parent:a,prop:s,value:o}=e,u=s.includes("rows"),c=s.includes("columns"),f=a.some(k=>k.prop==="grid-template"||k.prop==="grid-template-areas");if(f&&u)return!1;let p=new H_({options:{}}),d=p.gridStatus(a,n),h=W_(e);h=G_(e,h)||h;let y=u?h.row:h.column;(d==="no-autoplace"||d===!0)&&!f&&(y=null);let x=V_({value:o,gap:y});e.cloneBefore({prop:pw({prop:s,prefix:t}),value:x});let w=a.nodes.find(k=>k.prop==="grid-auto-flow"),b="row";if(w&&!p.disabled(w,n)&&(b=w.value.trim()),d==="autoplace"){let k=a.nodes.find(_=>_.prop==="grid-template-rows");if(!k&&f)return;if(!k&&!f){e.warn(n,"Autoplacement does not work without grid-template-rows property");return}!a.nodes.find(_=>_.prop==="grid-template-columns")&&!f&&e.warn(n,"Autoplacement does not work without grid-template-columns property"),c&&!f&&U_(e,n,h,b)}}};Ll.names=["grid-template-rows","grid-template-columns","grid-rows","grid-columns"];dw.exports=Ll});var gw=v((Nq,mw)=>{l();var Y_=R(),$l=class extends Y_{check(e){return!e.value.includes("flex-")&&e.value!=="baseline"}prefixed(e,t){return t+"grid-column-align"}normalize(){return"justify-self"}};$l.names=["grid-column-align"];mw.exports=$l});var ww=v((Lq,yw)=>{l();var Q_=R(),jl=class extends Q_{prefixed(e,t){return t+"scroll-chaining"}normalize(){return"overscroll-behavior"}set(e,t){return e.value==="auto"?e.value="chained":(e.value==="none"||e.value==="contain")&&(e.value="none"),super.set(e,t)}};jl.names=["overscroll-behavior","scroll-chaining"];yw.exports=jl});var xw=v(($q,vw)=>{l();var J_=R(),{parseGridAreas:X_,warnMissedAreas:K_,prefixTrackProp:Z_,prefixTrackValue:bw,getGridGap:eE,warnGridGap:tE,inheritGridGap:rE}=dt();function iE(i){return i.trim().slice(1,-1).split(/["']\s*["']?/g)}var zl=class extends J_{insert(e,t,r,n){if(t!=="-ms-")return super.insert(e,t,r);let a=!1,s=!1,o=e.parent,u=eE(e);u=rE(e,u)||u,o.walkDecls(/-ms-grid-rows/,p=>p.remove()),o.walkDecls(/grid-template-(rows|columns)/,p=>{if(p.prop==="grid-template-rows"){s=!0;let{prop:d,value:h}=p;p.cloneBefore({prop:Z_({prop:d,prefix:t}),value:bw({value:h,gap:u.row})})}else a=!0});let c=iE(e.value);a&&!s&&u.row&&c.length>1&&e.cloneBefore({prop:"-ms-grid-rows",value:bw({value:`repeat(${c.length}, auto)`,gap:u.row}),raws:{}}),tE({gap:u,hasColumns:a,decl:e,result:n});let f=X_({rows:c,gap:u});return K_(f,e,n),e}};zl.names=["grid-template-areas"];vw.exports=zl});var Sw=v((jq,kw)=>{l();var nE=R(),Vl=class extends nE{set(e,t){return t==="-webkit-"&&(e.value=e.value.replace(/\s*(right|left)\s*/i,"")),super.set(e,t)}};Vl.names=["text-emphasis-position"];kw.exports=Vl});var Aw=v((zq,Cw)=>{l();var sE=R(),Ul=class extends sE{set(e,t){return e.prop==="text-decoration-skip-ink"&&e.value==="auto"?(e.prop=t+"text-decoration-skip",e.value="ink",e):super.set(e,t)}};Ul.names=["text-decoration-skip-ink","text-decoration-skip"];Cw.exports=Ul});var Dw=v((Vq,Pw)=>{l();"use strict";Pw.exports={wrap:_w,limit:Ew,validate:Ow,test:Wl,curry:aE,name:Tw};function _w(i,e,t){var r=e-i;return((t-i)%r+r)%r+i}function Ew(i,e,t){return Math.max(i,Math.min(e,t))}function Ow(i,e,t,r,n){if(!Wl(i,e,t,r,n))throw new Error(t+" is outside of range ["+i+","+e+")");return t}function Wl(i,e,t,r,n){return!(te||n&&t===e||r&&t===i)}function Tw(i,e,t,r){return(t?"(":"[")+i+","+e+(r?")":"]")}function aE(i,e,t,r){var n=Tw.bind(null,i,e,t,r);return{wrap:_w.bind(null,i,e),limit:Ew.bind(null,i,e),validate:function(a){return Ow(i,e,a,t,r)},test:function(a){return Wl(i,e,a,t,r)},toString:n,name:n}}});var Rw=v((Uq,qw)=>{l();var Gl=Yn(),oE=Dw(),lE=Wt(),uE=ke(),fE=ue(),Iw=/top|left|right|bottom/gi,Qe=class extends uE{replace(e,t){let r=Gl(e);for(let n of r.nodes)if(n.type==="function"&&n.value===this.name)if(n.nodes=this.newDirection(n.nodes),n.nodes=this.normalize(n.nodes),t==="-webkit- old"){if(!this.oldWebkit(n))return!1}else n.nodes=this.convertDirection(n.nodes),n.value=t+n.value;return r.toString()}replaceFirst(e,...t){return t.map(n=>n===" "?{type:"space",value:n}:{type:"word",value:n}).concat(e.slice(1))}normalizeUnit(e,t){return`${parseFloat(e)/t*360}deg`}normalize(e){if(!e[0])return e;if(/-?\d+(.\d+)?grad/.test(e[0].value))e[0].value=this.normalizeUnit(e[0].value,400);else if(/-?\d+(.\d+)?rad/.test(e[0].value))e[0].value=this.normalizeUnit(e[0].value,2*Math.PI);else if(/-?\d+(.\d+)?turn/.test(e[0].value))e[0].value=this.normalizeUnit(e[0].value,1);else if(e[0].value.includes("deg")){let t=parseFloat(e[0].value);t=oE.wrap(0,360,t),e[0].value=`${t}deg`}return e[0].value==="0deg"?e=this.replaceFirst(e,"to"," ","top"):e[0].value==="90deg"?e=this.replaceFirst(e,"to"," ","right"):e[0].value==="180deg"?e=this.replaceFirst(e,"to"," ","bottom"):e[0].value==="270deg"&&(e=this.replaceFirst(e,"to"," ","left")),e}newDirection(e){if(e[0].value==="to"||(Iw.lastIndex=0,!Iw.test(e[0].value)))return e;e.unshift({type:"word",value:"to"},{type:"space",value:" "});for(let t=2;t0&&(e[0].value==="to"?this.fixDirection(e):e[0].value.includes("deg")?this.fixAngle(e):this.isRadial(e)&&this.fixRadial(e)),e}fixDirection(e){e.splice(0,2);for(let t of e){if(t.type==="div")break;t.type==="word"&&(t.value=this.revertDirection(t.value))}}fixAngle(e){let t=e[0].value;t=parseFloat(t),t=Math.abs(450-t)%360,t=this.roundFloat(t,3),e[0].value=`${t}deg`}fixRadial(e){let t=[],r=[],n,a,s,o,u;for(o=0;o{l();var cE=Wt(),pE=ke();function Mw(i){return new RegExp(`(^|[\\s,(])(${i}($|[\\s),]))`,"gi")}var Hl=class extends pE{regexp(){return this.regexpCache||(this.regexpCache=Mw(this.name)),this.regexpCache}isStretch(){return this.name==="stretch"||this.name==="fill"||this.name==="fill-available"}replace(e,t){return t==="-moz-"&&this.isStretch()?e.replace(this.regexp(),"$1-moz-available$3"):t==="-webkit-"&&this.isStretch()?e.replace(this.regexp(),"$1-webkit-fill-available$3"):super.replace(e,t)}old(e){let t=e+this.name;return this.isStretch()&&(e==="-moz-"?t="-moz-available":e==="-webkit-"&&(t="-webkit-fill-available")),new cE(this.name,t,t,Mw(t))}add(e,t){if(!(e.prop.includes("grid")&&t!=="-webkit-"))return super.add(e,t)}};Hl.names=["max-content","min-content","fit-content","fill","fill-available","stretch"];Bw.exports=Hl});var $w=v((Gq,Lw)=>{l();var Nw=Wt(),dE=ke(),Yl=class extends dE{replace(e,t){return t==="-webkit-"?e.replace(this.regexp(),"$1-webkit-optimize-contrast"):t==="-moz-"?e.replace(this.regexp(),"$1-moz-crisp-edges"):super.replace(e,t)}old(e){return e==="-webkit-"?new Nw(this.name,"-webkit-optimize-contrast"):e==="-moz-"?new Nw(this.name,"-moz-crisp-edges"):super.old(e)}};Yl.names=["pixelated"];Lw.exports=Yl});var zw=v((Hq,jw)=>{l();var hE=ke(),Ql=class extends hE{replace(e,t){let r=super.replace(e,t);return t==="-webkit-"&&(r=r.replace(/("[^"]+"|'[^']+')(\s+\d+\w)/gi,"url($1)$2")),r}};Ql.names=["image-set"];jw.exports=Ql});var Uw=v((Yq,Vw)=>{l();var mE=me().list,gE=ke(),Jl=class extends gE{replace(e,t){return mE.space(e).map(r=>{if(r.slice(0,+this.name.length+1)!==this.name+"(")return r;let n=r.lastIndexOf(")"),a=r.slice(n+1),s=r.slice(this.name.length+1,n);if(t==="-webkit-"){let o=s.match(/\d*.?\d+%?/);o?(s=s.slice(o[0].length).trim(),s+=`, ${o[0]}`):s+=", 0.5"}return t+this.name+"("+s+")"+a}).join(" ")}};Jl.names=["cross-fade"];Vw.exports=Jl});var Gw=v((Qq,Ww)=>{l();var yE=de(),wE=Wt(),bE=ke(),Xl=class extends bE{constructor(e,t){super(e,t);e==="display-flex"&&(this.name="flex")}check(e){return e.prop==="display"&&e.value===this.name}prefixed(e){let t,r;return[t,e]=yE(e),t===2009?this.name==="flex"?r="box":r="inline-box":t===2012?this.name==="flex"?r="flexbox":r="inline-flexbox":t==="final"&&(r=this.name),e+r}replace(e,t){return this.prefixed(t)}old(e){let t=this.prefixed(e);if(!!t)return new wE(this.name,t)}};Xl.names=["display-flex","inline-flex"];Ww.exports=Xl});var Yw=v((Jq,Hw)=>{l();var vE=ke(),Kl=class extends vE{constructor(e,t){super(e,t);e==="display-grid"&&(this.name="grid")}check(e){return e.prop==="display"&&e.value===this.name}};Kl.names=["display-grid","inline-grid"];Hw.exports=Kl});var Jw=v((Xq,Qw)=>{l();var xE=ke(),Zl=class extends xE{constructor(e,t){super(e,t);e==="filter-function"&&(this.name="filter")}};Zl.names=["filter","filter-function"];Qw.exports=Zl});var eb=v((Kq,Zw)=>{l();var Xw=ii(),M=R(),Kw=qm(),kE=Xm(),SE=il(),CE=gg(),eu=ct(),tr=Gt(),AE=Cg(),$e=ke(),rr=ue(),_E=_g(),EE=Og(),OE=Pg(),TE=Ig(),PE=Fg(),DE=$g(),IE=zg(),qE=Ug(),RE=Gg(),ME=Yg(),BE=Jg(),FE=Kg(),NE=ey(),LE=ry(),$E=ny(),jE=oy(),zE=uy(),VE=py(),UE=hy(),WE=gy(),GE=by(),HE=xy(),YE=Cy(),QE=_y(),JE=Oy(),XE=Py(),KE=Iy(),ZE=My(),e5=Fy(),t5=Ly(),r5=jy(),i5=Vy(),n5=Wy(),s5=Hy(),a5=Jy(),o5=Ky(),l5=ew(),u5=rw(),f5=nw(),c5=ow(),p5=uw(),d5=cw(),h5=hw(),m5=gw(),g5=ww(),y5=xw(),w5=Sw(),b5=Aw(),v5=Rw(),x5=Fw(),k5=$w(),S5=zw(),C5=Uw(),A5=Gw(),_5=Yw(),E5=Jw();tr.hack(_E);tr.hack(EE);tr.hack(OE);tr.hack(TE);M.hack(PE);M.hack(DE);M.hack(IE);M.hack(qE);M.hack(RE);M.hack(ME);M.hack(BE);M.hack(FE);M.hack(NE);M.hack(LE);M.hack($E);M.hack(jE);M.hack(zE);M.hack(VE);M.hack(UE);M.hack(WE);M.hack(GE);M.hack(HE);M.hack(YE);M.hack(QE);M.hack(JE);M.hack(XE);M.hack(KE);M.hack(ZE);M.hack(e5);M.hack(t5);M.hack(r5);M.hack(i5);M.hack(n5);M.hack(s5);M.hack(a5);M.hack(o5);M.hack(l5);M.hack(u5);M.hack(f5);M.hack(c5);M.hack(p5);M.hack(d5);M.hack(h5);M.hack(m5);M.hack(g5);M.hack(y5);M.hack(w5);M.hack(b5);$e.hack(v5);$e.hack(x5);$e.hack(k5);$e.hack(S5);$e.hack(C5);$e.hack(A5);$e.hack(_5);$e.hack(E5);var tu=new Map,si=class{constructor(e,t,r={}){this.data=e,this.browsers=t,this.options=r,[this.add,this.remove]=this.preprocess(this.select(this.data)),this.transition=new kE(this),this.processor=new SE(this)}cleaner(){if(this.cleanerCache)return this.cleanerCache;if(this.browsers.selected.length){let e=new eu(this.browsers.data,[]);this.cleanerCache=new si(this.data,e,this.options)}else return this;return this.cleanerCache}select(e){let t={add:{},remove:{}};for(let r in e){let n=e[r],a=n.browsers.map(u=>{let c=u.split(" ");return{browser:`${c[0]} ${c[1]}`,note:c[2]}}),s=a.filter(u=>u.note).map(u=>`${this.browsers.prefix(u.browser)} ${u.note}`);s=rr.uniq(s),a=a.filter(u=>this.browsers.isSelected(u.browser)).map(u=>{let c=this.browsers.prefix(u.browser);return u.note?`${c} ${u.note}`:c}),a=this.sort(rr.uniq(a)),this.options.flexbox==="no-2009"&&(a=a.filter(u=>!u.includes("2009")));let o=n.browsers.map(u=>this.browsers.prefix(u));n.mistakes&&(o=o.concat(n.mistakes)),o=o.concat(s),o=rr.uniq(o),a.length?(t.add[r]=a,a.length!a.includes(u)))):t.remove[r]=o}return t}sort(e){return e.sort((t,r)=>{let n=rr.removeNote(t).length,a=rr.removeNote(r).length;return n===a?r.length-t.length:a-n})}preprocess(e){let t={selectors:[],"@supports":new CE(si,this)};for(let n in e.add){let a=e.add[n];if(n==="@keyframes"||n==="@viewport")t[n]=new AE(n,a,this);else if(n==="@resolution")t[n]=new Kw(n,a,this);else if(this.data[n].selector)t.selectors.push(tr.load(n,a,this));else{let s=this.data[n].props;if(s){let o=$e.load(n,a,this);for(let u of s)t[u]||(t[u]={values:[]}),t[u].values.push(o)}else{let o=t[n]&&t[n].values||[];t[n]=M.load(n,a,this),t[n].values=o}}}let r={selectors:[]};for(let n in e.remove){let a=e.remove[n];if(this.data[n].selector){let s=tr.load(n,a);for(let o of a)r.selectors.push(s.old(o))}else if(n==="@keyframes"||n==="@viewport")for(let s of a){let o=`@${s}${n.slice(1)}`;r[o]={remove:!0}}else if(n==="@resolution")r[n]=new Kw(n,a,this);else{let s=this.data[n].props;if(s){let o=$e.load(n,[],this);for(let u of a){let c=o.old(u);if(c)for(let f of s)r[f]||(r[f]={}),r[f].values||(r[f].values=[]),r[f].values.push(c)}}else for(let o of a){let u=this.decl(n).old(n,o);if(n==="align-self"){let c=t[n]&&t[n].prefixes;if(c){if(o==="-webkit- 2009"&&c.includes("-webkit-"))continue;if(o==="-webkit-"&&c.includes("-webkit- 2009"))continue}}for(let c of u)r[c]||(r[c]={}),r[c].remove=!0}}}return[t,r]}decl(e){return tu.has(e)||tu.set(e,M.load(e)),tu.get(e)}unprefixed(e){let t=this.normalize(Xw.unprefixed(e));return t==="flex-direction"&&(t="flex-flow"),t}normalize(e){return this.decl(e).normalize(e)}prefixed(e,t){return e=Xw.unprefixed(e),this.decl(e).prefixed(e,t)}values(e,t){let r=this[e],n=r["*"]&&r["*"].values,a=r[t]&&r[t].values;return n&&a?rr.uniq(n.concat(a)):n||a||[]}group(e){let t=e.parent,r=t.index(e),{length:n}=t.nodes,a=this.unprefixed(e.prop),s=(o,u)=>{for(r+=o;r>=0&&r{l();tb.exports={"backdrop-filter":{feature:"css-backdrop-filter",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5","safari 16.5"]},element:{props:["background","background-image","border-image","mask","list-style","list-style-image","content","mask-image"],feature:"css-element-function",browsers:["firefox 114"]},"user-select":{mistakes:["-khtml-"],feature:"user-select-none",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5","safari 16.5"]},"background-clip":{feature:"background-clip-text",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},hyphens:{feature:"css-hyphens",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5","safari 16.5"]},fill:{props:["width","min-width","max-width","height","min-height","max-height","inline-size","min-inline-size","max-inline-size","block-size","min-block-size","max-block-size","grid","grid-template","grid-template-rows","grid-template-columns","grid-auto-columns","grid-auto-rows"],feature:"intrinsic-width",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"fill-available":{props:["width","min-width","max-width","height","min-height","max-height","inline-size","min-inline-size","max-inline-size","block-size","min-block-size","max-block-size","grid","grid-template","grid-template-rows","grid-template-columns","grid-auto-columns","grid-auto-rows"],feature:"intrinsic-width",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},stretch:{props:["width","min-width","max-width","height","min-height","max-height","inline-size","min-inline-size","max-inline-size","block-size","min-block-size","max-block-size","grid","grid-template","grid-template-rows","grid-template-columns","grid-auto-columns","grid-auto-rows"],feature:"intrinsic-width",browsers:["firefox 114"]},"fit-content":{props:["width","min-width","max-width","height","min-height","max-height","inline-size","min-inline-size","max-inline-size","block-size","min-block-size","max-block-size","grid","grid-template","grid-template-rows","grid-template-columns","grid-auto-columns","grid-auto-rows"],feature:"intrinsic-width",browsers:["firefox 114"]},"text-decoration-style":{feature:"text-decoration",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5"]},"text-decoration-color":{feature:"text-decoration",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5"]},"text-decoration-line":{feature:"text-decoration",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5"]},"text-decoration":{feature:"text-decoration",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5"]},"text-decoration-skip":{feature:"text-decoration",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5"]},"text-decoration-skip-ink":{feature:"text-decoration",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5"]},"text-size-adjust":{feature:"text-size-adjust",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5"]},"mask-clip":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-composite":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-image":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-origin":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-repeat":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-border-repeat":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-border-source":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},mask:{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-position":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-size":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-border":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-border-outset":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-border-width":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"mask-border-slice":{feature:"css-masks",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},"clip-path":{feature:"css-clip-path",browsers:["samsung 21"]},"box-decoration-break":{feature:"css-boxdecorationbreak",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5","opera 99","safari 16.5","samsung 21"]},appearance:{feature:"css-appearance",browsers:["samsung 21"]},"image-set":{props:["background","background-image","border-image","cursor","mask","mask-image","list-style","list-style-image","content"],feature:"css-image-set",browsers:["and_uc 15.5","chrome 109","samsung 21"]},"cross-fade":{props:["background","background-image","border-image","mask","list-style","list-style-image","content","mask-image"],feature:"css-cross-fade",browsers:["and_chr 114","and_uc 15.5","chrome 109","chrome 113","chrome 114","edge 114","opera 99","samsung 21"]},isolate:{props:["unicode-bidi"],feature:"css-unicode-bidi",browsers:["ios_saf 16.1","ios_saf 16.3","ios_saf 16.4","ios_saf 16.5","safari 16.5"]},"color-adjust":{feature:"css-color-adjust",browsers:["chrome 109","chrome 113","chrome 114","edge 114","opera 99"]}}});var nb=v((e6,ib)=>{l();ib.exports={}});var lb=v((t6,ob)=>{l();var O5=Wo(),{agents:T5}=(zn(),jn),ru=bm(),P5=ct(),D5=eb(),I5=rb(),q5=nb(),sb={browsers:T5,prefixes:I5},ab=` + Replace Autoprefixer \`browsers\` option to Browserslist config. + Use \`browserslist\` key in \`package.json\` or \`.browserslistrc\` file. + + Using \`browsers\` option can cause errors. Browserslist config can + be used for Babel, Autoprefixer, postcss-normalize and other tools. + + If you really need to use option, rename it to \`overrideBrowserslist\`. + + Learn more at: + https://github.com/browserslist/browserslist#readme + https://twitter.com/browserslist + +`;function R5(i){return Object.prototype.toString.apply(i)==="[object Object]"}var iu=new Map;function M5(i,e){e.browsers.selected.length!==0&&(e.add.selectors.length>0||Object.keys(e.add).length>2||i.warn(`Autoprefixer target browsers do not need any prefixes.You do not need Autoprefixer anymore. +Check your Browserslist config to be sure that your targets are set up correctly. + + Learn more at: + https://github.com/postcss/autoprefixer#readme + https://github.com/browserslist/browserslist#readme + +`))}ob.exports=ir;function ir(...i){let e;if(i.length===1&&R5(i[0])?(e=i[0],i=void 0):i.length===0||i.length===1&&!i[0]?i=void 0:i.length<=2&&(Array.isArray(i[0])||!i[0])?(e=i[1],i=i[0]):typeof i[i.length-1]=="object"&&(e=i.pop()),e||(e={}),e.browser)throw new Error("Change `browser` option to `overrideBrowserslist` in Autoprefixer");if(e.browserslist)throw new Error("Change `browserslist` option to `overrideBrowserslist` in Autoprefixer");e.overrideBrowserslist?i=e.overrideBrowserslist:e.browsers&&(typeof console!="undefined"&&console.warn&&(ru.red?console.warn(ru.red(ab.replace(/`[^`]+`/g,n=>ru.yellow(n.slice(1,-1))))):console.warn(ab)),i=e.browsers);let t={ignoreUnknownVersions:e.ignoreUnknownVersions,stats:e.stats,env:e.env};function r(n){let a=sb,s=new P5(a.browsers,i,n,t),o=s.selected.join(", ")+JSON.stringify(e);return iu.has(o)||iu.set(o,new D5(a.prefixes,s,e)),iu.get(o)}return{postcssPlugin:"autoprefixer",prepare(n){let a=r({from:n.opts.from,env:e.env});return{OnceExit(s){M5(n,a),e.remove!==!1&&a.processor.remove(s,n),e.add!==!1&&a.processor.add(s,n)}}},info(n){return n=n||{},n.from=n.from||m.cwd(),q5(r(n))},options:e,browsers:i}}ir.postcss=!0;ir.data=sb;ir.defaults=O5.defaults;ir.info=()=>ir().info()});var ub={};Ae(ub,{default:()=>B5});var B5,fb=C(()=>{l();B5=[]});var pb={};Ae(pb,{default:()=>F5});var cb,F5,db=C(()=>{l();hi();cb=K(bi()),F5=Ze(cb.default.theme)});var mb={};Ae(mb,{default:()=>N5});var hb,N5,gb=C(()=>{l();hi();hb=K(bi()),N5=Ze(hb.default)});l();"use strict";var L5=Je(ym()),$5=Je(me()),j5=Je(lb()),z5=Je((fb(),ub)),V5=Je((db(),pb)),U5=Je((gb(),mb)),W5=Je((ts(),ku)),G5=Je((bo(),wo)),H5=Je((gs(),rf));function Je(i){return i&&i.__esModule?i:{default:i}}console.warn("cdn.tailwindcss.com should not be used in production. To use Tailwind CSS in production, install it as a PostCSS plugin or use the Tailwind CLI: https://tailwindcss.com/docs/installation");var Qn="tailwind",nu="text/tailwindcss",yb="/template.html",vt,wb=!0,bb=0,su=new Set,au,vb="",xb=(i=!1)=>({get(e,t){return(!i||t==="config")&&typeof e[t]=="object"&&e[t]!==null?new Proxy(e[t],xb()):e[t]},set(e,t,r){return e[t]=r,(!i||t==="config")&&ou(!0),!0}});window[Qn]=new Proxy({config:{},defaultTheme:V5.default,defaultConfig:U5.default,colors:W5.default,plugin:G5.default,resolveConfig:H5.default},xb(!0));function kb(i){au.observe(i,{attributes:!0,attributeFilter:["type"],characterData:!0,subtree:!0,childList:!0})}new MutationObserver(async i=>{let e=!1;if(!au){au=new MutationObserver(async()=>await ou(!0));for(let t of document.querySelectorAll(`style[type="${nu}"]`))kb(t)}for(let t of i)for(let r of t.addedNodes)r.nodeType===1&&r.tagName==="STYLE"&&r.getAttribute("type")===nu&&(kb(r),e=!0);await ou(e)}).observe(document.documentElement,{attributes:!0,attributeFilter:["class"],childList:!0,subtree:!0});async function ou(i=!1){i&&(bb++,su.clear());let e="";for(let r of document.querySelectorAll(`style[type="${nu}"]`))e+=r.textContent;let t=new Set;for(let r of document.querySelectorAll("[class]"))for(let n of r.classList)su.has(n)||t.add(n);if(document.body&&(wb||t.size>0||e!==vb||!vt||!vt.isConnected)){for(let n of t)su.add(n);wb=!1,vb=e,self[yb]=Array.from(t).join(" ");let{css:r}=await(0,$5.default)([(0,L5.default)({...window[Qn].config,_hash:bb,content:[yb],plugins:[...z5.default,...Array.isArray(window[Qn].config.plugins)?window[Qn].config.plugins:[]]}),(0,j5.default)({remove:!1})]).process(`@tailwind base;@tailwind components;@tailwind utilities;${e}`);(!vt||!vt.isConnected)&&(vt=document.createElement("style"),document.head.append(vt)),vt.textContent=r}}})(); +/*! https://mths.be/cssesc v3.0.0 by @mathias */ \ No newline at end of file diff --git a/maixpy/static/css/theme_default/dark.css b/maixpy/static/css/theme_default/dark.css new file mode 100644 index 00000000..8b510256 --- /dev/null +++ b/maixpy/static/css/theme_default/dark.css @@ -0,0 +1,169 @@ +/** + teedoc light theme css + @author neucrack + @copyright (c) neucrack CZD666666@gmail.com with MIT License + @changes 2021.1.27 add basic attrributes + */ + + /* + use .dark class to cover light theme style + */ + +/* global template */ +.dark body { + color: #d1d1d1; + background-color: #1b1b1b; +} +.dark a { + color: #8a8a8a; +} +.dark a:visited { + color: #8a8a8a; +} +.dark code { + background-color: #2a2a2a; +} +.dark pre[class*="language-"].line-numbers > code { + background: none; + padding: 0; +} +.dark #navbar .sub_items ul { + box-shadow: 0 0 9px 0px #000000; + background-color: #232323; +} +.dark #sidebar .active > a, +.dark #navbar .active > a { + background-color: #2d2d2d; + color: #c33d45; +} +.dark #sidebar .active > a, +.dark #navbar .active > a, +.dark #navbar .active_parent > a { + background-color: #2d2d2d; +} +.dark #sidebar li > a:hover, +.dark #sidebar li.active_parent > a:hover, +.dark #navbar li > a:hover, +.dark #navbar .sub_items > a:hover { + background-color: #2d2d2d; +} +.dark #sidebar ul .active_parent > a { + background-color: #232323; +} +.dark .gutter.gutter-horizontal { + background-color: #484848; +} +.dark *::-webkit-scrollbar-track { + background: #484848; +} +.dark *::-webkit-scrollbar-thumb { + background-color: #6b6b6b; +} +.dark #article #toc { + background-color: #1b1b1b; +} +.dark #to_top { + background-color: #2d2d2d; + box-shadow: 8px 8px 20px #000000; +} +.dark #to_top:hover { + box-shadow: 8px 8px 28px #000000; +} +.dark #to_top:active { + box-shadow: 0px 0px 20px #000000; +} +.dark blockquote { + background-color: #2d2d2d; +} +.dark blockquote.spoiler { + border-left: 5px solid #FF9800; + background-color: #6e5200; + color: white; +} +.dark td { + background-color: #373737; + border: 2px solid #555555; +} +.dark th { + font-weight: 700; + background-color: #0f5943; + color: white; + border: 2px solid #006f4f; +} +.dark sup a { + background-color: #2d2d2d; +} +.dark a:hover { + background-color: #424242; +} +.dark #doc_footer { + background-color: #2d2d2d; + border-top: 1px solid #2d2d2d; +} +.dark #page_footer { + background-color: #2d2d2d; + border-top: 1px solid #2d2d2d; +} +.dark #footer a:hover { + background-color: #404040; +} +.dark #previous_next { + border-top: 1px solid #525252; +} +.dark #previous_next a { + background-color: #2d2d2d; +} + +/* google translate */ +.dark #navbar #google_translate_element .goog-te-gadget-simple { + background-color: #1b1b1b; +} +.dark #navbar #google_translate_element .goog-te-gadget-simple .goog-te-menu-value { + color: #8a8a8a; +} + +/* tabset */ +.dark .tabset { + border: 0.2em solid #4c4c4c; +} +.dark .tabset-text-container { + background-color: #212121; +} +.dark .tabset-tab-active { + background-color: #212121; +} + +/* details */ +.dark details { + border: 0.2em solid #4c4c4c; +} +.dark details > .details-content { + background-color: #212121; +} + +/* markdown */ +.dark #mermaid-1662893106119 .messageText { + fill: #6f6f6f; + stroke: #6f6f6f; +} +#mermaid-1662893106119 .loopText, #mermaid-1662893106119 .loopText>tspan { + fill: #a99b1a; + stroke: none; +} + +@media screen and (max-width: 900px) { + .dark #menu_wrapper.m_menu_fixed { + background-color: rgb(27, 27, 27, 0.9); + box-shadow: 0px 1px 10px 0px rgb(0, 0, 0, 0.32); + } + .dark #sidebar_wrapper { + background-color: #1b1b1b; + } + .dark #navbar { + display: block; + border-bottom: 1px solid #383838; + z-index: 89; + } +} + + diff --git a/maixpy/static/css/theme_default/light.css b/maixpy/static/css/theme_default/light.css new file mode 100644 index 00000000..4d56f095 --- /dev/null +++ b/maixpy/static/css/theme_default/light.css @@ -0,0 +1,1349 @@ +/** + teedoc light theme css + @author neucrack + @copyright (c) neucrack CZD666666@gmail.com with MIT License + @changes 2021.1.26 add basic attrributes + */ + +/* global template */ +body { + color: #606975; + background-color: white; + transition: 0.4s; + margin: 0; + display: flex; + flex-direction: column; + justify-content: space-between; + min-height: 100vh; + letter-spacing: 0.03em; + font-family: "Microsoft YaHei",Helvetica,"Meiryo UI","Malgun Gothic","Segoe UI","Trebuchet MS",Monaco,monospace,Tahoma,STXihei,"华文细黑",STHeiti,"Helvetica Neue","Droid Sans","wenquanyi micro hei",FreeSans,Arimo,Arial,SimSun,"宋体",Heiti,"黑体",sans-serif; +} +a { + color: #606975; + text-decoration: none; +} +a:visited { + color: #606975; +} +a:hover { + background-color: #d8d8d8; + border-radius: 5px; + transition: 0.4s; +} +h1 { + text-align: center; + font-size: 2.2em; +} +h2 { + font-size: 2em; +} +h3 { + font-size: 1.5em; +} +h4 { + font-size: 1.17em; +} +h5 { + font-size: 1em; +} +h6 { + font-size: 0.83em; +} + +p { + /* text-align: justify; */ + line-height: 2em; +} +blockquote { + border-left: 4px solid #c33d45; + margin: 0 0 1em 2px; + padding: 1px; + padding-left: 1em; + background-color: #f1f1f1; + border-radius: 0 5px 5px 0; + transition: 0.4s; +} +blockquote.spoiler { + border-left: 5px solid #FF9800; + background-color: #ffd65b; +} +*::-webkit-scrollbar { + width : 0.8rem; + height: 0.8rem; + min-width: 0.8rem; + min-height: 0.6rem; +} +#sidebar ul::-webkit-scrollbar { + width : 0.45rem; + height: 0.8rem; + min-width: 0.45rem; + min-height: 0.6rem; +} +*::-webkit-scrollbar-thumb { + border-radius : 0.6rem; + background-color: #b8b8b8; +} +*::-webkit-scrollbar-track { + background : #ededed; + border-radius: 10px; +} +sup a { + font-size: 1.1em; + background-color: #f1f1f1; + padding: 4px; + border-left: 1px solid #c33d45; + border-right: 1px solid #c33d45; +} +dl > dt { + font-weight: bold; +} +table { + border-collapse: collapse; + border-spacing: 0; + display: block; + width: 100%; + overflow: auto; + word-break: keep-all; + border-color: transparent; +} +tr { + background-color: #f1f1f1; + border-top: 1px solid #ccc; +} +td, th { + padding: 6px 13px; + transition: 0.4s; +} +th { + font-weight: 700; + color: white; + filter: brightness(110%); + border: 2px solid #c33d45; + background-color: #c33d45; +} +td { + background-color: #fbfbfb; + border: 2px solid #f1f1f1; +} +code { + background-color: #f1f1f1; + border-radius: 0.2em; + transition: 0.4s; + font-family: Menlo, Consolas, "DejaVu Sans Mono", Bitstream Vera Sans Mono, Courier New, monospace, Monaco, 'Andale Mono', 'Ubuntu Mono', "Microsoft YaHei"; + font-size: 85%; + padding: 0.2em 0.4em; + color: #c33d45; +} +pre[class*="language-"].line-numbers > code { + background: none; + padding: 0; +} +.btn, +#page_content .btn, +#content_body .btn { + color: white; + border-radius: 5px; + transition: 0.2s; + padding: 1em; + cursor: pointer; + transition: 0.2s; + background: #c33d45; + box-shadow: 1px 1px 2px 0px #c33d45; +} +.btn:hover, +#page_content .btn:hover, +#content_body .btn:hover { + background: #c33d45; + box-shadow: 1px 1px 8px 0px #c33d45; +} +.btn:visited, +#page_content .btn:visited, +#content_body .btn:visited { + color: white; +} + +/* wrapper */ +.type_doc #wrapper { + margin-top: 1.5em; +} +#wrapper { + display: flex; + flex-grow: 1; +} +#page_wrapper { + display: flex; + flex-grow: 1; + flex-direction: column; + justify-content: space-between; + text-align: center; +} + +/* page */ +#page_content { + width: 100%; + flex-grow: 1; + display: flex; + flex-direction: row; +} +#page_content > div { + flex-grow: 1; + align-self: center; +} +#page_content a { + color: #c33a3a; +} + +/* navbar */ +#navbar { + display: flex; + justify-content: start; + z-index: 100; +} +#navbar * { + display: flex; + align-items: center; +} +#navbar_menu_btn { + display: none; +} +#navbar #navbar_items { + display: flex; + flex-grow: 1; + justify-content: space-between; + padding-right: 1em; + word-break: keep-all; +} +#navbar h2 { + color: #c33d45; +} +#navbar a{ + margin: 5px; + padding: 10px 15px; + cursor: pointer; +} +#navbar a.site_title{ + padding: 0; +} +#navbar a.site_title:hover{ + background-color: transparent; +} +#navbar .site_logo { + max-height: 60px; +} +#navbar ul { + list-style: none; + padding-inline-start: 10px; +} +#navbar .sub_items { + position: relative; + display: block; +} +#navbar .sub_items > a { + margin: 5px; + padding: 10px 15px; +} +#navbar .sub_items > a:hover + ul { + visibility: visible; +} +#navbar .sub_items ul { + display: block; + position: absolute; + left: 0; + box-shadow: 0 0 9px 0px #dadada; + border-radius: 5px; + padding: 0; + width: max-content; + min-width: 100%; + background-color: white; + visibility: hidden; + margin-top: -5px; + z-index: 101; + transition: 0.2s; +} +#navbar .sub_items ul:hover { + visibility: visible; +} +#navbar .sub_items ul li { + display: block; +} + +#navbar .sub_items ul ul { + left: 100%; + top: 0; +} + + +/* sidebar */ +#sidebar_wrapper { + width: 300px; +} +/* sidebar splitter */ +.gutter_icon { + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==); + width: 3px; + height: 2em; + background-repeat: no-repeat; + position: fixed; + top: 50%; +} +.gutter { + background-color: #eee; + background-repeat: no-repeat; + background-position: 50%; + transition: 0.2s; + border-radius: 5px; + display: block; +} + +.gutter.gutter-horizontal { + /* background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg=='); */ + cursor: col-resize; +} + +#sidebar { + /* width: 300px; + min-width: 200px; + position: sticky; + top: 0; + overflow-x: hidden; */ + /* min-width: 200px; */ + /* position: sticky; */ + /* top: 0; */ + /* overflow-x: hidden; */ + display: flex; + flex-direction: column; + height: 100vh; + position: -webkit-sticky; + position: sticky; + top: 0; + padding-top: var(--ifm-navbar-height); + /* width: var(--doc-sidebar-width); */ + transition: opacity 50ms; + padding-top: 0; + z-index: 1; +} +#sidebar ul { + padding-inline-start: 20px; + display: none; +} +#sidebar > ul { + padding-inline-start: 0; + padding: .5rem; + display: block; + padding-bottom: 3em; + margin: 0; + overflow-y: auto; + overflow-x: hidden; +} +#sidebar ul .show{ + /* display: block; */ /* js instead, just reserve this item*/ +} +#sidebar ul .active_parent { + display: block; +} +#sidebar ul .active_parent > ul{ + display: block; +} +#sidebar ul.collapsed, #sidebar ul .active_parent > ul.collapsed{ + /* display: none; */ /* js instead, just reserve this item*/ +} +#sidebar ul .active_parent > a{ + background-color: #f1f1f1; + border-radius: 5px; + transition: 0.4s; +} +#sidebar li { + list-style: none; + margin: 2px 0; + position: relative; +} +#sidebar li > a { + display: flex; + justify-content: space-between; + padding: 0; + font-size: 0.9em; +} +#sidebar a:hover { + cursor: pointer; +} +#sidebar .active > a, #navbar .active > a, #navbar .active_parent > a{ + background-color: #f1f1f1; + border-radius: 5px; + color: #c33d45; + transition: 0.4s; +} +#navbar .sub_items .active > a { + transition: 0s; +} +#sidebar .active > a { + transition: 0.4s; +} +#sidebar li > a > .label { + padding: 10px; + display: inline-block; + white-space: nowrap; + width: 100%; + overflow: hidden; + text-overflow: ellipsis; +} + +#sidebar li > a:hover, +#sidebar li.active_parent > a:hover, +#navbar li > a:hover, +#navbar .sub_items > a:hover{ + background-color: #d8d8d8; + border-radius: 5px; + transition: 0.4s; +} +#sidebar .sub_indicator { + transition: transform 0.4s linear; + background: url("/maixpy/static/image/theme_default/indicator.svg"); + background-size: contain; + background-repeat: no-repeat; + background-position: center; + align-self: center; + height: 1.25rem; + width: 1.25rem; + -ms-transform: rotate(-45deg); + -moz-transform: rotate(-45deg); + -webkit-transform: rotate(-45deg); + transform: rotate(-45deg); + transition: 0.2s; +} + +#sidebar .sub_indicator:hover, +#sidebar li.no_link > a:hover > .sub_indicator, +#sidebar li.no_link > a.sub_indicator:hover, +#sidebar li.no_link > a.sub_indicator{ + height: 1.6em; + width: 1.6em; +} +#sidebar .sub_indicator_collapsed { + -ms-transform: rotate(0deg); + -moz-transform: rotate(0deg); + -webkit-transform: rotate(0deg); + transform: rotate(0deg); +} +#sidebar li.sidebar_category { + font-size: 0.9em; + color: #9e9e9e; + margin: 1em 0 0.1em 0; +} +#sidebar .tip { + position: fixed; + color: white; + left: 300px; + top: 18%; + box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.19); + border-radius: 0.2em; + padding: 1em; + display: flex; + flex-direction: column; + width: max-content; + transition: 0.4s; + visibility: hidden; + opacity: 0; + background: #c33d45; +} +#sidebar li > a:hover+.tip, #sidebar .tip:hover { + visibility: visible; + opacity: 1; +} +.blog_info > span { + margin: 0.4em; +} +.blog_tags { + text-align: center; + margin-top: 1em; +} +.blog_tags > span { + border-radius: 0.2em; + padding: 0.2em; + margin: 0.4em; + filter: brightness(120%); + border: 1px solid #c33d45; +} +#blog_list > ul { + padding-left: 0; +} +#blog_list > ul > li { + list-style: none; + box-shadow: 0px 0px 7px #00000033; + margin: 2em 1em; + padding: 2em; + border-radius: 0.4em; +} +#blog_list > ul > li a, #blog_list > ul > li a:visited { + padding: 0; + color: #c33d45; +} +html[lang^=zh] #article_content #blog_list h2:before { + content: ""; +} +#blog_list .blog_tags { + text-align: left; +} +#blog_list .blog_info { + color: #ababab; +} +#blog_list .blog_brief { + color: #828282; +} +.blog_cover { + text-align: center; + margin-top: 1em; +} +.blog_cover > img { + width: 100%; +} +#menu_wrapper { + width: 2%; +} +#menu { + background: url("/maixpy/static/image/theme_default/menu.svg"); + background-size: contain; + background-repeat: no-repeat; + background-position: center; + border-radius: 5px; + min-height: 2rem; + min-width: 2rem; + transition: 0.2s; + cursor: pointer; + position: sticky; + top: 1em; + z-index: 99; + margin-left: 0.2em; +} + +/* article */ +#article { + display: flex; + width: 98%; + margin: auto; + justify-content: space-evenly; +} +#toc_wrapper { + width: 25%; +} +#article #toc { + background-color: white; + position: sticky; + transition: 0.4s; + top: 15%; + max-height: calc(100vh - 15vh); + overflow-y: auto; +} +#article #toc a{ + padding: 0.2em 0.0em; + display: block; + font-size: 0.9em; +} +#article #toc ul, #article #toc ol { + list-style: none; + padding-left: 1.5em; +} +#article #toc > div > ul, #article #toc > div > ol { + padding-left: 1em; +} + +/* add numbers for toc */ +#toc {counter-reset: toc_l1;} +#toc #toc_content {counter-reset: toc_l2;} +#toc a.node-name--H1 { + counter-reset: toc_l2; +} +#toc a.node-name--H2 { + counter-reset: toc_l3; +} +#toc a.node-name--H1:before { + counter-increment: toc_l1; +} +#toc a.node-name--H2:before { + counter-increment: toc_l2; + content: counter(toc_l2, decimal) ".\00a0"; +} +html[lang^=zh] #toc a.node-name--H2:before { + counter-increment: toc_l2; + content: counter(toc_l2, simp-chinese-informal) "、"; +} +#toc a.node-name--H3:before { + counter-increment: toc_l3; + content: counter(toc_l2, decimal) "." counter(toc_l3, decimal) ".\00a0"; +} +.heading_no_counter #toc a.node-name--H2:before { + content: ""; +} +.heading_no_counter #toc a.node-name--H3:before { + content: ""; +} +html[lang^=zh].heading_no_counter #toc a.node-name--H2:before { + content: ""; +} +/* add numbers for titles toc*/ + + +/* article content */ +#content_wrapper { + flex-grow: 1; + justify-content: space-between; + flex-direction: column; + display: flex; + width: 65%; +} +#content_body { + max-width: 50em; + width: 90%; + display: flex; + flex-direction: column; + justify-content: space-between; + line-height: 2em; + margin: auto; +} +#content_body h1 { + line-height: initial; +} +#content_body a, #content_body a:visited { + color: #c33a3a; + padding: 0.2em; +} +#content_body a:hover { + background-color: #fde1e1; + padding: 0.2em; + border-radius: 0.2em; +} +#content_body img { + max-width: 100%; + object-fit: contain; + cursor: zoom-in; +} + +/* add numbers for titles */ +#article_content { + /* counter-reset: h2section h3section h4section; */ + min-height: 50vh; + word-break: break-word; +} +#article_content h1 { + /* counter-reset: h2section h3section h4section; */ + line-height: 1.3em; +} +#article_content h2 { + /* counter-reset: h3section h4section; */ + line-height: 1.3em; +} +/* #article_content h3 { + counter-reset: h4section; +} +#article_content h2:before +{ + counter-increment: h2section; + content: counter(h2section, upper-roman) "、"; +} +#article_content h3:before +{ + counter-increment: h3section; + content: counter(h2section, decimal) "." counter(h3section, decimal) "、"; +} +#article_content h4:before +{ + counter-increment: h4section; + content: counter(h2section, decimal) "." counter(h3section, decimal) "." counter(h4section, decimal) "、"; +} +html[lang^=zh] #article_content h2:before { + content: counter(h2section, simp-chinese-informal) "、"; +} +html[lang^=zh] #article_content h3:before { + content: counter(h2section, decimal) "." counter(h3section, decimal) "、"; +} +html[lang^=zh] #article_content h4:before { + content: counter(h2section, decimal) "." counter(h3section, decimal) "." counter(h4section, decimal) "、"; +} +.heading_no_counter #article_content h2:before { + content: ""; +} +.heading_no_counter #article_content h3:before { + content: ""; +} +.heading_no_counter #article_content h4:before { + content: ""; +} +html[lang^=zh].heading_no_counter #article_content h2:before { + content: ""; +} +html[lang^=zh].heading_no_counter #article_content h3:before { + content: ""; +} +html[lang^=zh].heading_no_counter #article_content h4:before { + content: ""; +} */ +/* add numbers for titles end*/ + +#article_head { + margin-bottom: 2em; +} +#article_tags ul { + list-style: none; + display: flex; + align-items: baseline; + justify-content: flex-end; + padding: 0 +} +#article_tags ul li{ + margin: 5px; + padding: 8px; + border-radius: 5px; + color: #ffffffcc; + font-size: 0.9em; + background-color: #c33d45; +} +#article_info { + display: flex; + flex-direction: row; + justify-content: space-between; +} +#article_info > div { + align-self: center; + display: flex; + flex-direction: row; + align-items: center; +} +#article_info > div > div { + margin: 2px; +} +#article_info #print_page { + height: 1em; + width: 1em; + cursor: pointer; + background-repeat: no-repeat; + background-size: contain; + background-image: url("/maixpy/static/image/theme_default/print.svg"); +} +#article_info>div>span { + padding: 0.2em; + color: #c33d45; +} +#source_link { + display: flex; + flex-direction: row; + justify-content: flex-end; +} + +/* cover prism.css */ + +:not(pre) > code[class*="language-"], pre[class*="language-"] { + background: #2d2d2d; + border-radius: 5px; +} +div.code-toolbar > .toolbar a, div.code-toolbar > .toolbar button, div.code-toolbar > .toolbar span { + color: #fff; + font-size: .8em; + padding: 1em; + background: #f5f2f0; + background: rgba(224, 224, 224, 0.2); + box-shadow: 0 2px 0 0 rgba(0,0,0,0.2); + border-radius: .5em; + cursor: pointer; +} +div.code-toolbar > .toolbar a:hover, div.code-toolbar > .toolbar a:focus, div.code-toolbar > .toolbar button:hover, div.code-toolbar > .toolbar button:focus, div.code-toolbar > .toolbar span:hover, div.code-toolbar > .toolbar span:focus { + color: #a9ffe0; + text-decoration: none; +} + +/* back to top button */ +/* #to_top_wrapper { +} */ +#to_top { + background: url("/maixpy/static/image/theme_default/to-top.svg"); + background-size: 2em; + background-repeat: no-repeat; + background-position: center; + align-self: flex-end; + position: sticky; + bottom: 6em; + right: 3em; + margin: 1em; + height: 3rem; + width: 3rem; + cursor: pointer; + transition: 0.4s; + z-index: 97; + border-radius: 100%; + padding: 2px; + background-color: #f1f1f1; + box-shadow: 8px 8px 20px rgba(0,0,0,0.13); +} +#to_top:hover { + background-size: 2.5em; + box-shadow: 8px 8px 20px rgba(0,0,0,0.24); +} +#to_top:active { + box-shadow: 0px 0px 20px rgba(0,0,0,0.05); +} + + +/* footer article */ +#previous_next { + min-height: 3em; + margin-top: 2em; + display: flex; + border-top: 1px solid #f1f1f1; + padding: 1em; + transition: 0.4s; + display: flex; + justify-content: space-between; +} +#previous_next > div { + margin: 1em; +} +#previous_next a{ + padding: 1em; + border-radius: 5px; + display: flex; + align-items: center; + background-color: #f1f1f1; + justify-content: flex-start; +} +#previous_next a:hover { + background-color: #dedede; +} +#previous_next #previous a > .label{ + flex-grow: 1; + text-align: center; + padding-right: 2.5em; +} +#previous_next #previous a > .icon{ + transition: transform 0.4s linear; + background: url("/maixpy/static/image/theme_default/to-top.svg"); + background-size: 2em; + background-repeat: no-repeat; + background-position: center; + min-height: 2.5rem; + min-width: 2.5rem; + -ms-transform: rotate(-90deg); + -moz-transform: rotate(-90deg); + -webkit-transform: rotate(-90deg); + transform: rotate(-90deg); + padding-right: 2em; + padding: 0; +} +#previous_next #next a { + justify-content: flex-end; +} +#previous_next #next a > .label{ + flex-grow: 1; + text-align: center; + padding-left: 2.5em; +} +#previous_next #next a > .icon{ + transition: transform 0.4s linear; + background: url("/maixpy/static/image/theme_default/to-top.svg"); + background-size: 2em; + background-repeat: no-repeat; + background-position: center; + min-height: 2.5rem; + min-width: 2.5rem; + -ms-transform: rotate(90deg); + -moz-transform: rotate(90deg); + -webkit-transform: rotate(90deg); + transform: rotate(90deg); + padding-left: 2em; + padding: 0; +} +.footnotes { + margin-top: 5em; +} +#doc_footer { + min-height: 2em; + display: flex; + background-color: #2d2d2d; + border-top: 1px solid #2d2d2d; + padding: 1em; + transition: 0.4s; +} +#page_footer { + min-height: 2em; + /* margin-top: 5em; */ + display: flex; + padding: 1em; + transition: 0.4s; + background-color: #292929; +} +#footer { + display: flex; + flex-direction: column; + align-items: center; + width: 100%; + line-height: 1em; +} +#footer ul { + list-style: none; + padding: 0; + margin: 0; +} +#footer a, #footer a:visited{ + color: #848fa0; + display: flex; + padding: 0.2em; + font-size: 0.9em; +} +#footer a:hover { + background-color: #e6e6e6; + border-radius: 0.1em; + padding: 0.2em; +} +#footer_top { + width: 100%; +} +#footer_top > ul { + display: flex; + justify-content: space-around; + flex-direction: row; +} +#footer_top > ul > li > a { + color: #cecece; + font-weight: 700; + margin: 1em 0 0.5em 0; +} +#footer_top > ul > li > a:hover { + background-color: transparent; +} +#footer_bottom { + margin-top: 2em; +} +#footer_bottom a { + justify-content: center; +} + +/* TOC */ +.anchor { + opacity: 0; + transition: 0.4s; +} +h2:hover > .anchor, h3:hover > .anchor, h4:hover > .anchor, h5:hover > .anchor { + opacity: 1; +} +.anchor:hover { + opacity: 1; +} +.anchor-link { + display: none; +} +#toc_content>.toc-list { + overflow: hidden; + position: relative +} + +#toc_content>.toc-list li { + list-style: none +} + +.toc-list { + margin: 0; + padding-left: 10px +} +#toc_content > .toc-list > .toc-list-item { + border-left: 2px solid #f1f1f1; + padding: 0.1em 0.1em; + line-height: 1.2em; +} + +a.toc-link { + color: currentColor; + height: 100% +} + +.is-collapsible { + /* max-height: 1000px; */ + overflow: hidden; + transition: all 300ms ease-in-out +} + +.is-collapsed { + max-height: 0 +} + +.is-position-fixed { + position: fixed !important; + top: 0 +} + +.is-active-link { + font-weight: 700 +} + +.toc-link::before { + content: ' '; + display: inline-block; + height: inherit; + left: 0; + margin-top: -1px; + padding-left: 6px; + margin-left: -2px; +} + +.is-active-link::before { + border-left: 2px solid #c33d45; +} + +/* class template */ +.md_page #page_content > div { + width: 90%; + max-width: 50em; + margin: auto; + line-height: 2em; +} + +/* jupyter notebook parser */ +.jp-InputArea { + display: flex; + flex-direction: row; +} +.jp-InputPrompt { + word-break: keep-all; + margin-right: 0.2em; + font-size: 0.8em; +} +.jp-CodeMirrorEditor { + flex-grow: 1; + overflow: auto; +} +.jp-OutputArea-child { + display: flex; + flex-direction: row; +} +.jp-OutputPrompt { + word-break: keep-all; + margin-right: 0.2em; + font-size: 0.8em; + min-width: 2.7em; +} +.jp-OutputArea-output { + flex-grow: 1; + overflow: auto; + background: #2d2d2d; +} + +/* google translate */ +#navbar #google_translate_element { + padding: 0; +} +#navbar #google_translate_element .goog-te-gadget-simple { + border-radius: 5px; + transition: 0.4s; +} +#navbar #google_translate_element .goog-te-gadget-simple .goog-te-menu-value { + transition: 0.4s; +} + +/* tabset */ +.tabset { + display: flex; + flex-direction: column; + align-items: normal; + border: 0.2em solid #ebedf0; + border-radius: 0.5em; + margin: 0.5em 0; +} +.tabset-title { + font-size: medium; + font-weight: 500; + padding: 0.5em 1em; +} +.tabset-content { + display: flex; + flex-direction: column; + align-items: normal; +} +.tabset-tab { + display: flex; + flex-direction: row; + padding: 0 1em; +} +.tabset-tab-label { + cursor: pointer; + font-size: large; + font-weight: 700; + padding: 0.5em 1em; + border-top-left-radius: 0.2em; + border-top-right-radius: 0.2em; +} +.tabset-tab-label:hover { + background-color: #0000000d; +} +.tabset-tab-active { + background-color: #0000000d; + border-bottom: 0.2em solid #c33d45; + color: #c33d45; +} +.tabset-text-container { + padding: 1em; + background-color: #0000000d; +} +.tabset-text-container > div { + display: none; +} +.tabset-text-container > div.tabset-text-active { + display: block; +} + +/* details */ +details { + display: flex; + flex-direction: column; + align-items: normal; + border: 0.2em solid #ebedf0; + border-radius: 0.5em; + margin: 0.5em 0; + transition: 0.4s; +} +details > summary { + font-size: medium; + font-weight: 500; + padding: 0.5em 1em; + cursor: pointer; +} +details > summary { + list-style-type:none; + position: relative; + padding-left: 2em; +} +details > summary:before { + display:inline-block; + content: url("/maixpy/static/image/theme_default/array.svg"); + transform:rotate(90deg); + transition: 0.4s; + left: 0.5em; + position: absolute; + top: 0.45rem; +} +details[open] > summary:before { + transform:rotate(180deg); + top: 0.35rem; +} +details[open] summary ~ * { + animation: sweep .4s ease-in-out; + } +@keyframes sweep { +0% {opacity: 0; margin-left: -10px} +100% {opacity: 1; margin-left: 0px} +} +details > .details-content, details > div { + padding: 1em; + background-color: #0000000d; +} + +#update_history { + overflow-x: auto; +} +#update_history details > div { + padding: 0; +} +#update_history details { + width: fit-content; +} + +/* mobile phone */ +@media screen and (max-width: 900px) { + #navbar { + display: block; + border-bottom: 1px solid #f1f1f1; + z-index: 89; + } + #navbar * { + display: block; + } + #navbar a.site_title { + display: flex; + } + #navbar_menu { + display: flex; + justify-content: space-between; + } + #navbar ul { + padding-left: 0; + } + #navbar_menu_btn { + background: url("/maixpy/static/image/theme_default/menu.svg"); + background-size: contain; + background-repeat: no-repeat; + background-position: center; + border-radius: 5px; + cursor: pointer; + width: 1em; + height: 1em; + display: block; + } + #navbar #navbar_items { + display: none; + padding-right: 0; + } + #navbar .sub_items ul { + left: 0; + right: auto; + } + #navbar .sub_items ul ul { + left: 0; + top: 3em; + } + #sidebar_wrapper { + position: fixed; + top: 0; + left: 0; + bottom: 0; + background-color: white; + box-shadow: 0 0 20px 0px #bbbbbb; + width: 100%; + z-index: 98; + display: none; + } + #sidebar { + position: relative; + width: 100%; + } + .gutter { + display: none; + } + #sidebar > ul { + padding-top: 4em; + } + #menu_wrapper { + z-index: 99; + } + #menu_wrapper.m_menu_fixed { + position: fixed; + left: 0; + top: 0; + width: 100%; + height: 4em; + background-color: rgb(255, 255, 255, 0.9); + box-shadow: 0px 1px 10px 0px rgb(0, 0, 0, 0.06); + } + #menu_wrapper.m_menu_fixed > #menu { + position: fixed; + left: 0.2em; + top: 1em; + } + #menu.close { + background: url("/maixpy/static/image/theme_default/back.svg"); + background-size: contain; + background-repeat: no-repeat; + background-position: center; + border-radius: 5px; + min-height: 2em; + min-width: 2em; + } + #content_body { + width: 90%; + } + #toc_wrapper { + display: none; + position: fixed; + width: 100vh; + height: 100vh; + top: 0; + left: 0; + background-color: rgb(0, 0, 0, 0.5); + z-index: 999; + transition: 0.4s; + } + #toc_wrapper.show { + display: block; + } + #article #toc{ + position: fixed; + top: 4em; + right: 0; + z-index: 200; + width: 90%; + padding: 1em 0 1em 0; + border-radius: 0.3em 0 0 0.3em; + } + #previous_next { + flex-direction: column; + } + + .m_hide { + display: none; + } + #footer_top > ul { + flex-direction: column; + } + #article_tools { + width: 100%; + display: flex; + flex-direction: column; + align-items: flex-end; + position: -webkit-sticky; + position: sticky; + top: 1em; + z-index: 97; + } + #toc_btn { + background: url("/maixpy/static/image/theme_default/anchor.svg"); + background-size: contain; + background-repeat: no-repeat; + background-position: center; + border-radius: 5px; + min-height: 2em; + min-width: 2em; + -ms-transform: rotate(12deg); + -moz-transform: rotate(12deg); + -webkit-transform: rotate(12deg); + transform: rotate(12deg); + } +} + + +/* special */ + +#themes{ + padding: 2px 5px; + cursor: pointer; +} +#navbar .light, #navbar .dark:hover { + background: url("/maixpy/static/image/theme_default/light_mode.svg"); + background-size: contain; + background-repeat: no-repeat; + background-position: center; + min-height: 1rem; + min-width: 1rem; +} +#navbar .dark, #navbar .light:hover { + background: url("/maixpy/static/image/theme_default/dark_mode.svg"); + background-size: contain; + background-repeat: no-repeat; + background-position: center; + min-height: 1rem; + min-width: 1rem; +} + + +@media print { + code[class*="language-"], pre[class*="language-"] { + white-space: pre-wrap; + } + pre[class*="language-"].line-numbers { + border: 1px solid #2d2d2d; + } + #navbar, + #sidebar_wrapper, .gutter, #menu_wrapper, + #toc, #to_top, #doc_footer, + #previous_next, + #source_link, #print_page, + #comments-container { + display: none; + } + #article { + width: 100%; + } + #content_body { + max-width: 100%; + width: 100%; + } + /* .line-numbers-rows { + display: none; + } */ + .gutter { + display: none; + } +} diff --git a/maixpy/static/css/theme_default/prism.min.css b/maixpy/static/css/theme_default/prism.min.css new file mode 100644 index 00000000..c087ba96 --- /dev/null +++ b/maixpy/static/css/theme_default/prism.min.css @@ -0,0 +1,261 @@ +/* PrismJS 1.23.0 +https://prismjs.com/download.html#themes=prism-tomorrow&languages=markup+css+clike+javascript+bash+c+cpp+cmake+coffeescript+docker+go+ini+java+json+json5+kotlin+latex+less+lua+makefile+markdown+markup-templating+objectivec+php+powershell+python+jsx+tsx+ruby+rust+sass+scss+shell-session+sql+swift+textile+typescript+yaml&plugins=line-numbers+highlight-keywords+toolbar+copy-to-clipboard+match-braces */ +/** + * prism.js tomorrow night eighties for JavaScript, CoffeeScript, CSS and HTML + * Based on https://github.com/chriskempson/tomorrow-theme + * @author Rose Pritchard + */ + +code[class*="language-"], +pre[class*="language-"] { + color: #ccc; + background: none; + font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; + font-size: 1em; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + word-wrap: normal; + line-height: 1.5; + + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; + +} + +/* Code blocks */ +pre[class*="language-"] { + padding: 1em; + margin: .5em 0; + overflow: auto; +} + +:not(pre) > code[class*="language-"], +pre[class*="language-"] { + background: #2d2d2d; +} + +/* Inline code */ +:not(pre) > code[class*="language-"] { + padding: .1em; + border-radius: .3em; + white-space: normal; +} + +.token.comment, +.token.block-comment, +.token.prolog, +.token.doctype, +.token.cdata { + color: #999; +} + +.token.punctuation { + color: #ccc; +} + +.token.tag, +.token.attr-name, +.token.namespace, +.token.deleted { + color: #e2777a; +} + +.token.function-name { + color: #6196cc; +} + +.token.boolean, +.token.number, +.token.function { + color: #f08d49; +} + +.token.property, +.token.class-name, +.token.constant, +.token.symbol { + color: #f8c555; +} + +.token.selector, +.token.important, +.token.atrule, +.token.keyword, +.token.builtin { + color: #cc99cd; +} + +.token.string, +.token.char, +.token.attr-value, +.token.regex, +.token.variable { + color: #7ec699; +} + +.token.operator, +.token.entity, +.token.url { + color: #67cdcc; +} + +.token.important, +.token.bold { + font-weight: bold; +} +.token.italic { + font-style: italic; +} + +.token.entity { + cursor: help; +} + +.token.inserted { + color: green; +} + +pre[class*="language-"].line-numbers { + position: relative; + padding-left: 3.8em; + counter-reset: linenumber; +} + +pre[class*="language-"].line-numbers > code { + position: relative; + white-space: inherit; +} + +.line-numbers .line-numbers-rows { + position: absolute; + pointer-events: none; + top: 0; + font-size: 100%; + left: -3.8em; + width: 3em; /* works for line-numbers below 1000 lines */ + letter-spacing: -1px; + border-right: 1px solid #999; + + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + +} + + .line-numbers-rows > span { + display: block; + counter-increment: linenumber; + } + + .line-numbers-rows > span:before { + content: counter(linenumber); + color: #999; + display: block; + padding-right: 0.8em; + text-align: right; + } + +div.code-toolbar { + position: relative; +} + +div.code-toolbar > .toolbar { + position: absolute; + top: .3em; + right: .2em; + transition: opacity 0.3s ease-in-out; + opacity: 0; +} + +div.code-toolbar:hover > .toolbar { + opacity: 1; +} + +/* Separate line b/c rules are thrown out if selector is invalid. + IE11 and old Edge versions don't support :focus-within. */ +div.code-toolbar:focus-within > .toolbar { + opacity: 1; +} + +div.code-toolbar > .toolbar .toolbar-item { + display: inline-block; +} + +div.code-toolbar > .toolbar a { + cursor: pointer; +} + +div.code-toolbar > .toolbar button { + background: none; + border: 0; + color: inherit; + font: inherit; + line-height: normal; + overflow: visible; + padding: 0; + -webkit-user-select: none; /* for button */ + -moz-user-select: none; + -ms-user-select: none; +} + +div.code-toolbar > .toolbar a, +div.code-toolbar > .toolbar button, +div.code-toolbar > .toolbar span { + color: #bbb; + font-size: .8em; + padding: 0 .5em; + background: #f5f2f0; + background: rgba(224, 224, 224, 0.2); + box-shadow: 0 2px 0 0 rgba(0,0,0,0.2); + border-radius: .5em; +} + +div.code-toolbar > .toolbar a:hover, +div.code-toolbar > .toolbar a:focus, +div.code-toolbar > .toolbar button:hover, +div.code-toolbar > .toolbar button:focus, +div.code-toolbar > .toolbar span:hover, +div.code-toolbar > .toolbar span:focus { + color: inherit; + text-decoration: none; +} + +.token.punctuation.brace-hover, +.token.punctuation.brace-selected { + outline: solid 1px; +} + +.rainbow-braces .token.punctuation.brace-level-1, +.rainbow-braces .token.punctuation.brace-level-5, +.rainbow-braces .token.punctuation.brace-level-9 { + color: #E50; + opacity: 1; +} +.rainbow-braces .token.punctuation.brace-level-2, +.rainbow-braces .token.punctuation.brace-level-6, +.rainbow-braces .token.punctuation.brace-level-10 { + color: #0B3; + opacity: 1; +} +.rainbow-braces .token.punctuation.brace-level-3, +.rainbow-braces .token.punctuation.brace-level-7, +.rainbow-braces .token.punctuation.brace-level-11 { + color: #26F; + opacity: 1; +} +.rainbow-braces .token.punctuation.brace-level-4, +.rainbow-braces .token.punctuation.brace-level-8, +.rainbow-braces .token.punctuation.brace-level-12 { + color: #E0E; + opacity: 1; +} + diff --git a/maixpy/static/css/theme_default/prism.min.js b/maixpy/static/css/theme_default/prism.min.js new file mode 100644 index 00000000..debc9322 --- /dev/null +++ b/maixpy/static/css/theme_default/prism.min.js @@ -0,0 +1,46 @@ +/* PrismJS 1.23.0 +https://prismjs.com/download.html#themes=prism-tomorrow&languages=markup+css+clike+javascript+bash+c+cpp+cmake+coffeescript+docker+go+ini+java+json+json5+kotlin+latex+less+lua+makefile+markdown+markup-templating+objectivec+php+powershell+python+jsx+tsx+ruby+rust+sass+scss+shell-session+sql+swift+textile+typescript+yaml&plugins=line-numbers+highlight-keywords+toolbar+copy-to-clipboard+match-braces */ +var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(u){var c=/\blang(?:uage)?-([\w-]+)\b/i,n=0,M={manual:u.Prism&&u.Prism.manual,disableWorkerMessageHandler:u.Prism&&u.Prism.disableWorkerMessageHandler,util:{encode:function e(n){return n instanceof W?new W(n.type,e(n.content),n.alias):Array.isArray(n)?n.map(e):n.replace(/&/g,"&").replace(/=l.reach);y+=m.value.length,m=m.next){var k=m.value;if(r.length>n.length)return;if(!(k instanceof W)){var b,x=1;if(h){if(!(b=z(p,y,n,f)))break;var w=b.index,A=b.index+b[0].length,P=y;for(P+=m.value.length;P<=w;)m=m.next,P+=m.value.length;if(P-=m.value.length,y=P,m.value instanceof W)continue;for(var S=m;S!==r.tail&&(Pl.reach&&(l.reach=N);var j=m.prev;O&&(j=I(r,j,O),y+=O.length),q(r,j,x);var C=new W(o,g?M.tokenize(E,g):E,d,E);if(m=I(r,j,C),L&&I(r,m,L),1l.reach&&(l.reach=_.reach)}}}}}}(e,a,n,a.head,0),function(e){var n=[],r=e.head.next;for(;r!==e.tail;)n.push(r.value),r=r.next;return n}(a)},hooks:{all:{},add:function(e,n){var r=M.hooks.all;r[e]=r[e]||[],r[e].push(n)},run:function(e,n){var r=M.hooks.all[e];if(r&&r.length)for(var t,a=0;t=r[a++];)t(n)}},Token:W};function W(e,n,r,t){this.type=e,this.content=n,this.alias=r,this.length=0|(t||"").length}function z(e,n,r,t){e.lastIndex=n;var a=e.exec(r);if(a&&t&&a[1]){var i=a[1].length;a.index+=i,a[0]=a[0].slice(i)}return a}function i(){var e={value:null,prev:null,next:null},n={value:null,prev:e,next:null};e.next=n,this.head=e,this.tail=n,this.length=0}function I(e,n,r){var t=n.next,a={value:r,prev:n,next:t};return n.next=a,t.prev=a,e.length++,a}function q(e,n,r){for(var t=n.next,a=0;a"+a.content+""},!u.document)return u.addEventListener&&(M.disableWorkerMessageHandler||u.addEventListener("message",function(e){var n=JSON.parse(e.data),r=n.language,t=n.code,a=n.immediateClose;u.postMessage(M.highlight(t,M.languages[r],r)),a&&u.close()},!1)),M;var e=M.util.currentScript();function r(){M.manual||M.highlightAll()}if(e&&(M.filename=e.src,e.hasAttribute("data-manual")&&(M.manual=!0)),!M.manual){var t=document.readyState;"loading"===t||"interactive"===t&&e&&e.defer?document.addEventListener("DOMContentLoaded",r):window.requestAnimationFrame?window.requestAnimationFrame(r):window.setTimeout(r,16)}return M}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism); +Prism.languages.markup={comment://,prolog:/<\?[\s\S]+?\?>/,doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/,name:/[^\s<>'"]+/}},cdata://i,tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},Prism.languages.markup.tag.inside["attr-value"].inside.entity=Prism.languages.markup.entity,Prism.languages.markup.doctype.inside["internal-subset"].inside=Prism.languages.markup,Prism.hooks.add("wrap",function(a){"entity"===a.type&&(a.attributes.title=a.content.replace(/&/,"&"))}),Object.defineProperty(Prism.languages.markup.tag,"addInlined",{value:function(a,e){var s={};s["language-"+e]={pattern:/(^$)/i,lookbehind:!0,inside:Prism.languages[e]},s.cdata=/^$/i;var n={"included-cdata":{pattern://i,inside:s}};n["language-"+e]={pattern:/[\s\S]+/,inside:Prism.languages[e]};var t={};t[a]={pattern:RegExp("(<__[^>]*>)(?:))*\\]\\]>|(?!)".replace(/__/g,function(){return a}),"i"),lookbehind:!0,greedy:!0,inside:n},Prism.languages.insertBefore("markup","cdata",t)}}),Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup,Prism.languages.xml=Prism.languages.extend("markup",{}),Prism.languages.ssml=Prism.languages.xml,Prism.languages.atom=Prism.languages.xml,Prism.languages.rss=Prism.languages.xml; +!function(s){var e=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;s.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+e.source+"|(?:[^\\\\\r\n()\"']|\\\\[^])*)\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+e.source+"$"),alias:"url"}}},selector:RegExp("[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+e.source+")*(?=\\s*\\{)"),string:{pattern:e,greedy:!0},property:/(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,important:/!important\b/i,function:/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:,]/},s.languages.css.atrule.inside.rest=s.languages.css;var t=s.languages.markup;t&&(t.tag.addInlined("style","css"),s.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/(^|["'\s])style\s*=\s*(?:"[^"]*"|'[^']*')/i,lookbehind:!0,inside:{"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{style:{pattern:/(["'])[\s\S]+(?=["']$)/,lookbehind:!0,alias:"language-css",inside:s.languages.css},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},"attr-name":/^style/i}}},t.tag))}(Prism); +Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|interface|extends|implements|trait|instanceof|new)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,boolean:/\b(?:true|false)\b/,function:/\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/}; +Prism.languages.javascript=Prism.languages.extend("clike",{"class-name":[Prism.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:prototype|constructor))/,lookbehind:!0}],keyword:[{pattern:/((?:^|})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:/\b(?:(?:0[xX](?:[\dA-Fa-f](?:_[\dA-Fa-f])?)+|0[bB](?:[01](?:_[01])?)+|0[oO](?:[0-7](?:_[0-7])?)+)n?|(?:\d(?:_\d)?)+n|NaN|Infinity)\b|(?:\b(?:\d(?:_\d)?)+\.?(?:\d(?:_\d)?)*|\B\.(?:\d(?:_\d)?)+)(?:[Ee][+-]?(?:\d(?:_\d)?)+)?/,operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),Prism.languages.javascript["class-name"][0].pattern=/(\b(?:class|interface|extends|implements|instanceof|new)\s+)[\w.\\]+/,Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*]|\\.|[^/\\\[\r\n])+\/[gimyus]{0,6}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:Prism.languages.regex},"regex-flags":/[a-z]+$/,"regex-delimiter":/^\/|\/$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,inside:Prism.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:Prism.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),Prism.languages.insertBefore("javascript","string",{"template-string":{pattern:/`(?:\\[\s\S]|\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}|(?!\${)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\${|}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}}}),Prism.languages.markup&&Prism.languages.markup.tag.addInlined("script","javascript"),Prism.languages.js=Prism.languages.javascript; +!function(e){var t="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",n={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},a={bash:n,environment:{pattern:RegExp("\\$"+t),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--?|-=|\+\+?|\+=|!=?|~|\*\*?|\*=|\/=?|%=?|<<=?|>>=?|<=?|>=?|==?|&&?|&=|\^=?|\|\|?|\|=|\?|:/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|x[0-9a-fA-F]{1,2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)\w+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b\w+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+?)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:a},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:n}},{pattern:/(^|[^\\](?:\\\\)*)(["'])(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|(?!\2)[^\\`$])*\2/,lookbehind:!0,greedy:!0,inside:a}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:a.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|aptitude|apt-cache|apt-get|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:if|then|else|elif|fi|for|while|in|case|esac|function|select|do|done|until)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|break|cd|continue|eval|exec|exit|export|getopts|hash|pwd|readonly|return|shift|test|times|trap|umask|unset|alias|bind|builtin|caller|command|declare|echo|enable|help|let|local|logout|mapfile|printf|read|readarray|source|type|typeset|ulimit|unalias|set|shopt)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:true|false)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|==?|!=?|=~|<<[<-]?|[&\d]?>>|\d?[<>]&?|&[>&]?|\|[&|]?|<=?|>=?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},n.inside=e.languages.bash;for(var s=["comment","function-name","for-or-select","assign-left","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],i=a.variable[1].inside,o=0;o>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),Prism.languages.insertBefore("c","string",{macro:{pattern:/(^\s*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},Prism.languages.c.string],comment:Prism.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:Prism.languages.c}}},constant:/\b(?:__FILE__|__LINE__|__DATE__|__TIME__|__TIMESTAMP__|__func__|EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|stdin|stdout|stderr)\b/}),delete Prism.languages.c.boolean; +!function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char8_t|char16_t|char32_t|class|compl|concept|const|consteval|constexpr|constinit|const_cast|continue|co_await|co_return|co_yield|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n="\\b(?!)\\w+(?:\\s*\\.\\s*\\w+)*\\b".replace(//g,function(){return t.source});e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp("(\\b(?:class|concept|enum|struct|typename)\\s+)(?!)\\w+".replace(//g,function(){return t.source})),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:true|false)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp('(\\b(?:module|import)\\s+)(?:"(?:\\\\(?:\r\n|[^])|[^"\\\\\r\n])*"|<[^<>\r\n]*>|'+"(?:\\s*:\\s*)?|:\\s*".replace(//g,function(){return n})+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","operator",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(Prism); +Prism.languages.cmake={comment:/#.*/,string:{pattern:/"(?:[^\\"]|\\.)*"/,greedy:!0,inside:{interpolation:{pattern:/\${(?:[^{}$]|\${[^{}$]*})*}/,inside:{punctuation:/\${|}/,variable:/\w+/}}}},variable:/\b(?:CMAKE_\w+|\w+_(?:VERSION(?:_MAJOR|_MINOR|_PATCH|_TWEAK)?|(?:BINARY|SOURCE)_DIR|DESCRIPTION|HOMEPAGE_URL|ROOT)|(?:CTEST_CUSTOM_(?:MAXIMUM_(?:(?:FAIL|PASS)ED_TEST_OUTPUT_SIZE|NUMBER_OF_(?:ERROR|WARNING)S)|ERROR_(?:P(?:OST|RE)_CONTEXT|EXCEPTION|MATCH)|P(?:OST|RE)_MEMCHECK|WARNING_(?:EXCEPTION|MATCH)|(?:MEMCHECK|TESTS)_IGNORE|P(?:OST|RE)_TEST|COVERAGE_EXCLUDE)|ANDROID|APPLE|BORLAND|BUILD_SHARED_LIBS|CACHE|CPACK_(?:ABSOLUTE_DESTINATION_FILES|COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY|ERROR_ON_ABSOLUTE_INSTALL_DESTINATION|INCLUDE_TOPLEVEL_DIRECTORY|INSTALL_DEFAULT_DIRECTORY_PERMISSIONS|INSTALL_SCRIPT|PACKAGING_INSTALL_PREFIX|SET_DESTDIR|WARN_ON_ABSOLUTE_INSTALL_DESTINATION)|CTEST_(?:BINARY_DIRECTORY|BUILD_COMMAND|BUILD_NAME|BZR_COMMAND|BZR_UPDATE_OPTIONS|CHANGE_ID|CHECKOUT_COMMAND|CONFIGURATION_TYPE|CONFIGURE_COMMAND|COVERAGE_COMMAND|COVERAGE_EXTRA_FLAGS|CURL_OPTIONS|CUSTOM_(?:COVERAGE_EXCLUDE|ERROR_EXCEPTION|ERROR_MATCH|ERROR_POST_CONTEXT|ERROR_PRE_CONTEXT|MAXIMUM_FAILED_TEST_OUTPUT_SIZE|MAXIMUM_NUMBER_OF_(?:ERRORS|WARNINGS)|MAXIMUM_PASSED_TEST_OUTPUT_SIZE|MEMCHECK_IGNORE|POST_MEMCHECK|POST_TEST|PRE_MEMCHECK|PRE_TEST|TESTS_IGNORE|WARNING_EXCEPTION|WARNING_MATCH)|CVS_CHECKOUT|CVS_COMMAND|CVS_UPDATE_OPTIONS|DROP_LOCATION|DROP_METHOD|DROP_SITE|DROP_SITE_CDASH|DROP_SITE_PASSWORD|DROP_SITE_USER|EXTRA_COVERAGE_GLOB|GIT_COMMAND|GIT_INIT_SUBMODULES|GIT_UPDATE_CUSTOM|GIT_UPDATE_OPTIONS|HG_COMMAND|HG_UPDATE_OPTIONS|LABELS_FOR_SUBPROJECTS|MEMORYCHECK_(?:COMMAND|COMMAND_OPTIONS|SANITIZER_OPTIONS|SUPPRESSIONS_FILE|TYPE)|NIGHTLY_START_TIME|P4_CLIENT|P4_COMMAND|P4_OPTIONS|P4_UPDATE_OPTIONS|RUN_CURRENT_SCRIPT|SCP_COMMAND|SITE|SOURCE_DIRECTORY|SUBMIT_URL|SVN_COMMAND|SVN_OPTIONS|SVN_UPDATE_OPTIONS|TEST_LOAD|TEST_TIMEOUT|TRIGGER_SITE|UPDATE_COMMAND|UPDATE_OPTIONS|UPDATE_VERSION_ONLY|USE_LAUNCHERS)|CYGWIN|ENV|EXECUTABLE_OUTPUT_PATH|GHS-MULTI|IOS|LIBRARY_OUTPUT_PATH|MINGW|MSVC(?:10|11|12|14|60|70|71|80|90|_IDE|_TOOLSET_VERSION|_VERSION)?|MSYS|PROJECT_(?:BINARY_DIR|DESCRIPTION|HOMEPAGE_URL|NAME|SOURCE_DIR|VERSION|VERSION_(?:MAJOR|MINOR|PATCH|TWEAK))|UNIX|WIN32|WINCE|WINDOWS_PHONE|WINDOWS_STORE|XCODE|XCODE_VERSION))\b/,property:/\b(?:cxx_\w+|(?:ARCHIVE_OUTPUT_(?:DIRECTORY|NAME)|COMPILE_DEFINITIONS|COMPILE_PDB_NAME|COMPILE_PDB_OUTPUT_DIRECTORY|EXCLUDE_FROM_DEFAULT_BUILD|IMPORTED_(?:IMPLIB|LIBNAME|LINK_DEPENDENT_LIBRARIES|LINK_INTERFACE_LANGUAGES|LINK_INTERFACE_LIBRARIES|LINK_INTERFACE_MULTIPLICITY|LOCATION|NO_SONAME|OBJECTS|SONAME)|INTERPROCEDURAL_OPTIMIZATION|LIBRARY_OUTPUT_DIRECTORY|LIBRARY_OUTPUT_NAME|LINK_FLAGS|LINK_INTERFACE_LIBRARIES|LINK_INTERFACE_MULTIPLICITY|LOCATION|MAP_IMPORTED_CONFIG|OSX_ARCHITECTURES|OUTPUT_NAME|PDB_NAME|PDB_OUTPUT_DIRECTORY|RUNTIME_OUTPUT_DIRECTORY|RUNTIME_OUTPUT_NAME|STATIC_LIBRARY_FLAGS|VS_CSHARP|VS_DOTNET_REFERENCEPROP|VS_DOTNET_REFERENCE|VS_GLOBAL_SECTION_POST|VS_GLOBAL_SECTION_PRE|VS_GLOBAL|XCODE_ATTRIBUTE)_\w+|\w+_(?:CLANG_TIDY|COMPILER_LAUNCHER|CPPCHECK|CPPLINT|INCLUDE_WHAT_YOU_USE|OUTPUT_NAME|POSTFIX|VISIBILITY_PRESET)|ABSTRACT|ADDITIONAL_MAKE_CLEAN_FILES|ADVANCED|ALIASED_TARGET|ALLOW_DUPLICATE_CUSTOM_TARGETS|ANDROID_(?:ANT_ADDITIONAL_OPTIONS|API|API_MIN|ARCH|ASSETS_DIRECTORIES|GUI|JAR_DEPENDENCIES|NATIVE_LIB_DEPENDENCIES|NATIVE_LIB_DIRECTORIES|PROCESS_MAX|PROGUARD|PROGUARD_CONFIG_PATH|SECURE_PROPS_PATH|SKIP_ANT_STEP|STL_TYPE)|ARCHIVE_OUTPUT_DIRECTORY|ARCHIVE_OUTPUT_NAME|ATTACHED_FILES|ATTACHED_FILES_ON_FAIL|AUTOGEN_(?:BUILD_DIR|ORIGIN_DEPENDS|PARALLEL|SOURCE_GROUP|TARGETS_FOLDER|TARGET_DEPENDS)|AUTOMOC|AUTOMOC_(?:COMPILER_PREDEFINES|DEPEND_FILTERS|EXECUTABLE|MACRO_NAMES|MOC_OPTIONS|SOURCE_GROUP|TARGETS_FOLDER)|AUTORCC|AUTORCC_EXECUTABLE|AUTORCC_OPTIONS|AUTORCC_SOURCE_GROUP|AUTOUIC|AUTOUIC_EXECUTABLE|AUTOUIC_OPTIONS|AUTOUIC_SEARCH_PATHS|BINARY_DIR|BUILDSYSTEM_TARGETS|BUILD_RPATH|BUILD_RPATH_USE_ORIGIN|BUILD_WITH_INSTALL_NAME_DIR|BUILD_WITH_INSTALL_RPATH|BUNDLE|BUNDLE_EXTENSION|CACHE_VARIABLES|CLEAN_NO_CUSTOM|COMMON_LANGUAGE_RUNTIME|COMPATIBLE_INTERFACE_(?:BOOL|NUMBER_MAX|NUMBER_MIN|STRING)|COMPILE_(?:DEFINITIONS|FEATURES|FLAGS|OPTIONS|PDB_NAME|PDB_OUTPUT_DIRECTORY)|COST|CPACK_DESKTOP_SHORTCUTS|CPACK_NEVER_OVERWRITE|CPACK_PERMANENT|CPACK_STARTUP_SHORTCUTS|CPACK_START_MENU_SHORTCUTS|CPACK_WIX_ACL|CROSSCOMPILING_EMULATOR|CUDA_EXTENSIONS|CUDA_PTX_COMPILATION|CUDA_RESOLVE_DEVICE_SYMBOLS|CUDA_SEPARABLE_COMPILATION|CUDA_STANDARD|CUDA_STANDARD_REQUIRED|CXX_EXTENSIONS|CXX_STANDARD|CXX_STANDARD_REQUIRED|C_EXTENSIONS|C_STANDARD|C_STANDARD_REQUIRED|DEBUG_CONFIGURATIONS|DEBUG_POSTFIX|DEFINE_SYMBOL|DEFINITIONS|DEPENDS|DEPLOYMENT_ADDITIONAL_FILES|DEPLOYMENT_REMOTE_DIRECTORY|DISABLED|DISABLED_FEATURES|ECLIPSE_EXTRA_CPROJECT_CONTENTS|ECLIPSE_EXTRA_NATURES|ENABLED_FEATURES|ENABLED_LANGUAGES|ENABLE_EXPORTS|ENVIRONMENT|EXCLUDE_FROM_ALL|EXCLUDE_FROM_DEFAULT_BUILD|EXPORT_NAME|EXPORT_PROPERTIES|EXTERNAL_OBJECT|EchoString|FAIL_REGULAR_EXPRESSION|FIND_LIBRARY_USE_LIB32_PATHS|FIND_LIBRARY_USE_LIB64_PATHS|FIND_LIBRARY_USE_LIBX32_PATHS|FIND_LIBRARY_USE_OPENBSD_VERSIONING|FIXTURES_CLEANUP|FIXTURES_REQUIRED|FIXTURES_SETUP|FOLDER|FRAMEWORK|Fortran_FORMAT|Fortran_MODULE_DIRECTORY|GENERATED|GENERATOR_FILE_NAME|GENERATOR_IS_MULTI_CONFIG|GHS_INTEGRITY_APP|GHS_NO_SOURCE_GROUP_FILE|GLOBAL_DEPENDS_DEBUG_MODE|GLOBAL_DEPENDS_NO_CYCLES|GNUtoMS|HAS_CXX|HEADER_FILE_ONLY|HELPSTRING|IMPLICIT_DEPENDS_INCLUDE_TRANSFORM|IMPORTED|IMPORTED_(?:COMMON_LANGUAGE_RUNTIME|CONFIGURATIONS|GLOBAL|IMPLIB|LIBNAME|LINK_DEPENDENT_LIBRARIES|LINK_INTERFACE_(?:LANGUAGES|LIBRARIES|MULTIPLICITY)|LOCATION|NO_SONAME|OBJECTS|SONAME)|IMPORT_PREFIX|IMPORT_SUFFIX|INCLUDE_DIRECTORIES|INCLUDE_REGULAR_EXPRESSION|INSTALL_NAME_DIR|INSTALL_RPATH|INSTALL_RPATH_USE_LINK_PATH|INTERFACE_(?:AUTOUIC_OPTIONS|COMPILE_DEFINITIONS|COMPILE_FEATURES|COMPILE_OPTIONS|INCLUDE_DIRECTORIES|LINK_DEPENDS|LINK_DIRECTORIES|LINK_LIBRARIES|LINK_OPTIONS|POSITION_INDEPENDENT_CODE|SOURCES|SYSTEM_INCLUDE_DIRECTORIES)|INTERPROCEDURAL_OPTIMIZATION|IN_TRY_COMPILE|IOS_INSTALL_COMBINED|JOB_POOLS|JOB_POOL_COMPILE|JOB_POOL_LINK|KEEP_EXTENSION|LABELS|LANGUAGE|LIBRARY_OUTPUT_DIRECTORY|LIBRARY_OUTPUT_NAME|LINKER_LANGUAGE|LINK_(?:DEPENDS|DEPENDS_NO_SHARED|DIRECTORIES|FLAGS|INTERFACE_LIBRARIES|INTERFACE_MULTIPLICITY|LIBRARIES|OPTIONS|SEARCH_END_STATIC|SEARCH_START_STATIC|WHAT_YOU_USE)|LISTFILE_STACK|LOCATION|MACOSX_BUNDLE|MACOSX_BUNDLE_INFO_PLIST|MACOSX_FRAMEWORK_INFO_PLIST|MACOSX_PACKAGE_LOCATION|MACOSX_RPATH|MACROS|MANUALLY_ADDED_DEPENDENCIES|MEASUREMENT|MODIFIED|NAME|NO_SONAME|NO_SYSTEM_FROM_IMPORTED|OBJECT_DEPENDS|OBJECT_OUTPUTS|OSX_ARCHITECTURES|OUTPUT_NAME|PACKAGES_FOUND|PACKAGES_NOT_FOUND|PARENT_DIRECTORY|PASS_REGULAR_EXPRESSION|PDB_NAME|PDB_OUTPUT_DIRECTORY|POSITION_INDEPENDENT_CODE|POST_INSTALL_SCRIPT|PREDEFINED_TARGETS_FOLDER|PREFIX|PRE_INSTALL_SCRIPT|PRIVATE_HEADER|PROCESSORS|PROCESSOR_AFFINITY|PROJECT_LABEL|PUBLIC_HEADER|REPORT_UNDEFINED_PROPERTIES|REQUIRED_FILES|RESOURCE|RESOURCE_LOCK|RULE_LAUNCH_COMPILE|RULE_LAUNCH_CUSTOM|RULE_LAUNCH_LINK|RULE_MESSAGES|RUNTIME_OUTPUT_DIRECTORY|RUNTIME_OUTPUT_NAME|RUN_SERIAL|SKIP_AUTOGEN|SKIP_AUTOMOC|SKIP_AUTORCC|SKIP_AUTOUIC|SKIP_BUILD_RPATH|SKIP_RETURN_CODE|SOURCES|SOURCE_DIR|SOVERSION|STATIC_LIBRARY_FLAGS|STATIC_LIBRARY_OPTIONS|STRINGS|SUBDIRECTORIES|SUFFIX|SYMBOLIC|TARGET_ARCHIVES_MAY_BE_SHARED_LIBS|TARGET_MESSAGES|TARGET_SUPPORTS_SHARED_LIBS|TESTS|TEST_INCLUDE_FILE|TEST_INCLUDE_FILES|TIMEOUT|TIMEOUT_AFTER_MATCH|TYPE|USE_FOLDERS|VALUE|VARIABLES|VERSION|VISIBILITY_INLINES_HIDDEN|VS_(?:CONFIGURATION_TYPE|COPY_TO_OUT_DIR|DEBUGGER_(?:COMMAND|COMMAND_ARGUMENTS|ENVIRONMENT|WORKING_DIRECTORY)|DEPLOYMENT_CONTENT|DEPLOYMENT_LOCATION|DOTNET_REFERENCES|DOTNET_REFERENCES_COPY_LOCAL|GLOBAL_KEYWORD|GLOBAL_PROJECT_TYPES|GLOBAL_ROOTNAMESPACE|INCLUDE_IN_VSIX|IOT_STARTUP_TASK|KEYWORD|RESOURCE_GENERATOR|SCC_AUXPATH|SCC_LOCALPATH|SCC_PROJECTNAME|SCC_PROVIDER|SDK_REFERENCES|SHADER_(?:DISABLE_OPTIMIZATIONS|ENABLE_DEBUG|ENTRYPOINT|FLAGS|MODEL|OBJECT_FILE_NAME|OUTPUT_HEADER_FILE|TYPE|VARIABLE_NAME)|STARTUP_PROJECT|TOOL_OVERRIDE|USER_PROPS|WINRT_COMPONENT|WINRT_EXTENSIONS|WINRT_REFERENCES|XAML_TYPE)|WILL_FAIL|WIN32_EXECUTABLE|WINDOWS_EXPORT_ALL_SYMBOLS|WORKING_DIRECTORY|WRAP_EXCLUDE|XCODE_(?:EMIT_EFFECTIVE_PLATFORM_NAME|EXPLICIT_FILE_TYPE|FILE_ATTRIBUTES|LAST_KNOWN_FILE_TYPE|PRODUCT_TYPE|SCHEME_(?:ADDRESS_SANITIZER|ADDRESS_SANITIZER_USE_AFTER_RETURN|ARGUMENTS|DISABLE_MAIN_THREAD_CHECKER|DYNAMIC_LIBRARY_LOADS|DYNAMIC_LINKER_API_USAGE|ENVIRONMENT|EXECUTABLE|GUARD_MALLOC|MAIN_THREAD_CHECKER_STOP|MALLOC_GUARD_EDGES|MALLOC_SCRIBBLE|MALLOC_STACK|THREAD_SANITIZER(?:_STOP)?|UNDEFINED_BEHAVIOUR_SANITIZER(?:_STOP)?|ZOMBIE_OBJECTS))|XCTEST)\b/,keyword:/\b(?:add_compile_definitions|add_compile_options|add_custom_command|add_custom_target|add_definitions|add_dependencies|add_executable|add_library|add_link_options|add_subdirectory|add_test|aux_source_directory|break|build_command|build_name|cmake_host_system_information|cmake_minimum_required|cmake_parse_arguments|cmake_policy|configure_file|continue|create_test_sourcelist|ctest_build|ctest_configure|ctest_coverage|ctest_empty_binary_directory|ctest_memcheck|ctest_read_custom_files|ctest_run_script|ctest_sleep|ctest_start|ctest_submit|ctest_test|ctest_update|ctest_upload|define_property|else|elseif|enable_language|enable_testing|endforeach|endfunction|endif|endmacro|endwhile|exec_program|execute_process|export|export_library_dependencies|file|find_file|find_library|find_package|find_path|find_program|fltk_wrap_ui|foreach|function|get_cmake_property|get_directory_property|get_filename_component|get_property|get_source_file_property|get_target_property|get_test_property|if|include|include_directories|include_external_msproject|include_guard|include_regular_expression|install|install_files|install_programs|install_targets|link_directories|link_libraries|list|load_cache|load_command|macro|make_directory|mark_as_advanced|math|message|option|output_required_files|project|qt_wrap_cpp|qt_wrap_ui|remove|remove_definitions|return|separate_arguments|set|set_directory_properties|set_property|set_source_files_properties|set_target_properties|set_tests_properties|site_name|source_group|string|subdir_depends|subdirs|target_compile_definitions|target_compile_features|target_compile_options|target_include_directories|target_link_directories|target_link_libraries|target_link_options|target_sources|try_compile|try_run|unset|use_mangled_mesa|utility_source|variable_requires|variable_watch|while|write_file)(?=\s*\()\b/,boolean:/\b(?:ON|OFF|TRUE|FALSE)\b/,namespace:/\b(?:PROPERTIES|SHARED|PRIVATE|STATIC|PUBLIC|INTERFACE|TARGET_OBJECTS)\b/,operator:/\b(?:NOT|AND|OR|MATCHES|LESS|GREATER|EQUAL|STRLESS|STRGREATER|STREQUAL|VERSION_LESS|VERSION_EQUAL|VERSION_GREATER|DEFINED)\b/,inserted:{pattern:/\b\w+::\w+\b/,alias:"class-name"},number:/\b\d+(?:\.\d+)*\b/,function:/\b[a-z_]\w*(?=\s*\()\b/i,punctuation:/[()>}]|\$[<{]/}; +!function(e){var t=/#(?!\{).+/,n={pattern:/#\{[^}]+\}/,alias:"variable"};e.languages.coffeescript=e.languages.extend("javascript",{comment:t,string:[{pattern:/'(?:\\[\s\S]|[^\\'])*'/,greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0,inside:{interpolation:n}}],keyword:/\b(?:and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,"class-member":{pattern:/@(?!\d)\w+/,alias:"variable"}}),e.languages.insertBefore("coffeescript","comment",{"multiline-comment":{pattern:/###[\s\S]+?###/,alias:"comment"},"block-regex":{pattern:/\/{3}[\s\S]*?\/{3}/,alias:"regex",inside:{comment:t,interpolation:n}}}),e.languages.insertBefore("coffeescript","string",{"inline-javascript":{pattern:/`(?:\\[\s\S]|[^\\`])*`/,inside:{delimiter:{pattern:/^`|`$/,alias:"punctuation"},script:{pattern:/[\s\S]+/,alias:"language-javascript",inside:e.languages.javascript}}},"multiline-string":[{pattern:/'''[\s\S]*?'''/,greedy:!0,alias:"string"},{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string",inside:{interpolation:n}}]}),e.languages.insertBefore("coffeescript","keyword",{property:/(?!\d)\w+(?=\s*:(?!:))/}),delete e.languages.coffeescript["template-string"],e.languages.coffee=e.languages.coffeescript}(Prism); +!function(e){var r="(?:[ \t]+(?![ \t])(?:)?|)".replace(//g,function(){return"\\\\[\r\n](?:\\s|\\\\[\r\n]|#.*(?!.))*(?![\\s#]|\\\\[\r\n])"}),n="\"(?:[^\"\\\\\r\n]|\\\\(?:\r\n|[^]))*\"|'(?:[^'\\\\\r\n]|\\\\(?:\r\n|[^]))*'",t="--[\\w-]+=(?:|(?![\"'])(?:[^\\s\\\\]|\\\\.)+)".replace(//g,function(){return n}),o={pattern:RegExp(n),greedy:!0},i={pattern:/(^[ \t]*)#.*/m,lookbehind:!0,greedy:!0};function a(e,n){return e=e.replace(//g,function(){return t}).replace(//g,function(){return r}),RegExp(e,n)}e.languages.docker={instruction:{pattern:/(^[ \t]*)(?:ADD|ARG|CMD|COPY|ENTRYPOINT|ENV|EXPOSE|FROM|HEALTHCHECK|LABEL|MAINTAINER|ONBUILD|RUN|SHELL|STOPSIGNAL|USER|VOLUME|WORKDIR)(?=\s)(?:\\.|[^\r\n\\])*(?:\\$(?:\s|#.*$)*(?![\s#])(?:\\.|[^\r\n\\])*)*/im,lookbehind:!0,greedy:!0,inside:{options:{pattern:a("(^(?:ONBUILD)?\\w+)(?:)*","i"),lookbehind:!0,greedy:!0,inside:{property:{pattern:/(^|\s)--[\w-]+/,lookbehind:!0},string:[o,{pattern:/(=)(?!["'])(?:[^\s\\]|\\.)+/,lookbehind:!0}],operator:/\\$/m,punctuation:/=/}},keyword:[{pattern:a("(^(?:ONBUILD)?HEALTHCHECK(?:)*)(?:CMD|NONE)\\b","i"),lookbehind:!0,greedy:!0},{pattern:a("(^(?:ONBUILD)?FROM(?:)*(?!--)[^ \t\\\\]+)AS","i"),lookbehind:!0,greedy:!0},{pattern:a("(^ONBUILD)\\w+","i"),lookbehind:!0,greedy:!0},{pattern:/^\w+/,greedy:!0}],comment:i,string:o,variable:/\$(?:\w+|\{[^{}"'\\]*\})/,operator:/\\$/m}},comment:i},e.languages.dockerfile=e.languages.docker}(Prism); +Prism.languages.go=Prism.languages.extend("clike",{string:{pattern:/(["'`])(?:\\[\s\S]|(?!\1)[^\\])*\1/,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|iota|nil|true|false)\b/,number:/(?:\b0x[a-f\d]+|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[-+]?\d+)?)i?/i,operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:bool|byte|complex(?:64|128)|error|float(?:32|64)|rune|string|u?int(?:8|16|32|64)?|uintptr|append|cap|close|complex|copy|delete|imag|len|make|new|panic|print(?:ln)?|real|recover)\b/}),delete Prism.languages.go["class-name"]; +Prism.languages.ini={comment:/^[ \t]*[;#].*$/m,selector:/^[ \t]*\[.*?\]/m,constant:/^[ \t]*[^\s=]+?(?=[ \t]*=)/m,"attr-value":{pattern:/=.*/,inside:{punctuation:/^[=]/}}}; +!function(e){var t=/\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|non-sealed|null|open|opens|package|permits|private|protected|provides|public|record|requires|return|sealed|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/,n="(^|[^\\w.])(?:[a-z]\\w*\\s*\\.\\s*)*(?:[A-Z]\\w*\\s*\\.\\s*)*",a={pattern:RegExp(n+"[A-Z](?:[\\d_A-Z]*[a-z]\\w*)?\\b"),lookbehind:!0,inside:{namespace:{pattern:/^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/,inside:{punctuation:/\./}},punctuation:/\./}};e.languages.java=e.languages.extend("clike",{"class-name":[a,{pattern:RegExp(n+"[A-Z]\\w*(?=\\s+\\w+\\s*[;,=())])"),lookbehind:!0,inside:a.inside}],keyword:t,function:[e.languages.clike.function,{pattern:/(\:\:\s*)[a-z_]\w*/,lookbehind:!0}],number:/\b0b[01][01_]*L?\b|\b0x(?:\.[\da-f_p+-]+|[\da-f_]+(?:\.[\da-f_p+-]+)?)\b|(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i,operator:{pattern:/(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,lookbehind:!0}}),e.languages.insertBefore("java","string",{"triple-quoted-string":{pattern:/"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,greedy:!0,alias:"string"}}),e.languages.insertBefore("java","class-name",{annotation:{pattern:/(^|[^.])@\w+(?:\s*\.\s*\w+)*/,lookbehind:!0,alias:"punctuation"},generics:{pattern:/<(?:[\w\s,.&?]|<(?:[\w\s,.&?]|<(?:[\w\s,.&?]|<[\w\s,.&?]*>)*>)*>)*>/,inside:{"class-name":a,keyword:t,punctuation:/[<>(),.:]/,operator:/[?&|]/}},namespace:{pattern:RegExp("(\\b(?:exports|import(?:\\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\\s+)(?!)[a-z]\\w*(?:\\.[a-z]\\w*)*\\.?".replace(//g,function(){return t.source})),lookbehind:!0,inside:{punctuation:/\./}}})}(Prism); +Prism.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:true|false)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},Prism.languages.webmanifest=Prism.languages.json; +!function(n){var e=/("|')(?:\\(?:\r\n?|\n|.)|(?!\1)[^\\\r\n])*\1/;n.languages.json5=n.languages.extend("json",{property:[{pattern:RegExp(e.source+"(?=\\s*:)"),greedy:!0},{pattern:/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/,alias:"unquoted"}],string:{pattern:e,greedy:!0},number:/[+-]?\b(?:NaN|Infinity|0x[a-fA-F\d]+)\b|[+-]?(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[eE][+-]?\d+\b)?/})}(Prism); +!function(e){e.languages.kotlin=e.languages.extend("clike",{keyword:{pattern:/(^|[^.])\b(?:abstract|actual|annotation|as|break|by|catch|class|companion|const|constructor|continue|crossinline|data|do|dynamic|else|enum|expect|external|final|finally|for|fun|get|if|import|in|infix|init|inline|inner|interface|internal|is|lateinit|noinline|null|object|open|operator|out|override|package|private|protected|public|reified|return|sealed|set|super|suspend|tailrec|this|throw|to|try|typealias|val|var|vararg|when|where|while)\b/,lookbehind:!0},function:[{pattern:/(?:`[^\r\n`]+`|\w+)(?=\s*\()/,greedy:!0},{pattern:/(\.)(?:`[^\r\n`]+`|\w+)(?=\s*\{)/,lookbehind:!0,greedy:!0}],number:/\b(?:0[xX][\da-fA-F]+(?:_[\da-fA-F]+)*|0[bB][01]+(?:_[01]+)*|\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?(?:[eE][+-]?\d+(?:_\d+)*)?[fFL]?)\b/,operator:/\+[+=]?|-[-=>]?|==?=?|!(?:!|==?)?|[\/*%<>]=?|[?:]:?|\.\.|&&|\|\||\b(?:and|inv|or|shl|shr|ushr|xor)\b/}),delete e.languages.kotlin["class-name"],e.languages.insertBefore("kotlin","string",{"raw-string":{pattern:/("""|''')[\s\S]*?\1/,alias:"string"}}),e.languages.insertBefore("kotlin","keyword",{annotation:{pattern:/\B@(?:\w+:)?(?:[A-Z]\w*|\[[^\]]+\])/,alias:"builtin"}}),e.languages.insertBefore("kotlin","function",{label:{pattern:/\w+@|@\w+/,alias:"symbol"}});var n=[{pattern:/\$\{[^}]+\}/,inside:{delimiter:{pattern:/^\$\{|\}$/,alias:"variable"},rest:e.languages.kotlin}},{pattern:/\$\w+/,alias:"variable"}];e.languages.kotlin.string.inside=e.languages.kotlin["raw-string"].inside={interpolation:n},e.languages.kt=e.languages.kotlin,e.languages.kts=e.languages.kotlin}(Prism); +!function(a){var e=/\\(?:[^a-z()[\]]|[a-z*]+)/i,n={"equation-command":{pattern:e,alias:"regex"}};a.languages.latex={comment:/%.*/m,cdata:{pattern:/(\\begin\{((?:verbatim|lstlisting)\*?)\})[\s\S]*?(?=\\end\{\2\})/,lookbehind:!0},equation:[{pattern:/\$\$(?:\\[\s\S]|[^\\$])+\$\$|\$(?:\\[\s\S]|[^\\$])+\$|\\\([\s\S]*?\\\)|\\\[[\s\S]*?\\\]/,inside:n,alias:"string"},{pattern:/(\\begin\{((?:equation|math|eqnarray|align|multline|gather)\*?)\})[\s\S]*?(?=\\end\{\2\})/,lookbehind:!0,inside:n,alias:"string"}],keyword:{pattern:/(\\(?:begin|end|ref|cite|label|usepackage|documentclass)(?:\[[^\]]+\])?\{)[^}]+(?=\})/,lookbehind:!0},url:{pattern:/(\\url\{)[^}]+(?=\})/,lookbehind:!0},headline:{pattern:/(\\(?:part|chapter|section|subsection|frametitle|subsubsection|paragraph|subparagraph|subsubparagraph|subsubsubparagraph)\*?(?:\[[^\]]+\])?\{)[^}]+(?=\}(?:\[[^\]]+\])?)/,lookbehind:!0,alias:"class-name"},function:{pattern:e,alias:"selector"},punctuation:/[[\]{}&]/},a.languages.tex=a.languages.latex,a.languages.context=a.languages.latex}(Prism); +Prism.languages.less=Prism.languages.extend("css",{comment:[/\/\*[\s\S]*?\*\//,{pattern:/(^|[^\\])\/\/.*/,lookbehind:!0}],atrule:{pattern:/@[\w-](?:\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{punctuation:/[:()]/}},selector:{pattern:/(?:@\{[\w-]+\}|[^{};\s@])(?:@\{[\w-]+\}|\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};@\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{variable:/@+[\w-]+/}},property:/(?:@\{[\w-]+\}|[\w-])+(?:\+_?)?(?=\s*:)/i,operator:/[+\-*\/]/}),Prism.languages.insertBefore("less","property",{variable:[{pattern:/@[\w-]+\s*:/,inside:{punctuation:/:/}},/@@?[\w-]+/],"mixin-usage":{pattern:/([{;]\s*)[.#](?!\d)[\w-].*?(?=[(;])/,lookbehind:!0,alias:"function"}}); +Prism.languages.lua={comment:/^#!.+|--(?:\[(=*)\[[\s\S]*?\]\1\]|.*)/m,string:{pattern:/(["'])(?:(?!\1)[^\\\r\n]|\\z(?:\r\n|\s)|\\(?:\r\n|[^z]))*\1|\[(=*)\[[\s\S]*?\]\2\]/,greedy:!0},number:/\b0x[a-f\d]+(?:\.[a-f\d]*)?(?:p[+-]?\d+)?\b|\b\d+(?:\.\B|(?:\.\d*)?(?:e[+-]?\d+)?\b)|\B\.\d+(?:e[+-]?\d+)?\b/i,keyword:/\b(?:and|break|do|else|elseif|end|false|for|function|goto|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b/,function:/(?!\d)\w+(?=\s*(?:[({]))/,operator:[/[-+*%^&|#]|\/\/?|<[<=]?|>[>=]?|[=~]=?/,{pattern:/(^|[^.])\.\.(?!\.)/,lookbehind:!0}],punctuation:/[\[\](){},;]|\.+|:+/}; +Prism.languages.makefile={comment:{pattern:/(^|[^\\])#(?:\\(?:\r\n|[\s\S])|[^\\\r\n])*/,lookbehind:!0},string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},builtin:/\.[A-Z][^:#=\s]+(?=\s*:(?!=))/,symbol:{pattern:/^(?:[^:=\s]|[ \t]+(?![\s:]))+(?=\s*:(?!=))/m,inside:{variable:/\$+(?:(?!\$)[^(){}:#=\s]+|(?=[({]))/}},variable:/\$+(?:(?!\$)[^(){}:#=\s]+|\([@*%<^+?][DF]\)|(?=[({]))/,keyword:[/-include\b|\b(?:define|else|endef|endif|export|ifn?def|ifn?eq|include|override|private|sinclude|undefine|unexport|vpath)\b/,{pattern:/(\()(?:addsuffix|abspath|and|basename|call|dir|error|eval|file|filter(?:-out)?|findstring|firstword|flavor|foreach|guile|if|info|join|lastword|load|notdir|or|origin|patsubst|realpath|shell|sort|strip|subst|suffix|value|warning|wildcard|word(?:s|list)?)(?=[ \t])/,lookbehind:!0}],operator:/(?:::|[?:+!])?=|[|@]/,punctuation:/[:;(){}]/}; +!function(u){function n(n){return n=n.replace(//g,function(){return"(?:\\\\.|[^\\\\\n\r]|(?:\n|\r\n?)(?!\n|\r\n?))"}),RegExp("((?:^|[^\\\\])(?:\\\\{2})*)(?:"+n+")")}var e="(?:\\\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\\\|\r\n`])+",t="\\|?__(?:\\|__)+\\|?(?:(?:\n|\r\n?)|(?![^]))".replace(/__/g,function(){return e}),a="\\|?[ \t]*:?-{3,}:?[ \t]*(?:\\|[ \t]*:?-{3,}:?[ \t]*)+\\|?(?:\n|\r\n?)";u.languages.markdown=u.languages.extend("markup",{}),u.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"font-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:u.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+t+a+"(?:"+t+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+t+a+")(?:"+t+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(e),inside:u.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+t+")"+a+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+t+"$"),inside:{"table-header":{pattern:RegExp(e),alias:"important",inside:u.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/``.+?``|`[^`\r\n]+`/,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n("\\b__(?:(?!_)|_(?:(?!_))+_)+__\\b|\\*\\*(?:(?!\\*)|\\*(?:(?!\\*))+\\*)+\\*\\*"),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n("\\b_(?:(?!_)|__(?:(?!_))+__)+_\\b|\\*(?:(?!\\*)|\\*\\*(?:(?!\\*))+\\*\\*)+\\*"),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n("(~~?)(?:(?!~))+?\\2"),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},url:{pattern:n('!?\\[(?:(?!\\]))+\\](?:\\([^\\s)]+(?:[\t ]+"(?:\\\\.|[^"\\\\])*")?\\)|[ \t]?\\[(?:(?!\\]))+\\])'),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach(function(e){["url","bold","italic","strike"].forEach(function(n){e!==n&&(u.languages.markdown[e].inside.content.inside[n]=u.languages.markdown[n])})}),u.hooks.add("after-tokenize",function(n){"markdown"!==n.language&&"md"!==n.language||!function n(e){if(e&&"string"!=typeof e)for(var t=0,a=e.length;t=d.length);t++){var a=n[t];if("string"==typeof a||a.content&&"string"==typeof a.content){var r=d[m],o=p.tokenStack[r],c="string"==typeof a?a:a.content,i=v(k,r),u=c.indexOf(i);if(-1]?|\+\+?|!=?|<>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete Prism.languages.objectivec["class-name"],Prism.languages.objc=Prism.languages.objectivec; +!function(a){var e=/\/\*[\s\S]*?\*\/|\/\/.*|#(?!\[).*/,t=[{pattern:/\b(?:false|true)\b/i,alias:"boolean"},{pattern:/(::\s*)\b[a-z_]\w*\b(?!\s*\()/i,greedy:!0,lookbehind:!0},{pattern:/(\b(?:case|const)\s+)\b[a-z_]\w*(?=\s*[;=])/i,greedy:!0,lookbehind:!0},/\b(?:null)\b/i,/\b[A-Z_][A-Z0-9_]*\b(?!\s*\()/],i=/\b0b[01]+(?:_[01]+)*\b|\b0o[0-7]+(?:_[0-7]+)*\b|\b0x[\da-f]+(?:_[\da-f]+)*\b|(?:\b\d+(?:_\d+)*\.?(?:\d+(?:_\d+)*)?|\B\.\d+)(?:e[+-]?\d+)?/i,n=/|\?\?=?|\.{3}|\??->|[!=]=?=?|::|\*\*=?|--|\+\+|&&|\|\||<<|>>|[?~]|[/^|%*&<>.+-]=?/,s=/[{}\[\](),:;]/;a.languages.php={delimiter:{pattern:/\?>$|^<\?(?:php(?=\s)|=)?/i,alias:"important"},comment:e,variable:/\$+(?:\w+\b|(?={))/i,package:{pattern:/(namespace\s+|use\s+(?:function\s+)?)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,lookbehind:!0,inside:{punctuation:/\\/}},"class-name-definition":{pattern:/(\b(?:class|enum|interface|trait)\s+)\b[a-z_]\w*(?!\\)\b/i,lookbehind:!0,alias:"class-name"},keyword:[{pattern:/(\(\s*)\b(?:bool|boolean|int|integer|float|string|object|array)\b(?=\s*\))/i,alias:"type-casting",greedy:!0,lookbehind:!0},{pattern:/([(,?]\s*)\b(?:bool|int|float|string|object|array(?!\s*\()|mixed|self|static|callable|iterable|(?:null|false)(?=\s*\|))\b(?=\s*\$)/i,alias:"type-hint",greedy:!0,lookbehind:!0},{pattern:/([(,?]\s*[a-z0-9_|]\|\s*)(?:null|false)\b(?=\s*\$)/i,alias:"type-hint",greedy:!0,lookbehind:!0},{pattern:/(\)\s*:\s*(?:\?\s*)?)\b(?:bool|int|float|string|object|void|array(?!\s*\()|mixed|self|static|callable|iterable|(?:null|false)(?=\s*\|))\b/i,alias:"return-type",greedy:!0,lookbehind:!0},{pattern:/(\)\s*:\s*(?:\?\s*)?[a-z0-9_|]\|\s*)(?:null|false)\b/i,alias:"return-type",greedy:!0,lookbehind:!0},{pattern:/\b(?:bool|int|float|string|object|void|array(?!\s*\()|mixed|iterable|(?:null|false)(?=\s*\|))\b/i,alias:"type-declaration",greedy:!0},{pattern:/(\|\s*)(?:null|false)\b/i,alias:"type-declaration",greedy:!0,lookbehind:!0},{pattern:/\b(?:parent|self|static)(?=\s*::)/i,alias:"static-context",greedy:!0},/\b(?:__halt_compiler|abstract|and|array|as|break|callable|case|catch|class|clone|const|continue|declare|default|die|do|echo|else|elseif|empty|enddeclare|endfor|endforeach|endif|endswitch|endwhile|enum|eval|exit|extends|final|finally|for|foreach|function|global|goto|if|implements|include|include_once|instanceof|insteadof|interface|isset|list|namespace|match|new|or|parent|print|private|protected|public|require|require_once|return|self|static|switch|throw|trait|try|unset|use|var|while|xor|yield)\b/i],"argument-name":{pattern:/([(,]\s+)\b[a-z_]\w*(?=\s*:(?!:))/i,lookbehind:!0},"class-name":[{pattern:/(\b(?:extends|implements|instanceof|new(?!\s+self|\s+static))\s+|\bcatch\s*\()\b[a-z_]\w*(?!\\)\b/i,greedy:!0,lookbehind:!0},{pattern:/(\|\s*)\b[a-z_]\w*(?!\\)\b/i,greedy:!0,lookbehind:!0},{pattern:/\b[a-z_]\w*(?!\\)\b(?=\s*\|)/i,greedy:!0},{pattern:/(\|\s*)(?:\\?\b[a-z_]\w*)+\b/i,alias:"class-name-fully-qualified",greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/(?:\\?\b[a-z_]\w*)+\b(?=\s*\|)/i,alias:"class-name-fully-qualified",greedy:!0,inside:{punctuation:/\\/}},{pattern:/(\b(?:extends|implements|instanceof|new(?!\s+self\b|\s+static\b))\s+|\bcatch\s*\()(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,alias:"class-name-fully-qualified",greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/\b[a-z_]\w*(?=\s*\$)/i,alias:"type-declaration",greedy:!0},{pattern:/(?:\\?\b[a-z_]\w*)+(?=\s*\$)/i,alias:["class-name-fully-qualified","type-declaration"],greedy:!0,inside:{punctuation:/\\/}},{pattern:/\b[a-z_]\w*(?=\s*::)/i,alias:"static-context",greedy:!0},{pattern:/(?:\\?\b[a-z_]\w*)+(?=\s*::)/i,alias:["class-name-fully-qualified","static-context"],greedy:!0,inside:{punctuation:/\\/}},{pattern:/([(,?]\s*)[a-z_]\w*(?=\s*\$)/i,alias:"type-hint",greedy:!0,lookbehind:!0},{pattern:/([(,?]\s*)(?:\\?\b[a-z_]\w*)+(?=\s*\$)/i,alias:["class-name-fully-qualified","type-hint"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/(\)\s*:\s*(?:\?\s*)?)\b[a-z_]\w*(?!\\)\b/i,alias:"return-type",greedy:!0,lookbehind:!0},{pattern:/(\)\s*:\s*(?:\?\s*)?)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,alias:["class-name-fully-qualified","return-type"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}}],constant:t,function:/\w+\s*(?=\()/,property:{pattern:/(->)[\w]+/,lookbehind:!0},number:i,operator:n,punctuation:s};var l={pattern:/{\$(?:{(?:{[^{}]+}|[^{}]+)}|[^{}])+}|(^|[^\\{])\$+(?:\w+(?:\[[^\r\n\[\]]+\]|->\w+)*)/,lookbehind:!0,inside:a.languages.php},r=[{pattern:/<<<'([^']+)'[\r\n](?:.*[\r\n])*?\1;/,alias:"nowdoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<<'[^']+'|[a-z_]\w*;$/i,alias:"symbol",inside:{punctuation:/^<<<'?|[';]$/}}}},{pattern:/<<<(?:"([^"]+)"[\r\n](?:.*[\r\n])*?\1;|([a-z_]\w*)[\r\n](?:.*[\r\n])*?\2;)/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<<(?:"[^"]+"|[a-z_]\w*)|[a-z_]\w*;$/i,alias:"symbol",inside:{punctuation:/^<<<"?|[";]$/}},interpolation:l}},{pattern:/`(?:\\[\s\S]|[^\\`])*`/,alias:"backtick-quoted-string",greedy:!0},{pattern:/'(?:\\[\s\S]|[^\\'])*'/,alias:"single-quoted-string",greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,alias:"double-quoted-string",greedy:!0,inside:{interpolation:l}}];a.languages.insertBefore("php","variable",{string:r}),a.languages.insertBefore("php","variable",{attribute:{pattern:/#\[(?:[^"'\/#]|\/(?![*/])|\/\/.*$|#(?!\[).*$|\/\*(?:[^*]|\*(?!\/))*\*\/|"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*')+\](?=\s*[a-z$#])/im,greedy:!0,inside:{"attribute-content":{pattern:/^(#\[)[\s\S]+(?=]$)/,lookbehind:!0,inside:{comment:e,string:r,"attribute-class-name":[{pattern:/([^:]|^)\b[a-z_]\w*(?!\\)\b/i,alias:"class-name",greedy:!0,lookbehind:!0},{pattern:/([^:]|^)(?:\\?\b[a-z_]\w*)+/i,alias:["class-name","class-name-fully-qualified"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}}],constant:t,number:i,operator:n,punctuation:s}},delimiter:{pattern:/^#\[|]$/,alias:"punctuation"}}}}),a.hooks.add("before-tokenize",function(e){if(/<\?/.test(e.code)){a.languages["markup-templating"].buildPlaceholders(e,"php",/<\?(?:[^"'/#]|\/(?![*/])|("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|(?:\/\/|#(?!\[))(?:[^?\n\r]|\?(?!>))*(?=$|\?>|[\r\n])|#\[|\/\*(?:[^*]|\*(?!\/))*(?:\*\/|$))*?(?:\?>|$)/gi)}}),a.hooks.add("after-tokenize",function(e){a.languages["markup-templating"].tokenizePlaceholders(e,"php")})}(Prism); +!function(e){var i=Prism.languages.powershell={comment:[{pattern:/(^|[^`])<#[\s\S]*?#>/,lookbehind:!0},{pattern:/(^|[^`])#.*/,lookbehind:!0}],string:[{pattern:/"(?:`[\s\S]|[^`"])*"/,greedy:!0,inside:{function:{pattern:/(^|[^`])\$\((?:\$\([^\r\n()]*\)|(?!\$\()[^\r\n)])*\)/,lookbehind:!0,inside:{}}}},{pattern:/'(?:[^']|'')*'/,greedy:!0}],namespace:/\[[a-z](?:\[(?:\[[^\]]*]|[^\[\]])*]|[^\[\]])*]/i,boolean:/\$(?:true|false)\b/i,variable:/\$\w+\b/,function:[/\b(?:Add|Approve|Assert|Backup|Block|Checkpoint|Clear|Close|Compare|Complete|Compress|Confirm|Connect|Convert|ConvertFrom|ConvertTo|Copy|Debug|Deny|Disable|Disconnect|Dismount|Edit|Enable|Enter|Exit|Expand|Export|Find|ForEach|Format|Get|Grant|Group|Hide|Import|Initialize|Install|Invoke|Join|Limit|Lock|Measure|Merge|Move|New|Open|Optimize|Out|Ping|Pop|Protect|Publish|Push|Read|Receive|Redo|Register|Remove|Rename|Repair|Request|Reset|Resize|Resolve|Restart|Restore|Resume|Revoke|Save|Search|Select|Send|Set|Show|Skip|Sort|Split|Start|Step|Stop|Submit|Suspend|Switch|Sync|Tee|Test|Trace|Unblock|Undo|Uninstall|Unlock|Unprotect|Unpublish|Unregister|Update|Use|Wait|Watch|Where|Write)-[a-z]+\b/i,/\b(?:ac|cat|chdir|clc|cli|clp|clv|compare|copy|cp|cpi|cpp|cvpa|dbp|del|diff|dir|ebp|echo|epal|epcsv|epsn|erase|fc|fl|ft|fw|gal|gbp|gc|gci|gcs|gdr|gi|gl|gm|gp|gps|group|gsv|gu|gv|gwmi|iex|ii|ipal|ipcsv|ipsn|irm|iwmi|iwr|kill|lp|ls|measure|mi|mount|move|mp|mv|nal|ndr|ni|nv|ogv|popd|ps|pushd|pwd|rbp|rd|rdr|ren|ri|rm|rmdir|rni|rnp|rp|rv|rvpa|rwmi|sal|saps|sasv|sbp|sc|select|set|shcm|si|sl|sleep|sls|sort|sp|spps|spsv|start|sv|swmi|tee|trcm|type|write)\b/i],keyword:/\b(?:Begin|Break|Catch|Class|Continue|Data|Define|Do|DynamicParam|Else|ElseIf|End|Exit|Filter|Finally|For|ForEach|From|Function|If|InlineScript|Parallel|Param|Process|Return|Sequence|Switch|Throw|Trap|Try|Until|Using|Var|While|Workflow)\b/i,operator:{pattern:/(\W?)(?:!|-(?:eq|ne|gt|ge|lt|le|sh[lr]|not|b?(?:and|x?or)|(?:Not)?(?:Like|Match|Contains|In)|Replace|Join|is(?:Not)?|as)\b|-[-=]?|\+[+=]?|[*\/%]=?)/i,lookbehind:!0},punctuation:/[|{}[\];(),.]/},r=i.string[0].inside;r.boolean=i.boolean,r.variable=i.variable,r.function.inside=i}(); +Prism.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0},"string-interpolation":{pattern:/(?:f|rf|fr)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:{{)*){(?!{)(?:[^{}]|{(?!{)(?:[^{}]|{(?!{)(?:[^{}])+})+})+}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|rb|br)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|rb|br)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^\s*)@\w+(?:\.\w+)*/im,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:and|as|assert|async|await|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:True|False|None)\b/,number:/(?:\b(?=\d)|\B(?=\.))(?:0[bo])?(?:(?:\d|0x[\da-f])[\da-f]*(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?j?\b/i,operator:/[-+%=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},Prism.languages.python["string-interpolation"].inside.interpolation.inside.rest=Prism.languages.python,Prism.languages.py=Prism.languages.python; +!function(o){var t=o.util.clone(o.languages.javascript),e="(?:\\{*\\.{3}(?:[^{}]|)*\\})";function n(t,n){return t=t.replace(//g,function(){return"(?:\\s|//.*(?!.)|/\\*(?:[^*]|\\*(?!/))\\*/)"}).replace(//g,function(){return"(?:\\{(?:\\{(?:\\{[^{}]*\\}|[^{}])*\\}|[^{}])*\\})"}).replace(//g,function(){return e}),RegExp(t,n)}e=n(e).source,o.languages.jsx=o.languages.extend("markup",t),o.languages.jsx.tag.pattern=n("+(?:[\\w.:$-]+(?:=(?:\"(?:\\\\[^]|[^\\\\\"])*\"|'(?:\\\\[^]|[^\\\\'])*'|[^\\s{'\"/>=]+|))?|))**/?)?>"),o.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/i,o.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[^]|[^\\"])*"|'(?:\\[^]|[^\\'])*'|[^\s'">]+)/i,o.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,o.languages.jsx.tag.inside.comment=t.comment,o.languages.insertBefore("inside","attr-name",{spread:{pattern:n(""),inside:o.languages.jsx}},o.languages.jsx.tag),o.languages.insertBefore("inside","attr-value",{script:{pattern:n("="),inside:{"script-punctuation":{pattern:/^=(?={)/,alias:"punctuation"},rest:o.languages.jsx},alias:"language-javascript"}},o.languages.jsx.tag);var i=function(t){return t?"string"==typeof t?t:"string"==typeof t.content?t.content:t.content.map(i).join(""):""},r=function(t){for(var n=[],e=0;e"===a.content[a.content.length-1].content||n.push({tagName:i(a.content[0].content[1]),openedBraces:0}):0]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},keyword:/\b(?:abstract|as|asserts|async|await|break|case|catch|class|const|constructor|continue|debugger|declare|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|is|keyof|let|module|namespace|new|null|of|package|private|protected|public|readonly|return|require|set|static|super|switch|this|throw|try|type|typeof|undefined|var|void|while|with|yield)\b/,builtin:/\b(?:string|Function|any|number|boolean|Array|symbol|console|Promise|unknown|never)\b/}),delete e.languages.typescript.parameter;var n=e.languages.extend("typescript",{});delete n["class-name"],e.languages.typescript["class-name"].inside=n,e.languages.insertBefore("typescript","function",{"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:n}}}}),e.languages.ts=e.languages.typescript}(Prism); +!function(a){var e=a.util.clone(a.languages.typescript);a.languages.tsx=a.languages.extend("jsx",e);var t=a.languages.tsx.tag;t.pattern=RegExp("(^|[^\\w$]|(?=\\\\]|\\\\[^])*>[gim]{0,3}"].join("|")+")"),greedy:!0,inside:{interpolation:n}},{pattern:/(^|[^/])\/(?!\/)(?:\[[^\r\n\]]+\]|\\.|[^[/\\\r\n])+\/[gim]{0,3}(?=\s*(?:$|[\r\n,.;})]))/,lookbehind:!0,greedy:!0}],variable:/[@$]+[a-zA-Z_]\w*(?:[?!]|\b)/,symbol:{pattern:/(^|[^:]):[a-zA-Z_]\w*(?:[?!]|\b)/,lookbehind:!0},"method-definition":{pattern:/(\bdef\s+)[\w.]+/,lookbehind:!0,inside:{function:/\w+$/,rest:e.languages.ruby}}}),e.languages.insertBefore("ruby","number",{builtin:/\b(?:Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Stat|Fixnum|Float|Hash|Integer|IO|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|String|Struct|TMS|Symbol|ThreadGroup|Thread|Time|TrueClass)\b/,constant:/\b[A-Z]\w*(?:[?!]|\b)/}),e.languages.ruby.string=[{pattern:RegExp("%[qQiIwWxs]?(?:"+["([^a-zA-Z0-9\\s{(\\[<])(?:(?!\\1)[^\\\\]|\\\\[^])*\\1","\\((?:[^()\\\\]|\\\\[^])*\\)","\\{(?:[^#{}\\\\]|#(?:\\{[^}]+\\})?|\\\\[^])*\\}","\\[(?:[^\\[\\]\\\\]|\\\\[^])*\\]","<(?:[^<>\\\\]|\\\\[^])*>"].join("|")+")"),greedy:!0,inside:{interpolation:n}},{pattern:/("|')(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|(?!\1)[^\\#\r\n])*\1/,greedy:!0,inside:{interpolation:n}}],e.languages.rb=e.languages.ruby}(Prism); +!function(e){for(var a="/\\*(?:[^*/]|\\*(?!/)|/(?!\\*)|)*\\*/",t=0;t<2;t++)a=a.replace(//g,function(){return a});a=a.replace(//g,function(){return"[^\\s\\S]"}),e.languages.rust={comment:[{pattern:RegExp("(^|[^\\\\])"+a),lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/b?"(?:\\[\s\S]|[^\\"])*"|b?r(#*)"(?:[^"]|"(?!\1))*"\1/,greedy:!0},char:{pattern:/b?'(?:\\(?:x[0-7][\da-fA-F]|u\{(?:[\da-fA-F]_*){1,6}\}|.)|[^\\\r\n\t'])'/,greedy:!0,alias:"string"},attribute:{pattern:/#!?\[(?:[^\[\]"]|"(?:\\[\s\S]|[^\\"])*")*\]/,greedy:!0,alias:"attr-name",inside:{string:null}},"closure-params":{pattern:/([=(,:]\s*|\bmove\s*)\|[^|]*\||\|[^|]*\|(?=\s*(?:\{|->))/,lookbehind:!0,greedy:!0,inside:{"closure-punctuation":{pattern:/^\||\|$/,alias:"punctuation"},rest:null}},"lifetime-annotation":{pattern:/'\w+/,alias:"symbol"},"fragment-specifier":{pattern:/(\$\w+:)[a-z]+/,lookbehind:!0,alias:"punctuation"},variable:/\$\w+/,"function-definition":{pattern:/(\bfn\s+)\w+/,lookbehind:!0,alias:"function"},"type-definition":{pattern:/(\b(?:enum|struct|union)\s+)\w+/,lookbehind:!0,alias:"class-name"},"module-declaration":[{pattern:/(\b(?:crate|mod)\s+)[a-z][a-z_\d]*/,lookbehind:!0,alias:"namespace"},{pattern:/(\b(?:crate|self|super)\s*)::\s*[a-z][a-z_\d]*\b(?:\s*::(?:\s*[a-z][a-z_\d]*\s*::)*)?/,lookbehind:!0,alias:"namespace",inside:{punctuation:/::/}}],keyword:[/\b(?:abstract|as|async|await|become|box|break|const|continue|crate|do|dyn|else|enum|extern|final|fn|for|if|impl|in|let|loop|macro|match|mod|move|mut|override|priv|pub|ref|return|self|Self|static|struct|super|trait|try|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/,/\b(?:[ui](?:8|16|32|64|128|size)|f(?:32|64)|bool|char|str)\b/],function:/\b[a-z_]\w*(?=\s*(?:::\s*<|\())/,macro:{pattern:/\w+!/,alias:"property"},constant:/\b[A-Z_][A-Z_\d]+\b/,"class-name":/\b[A-Z]\w*\b/,namespace:{pattern:/(?:\b[a-z][a-z_\d]*\s*::\s*)*\b[a-z][a-z_\d]*\s*::(?!\s*<)/,inside:{punctuation:/::/}},number:/\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(?:(?:\d(?:_?\d)*)?\.)?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:[iu](?:8|16|32|64|size)?|f32|f64))?\b/,boolean:/\b(?:false|true)\b/,punctuation:/->|\.\.=|\.{1,3}|::|[{}[\];(),:]/,operator:/[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<>?=?|[@?]/},e.languages.rust["closure-params"].inside.rest=e.languages.rust,e.languages.rust.attribute.inside.string=e.languages.rust.string}(Prism); +!function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t].+)*/m,lookbehind:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,inside:{atrule:/(?:@[\w-]+|[+=])/m}}}),delete e.languages.sass.atrule;var t=/\$[-\w]+|#\{\$[-\w]+\}/,a=[/[+*\/%]|[=!]=|<=?|>=?|\b(?:and|or|not)\b/,{pattern:/(\s+)-(?=\s)/,lookbehind:!0}];e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,inside:{punctuation:/:/,variable:t,operator:a}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s].*)/m,inside:{property:[/[^:\s]+(?=\s*:)/,{pattern:/(:)[^:\s]+/,lookbehind:!0}],punctuation:/:/,variable:t,operator:a,important:e.languages.sass.important}}}),delete e.languages.sass.property,delete e.languages.sass.important,e.languages.insertBefore("sass","punctuation",{selector:{pattern:/([ \t]*)\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*)*/,lookbehind:!0}})}(Prism); +Prism.languages.scss=Prism.languages.extend("css",{comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},atrule:{pattern:/@[\w-](?:\([^()]+\)|[^()\s]|\s+(?!\s))*?(?=\s+[{;])/,inside:{rule:/@[\w-]+/}},url:/(?:[-a-z]+-)?url(?=\()/i,selector:{pattern:/(?=\S)[^@;{}()]?(?:[^@;{}()\s]|\s+(?!\s)|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}][^:{}]*[:{][^}]+))/m,inside:{parent:{pattern:/&/,alias:"important"},placeholder:/%[-\w]+/,variable:/\$[-\w]+|#\{\$[-\w]+\}/}},property:{pattern:/(?:[-\w]|\$[-\w]|#\{\$[-\w]+\})+(?=\s*:)/,inside:{variable:/\$[-\w]+|#\{\$[-\w]+\}/}}}),Prism.languages.insertBefore("scss","atrule",{keyword:[/@(?:if|else(?: if)?|forward|for|each|while|import|use|extend|debug|warn|mixin|include|function|return|content)\b/i,{pattern:/( +)(?:from|through)(?= )/,lookbehind:!0}]}),Prism.languages.insertBefore("scss","important",{variable:/\$[-\w]+|#\{\$[-\w]+\}/}),Prism.languages.insertBefore("scss","function",{"module-modifier":{pattern:/\b(?:as|with|show|hide)\b/i,alias:"keyword"},placeholder:{pattern:/%[-\w]+/,alias:"selector"},statement:{pattern:/\B!(?:default|optional)\b/i,alias:"keyword"},boolean:/\b(?:true|false)\b/,null:{pattern:/\bnull\b/,alias:"keyword"},operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|or|not)(?=\s)/,lookbehind:!0}}),Prism.languages.scss.atrule.inside.rest=Prism.languages.scss; +!function(s){var n=["([\"'])(?:\\\\[^]|\\$\\([^)]+\\)|\\$(?!\\()|`[^`]+`|(?!\\1)[^\\\\`$])*\\1","<<-?\\s*([\"']?)(\\w+)\\2\\s[^]*?[\r\n]\\3"].join("|");s.languages["shell-session"]={command:{pattern:RegExp('^(?:[^\\s@:$#*!/\\\\]+@[^\\s@:$#*!/\\\\]+(?::[^\0-\\x1F$#*?"<>:;|]+)?|[^\0-\\x1F$#*?"<>:;|]+)?[$#](?:[^\\\\\r\n\'"<]|\\\\.|<>)+'.replace(/<>/g,function(){return n}),"m"),greedy:!0,inside:{info:{pattern:/^[^#$]+/,alias:"punctuation",inside:{user:/^[^\s@:$#*!/\\]+@[^\s@:$#*!/\\]+/,punctuation:/:/,path:/[\s\S]+/}},bash:{pattern:/(^[$#]\s*)\S[\s\S]*/,lookbehind:!0,alias:"language-bash",inside:s.languages.bash},"shell-symbol":{pattern:/^[$#]/,alias:"important"}}},output:/.(?:.*(?:[\r\n]|.$))*/},s.languages["sh-session"]=s.languages.shellsession=s.languages["shell-session"]}(Prism); +Prism.languages.sql={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/,lookbehind:!0},variable:[{pattern:/@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/,greedy:!0},/@[\w.$]+/],string:{pattern:/(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\]|\2\2)*\2/,greedy:!0,lookbehind:!0},function:/\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\s*\()/i,keyword:/\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:_INSERT|COL)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURN(?:S|ING)?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i,boolean:/\b(?:TRUE|FALSE|NULL)\b/i,number:/\b0x[\da-f]+\b|\b\d+(?:\.\d*)?|\B\.\d+\b/i,operator:/[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|IN|ILIKE|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/}; +Prism.languages.swift=Prism.languages.extend("clike",{string:{pattern:/("|')(?:\\(?:\((?:[^()]|\([^)]+\))+\)|\r\n|[^(])|(?!\1)[^\\\r\n])*\1/,greedy:!0,inside:{interpolation:{pattern:/\\\((?:[^()]|\([^)]+\))+\)/,inside:{delimiter:{pattern:/^\\\(|\)$/,alias:"variable"}}}}},keyword:/\b(?:as|associativity|break|case|catch|class|continue|convenience|default|defer|deinit|didSet|do|dynamic(?:Type)?|else|enum|extension|fallthrough|final|for|func|get|guard|if|import|in|infix|init|inout|internal|is|lazy|left|let|mutating|new|none|nonmutating|operator|optional|override|postfix|precedence|prefix|private|protocol|public|repeat|required|rethrows|return|right|safe|self|Self|set|some|static|struct|subscript|super|switch|throws?|try|Type|typealias|unowned|unsafe|var|weak|where|while|willSet|__(?:COLUMN__|FILE__|FUNCTION__|LINE__))\b/,number:/\b(?:[\d_]+(?:\.[\de_]+)?|0x[a-f0-9_]+(?:\.[a-f0-9p_]+)?|0b[01_]+|0o[0-7_]+)\b/i,constant:/\b(?:nil|[A-Z_]{2,}|k[A-Z][A-Za-z_]+)\b/,atrule:/@\b(?:IB(?:Outlet|Designable|Action|Inspectable)|class_protocol|exported|noreturn|NS(?:Copying|Managed)|objc|UIApplicationMain|auto_closure)\b/,builtin:/\b(?:[A-Z]\S+|abs|advance|alignof(?:Value)?|assert|contains|count(?:Elements)?|debugPrint(?:ln)?|distance|drop(?:First|Last)|dump|enumerate|equal|filter|find|first|getVaList|indices|isEmpty|join|last|lexicographicalCompare|map|max(?:Element)?|min(?:Element)?|numericCast|overlaps|partition|print(?:ln)?|reduce|reflect|reverse|sizeof(?:Value)?|sort(?:ed)?|split|startsWith|stride(?:of(?:Value)?)?|suffix|swap|toDebugString|toString|transcode|underestimateCount|unsafeBitCast|with(?:ExtendedLifetime|Unsafe(?:MutablePointers?|Pointers?)|VaList))\b/}),Prism.languages.swift.string.inside.interpolation.inside.rest=Prism.languages.swift; +!function(n){function e(n,e){return RegExp(n.replace(//g,function(){return"(?:\\([^|()\n]+\\)|\\[[^\\]\n]+\\]|\\{[^}\n]+\\})"}).replace(//g,function(){return"(?:\\)|\\((?![^|()\n]+\\)))"}),e||"")}var i={css:{pattern:/\{[^}]+\}/,inside:{rest:n.languages.css}},"class-id":{pattern:/(\()[^)]+(?=\))/,lookbehind:!0,alias:"attr-value"},lang:{pattern:/(\[)[^\]]+(?=\])/,lookbehind:!0,alias:"attr-value"},punctuation:/[\\\/]\d+|\S/},t=n.languages.textile=n.languages.extend("markup",{phrase:{pattern:/(^|\r|\n)\S[\s\S]*?(?=$|\r?\n\r?\n|\r\r)/,lookbehind:!0,inside:{"block-tag":{pattern:e("^[a-z]\\w*(?:||[<>=])*\\."),inside:{modifier:{pattern:e("(^[a-z]\\w*)(?:||[<>=])+(?=\\.)"),lookbehind:!0,inside:i},tag:/^[a-z]\w*/,punctuation:/\.$/}},list:{pattern:e("^[*#]+*\\s+\\S.*","m"),inside:{modifier:{pattern:e("(^[*#]+)+"),lookbehind:!0,inside:i},punctuation:/^[*#]+/}},table:{pattern:e("^(?:(?:||[<>=^~])+\\.\\s*)?(?:\\|(?:(?:||[<>=^~_]|[\\\\/]\\d+)+\\.|(?!(?:||[<>=^~_]|[\\\\/]\\d+)+\\.))[^|]*)+\\|","m"),inside:{modifier:{pattern:e("(^|\\|(?:\r?\n|\r)?)(?:||[<>=^~_]|[\\\\/]\\d+)+(?=\\.)"),lookbehind:!0,inside:i},punctuation:/\||^\./}},inline:{pattern:e("(^|[^a-zA-Z\\d])(\\*\\*|__|\\?\\?|[*_%@+\\-^~])*.+?\\2(?![a-zA-Z\\d])"),lookbehind:!0,inside:{bold:{pattern:e("(^(\\*\\*?)*).+?(?=\\2)"),lookbehind:!0},italic:{pattern:e("(^(__?)*).+?(?=\\2)"),lookbehind:!0},cite:{pattern:e("(^\\?\\?*).+?(?=\\?\\?)"),lookbehind:!0,alias:"string"},code:{pattern:e("(^@*).+?(?=@)"),lookbehind:!0,alias:"keyword"},inserted:{pattern:e("(^\\+*).+?(?=\\+)"),lookbehind:!0},deleted:{pattern:e("(^-*).+?(?=-)"),lookbehind:!0},span:{pattern:e("(^%*).+?(?=%)"),lookbehind:!0},modifier:{pattern:e("(^\\*\\*|__|\\?\\?|[*_%@+\\-^~])+"),lookbehind:!0,inside:i},punctuation:/[*_%?@+\-^~]+/}},"link-ref":{pattern:/^\[[^\]]+\]\S+$/m,inside:{string:{pattern:/(\[)[^\]]+(?=\])/,lookbehind:!0},url:{pattern:/(\])\S+$/,lookbehind:!0},punctuation:/[\[\]]/}},link:{pattern:e('"*[^"]+":.+?(?=[^\\w/]?(?:\\s|$))'),inside:{text:{pattern:e('(^"*)[^"]+(?=")'),lookbehind:!0},modifier:{pattern:e('(^")+'),lookbehind:!0,inside:i},url:{pattern:/(:).+/,lookbehind:!0},punctuation:/[":]/}},image:{pattern:e("!(?:||[<>=])*(?![<>=])[^!\\s()]+(?:\\([^)]+\\))?!(?::.+?(?=[^\\w/]?(?:\\s|$)))?"),inside:{source:{pattern:e("(^!(?:||[<>=])*)(?![<>=])[^!\\s()]+(?:\\([^)]+\\))?(?=!)"),lookbehind:!0,alias:"url"},modifier:{pattern:e("(^!)(?:||[<>=])+"),lookbehind:!0,inside:i},url:{pattern:/(:).+/,lookbehind:!0},punctuation:/[!:]/}},footnote:{pattern:/\b\[\d+\]/,alias:"comment",inside:{punctuation:/\[|\]/}},acronym:{pattern:/\b[A-Z\d]+\([^)]+\)/,inside:{comment:{pattern:/(\()[^)]+(?=\))/,lookbehind:!0},punctuation:/[()]/}},mark:{pattern:/\b\((?:TM|R|C)\)/,alias:"comment",inside:{punctuation:/[()]/}}}}}),a=t.phrase.inside,o={inline:a.inline,link:a.link,image:a.image,footnote:a.footnote,acronym:a.acronym,mark:a.mark};t.tag.pattern=/<\/?(?!\d)[a-z0-9]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+))?)*\s*\/?>/i;var r=a.inline.inside;r.bold.inside=o,r.italic.inside=o,r.inserted.inside=o,r.deleted.inside=o,r.span.inside=o;var d=a.table.inside;d.inline=o.inline,d.link=o.link,d.image=o.image,d.footnote=o.footnote,d.acronym=o.acronym,d.mark=o.mark}(Prism); +!function(e){var n=/[*&][^\s[\]{},]+/,r=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,t="(?:"+r.source+"(?:[ \t]+"+n.source+")?|"+n.source+"(?:[ \t]+"+r.source+")?)",a="(?:[^\\s\\x00-\\x08\\x0e-\\x1f!\"#%&'*,\\-:>?@[\\]`{|}\\x7f-\\x84\\x86-\\x9f\\ud800-\\udfff\\ufffe\\uffff]|[?:-])(?:[ \t]*(?:(?![#:])|:))*".replace(//g,function(){return"[^\\s\\x00-\\x08\\x0e-\\x1f,[\\]{}\\x7f-\\x84\\x86-\\x9f\\ud800-\\udfff\\ufffe\\uffff]"}),d="\"(?:[^\"\\\\\r\n]|\\\\.)*\"|'(?:[^'\\\\\r\n]|\\\\.)*'";function o(e,n){n=(n||"").replace(/m/g,"")+"m";var r="([:\\-,[{]\\s*(?:\\s<>[ \t]+)?)(?:<>)(?=[ \t]*(?:$|,|]|}|(?:[\r\n]\\s*)?#))".replace(/<>/g,function(){return t}).replace(/<>/g,function(){return e});return RegExp(r,n)}e.languages.yaml={scalar:{pattern:RegExp("([\\-:]\\s*(?:\\s<>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\\S[^\r\n]*(?:\\2[^\r\n]+)*)".replace(/<>/g,function(){return t})),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp("((?:^|[:\\-,[{\r\n?])[ \t]*(?:<>[ \t]+)?)<>(?=\\s*:\\s)".replace(/<>/g,function(){return t}).replace(/<>/g,function(){return"(?:"+a+"|"+d+")"})),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:o("\\d{4}-\\d\\d?-\\d\\d?(?:[tT]|[ \t]+)\\d\\d?:\\d{2}:\\d{2}(?:\\.\\d*)?(?:[ \t]*(?:Z|[-+]\\d\\d?(?::\\d{2})?))?|\\d{4}-\\d{2}-\\d{2}|\\d\\d?:\\d{2}(?::\\d{2}(?:\\.\\d*)?)?"),lookbehind:!0,alias:"number"},boolean:{pattern:o("true|false","i"),lookbehind:!0,alias:"important"},null:{pattern:o("null|~","i"),lookbehind:!0,alias:"important"},string:{pattern:o(d),lookbehind:!0,greedy:!0},number:{pattern:o("[+-]?(?:0x[\\da-f]+|0o[0-7]+|(?:\\d+(?:\\.\\d*)?|\\.?\\d+)(?:e[+-]?\\d+)?|\\.inf|\\.nan)","i"),lookbehind:!0},tag:r,important:n,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(Prism); +!function(){if("undefined"!=typeof self&&self.Prism&&self.document){var o="line-numbers",a=/\n(?!$)/g,e=Prism.plugins.lineNumbers={getLine:function(e,n){if("PRE"===e.tagName&&e.classList.contains(o)){var t=e.querySelector(".line-numbers-rows");if(t){var i=parseInt(e.getAttribute("data-start"),10)||1,r=i+(t.children.length-1);n");(i=document.createElement("span")).setAttribute("aria-hidden","true"),i.className="line-numbers-rows",i.innerHTML=l,t.hasAttribute("data-start")&&(t.style.counterReset="linenumber "+(parseInt(t.getAttribute("data-start"),10)-1)),e.element.appendChild(i),u([t]),Prism.hooks.run("line-numbers",e)}}}),Prism.hooks.add("line-numbers",function(e){e.plugins=e.plugins||{},e.plugins.lineNumbers=!0})}function u(e){if(0!=(e=e.filter(function(e){var n=t(e)["white-space"];return"pre-wrap"===n||"pre-line"===n})).length){var n=e.map(function(e){var n=e.querySelector("code"),t=e.querySelector(".line-numbers-rows");if(n&&t){var i=e.querySelector(".line-numbers-sizer"),r=n.textContent.split(a);i||((i=document.createElement("span")).className="line-numbers-sizer",n.appendChild(i)),i.innerHTML="0",i.style.display="block";var s=i.getBoundingClientRect().height;return i.innerHTML="",{element:e,lines:r,lineHeights:[],oneLinerHeight:s,sizer:i}}}).filter(Boolean);n.forEach(function(e){var i=e.sizer,n=e.lines,r=e.lineHeights,s=e.oneLinerHeight;r[n.length-1]=void 0,n.forEach(function(e,n){if(e&&1img{height:auto;margin:15px auto;max-width:90%!important;width:auto}.viewer-footer{bottom:0;left:0;overflow:hidden;position:absolute;right:0;text-align:center}.viewer-navbar{background-color:rgba(0,0,0,.5);overflow:hidden}.viewer-list{-webkit-box-sizing:content-box;box-sizing:content-box;height:50px;margin:0;overflow:hidden;padding:1px 0}.viewer-list>li{color:transparent;cursor:pointer;float:left;font-size:0;height:50px;line-height:0;opacity:.5;overflow:hidden;-webkit-transition:opacity .15s;transition:opacity .15s;width:30px}.viewer-list>li:focus,.viewer-list>li:hover{opacity:.75}.viewer-list>li:focus{outline:0}.viewer-list>li+li{margin-left:1px}.viewer-list>.viewer-loading{position:relative}.viewer-list>.viewer-loading:after{border-width:2px;height:20px;margin-left:-10px;margin-top:-10px;width:20px}.viewer-list>.viewer-active,.viewer-list>.viewer-active:focus,.viewer-list>.viewer-active:hover{opacity:1}.viewer-player{background-color:#000;bottom:0;cursor:none;display:none;right:0;z-index:1}.viewer-player,.viewer-player>img{left:0;position:absolute;top:0}.viewer-toolbar>ul{display:inline-block;margin:0 auto 5px;overflow:hidden;padding:6px 3px}.viewer-toolbar>ul>li{background-color:rgba(0,0,0,.5);border-radius:50%;cursor:pointer;float:left;height:24px;overflow:hidden;-webkit-transition:background-color .15s;transition:background-color .15s;width:24px}.viewer-toolbar>ul>li:focus,.viewer-toolbar>ul>li:hover{background-color:rgba(0,0,0,.8)}.viewer-toolbar>ul>li:focus{-webkit-box-shadow:0 0 3px #fff;box-shadow:0 0 3px #fff;outline:0;position:relative;z-index:1}.viewer-toolbar>ul>li:before{margin:2px}.viewer-toolbar>ul>li+li{margin-left:1px}.viewer-toolbar>ul>.viewer-small{height:18px;margin-bottom:3px;margin-top:3px;width:18px}.viewer-toolbar>ul>.viewer-small:before{margin:-1px}.viewer-toolbar>ul>.viewer-large{height:30px;margin-bottom:-3px;margin-top:-3px;width:30px}.viewer-toolbar>ul>.viewer-large:before{margin:5px}.viewer-tooltip{background-color:rgba(0,0,0,.8);border-radius:10px;color:#fff;display:none;font-size:12px;height:20px;left:50%;line-height:20px;margin-left:-25px;margin-top:-10px;position:absolute;text-align:center;top:50%;width:50px}.viewer-title{color:#ccc;display:inline-block;font-size:12px;line-height:1;margin:0 5% 5px;max-width:90%;opacity:.8;overflow:hidden;text-overflow:ellipsis;-webkit-transition:opacity .15s;transition:opacity .15s;white-space:nowrap}.viewer-title:hover{opacity:1}.viewer-button{background-color:rgba(0,0,0,.5);border-radius:50%;cursor:pointer;height:80px;overflow:hidden;position:absolute;right:-40px;top:-40px;-webkit-transition:background-color .15s;transition:background-color .15s;width:80px}.viewer-button:focus,.viewer-button:hover{background-color:rgba(0,0,0,.8)}.viewer-button:focus{-webkit-box-shadow:0 0 3px #fff;box-shadow:0 0 3px #fff;outline:0}.viewer-button:before{bottom:15px;left:15px;position:absolute}.viewer-fixed{position:fixed}.viewer-open{overflow:hidden}.viewer-show{display:block}.viewer-hide{display:none}.viewer-backdrop{background-color:rgba(0,0,0,.5)}.viewer-invisible{visibility:hidden}.viewer-move{cursor:move;cursor:-webkit-grab;cursor:grab}.viewer-fade{opacity:0}.viewer-in{opacity:1}.viewer-transition{-webkit-transition:all .3s;transition:all .3s}@-webkit-keyframes viewer-spinner{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes viewer-spinner{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.viewer-loading:after{-webkit-animation:viewer-spinner 1s linear infinite;animation:viewer-spinner 1s linear infinite;border:4px solid hsla(0,0%,100%,.1);border-left-color:hsla(0,0%,100%,.5);border-radius:50%;content:"";display:inline-block;height:40px;left:50%;margin-left:-20px;margin-top:-20px;position:absolute;top:50%;width:40px;z-index:1}@media (max-width:767px){.viewer-hide-xs-down{display:none}}@media (max-width:991px){.viewer-hide-sm-down{display:none}}@media (max-width:1199px){.viewer-hide-md-down{display:none}} \ No newline at end of file diff --git a/maixpy/static/image/body_keypoint.jpg b/maixpy/static/image/body_keypoint.jpg new file mode 100644 index 00000000..5e0e14e0 Binary files /dev/null and b/maixpy/static/image/body_keypoint.jpg differ diff --git a/maixpy/static/image/camera.png b/maixpy/static/image/camera.png new file mode 100644 index 00000000..0fa70af0 Binary files /dev/null and b/maixpy/static/image/camera.png differ diff --git a/maixpy/static/image/face_recognize.jpg b/maixpy/static/image/face_recognize.jpg new file mode 100644 index 00000000..c04f89e2 Binary files /dev/null and b/maixpy/static/image/face_recognize.jpg differ diff --git a/maixpy/static/image/find_blobs_app.jpg b/maixpy/static/image/find_blobs_app.jpg new file mode 100644 index 00000000..f01d0932 Binary files /dev/null and b/maixpy/static/image/find_blobs_app.jpg differ diff --git a/maixpy/static/image/github-fill.svg b/maixpy/static/image/github-fill.svg new file mode 100644 index 00000000..d3fd1f6d --- /dev/null +++ b/maixpy/static/image/github-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/maixpy/static/image/hdmi_capture.jpg b/maixpy/static/image/hdmi_capture.jpg new file mode 100644 index 00000000..969c77c9 Binary files /dev/null and b/maixpy/static/image/hdmi_capture.jpg differ diff --git a/maixpy/static/image/language.svg b/maixpy/static/image/language.svg new file mode 100644 index 00000000..b1903d01 --- /dev/null +++ b/maixpy/static/image/language.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/maixpy/static/image/line_tracking_demo.jpg b/maixpy/static/image/line_tracking_demo.jpg new file mode 100644 index 00000000..3bd95870 Binary files /dev/null and b/maixpy/static/image/line_tracking_demo.jpg differ diff --git a/maixpy/static/image/maix-ecosystem.excalidraw b/maixpy/static/image/maix-ecosystem.excalidraw new file mode 100644 index 00000000..794d2bd5 --- /dev/null +++ b/maixpy/static/image/maix-ecosystem.excalidraw @@ -0,0 +1,974 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "type": "rectangle", + "version": 149, + "versionNonce": 170295430, + "isDeleted": false, + "id": "lgDrdWXT9bbyk2trMN6Vw", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 542, + "y": 545, + "strokeColor": "#343a40", + "backgroundColor": "transparent", + "width": 602.8055468764685, + "height": 133, + "seed": 1518581314, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1705903395747, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 171, + "versionNonce": 1910780634, + "isDeleted": false, + "id": "yN5xUSW8oMw5XX3EP_QN5", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 543.8055468764685, + "y": 480.0277343823424, + "strokeColor": "#343a40", + "backgroundColor": "transparent", + "width": 602.388906247063, + "height": 64, + "seed": 1257741826, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1705903395747, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 196, + "versionNonce": 869302214, + "isDeleted": false, + "id": "pZsOD-erMl2GhwgdB3len", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 544.3303130110232, + "y": 415.05640610609106, + "strokeColor": "#343a40", + "backgroundColor": "transparent", + "width": 602.388906247063, + "height": 64, + "seed": 471371202, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1705903395747, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 110, + "versionNonce": 256690074, + "isDeleted": false, + "id": "-bPjeuUMFo6K5trDKlsX1", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 541.0280468294778, + "y": 263.3917182712827, + "strokeColor": "#343a40", + "backgroundColor": "transparent", + "width": 604.1601573513434, + "height": 150.63726589960157, + "seed": 1124435330, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1705903395747, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 140, + "versionNonce": 1853396742, + "isDeleted": false, + "id": "lfgD3TSEibNF4UEOT65O6", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 822.1639067169694, + "y": 263.3917182712827, + "strokeColor": "#343a40", + "backgroundColor": "transparent", + "width": 323.0242974638518, + "height": 116.80429708792639, + "seed": 956138818, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "jFsobJvvk3oLsXpIMZZGR" + } + ], + "updated": 1705903395747, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 53, + "versionNonce": 1145357402, + "isDeleted": false, + "id": "jFsobJvvk3oLsXpIMZZGR", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 876.139831083661, + "y": 291.7938668152459, + "strokeColor": "#343a40", + "backgroundColor": "transparent", + "width": 215.07244873046875, + "height": 60, + "seed": 1960559838, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1705903395747, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "MaixPy\nPython API\n(Auto Sync with MaixCDK)", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "lfgD3TSEibNF4UEOT65O6", + "originalText": "MaixPy\nPython API\n(Auto Sync with MaixCDK)", + "lineHeight": 1.25, + "baseline": 55 + }, + { + "type": "rectangle", + "version": 148, + "versionNonce": 580634182, + "isDeleted": false, + "id": "4EvFUYMCaR0VTnX-qZHxz", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 957.7240489190394, + "y": -159.09379322492532, + "strokeColor": "#343a40", + "backgroundColor": "transparent", + "width": 186.8868753406823, + "height": 420.0688708668026, + "seed": 2002750722, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "87m8Zy2thgUpCwI3aLGLU" + } + ], + "updated": 1705903395747, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 88, + "versionNonce": 983509274, + "isDeleted": false, + "id": "87m8Zy2thgUpCwI3aLGLU", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 962.9272827319587, + "y": 0.9406422084759924, + "strokeColor": "#343a40", + "backgroundColor": "transparent", + "width": 176.48040771484375, + "height": 100, + "seed": 322530910, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1705903395747, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "MaixVision Workstation\n\npython coding, camera\npreview, graphic coding,\ncamera monitor...", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "4EvFUYMCaR0VTnX-qZHxz", + "originalText": "MaixVision Workstation\n\npython coding, camera preview, graphic coding, camera monitor...", + "lineHeight": 1.25, + "baseline": 95 + }, + { + "type": "rectangle", + "version": 304, + "versionNonce": 555158918, + "isDeleted": false, + "id": "EcrNFNI6yL92AoSlIWVVO", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 544.3798973239758, + "y": -160.84555157963533, + "strokeColor": "#343a40", + "backgroundColor": "transparent", + "width": 413.2455476283189, + "height": 297.55670053920767, + "seed": 1940561090, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1705903395747, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 411, + "versionNonce": 1775171034, + "isDeleted": false, + "id": "rRCFAQjwm1vnYBnizXNgV", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 645.073256882533, + "y": -152.95838497869576, + "strokeColor": "#343a40", + "backgroundColor": "transparent", + "width": 152.7585529775803, + "height": 137.38091739682395, + "seed": 461223042, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "IljY5UxdaUGFHT9sh3TVh" + } + ], + "updated": 1705903395747, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 206, + "versionNonce": 388459718, + "isDeleted": false, + "id": "IljY5UxdaUGFHT9sh3TVh", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 659.1804157565771, + "y": -104.26792628028379, + "strokeColor": "#343a40", + "backgroundColor": "transparent", + "width": 124.54423522949219, + "height": 40, + "seed": 1150609118, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1705903395747, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "AI model online \ntraining", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "rRCFAQjwm1vnYBnizXNgV", + "originalText": "AI model online training", + "lineHeight": 1.25, + "baseline": 35 + }, + { + "type": "rectangle", + "version": 429, + "versionNonce": 1659316890, + "isDeleted": false, + "id": "-s8ub4VAaSqSgcxn_ClB6", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 806.195982956134, + "y": -152.1965882262943, + "strokeColor": "#343a40", + "backgroundColor": "transparent", + "width": 143.40089934047262, + "height": 135.41277270964167, + "seed": 1352127554, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "HiKrFzJa43Cm5SmFjQ47Z" + } + ], + "updated": 1705903395747, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 209, + "versionNonce": 40494086, + "isDeleted": false, + "id": "HiKrFzJa43Cm5SmFjQ47Z", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 813.1922929168977, + "y": -94.49020187147346, + "strokeColor": "#343a40", + "backgroundColor": "transparent", + "width": 129.4082794189453, + "height": 20, + "seed": 1527204318, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1705903395747, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "AI model sharing", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "-s8ub4VAaSqSgcxn_ClB6", + "originalText": "AI model sharing", + "lineHeight": 1.25, + "baseline": 15 + }, + { + "type": "rectangle", + "version": 471, + "versionNonce": 479905626, + "isDeleted": false, + "id": "4LZjGT8mwEbDX3LZWxl6R", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 645.8346979642795, + "y": -8.461871689459826, + "strokeColor": "#343a40", + "backgroundColor": "transparent", + "width": 151.86479451166826, + "height": 139.42752107389416, + "seed": 1691876354, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "K0Wr4IrqdbZ8pYoLS5o9U" + } + ], + "updated": 1705903395747, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 213, + "versionNonce": 618361670, + "isDeleted": false, + "id": "K0Wr4IrqdbZ8pYoLS5o9U", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 656.4469429373987, + "y": 41.25188884748725, + "strokeColor": "#343a40", + "backgroundColor": "transparent", + "width": 130.6403045654297, + "height": 40, + "seed": 1106354562, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1705903395747, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "Project sharing, \nreward", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "4LZjGT8mwEbDX3LZWxl6R", + "originalText": "Project sharing, reward", + "lineHeight": 1.25, + "baseline": 35 + }, + { + "type": "rectangle", + "version": 477, + "versionNonce": 1060949018, + "isDeleted": false, + "id": "fawTMpzGHBvMo4rpWSaai", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 806.6026053001843, + "y": -8.271965644919078, + "strokeColor": "#343a40", + "backgroundColor": "transparent", + "width": 143.81518326443873, + "height": 139.21006740019186, + "seed": 373107650, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "znJrxwJJU0EAYq6Tw-t9R" + } + ], + "updated": 1705903395747, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 249, + "versionNonce": 2027494022, + "isDeleted": false, + "id": "znJrxwJJU0EAYq6Tw-t9R", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 837.0541117273256, + "y": 51.33306805517685, + "strokeColor": "#343a40", + "backgroundColor": "transparent", + "width": 82.91217041015625, + "height": 20, + "seed": 1660884994, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1705903395747, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "APP Store", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "fawTMpzGHBvMo4rpWSaai", + "originalText": "APP Store", + "lineHeight": 1.25, + "baseline": 15 + }, + { + "type": "rectangle", + "version": 103, + "versionNonce": 1891645658, + "isDeleted": false, + "id": "AD9gq4p6sVlK5uCSSdF79", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 541.7062882439832, + "y": 137.47954767793942, + "strokeColor": "#343a40", + "backgroundColor": "transparent", + "width": 414.3818235520964, + "height": 125.37029693455148, + "seed": 182870914, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1705903395747, + "link": null, + "locked": false + }, + { + "type": "rectangle", + "version": 129, + "versionNonce": 622844358, + "isDeleted": false, + "id": "rBVBpnjw-mw4TFaxBVqob", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 546.9896785754999, + "y": 143.80647502552387, + "strokeColor": "#343a40", + "backgroundColor": "transparent", + "width": 156.74454974378438, + "height": 114.3227462361117, + "seed": 1293067074, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "N9U-XXCh_1lmG6TFdyWZf" + } + ], + "updated": 1705903395747, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 59, + "versionNonce": 548933018, + "isDeleted": false, + "id": "N9U-XXCh_1lmG6TFdyWZf", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 583.3218686085248, + "y": 190.96784814357972, + "strokeColor": "#343a40", + "backgroundColor": "transparent", + "width": 84.08016967773438, + "height": 20, + "seed": 1628866946, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1705903395747, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "User APPs", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "rBVBpnjw-mw4TFaxBVqob", + "originalText": "User APPs", + "lineHeight": 1.25, + "baseline": 15 + }, + { + "type": "rectangle", + "version": 227, + "versionNonce": 1892462854, + "isDeleted": false, + "id": "taBSuFoogLth7z8TAIGfA", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 711.7353054438793, + "y": 143.5381217253858, + "strokeColor": "#343a40", + "backgroundColor": "transparent", + "width": 238.5851579676612, + "height": 113.2492266066432, + "seed": 1193339650, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "zbtofl7zMyang1nAhL_EV" + } + ], + "updated": 1705903395747, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 154, + "versionNonce": 1415006810, + "isDeleted": false, + "id": "zbtofl7zMyang1nAhL_EV", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 717.9876241127685, + "y": 150.1627350287074, + "strokeColor": "#343a40", + "backgroundColor": "transparent", + "width": 226.0805206298828, + "height": 100, + "seed": 756599262, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1705903395747, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "Official APPs:\nLauncher, APP store, \nSettings,Camera, Monitor, AI\ndetector, line tracer, QR \ncode finder etc.", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "taBSuFoogLth7z8TAIGfA", + "originalText": "Official APPs:\nLauncher, APP store, Settings,Camera, Monitor, AI detector, line tracer, QR code finder etc.", + "lineHeight": 1.25, + "baseline": 95 + }, + { + "type": "text", + "version": 49, + "versionNonce": 928817222, + "isDeleted": false, + "id": "sFPgg4fqvH6SkVMAcU2Ic", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 609.1081303162628, + "y": 321.1711479479845, + "strokeColor": "#343a40", + "backgroundColor": "transparent", + "width": 86.400146484375, + "height": 40, + "seed": 1066416834, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1705903395747, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "MaixCDK\nC/C++ API", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "MaixCDK\nC/C++ API", + "lineHeight": 1.25, + "baseline": 34 + }, + { + "type": "text", + "version": 60, + "versionNonce": 1920003866, + "isDeleted": false, + "id": "mdOMOmkUcecRL2pFLwKdr", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 797.665729771511, + "y": 435.4203338248098, + "strokeColor": "#343a40", + "backgroundColor": "transparent", + "width": 55.5521240234375, + "height": 20, + "seed": 1426035330, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1705903395747, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "Drivers", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Drivers", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "type": "text", + "version": 79, + "versionNonce": 1554818950, + "isDeleted": false, + "id": "HEf5jPBhfnk4ha0pwN7__", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 778.159771207175, + "y": 502.2979060453904, + "strokeColor": "#343a40", + "backgroundColor": "transparent", + "width": 104.52821350097656, + "height": 20, + "seed": 2049831490, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1705903395747, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "System(Linux)", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "System(Linux)", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "type": "text", + "version": 101, + "versionNonce": 259521498, + "isDeleted": false, + "id": "huzNuYRp7_Zxwnq1MvOpN", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 798.594584941241, + "y": 584.0371609816557, + "strokeColor": "#343a40", + "backgroundColor": "transparent", + "width": 66.52815246582031, + "height": 20, + "seed": 1912232450, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1705903395747, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "MaixCam", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "MaixCam", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "type": "text", + "version": 78, + "versionNonce": 1090111174, + "isDeleted": false, + "id": "BNhQWU8ZdE9UUh9PGz8WY", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 729.8593023811998, + "y": 614.0371609816557, + "strokeColor": "#343a40", + "backgroundColor": "transparent", + "width": 248.54452514648438, + "height": 20, + "seed": 1264830914, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1705903395747, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "For STEM, Industry, Personal...", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "For STEM, Industry, Personal...", + "lineHeight": 1.25, + "baseline": 14 + }, + { + "type": "text", + "version": 75, + "versionNonce": 964653210, + "isDeleted": false, + "id": "DsZ8iDV3d86Jb4hh_bEIW", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 567.7901931261797, + "y": -20.78670585983116, + "strokeColor": "#343a40", + "backgroundColor": "transparent", + "width": 61.456146240234375, + "height": 20, + "seed": 1569276290, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1705903395747, + "link": null, + "locked": false, + "fontSize": 16, + "fontFamily": 1, + "text": "MaixHub", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "MaixHub", + "lineHeight": 1.25, + "baseline": 14 + } + ], + "appState": { + "gridSize": null, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} \ No newline at end of file diff --git a/maixpy/static/image/maix_ecosystem.png b/maixpy/static/image/maix_ecosystem.png new file mode 100644 index 00000000..dff03994 Binary files /dev/null and b/maixpy/static/image/maix_ecosystem.png differ diff --git a/maixpy/static/image/maixcam.png b/maixpy/static/image/maixcam.png new file mode 100644 index 00000000..20a1f8cc Binary files /dev/null and b/maixpy/static/image/maixcam.png differ diff --git a/maixpy/static/image/maixcam_back.png b/maixpy/static/image/maixcam_back.png new file mode 100644 index 00000000..44c5ed0d Binary files /dev/null and b/maixpy/static/image/maixcam_back.png differ diff --git a/maixpy/static/image/maixcam_font.png b/maixpy/static/image/maixcam_font.png new file mode 100644 index 00000000..268ea6e6 Binary files /dev/null and b/maixpy/static/image/maixcam_font.png differ diff --git a/maixpy/static/image/maixcdk.png b/maixpy/static/image/maixcdk.png new file mode 100644 index 00000000..0d4262ed Binary files /dev/null and b/maixpy/static/image/maixcdk.png differ diff --git a/maixpy/static/image/maixhub.jpg b/maixpy/static/image/maixhub.jpg new file mode 100644 index 00000000..eddf004a Binary files /dev/null and b/maixpy/static/image/maixhub.jpg differ diff --git a/maixpy/static/image/maixpy-v1-square.png b/maixpy/static/image/maixpy-v1-square.png new file mode 100644 index 00000000..c6d54c57 Binary files /dev/null and b/maixpy/static/image/maixpy-v1-square.png differ diff --git a/maixpy/static/image/maixpy-v1.png b/maixpy/static/image/maixpy-v1.png new file mode 100644 index 00000000..2df0900a Binary files /dev/null and b/maixpy/static/image/maixpy-v1.png differ diff --git a/maixpy/static/image/maixpy_banner.png b/maixpy/static/image/maixpy_banner.png new file mode 100644 index 00000000..3b290144 Binary files /dev/null and b/maixpy/static/image/maixpy_banner.png differ diff --git a/maixpy/static/image/maixvision.jpg b/maixpy/static/image/maixvision.jpg new file mode 100644 index 00000000..e6f6e33d Binary files /dev/null and b/maixpy/static/image/maixvision.jpg differ diff --git a/maixpy/static/image/monitor.jpg b/maixpy/static/image/monitor.jpg new file mode 100644 index 00000000..8bc3f1a1 Binary files /dev/null and b/maixpy/static/image/monitor.jpg differ diff --git a/maixpy/static/image/object_track.jpg b/maixpy/static/image/object_track.jpg new file mode 100644 index 00000000..d12036f0 Binary files /dev/null and b/maixpy/static/image/object_track.jpg differ diff --git a/maixpy/static/image/ocr.jpg b/maixpy/static/image/ocr.jpg new file mode 100644 index 00000000..cebf2344 Binary files /dev/null and b/maixpy/static/image/ocr.jpg differ diff --git a/maixpy/static/image/rndis_windows.jpg b/maixpy/static/image/rndis_windows.jpg new file mode 100644 index 00000000..58cb5e5b Binary files /dev/null and b/maixpy/static/image/rndis_windows.jpg differ diff --git a/maixpy/static/image/search/cancel.svg b/maixpy/static/image/search/cancel.svg new file mode 100644 index 00000000..46102a4c --- /dev/null +++ b/maixpy/static/image/search/cancel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/maixpy/static/image/search/close.svg b/maixpy/static/image/search/close.svg new file mode 100644 index 00000000..87c50f5d --- /dev/null +++ b/maixpy/static/image/search/close.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/maixpy/static/image/search/search.svg b/maixpy/static/image/search/search.svg new file mode 100644 index 00000000..3fafc630 --- /dev/null +++ b/maixpy/static/image/search/search.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/maixpy/static/image/search/up.svg b/maixpy/static/image/search/up.svg new file mode 100644 index 00000000..1ed67152 --- /dev/null +++ b/maixpy/static/image/search/up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/maixpy/static/image/self_learn_classifier.jpg b/maixpy/static/image/self_learn_classifier.jpg new file mode 100644 index 00000000..0ce807b1 Binary files /dev/null and b/maixpy/static/image/self_learn_classifier.jpg differ diff --git a/maixpy/static/image/self_learn_detector.jpg b/maixpy/static/image/self_learn_detector.jpg new file mode 100644 index 00000000..a4e5710a Binary files /dev/null and b/maixpy/static/image/self_learn_detector.jpg differ diff --git a/maixpy/static/image/serial_module.png b/maixpy/static/image/serial_module.png new file mode 100644 index 00000000..d2b6e042 Binary files /dev/null and b/maixpy/static/image/serial_module.png differ diff --git a/maixpy/static/image/sipeed_splash.jpeg b/maixpy/static/image/sipeed_splash.jpeg new file mode 100644 index 00000000..e5d0980a Binary files /dev/null and b/maixpy/static/image/sipeed_splash.jpeg differ diff --git a/maixpy/static/image/theme_default/anchor.svg b/maixpy/static/image/theme_default/anchor.svg new file mode 100644 index 00000000..4cbdda12 --- /dev/null +++ b/maixpy/static/image/theme_default/anchor.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/maixpy/static/image/theme_default/array.svg b/maixpy/static/image/theme_default/array.svg new file mode 100644 index 00000000..5c5c5148 --- /dev/null +++ b/maixpy/static/image/theme_default/array.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/maixpy/static/image/theme_default/back.svg b/maixpy/static/image/theme_default/back.svg new file mode 100644 index 00000000..e2729940 --- /dev/null +++ b/maixpy/static/image/theme_default/back.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/maixpy/static/image/theme_default/dark_mode.svg b/maixpy/static/image/theme_default/dark_mode.svg new file mode 100644 index 00000000..15523d8e --- /dev/null +++ b/maixpy/static/image/theme_default/dark_mode.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/maixpy/static/image/theme_default/ext_link.svg b/maixpy/static/image/theme_default/ext_link.svg new file mode 100644 index 00000000..ded48739 --- /dev/null +++ b/maixpy/static/image/theme_default/ext_link.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/maixpy/static/image/theme_default/indicator.svg b/maixpy/static/image/theme_default/indicator.svg new file mode 100644 index 00000000..7170d305 --- /dev/null +++ b/maixpy/static/image/theme_default/indicator.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/maixpy/static/image/theme_default/light_mode.svg b/maixpy/static/image/theme_default/light_mode.svg new file mode 100644 index 00000000..0be13395 --- /dev/null +++ b/maixpy/static/image/theme_default/light_mode.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/maixpy/static/image/theme_default/menu.svg b/maixpy/static/image/theme_default/menu.svg new file mode 100644 index 00000000..5f9cdda6 --- /dev/null +++ b/maixpy/static/image/theme_default/menu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/maixpy/static/image/theme_default/print.svg b/maixpy/static/image/theme_default/print.svg new file mode 100644 index 00000000..3b343178 --- /dev/null +++ b/maixpy/static/image/theme_default/print.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/maixpy/static/image/theme_default/to-top.svg b/maixpy/static/image/theme_default/to-top.svg new file mode 100644 index 00000000..59f0a172 --- /dev/null +++ b/maixpy/static/image/theme_default/to-top.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/maixpy/static/image/thermal.jpg b/maixpy/static/image/thermal.jpg new file mode 100644 index 00000000..50cbfc19 Binary files /dev/null and b/maixpy/static/image/thermal.jpg differ diff --git a/maixpy/static/image/voice_recognize.jpg b/maixpy/static/image/voice_recognize.jpg new file mode 100644 index 00000000..c02f8b4a Binary files /dev/null and b/maixpy/static/image/voice_recognize.jpg differ diff --git a/maixpy/static/image/weather_station.jpg b/maixpy/static/image/weather_station.jpg new file mode 100644 index 00000000..e03e0df7 Binary files /dev/null and b/maixpy/static/image/weather_station.jpg differ diff --git a/maixpy/static/image/wechat.png b/maixpy/static/image/wechat.png new file mode 100644 index 00000000..13978a67 Binary files /dev/null and b/maixpy/static/image/wechat.png differ diff --git a/maixpy/static/js/custom.js b/maixpy/static/js/custom.js new file mode 100644 index 00000000..e69de29b diff --git a/maixpy/static/js/search/search_main.js b/maixpy/static/js/search/search_main.js new file mode 100644 index 00000000..fdd3d7c6 --- /dev/null +++ b/maixpy/static/js/search/search_main.js @@ -0,0 +1,351 @@ + +jQuery.fn.highlight = function (pat) { + function innerHighlight(node, pat) { + var skip = 0; + if (node.nodeType == 3) { + var pos = node.data.toUpperCase().indexOf(pat); + if (pos >= 0) { + var spannode = document.createElement('span'); + spannode.className = 'search_highlight'; + var middlebit = node.splitText(pos); + var endbit = middlebit.splitText(pat.length); + var middleclone = middlebit.cloneNode(true); + spannode.appendChild(middleclone); + middlebit.parentNode.replaceChild(spannode, middlebit); + skip = 1; + } + } + else if (node.nodeType == 1 && node.childNodes && !/(script|style)/i.test(node.tagName)) { + for (var i = 0; i < node.childNodes.length; ++i) { + i += innerHighlight(node.childNodes[i], pat); + } + } + return skip; + } + return this.each(function () { + innerHighlight(this, pat.toUpperCase()); + }); +}; + +window.onload = function(){ +} + +$(document).ready(function(){ + var waiting_search = false; + var search_index = null; + var search_content = { + "curr": null, + "others":{} + } + function onDownloadOk(data, arg1, arg2){ + search_index = data; + var pathname = window.location.pathname; + var curr_url = null; + var others_url = []; + for(var url in search_index){ + if(pathname.indexOf(url) != -1){ + if(!curr_url){ + curr_url = url; + }else{ // already have math item, e.g. `/get_started/zh/install/index.html /get_started/zh` + // and now `/get_started/zh/install/index.html /` + // choose longger one + if(url.length > curr_url.length){ + others_url.push(curr_url); + curr_url = url; + }else{ + others_url.push(url); + } + } + }else{ + others_url.push(url); + } + } + if(search_index[curr_url]){ + downloadJson(search_index[curr_url][1], onIndexDownloadOk, curr_url, true, search_index[curr_url][0]); + } + for(var i in others_url){ + url = others_url[i]; + downloadJson(search_index[url][1], onIndexDownloadOk, url, false, search_index[url][0]); + } + } + function onIndexDownloadOk(data, url, is_curr, doc_name){ + if(is_curr){ + search_content["curr"] = [url, doc_name, data]; + }else{ + search_content["others"][url] = [url, doc_name, data]; + } + if(waiting_search == true){ + waiting_search = false; + onSearch(); + } + } + downloadJson("/maixpy/static/search_index/index.json", onDownloadOk); + var input_hint = $("#search_input_hint").html(); + var loading_hint = $("#search_loading_hint").html(); + var download_err_hint = $("#search_download_err_hint").html(); + var other_docs_result_hint = $("#search_other_docs_result_hint").html(); + var curr_doc_result_hint = $("#search_curr_doc_result_hint").html(); + $("body").append('
\ +
\ +
\ +
\ +
\ + \ +
\ +
\ +
\ +
\ +
\ +
\ +
\ +
'); + $("#search").bind("click", function(e){ + $("body").css("overflow-y", "hidden"); + $("#search_wrapper").show(); + $("#search_input").focus(); + $("#wrapper").addClass("blur"); + $("#navbar").addClass("blur"); + }); + $("#search_wrapper .close").bind("click", function(e){ + $("body").css("overflow-y", "auto"); + $("#search_wrapper").hide(); + $("#wrapper").removeClass("blur"); + $("#navbar").removeClass("blur"); + }); + $("#search_input").bind("input propertychange", function(){ + setTimeout(() => { + onSearch(); + }, 1000); + }); + function onSearch(){ + $("#search_result_name").empty(); + $("#search_result_content").empty(); + $("#search_result_content").append('
    '+ curr_doc_result_hint +'
'); + $("#search_result_content").append('
    '+ other_docs_result_hint +'
'); + if(!search_index){ + $("#search_result_content").append('
'+ loading_hint +'
'); + waiting_search = true; + return; + } + if(!search_content["curr"] && search_content["others"].length == 0){ + $("#search_result_content").append('
'+ loading_hint +'
'); + waiting_search = true; + return; + } + $("#search_curr_result > .hint").addClass("searching"); + var search_keywords = $("#search_input").val(); + search_doc(search_content["curr"], "#search_curr_result"); + var doc_id = 0; + for(var url in search_content["others"]){ + search_doc(search_content["others"][url], "#search_others_result", doc_id); + doc_id += 1; + } + addSearchResultClickListener(); + function search_doc(data, containerId, doc_id="curr"){ + var doc_id_str = 'result_wrapper_' + doc_id; + var findFlag = false; + var items = data[2]; + for(var url in items){ + var content = items[url]; + search_keywords = search_keywords.trim(); + if(search_keywords.length <= 0){ + return; + } + var keywords = search_keywords.split(" "); + var find = false; + var find_strs = ""; + for(var i in keywords){ + var keyword = keywords[i]; + if(content["title"] && content["title"].indexOf(keyword) >= 0){ + find = true; + } + } + if(content["content"] && content["content"].length > 0){ + find_strs = search(keywords, content["content"]); + if(find_strs.length > 0){ + find = true; + } + } + if(find){ + if(!findFlag){ + $("#search_result_name").append('
  • '+ data[1] +'
  • '); + $(containerId).append('
    '+data[1]+'
    '); + findFlag = true; + } + $("#"+doc_id_str).append('
  • '+ (content["title"]?content["title"]:url) + + '

    ' + find_strs + '
  • '); + } + } + } + $("#search_curr_result > .hint").removeClass("searching"); + } + function downloadJson(url, callback, arg1=null, arg2=null, arg3=null){ + $.ajax({ + type: "GET", + url: url, + contentType: "application/json", + dataType: "json", + success: function(data){ + callback(data, arg1, arg2, arg3); + }, + error: function(){ + $("#search_result_content").empty(); + $("#search_result_content").append('
    '+ download_err_hint + ': '+ url +'
    '); + } + }); + } + highlightKeywords(); +}); + +function focusItems(id, contrainerId, offset=0, classname=null){ + var elementTop = 0; + if(classname){ + elementTop = $("."+classname)[0].offsetTop - offset; + }else{ + elementTop = $("#"+id)[0].offsetTop - offset; + } + + $("#"+contrainerId).animate({scrollTop: elementTop},500); +} + + +function addSearchResultClickListener(){ + $("#search_result_name > li").on("click", function(e){ + var targetId = e.target.attributes.result_id.value; + focusItems(targetId, "search_result_content", $("#search_title").height() + $("#search_result .hint").height()); + }); +} + +function highlightKeywords(){ + var highlight_keywords = getQueryVariable("highlight"); + if(highlight_keywords){ + // add search result btn + var html = document.getElementsByTagName("html")[0]; + var lang = html.lang.split("-")[0].toLowerCase() + let strs = { + "zh": { + "Previous": "上一个", + "Next": "下一个" + } + } + if(lang in strs){ + var pre_name = strs[lang]["Previous"]; + var next_name = strs[lang]["Next"]; + }else{ + var pre_name = "Previous"; + var next_name = "Next"; + } + $("body").append('
    ' + + '' + + '' + + '' + + '
    '); + var highlight_keywords = decodeURI(highlight_keywords); + highlight_keywords = highlight_keywords.split(" "); + for(var i=0; i .previous").on("click", function(){ + let old = currSearchIdx; + currSearchIdx -= 1; + if (currSearchIdx < 0){ + currSearchIdx = $(".search_highlight").length - 1; + } + window.scrollTo({ + top: $(".search_highlight")[currSearchIdx].offsetTop - window.screen.height / 3, + behavior: "smooth" + }); + $($(".search_highlight")[old]).removeClass("selected_highlight") + $($(".search_highlight")[currSearchIdx]).addClass("selected_highlight") + }); + $("#search_ctrl_btn > .next").on("click", function(){ + let old = currSearchIdx; + currSearchIdx += 1; + if (currSearchIdx >= $(".search_highlight").length){ + currSearchIdx = 0; + } + window.scrollTo({ + top: $(".search_highlight")[currSearchIdx].offsetTop - window.screen.height / 3, + behavior: "smooth" + }); + $($(".search_highlight")[old]).removeClass("selected_highlight") + $($(".search_highlight")[currSearchIdx]).addClass("selected_highlight") + }); + } +} +function getQueryVariable(variable) +{ + var query = window.location.search.substring(1); + var vars = query.split("&"); + for (var i=0;i= 0){ + idxs.push({ + "idx": idx + idx_rel, + "len": keyword.length + }); + _idxs = _search([keyword], content.substr(idx + keyword.length), idx_rel + idx + keyword.length); + idxs = idxs.concat(_idxs); + } + } + return idxs + } + var find_strs = ""; + idxs = _search(keywords, content); + idxs = idxs.sort((a, b)=> a.idx-b.idx); + var idx_last = -1; + var len_last = 0; + for(var i=0; i= 0 && (idx - idx_last -len_last) < show_length){ // last keyword too close + find_strs += content.substr(idx_last + len_last, idx - (idx_last + len_last)) + ''+ content.substr(idx, len) +'' + }else{ + var start_idx = (idx - show_length < 0) ? 0 : (idx - show_length); + find_strs += '...' + content.substr(start_idx, idx - start_idx) + + '' + content.substr(idx, len) + + ''; + } + var idx_next = -1; + if(i < idxs.length -1){ + idx_next = idxs[i + 1]['idx']; + } + if(idx_next >= 0 && ((idx_next - idx - len) < show_length) ){ // next keywor too close + }else{ + find_strs += content.substr(idx + len, show_length) + '...'; + } + idx_last = idx; + len_last = len; + } + return find_strs +} + diff --git a/maixpy/static/js/theme_default/jquery.min.js b/maixpy/static/js/theme_default/jquery.min.js new file mode 100644 index 00000000..b0614034 --- /dev/null +++ b/maixpy/static/js/theme_default/jquery.min.js @@ -0,0 +1,2 @@ +/*! jQuery v3.5.1 | (c) JS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.5.1",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function D(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||j,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,j=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function qe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function Le(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function He(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="
    ",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):("number"==typeof f.top&&(f.top+="px"),"number"==typeof f.left&&(f.left+="px"),c.css(f))}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=$e(y.pixelPosition,function(e,t){if(t)return t=Be(e,n),Me.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0 a").bind("click", function(e){ + var is_click_indicator = $(e.target).hasClass("sub_indicator"); + var a_obj = $(this); + if(a_obj.attr("href") == window.location.pathname){ + show_collapse_item(a_obj); + return false; + } + show_collapse_item(a_obj); + if(is_click_indicator){ // click indicator, only collapse, not jump to link + return false; + } + var screenW = $(window).width(); + if(screenW > 900){ + return; + } + link_href = $(this).attr("href").split(location.host); + if(link_href.length > 1){ + link_href = link_href[1]; + }else{ + link_href = link_href[0]; + } + url_href = location.href.split(location.host)[1] + let link_url = link_href.split("#")[0]; + let sub = $(this).next(); + var haveSub = false; + if(sub && sub.prop("nodeName")){ + haveSub = sub.prop("nodeName").toLowerCase() == "ul"; + } + if((link_href != decodeURIComponent(url_href) || !haveSub) && location.pathname == link_url){ // current page, and jump to header, close sidebar + location.href = link_href; + menu_toggle(); + } + }); +} + +function hello(){ + console.log('\n\n\ + _ _ \n\ + | | | | \n\ + | |_ ___ ___ __| | ___ ___ \n\ + | __/ _ \\/ _ \\/ _` |/ _ \\ / __|\n\ + | || __/ __/ (_| | (_) | (__ \n\ + \\__\\___|\\___|\\__,_|\\___/ \\___|\n\ + \n\ + generated by teedoc: \n\ + \n\ + https://github.com/teedoc/teedoc\n\ + \n\n\n\ +'); +} + + +function addTOC(){ + if(!document.getElementById("toc_content")) + return; + tocbot.init({ + // Where to render the table of contents. + tocSelector: '#toc_content', + // Where to grab the headings to build the table of contents. + contentSelector: '#article_content', + // Which headings to grab inside of the contentSelector element. + headingSelector: 'h1, h2, h3, h4', + // For headings inside relative or absolute positioned containers within content. + hasInnerContainers: true, + }); +} + +function toChineseNumber(n) { + if (!Number.isInteger(n) && n < 0) { + throw Error('请输入自然数'); + } + + const digits = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']; + const positions = ['', '十', '百', '千', '万', '十万', '百万', '千万', '亿', '十亿', '百亿', '千亿']; + const charArray = String(n).split(''); + let result = ''; + let prevIsZero = false; + //处理0 deal zero + for (let i = 0; i < charArray.length; i++) { + const ch = charArray[i]; + if (ch !== '0' && !prevIsZero) { + result += digits[parseInt(ch)] + positions[charArray.length - i - 1]; + } else if (ch === '0') { + prevIsZero = true; + } else if (ch !== '0' && prevIsZero) { + result += '零' + digits[parseInt(ch)] + positions[charArray.length - i - 1]; + } + } + //处理十 deal ten + if (n < 100) { + result = result.replace('一十', '十'); + } + return result; + } + +function addSequence(){ + if(!tocbot._parseContent){ + return; + } + var headings = tocbot._parseContent.selectHeadings(document.getElementById("article_content"), tocbot.options.headingSelector); + var counth2=0, counth3=0, counth4=0; + var html = document.getElementsByTagName("html")[0]; + var isZh = html.lang.substring(0, 2).toLowerCase() == "zh"; + for(var i=0; i' + seq + ''); + } +} + + +function getSplitter(){ + var sizes = localStorage.getItem("splitter_w"); + if(sizes){ + try + { + sizes = JSON.parse(sizes); + } + catch(err) + { + sizes = false; + } + } + if(!sizes){ + var screenW = $(window).width(); + var split_w = 0; + if(!sidebar_width_is_percent){ + split_w = parseInt(sidebar_width/screenW*100); + }else{ + split_w = sidebar_width; + } + sizes = [split_w, 100-split_w]; + setSplitter(sizes); + } + return sizes; +} +function setSplitter(sizes){ + localStorage.setItem("splitter_w", JSON.stringify(sizes)); +} + +var hasSplitter = false; + +function createSplitter(){ + var split = Split(["#sidebar_wrapper", "#article"],{ + gutterSize: 3, + gutterAlign: 'start', + minSize: 200, + elementStyle: function (dimension, size, gutterSize) { + return { + 'width': 'calc(' + size + '% - ' + gutterSize + 'px)', + } + }, + onDragEnd: function (sizes) { + setSplitter(sizes) + }, + }); + hasSplitter = true; + var screenW = $(window).width(); + var sizes = getSplitter(); + split_w = parseInt(sizes[0]); + if(isNaN(split_w) || (split_w + 20) >= screenW){ + if(!sidebar_width_is_percent){ + split_w = parseInt(sidebar_width/screenW*100); + }else{ + split_w = sidebar_width; + } + } + split.setSizes([split_w, 100 - split_w]); + $(".gutter").append('
    '); + $(".gutter").hover(function(){ + $(".gutter").css("width", "10px"); + $(".gutter_icon").css("width", "10px"); + },function(){ + $(".gutter").css("width", "3px"); + $(".gutter_icon").css("width", "3px"); + }); +} + +function addSplitter(){ + var screenW = $(window).width(); + if(screenW > 900) + { + createSplitter(); + } +} + +function registerOnWindowResize(has_sidebar){ + window.onresize = function(){ + var screenW = $(window).width(); + if(!has_sidebar){ + return; + } + if(screenW < 900){ + $("#sidebar_wrapper").removeAttr("style"); + if($("#menu").hasClass("close")){ + $("#sidebar_wrapper").css("display", "block"); + } + $(".gutter").css("display", "none"); + $("#article").css("width", "100%"); + }else{ + if(!hasSplitter){ + createSplitter(); + } + if($("#sidebar_wrapper").css("display") != "none"){ + $(".gutter").css("display", "block"); + } + } + } +} + +function focusSidebar(){ + var windowH = window.innerHeight; + var active = $("#sidebar .active")[0]; + if(!active) + return; + var offset = active.offsetTop; + if(offset > windowH/2){ + $("#sidebar .show").scrollTop(offset); + } +} + +function imageViewer(){ + var content_e = document.getElementById("content_body"); + if(!content_e){ + content_e = document.getElementById("page_wrapper"); + } + const gallery = new Viewer(content_e); +} + +function addAnchor(){ + $("#content_body h2, #content_body h3, #content_body h4, #content_body h5").each(function(){ + if($(this).attr("id")){ + $(this).append('#'); + } + }); +} + +function rerender(){ + Prism.highlightAll(); +} + +function addPrintPage(){ + if(!$("#article_info_right")){ + return; + } + $("#article_info_right").append(''); + + var beforePrint = function(){ + // update style changed by js: + $("#article").css("width", "100%"); + // rerender for proper output + rerender(); + } + var afterPrint = function() { + // location.reload(); + } + if (window.matchMedia) { + var mediaQueryList = window.matchMedia('print'); + mediaQueryList.addListener(function(mql) { + if (mql.matches) { + beforePrint(); + } else { + afterPrint(); + } + }); + } + window.onbeforeprint = beforePrint; + window.onafterprint = afterPrint; + $("#print_page").click(function(){ + window.print(); + }); +} + +function addTocMobileListener(){ + $("#toc_btn").click(function(){ + if($("#toc_wrapper").hasClass("show")){ + $("#toc_wrapper").removeClass("show"); + }else{ + $("#toc_wrapper").addClass("show"); + } + }); + $("#toc_wrapper").click(function(){ + if($("#toc_btn").is(":visible")){ + $("#toc_wrapper").removeClass("show"); + } + }); +} + +function addTabsetListener(){ + $(".tabset-tab-label").on("click", function(){ + let this_obj = $(this); + // already active, do nothing + if(this_obj.hasClass("tabset-tab-active")){ + return; + } + // remove all active tabset-tab-active and tabset-text-active class from all have class that startswith tabset-id-, + // then add active class to the same idx tab-label and tab-text + let tabset_id = null; + let same_id_tabsets = []; + let old_idx = this_obj.parent().find(".tabset-tab-active").attr("idx"); + let new_idx = this_obj.attr("idx"); + let tabset_obj = this_obj.parent().parent().parent(); + tabset_obj.attr("class").split(' ').forEach(function(item){ + if(item.startsWith("tabset-id-")){ + tabset_id = item; + } + }); + if(!tabset_id){ + same_id_tabsets = [tabset_obj[0]]; // to DOM element + }else{ + same_id_tabsets = document.getElementsByClassName(tabset_id); + } + for (let tabset of same_id_tabsets) { + console.log(tabset); + let tab_labels = tabset.getElementsByClassName("tabset-tab-label"); + tab_labels[old_idx].classList.remove("tabset-tab-active"); + tab_labels[new_idx].classList.add("tabset-tab-active"); + let tab_texts = tabset.getElementsByClassName("tabset-text"); + tab_texts[old_idx].classList.remove("tabset-text-active"); + tab_texts[new_idx].classList.add("tabset-text-active"); + } + }); +} diff --git a/maixpy/static/js/theme_default/pre_main.js b/maixpy/static/js/theme_default/pre_main.js new file mode 100644 index 00000000..1cb38adc --- /dev/null +++ b/maixpy/static/js/theme_default/pre_main.js @@ -0,0 +1,54 @@ +(function(){ + var theme = getTheme(); + setTheme(theme); +}()); + +function addCss(filename) { + var head = document.getElementsByTagName('head')[0]; + var link = document.createElement('link'); + link.rel = 'stylesheet'; + link.type = 'text/css'; + link.href = filename; + head.appendChild(link); +} +function removejscssfile(filename, filetype) { + var targetelement = (filetype == "js") ? "script" : (filetype == "css") ? "link" : "none" + var targetattr = (filetype == "js") ? "src" : (filetype == "css") ? "href" : "none" + var allsuspects = document.getElementsByTagName(targetelement) + for (var i = allsuspects.length; i >= 0; i--) { + if (allsuspects[i] && allsuspects[i].getAttribute(targetattr) != null && allsuspects[i].getAttribute(targetattr).indexOf(filename) != -1) + allsuspects[i].parentNode.removeChild(allsuspects[i]) + } +} + + +function getTheme(){ + var t = localStorage.getItem("theme"); + if(!t){ + t = "light"; + setTheme(t); + } + return t; +} +function setTheme(theme){ + var obj = document.getElementById("themes"); + if(theme=="dark"){ + if(obj){ + obj.classList.remove("light"); + obj.classList.add("dark"); + } + document.getElementsByTagName("html")[0].classList.add("dark"); + // load dark and light togher, distingush by .dark class instead use single css file + // removejscssfile("/maixpy/static/css/theme_default/light.css", "css"); + // addCss("/maixpy/static/css/theme_default/dark.css"); + }else{ + if(obj){ + obj.classList.remove("dark"); + obj.classList.add("light"); + } + document.getElementsByTagName("html")[0].classList.remove("dark"); + // removejscssfile("/maixpy/static/css/theme_default/dark.css", "css"); + // addCss("/maixpy/static/css/theme_default/light.css"); + } + localStorage.setItem("theme", theme); +} diff --git a/maixpy/static/js/theme_default/split.js b/maixpy/static/js/theme_default/split.js new file mode 100644 index 00000000..79f2131a --- /dev/null +++ b/maixpy/static/js/theme_default/split.js @@ -0,0 +1,3 @@ +/*! Split.js - v1.6.4 */ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Split=t()}(this,(function(){"use strict";var e="undefined"!=typeof window?window:null,t=null===e,n=t?void 0:e.document,i=function(){return!1},r=t?"calc":["","-webkit-","-moz-","-o-"].filter((function(e){var t=n.createElement("div");return t.style.cssText="width:"+e+"calc(9px)",!!t.style.length})).shift()+"calc",s=function(e){return"string"==typeof e||e instanceof String},o=function(e){if(s(e)){var t=n.querySelector(e);if(!t)throw new Error("Selector "+e+" did not match a DOM element");return t}return e},a=function(e,t,n){var i=e[t];return void 0!==i?i:n},u=function(e,t,n,i){if(t){if("end"===i)return 0;if("center"===i)return e/2}else if(n){if("start"===i)return 0;if("center"===i)return e/2}return e},l=function(e,t){var i=n.createElement("div");return i.className="gutter gutter-"+t,i},c=function(e,t,n){var i={};return s(t)?i[e]=t:i[e]=r+"("+t+"% - "+n+"px)",i},h=function(e,t){var n;return(n={})[e]=t+"px",n};return function(r,s){if(void 0===s&&(s={}),t)return{};var d,f,v,m,g,p,y=r;Array.from&&(y=Array.from(y));var z=o(y[0]).parentNode,S=getComputedStyle?getComputedStyle(z):null,b=S?S.flexDirection:null,E=a(s,"sizes")||y.map((function(){return 100/y.length})),_=a(s,"minSize",100),L=Array.isArray(_)?_:y.map((function(){return _})),w=a(s,"maxSize",1/0),x=Array.isArray(w)?w:y.map((function(){return w})),k=a(s,"expandToMin",!1),C=a(s,"gutterSize",10),M=a(s,"gutterAlign","center"),U=a(s,"snapOffset",30),A=a(s,"dragInterval",1),O=a(s,"direction","horizontal"),D=a(s,"cursor","horizontal"===O?"col-resize":"row-resize"),B=a(s,"gutter",l),T=a(s,"elementStyle",c),j=a(s,"gutterStyle",h);function F(e,t,n,i){var r=T(d,t,n,i);Object.keys(r).forEach((function(t){e.style[t]=r[t]}))}function R(){return p.map((function(e){return e.size}))}function N(e){return"touches"in e?e.touches[0][f]:e[f]}function q(e){var t=p[this.a],n=p[this.b],i=t.size+n.size;t.size=e/this.size*i,n.size=i-e/this.size*i,F(t.element,t.size,this._b,t.i),F(n.element,n.size,this._c,n.i)}function H(e){var t,n=p[this.a],r=p[this.b];this.dragging&&(t=N(e)-this.start+(this._b-this.dragOffset),A>1&&(t=Math.round(t/A)*A),t<=n.minSize+U+this._b?t=n.minSize+this._b:t>=this.size-(r.minSize+U+this._c)&&(t=this.size-(r.minSize+this._c)),t>=n.maxSize-U+this._b?t=n.maxSize+this._b:t<=this.size-(r.maxSize-U+this._c)&&(t=this.size-(r.maxSize+this._c)),q.call(this,t),a(s,"onDrag",i)(R()))}function I(){var e=p[this.a].element,t=p[this.b].element,n=e.getBoundingClientRect(),i=t.getBoundingClientRect();this.size=n[d]+i[d]+this._b+this._c,this.start=n[v],this.end=n[m]}function W(e){var t=function(e){if(!getComputedStyle)return null;var t=getComputedStyle(e);if(!t)return null;var n=e[g];return 0===n?null:n-="horizontal"===O?parseFloat(t.paddingLeft)+parseFloat(t.paddingRight):parseFloat(t.paddingTop)+parseFloat(t.paddingBottom)}(z);if(null===t)return e;if(L.reduce((function(e,t){return e+t}),0)>t)return e;var n=0,i=[],r=e.map((function(r,s){var o=t*r/100,a=u(C,0===s,s===e.length-1,M),l=L[s]+a;return o0&&i[r]-n>0){var o=Math.min(n,i[r]-n);n-=o,s=e-o}return s/t*100}))}function X(){var t=p[this.a].element,r=p[this.b].element;this.dragging&&a(s,"onDragEnd",i)(R()),this.dragging=!1,e.removeEventListener("mouseup",this.stop),e.removeEventListener("touchend",this.stop),e.removeEventListener("touchcancel",this.stop),e.removeEventListener("mousemove",this.move),e.removeEventListener("touchmove",this.move),this.stop=null,this.move=null,t.removeEventListener("selectstart",i),t.removeEventListener("dragstart",i),r.removeEventListener("selectstart",i),r.removeEventListener("dragstart",i),t.style.userSelect="",t.style.webkitUserSelect="",t.style.MozUserSelect="",t.style.pointerEvents="",r.style.userSelect="",r.style.webkitUserSelect="",r.style.MozUserSelect="",r.style.pointerEvents="",this.gutter.style.cursor="",this.parent.style.cursor="",n.body.style.cursor=""}function Y(t){if(!("button"in t)||0===t.button){var r=p[this.a].element,o=p[this.b].element;this.dragging||a(s,"onDragStart",i)(R()),t.preventDefault(),this.dragging=!0,this.move=H.bind(this),this.stop=X.bind(this),e.addEventListener("mouseup",this.stop),e.addEventListener("touchend",this.stop),e.addEventListener("touchcancel",this.stop),e.addEventListener("mousemove",this.move),e.addEventListener("touchmove",this.move),r.addEventListener("selectstart",i),r.addEventListener("dragstart",i),o.addEventListener("selectstart",i),o.addEventListener("dragstart",i),r.style.userSelect="none",r.style.webkitUserSelect="none",r.style.MozUserSelect="none",r.style.pointerEvents="none",o.style.userSelect="none",o.style.webkitUserSelect="none",o.style.MozUserSelect="none",o.style.pointerEvents="none",this.gutter.style.cursor=D,this.parent.style.cursor=D,n.body.style.cursor=D,I.call(this),this.dragOffset=N(t)-this.end}}"horizontal"===O?(d="width",f="clientX",v="left",m="right",g="clientWidth"):"vertical"===O&&(d="height",f="clientY",v="top",m="bottom",g="clientHeight"),E=W(E);var G=[];function J(e){var t=e.i===G.length,n=t?G[e.i-1]:G[e.i];I.call(n);var i=t?n.size-e.minSize-n._c:e.minSize+n._b;q.call(n,i)}return(p=y.map((function(e,t){var n,i={element:o(e),size:E[t],minSize:L[t],maxSize:x[t],i:t};if(t>0&&((n={a:t-1,b:t,dragging:!1,direction:O,parent:z})._b=u(C,t-1==0,!1,M),n._c=u(C,!1,t===y.length-1,M),"row-reverse"===b||"column-reverse"===b)){var r=n.a;n.a=n.b,n.b=r}if(t>0){var s=B(t,O,i.element);!function(e,t,n){var i=j(d,t,n);Object.keys(i).forEach((function(t){e.style[t]=i[t]}))}(s,C,t),n._a=Y.bind(n),s.addEventListener("mousedown",n._a),s.addEventListener("touchstart",n._a),z.insertBefore(s,i.element),n.gutter=s}return F(i.element,i.size,u(C,0===t,t===y.length-1,M),t),t>0&&G.push(n),i}))).forEach((function(e){var t=e.element.getBoundingClientRect()[d];t0){var i=G[n-1],r=p[i.a],s=p[i.b];r.size=t[n-1],s.size=e,F(r.element,r.size,i._b,r.i),F(s.element,s.size,i._c,s.i)}}))},getSizes:R,collapse:function(e){J(p[e])},destroy:function(e,t){G.forEach((function(n){if(!0!==t?n.parent.removeChild(n.gutter):(n.gutter.removeEventListener("mousedown",n._a),n.gutter.removeEventListener("touchstart",n._a)),!0!==e){var i=T(d,n.a.size,n._b);Object.keys(i).forEach((function(e){p[n.a].element.style[e]="",p[n.b].element.style[e]=""}))}}))},parent:z,pairs:G}}})); +//# sourceMappingURL=split.min.js.map diff --git a/maixpy/static/js/theme_default/tocbot.min.js b/maixpy/static/js/theme_default/tocbot.min.js new file mode 100644 index 00000000..64f46c79 --- /dev/null +++ b/maixpy/static/js/theme_default/tocbot.min.js @@ -0,0 +1 @@ +(()=>{var e={163:e=>{e.exports=function(e){var t=[].forEach,n=[].some,o=document.body,l=!0,r=" ";function i(n,o){var l,c,a,u=o.appendChild((l=n,c=document.createElement("li"),a=document.createElement("a"),e.listItemClass&&c.setAttribute("class",e.listItemClass),e.onClick&&(a.onclick=e.onClick),e.includeTitleTags&&a.setAttribute("title",l.textContent),e.includeHtml&&l.childNodes.length?t.call(l.childNodes,(function(e){a.appendChild(e.cloneNode(!0))})):a.textContent=l.textContent,a.setAttribute("href",e.basePath+"#"+l.id),a.setAttribute("class",e.linkClass+r+"node-name--"+l.nodeName+r+e.extraLinkClasses),c.appendChild(a),c));if(n.children.length){var d=s(n.isCollapsed);n.children.forEach((function(e){i(e,d)})),u.appendChild(d)}}function s(t){var n=e.orderedList?"ol":"ul",o=document.createElement(n),l=e.listClass+r+e.extraListClasses;return t&&(l+=r+e.collapsibleClass,l+=r+e.isCollapsedClass),o.setAttribute("class",l),o}function c(t){var n=0;return t!==document.querySelector(e.contentSelector&&null!=t)&&(n=t.offsetTop,e.hasInnerContainers&&(n+=c(t.offsetParent))),n}function a(t){return t&&-1!==t.className.indexOf(e.collapsibleClass)&&-1!==t.className.indexOf(e.isCollapsedClass)?(t.className=t.className.split(r+e.isCollapsedClass).join(""),a(t.parentNode.parentNode)):t}return{enableTocAnimation:function(){l=!0},disableTocAnimation:function(t){var n=t.target||t.srcElement;"string"==typeof n.className&&-1!==n.className.indexOf(e.linkClass)&&(l=!1)},render:function(e,t){var n=s(!1);if(t.forEach((function(e){i(e,n)})),null!==e)return e.firstChild&&e.removeChild(e.firstChild),0===t.length?e:e.appendChild(n)},updateToc:function(i){var s;s=e.scrollContainer&&document.querySelector(e.scrollContainer)?document.querySelector(e.scrollContainer).scrollTop:document.documentElement.scrollTop||o.scrollTop,e.positionFixedSelector&&function(){var t;t=e.scrollContainer&&document.querySelector(e.scrollContainer)?document.querySelector(e.scrollContainer).scrollTop:document.documentElement.scrollTop||o.scrollTop;var n=document.querySelector(e.positionFixedSelector);"auto"===e.fixedSidebarOffset&&(e.fixedSidebarOffset=document.querySelector(e.tocSelector).offsetTop),t>e.fixedSidebarOffset?-1===n.className.indexOf(e.positionFixedClass)&&(n.className+=r+e.positionFixedClass):n.className=n.className.split(r+e.positionFixedClass).join("")}();var u,d=i;if(l&&null!==document.querySelector(e.tocSelector)&&d.length>0){n.call(d,(function(t,n){return c(t)>s+e.headingsOffset+10?(u=d[0===n?n:n-1],!0):n===d.length-1?(u=d[d.length-1],!0):void 0}));var f=document.querySelector(e.tocSelector).querySelectorAll("."+e.linkClass);t.call(f,(function(t){t.className=t.className.split(r+e.activeLinkClass).join("")}));var m=document.querySelector(e.tocSelector).querySelectorAll("."+e.listItemClass);t.call(m,(function(t){t.className=t.className.split(r+e.activeListItemClass).join("")}));var h=document.querySelector(e.tocSelector).querySelector("."+e.linkClass+".node-name--"+u.nodeName+'[href="'+e.basePath+"#"+u.id.replace(/([ #;&,.+*~':"!^$[\]()=>|/@])/g,"\\$1")+'"]');h&&-1===h.className.indexOf(e.activeLinkClass)&&(h.className+=r+e.activeLinkClass);var p=h&&h.parentNode;p&&-1===p.className.indexOf(e.activeListItemClass)&&(p.className+=r+e.activeListItemClass);var C=document.querySelector(e.tocSelector).querySelectorAll("."+e.listClass+"."+e.collapsibleClass);t.call(C,(function(t){-1===t.className.indexOf(e.isCollapsedClass)&&(t.className+=r+e.isCollapsedClass)})),h&&h.nextSibling&&-1!==h.nextSibling.className.indexOf(e.isCollapsedClass)&&(h.nextSibling.className=h.nextSibling.className.split(r+e.isCollapsedClass).join("")),a(h&&h.parentNode.parentNode)}}}}},547:e=>{e.exports={tocSelector:".js-toc",contentSelector:".js-toc-content",headingSelector:"h1, h2, h3",ignoreSelector:".js-toc-ignore",hasInnerContainers:!1,linkClass:"toc-link",extraLinkClasses:"",activeLinkClass:"is-active-link",listClass:"toc-list",extraListClasses:"",isCollapsedClass:"is-collapsed",collapsibleClass:"is-collapsible",listItemClass:"toc-list-item",activeListItemClass:"is-active-li",collapseDepth:0,scrollSmooth:!0,scrollSmoothDuration:420,scrollSmoothOffset:0,scrollEndCallback:function(e){},headingsOffset:1,throttleTimeout:50,positionFixedSelector:null,positionFixedClass:"is-position-fixed",fixedSidebarOffset:"auto",includeHtml:!1,includeTitleTags:!1,onClick:function(e){},orderedList:!0,scrollContainer:null,skipRendering:!1,headingLabelCallback:!1,ignoreHiddenElements:!1,headingObjectCallback:null,basePath:"",disableTocScrollSync:!1}},971:function(e,t,n){var o,l,r;l=[],o=function(e){"use strict";var t,o,l,r=n(547),i={},s={},c=n(163),a=n(279),u=n(938),d=!!(e&&e.document&&e.document.querySelector&&e.addEventListener);if("undefined"!=typeof window||d){var f=Object.prototype.hasOwnProperty;return s.destroy=function(){var e=h(i);null!==e&&(i.skipRendering||e&&(e.innerHTML=""),i.scrollContainer&&document.querySelector(i.scrollContainer)?(document.querySelector(i.scrollContainer).removeEventListener("scroll",this._scrollListener,!1),document.querySelector(i.scrollContainer).removeEventListener("resize",this._scrollListener,!1),t&&document.querySelector(i.scrollContainer).removeEventListener("click",this._clickListener,!1)):(document.removeEventListener("scroll",this._scrollListener,!1),document.removeEventListener("resize",this._scrollListener,!1),t&&document.removeEventListener("click",this._clickListener,!1)))},s.init=function(e){if(d){i=function(){for(var e={},t=0;t{e.exports=function(e){var t=[].reduce;function n(e){return e[e.length-1]}function o(e){return+e.nodeName.toUpperCase().replace("H","")}function l(t){if(!(t instanceof window.HTMLElement))return t;if(e.ignoreHiddenElements&&(!t.offsetHeight||!t.offsetParent))return null;const n=t.getAttribute("data-heading-label")||(e.headingLabelCallback?String(e.headingLabelCallback(t.textContent)):t.textContent.trim());var l={id:t.id,children:[],nodeName:t.nodeName,headingLevel:o(t),textContent:n};return e.includeHtml&&(l.childNodes=t.childNodes),e.headingObjectCallback?e.headingObjectCallback(l,t):l}return{nestHeadingsArray:function(o){return t.call(o,(function(t,o){var r=l(o);return r&&function(t,o){for(var r=l(t),i=r.headingLevel,s=o,c=n(s),a=i-(c?c.headingLevel:0);a>0&&(!(c=n(s))||i!==c.headingLevel);)c&&void 0!==c.children&&(s=c.children),a--;i>=e.collapseDepth&&(r.isCollapsed=!0),s.push(r)}(r,t.nest),t}),{nest:[]})},selectHeadings:function(t,n){var o=n;e.ignoreSelector&&(o=n.split(",").map((function(t){return t.trim()+":not("+e.ignoreSelector+")"})));try{return t.querySelectorAll(o)}catch(e){return console.warn("Headers not found with selector: "+o),null}}}}},374:(e,t)=>{t.initSmoothScrolling=function(e){var t=e.duration,n=e.offset,o=location.hash?l(location.href):location.href;function l(e){return e.slice(0,e.lastIndexOf("#"))}document.body.addEventListener("click",(function(r){var i;"a"!==(i=r.target).tagName.toLowerCase()||!(i.hash.length>0||"#"===i.href.charAt(i.href.length-1))||l(i.href)!==o&&l(i.href)+"#"!==o||r.target.className.indexOf("no-smooth-scroll")>-1||"#"===r.target.href.charAt(r.target.href.length-2)&&"!"===r.target.href.charAt(r.target.href.length-1)||-1===r.target.className.indexOf(e.linkClass)||function(e,t){var n,o,l=window.pageYOffset,r={duration:t.duration,offset:t.offset||0,callback:t.callback,easing:t.easing||function(e,t,n,o){return(e/=o/2)<1?n/2*e*e+t:-n/2*(--e*(e-2)-1)+t}},i=document.querySelector('[id="'+decodeURI(e).split("#").join("")+'"]')||document.querySelector('[id="'+e.split("#").join("")+'"]'),s="string"==typeof e?r.offset+(e?i&&i.getBoundingClientRect().top||0:-(document.documentElement.scrollTop||document.body.scrollTop)):e,c="function"==typeof r.duration?r.duration(s):r.duration;function a(e){o=e-n,window.scrollTo(0,r.easing(o,l,s,c)),o{e.exports=function(e){var t=document.querySelector(e.tocSelector);if(t&&t.scrollHeight>t.clientHeight){var n=t.querySelector("."+e.activeListItemClass);n&&(t.scrollTop=n.offsetTop)}}}},t={};function n(o){var l=t[o];if(void 0!==l)return l.exports;var r=t[o]={exports:{}};return e[o].call(r.exports,r,r.exports,n),r.exports}n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),n(971)})(); \ No newline at end of file diff --git a/maixpy/static/js/theme_default/viewer.min.js b/maixpy/static/js/theme_default/viewer.min.js new file mode 100644 index 00000000..c5376e39 --- /dev/null +++ b/maixpy/static/js/theme_default/viewer.min.js @@ -0,0 +1,10 @@ +/*! + * Viewer.js v1.10.0 + * https://fengyuanchen.github.io/viewerjs + * + * Copyright 2015-present Chen Fengyuan + * Released under the MIT license + * + * Date: 2021-06-12T07:57:10.970Z + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Viewer=e()}(this,function(){"use strict";function e(e,t){var i,n=Object.keys(e);return Object.getOwnPropertySymbols&&(i=Object.getOwnPropertySymbols(e),t&&(i=i.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,i)),n}function l(n){for(var t=1;t=this.length||this.viewed&&t===this.index)return this;if(!this.isShown)return this.index=t,this.show();this.viewing&&this.viewing.abort();var e=this.element,n=this.options,o=this.title,s=this.canvas,a=this.items[t],r=a.querySelector("img"),h=gt(r,"originalUrl"),l=r.getAttribute("alt"),c=document.createElement("img");if(ot(n.inheritedAttributes,function(t){var e=r.getAttribute(t);null!==e&&c.setAttribute(t,e)}),c.src=h,c.alt=l,nt(n.view)&&yt(e,"view",n.view,{once:!0}),!1===xt(e,"view",{originalImage:this.images[t],index:t,image:c})||!this.isShown||this.hiding||this.played)return this;h=this.items[this.index];ct(h,m),h.removeAttribute("aria-selected"),lt(a,m),a.setAttribute("aria-selected",!0),n.focus&&a.focus(),this.image=c,this.viewed=!1,this.index=t,this.imageData={},lt(c,D),n.loading&<(s,T),s.innerHTML="",s.appendChild(c),this.renderList(),o.innerHTML="";function u(){var t=i.imageData,e=Array.isArray(n.title)?n.title[1]:n.title;o.innerHTML=_(t=nt(e)?e.call(i,c,t):"".concat(l," (").concat(t.naturalWidth," × ").concat(t.naturalHeight,")"))?t.replace(/&(?!amp;|quot;|#39;|lt;|gt;)/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(//g,">"):t}var d;return yt(e,V,u,{once:!0}),this.viewing={abort:function(){wt(e,V,u),c.complete?i.imageRendering?i.imageRendering.abort():i.imageInitializing&&i.imageInitializing.abort():(c.src="",wt(c,N,d),i.timeout&&clearTimeout(i.timeout))}},c.complete?this.load():(yt(c,N,d=this.load.bind(this),{once:!0}),this.timeout&&clearTimeout(this.timeout),this.timeout=setTimeout(function(){ct(c,D),i.timeout=!1},1e3)),this},prev:function(){var t=this.index-1;return t<0&&(t=0Math.abs(r)&&(this.pointers={},1
    ',n=(i=d.querySelector(".".concat(g,"-container"))).querySelector(".".concat(g,"-title")),o=i.querySelector(".".concat(g,"-toolbar")),a=i.querySelector(".".concat(g,"-navbar")),m=i.querySelector(".".concat(g,"-button")),d=i.querySelector(".".concat(g,"-canvas")),this.parent=e,this.viewer=i,this.title=n,this.toolbar=o,this.navbar=a,this.button=m,this.canvas=d,this.footer=i.querySelector(".".concat(g,"-footer")),this.tooltipBox=i.querySelector(".".concat(g,"-tooltip")),this.player=i.querySelector(".".concat(g,"-player")),this.list=i.querySelector(".".concat(g,"-list")),i.id="".concat(g).concat(this.id),n.id="".concat(g,"Title").concat(this.id),lt(n,s.title?Tt(Array.isArray(s.title)?s.title[0]:s.title):w),lt(a,s.navbar?Tt(s.navbar):w),ut(m,w,!s.button),s.keyboard&&m.setAttribute("tabindex",0),s.backdrop&&(lt(i,"".concat(g,"-backdrop")),s.inline||"static"===s.backdrop||ft(d,K,"hide")),_(s.className)&&s.className&&s.className.split(Z).forEach(function(t){lt(i,t)}),s.toolbar?(r=document.createElement("ul"),h=it(s.toolbar),l=$.slice(0,3),c=$.slice(7,9),u=$.slice(9),h||lt(o,Tt(s.toolbar)),ot(h?s.toolbar:$,function(t,e){var i=h&&it(t),n=h?mt(e):t,o=i&&!Q(t.show)?t.show:t;!o||!s.zoomable&&-1!==l.indexOf(n)||!s.rotatable&&-1!==c.indexOf(n)||!s.scalable&&-1!==u.indexOf(n)||(e=i&&!Q(t.size)?t.size:t,i=i&&!Q(t.click)?t.click:t,t=document.createElement("li"),s.keyboard&&t.setAttribute("tabindex",0),t.setAttribute("role","button"),lt(t,"".concat(g,"-").concat(n)),nt(i)||ft(t,K,n),J(o)&<(t,Tt(o)),-1!==["small","large"].indexOf(e)?lt(t,"".concat(g,"-").concat(e)):"play"===n&<(t,"".concat(g,"-large")),nt(i)&&yt(t,O,i),r.appendChild(t))}),o.appendChild(r)):lt(o,w),s.rotatable||(lt(d=o.querySelectorAll('li[class*="rotate"]'),D),ot(d,function(t){o.appendChild(t)})),s.inline?(lt(m,b),rt(i,{zIndex:s.zIndexInline}),"static"===window.getComputedStyle(e).position&&rt(e,{position:"relative"}),e.insertBefore(i,t.nextSibling)):(lt(m,f),lt(i,p),lt(i,v),lt(i,w),rt(i,{zIndex:s.zIndex}),(m=(m=_(m=s.container)?t.ownerDocument.querySelector(m):m)||this.body).appendChild(i)),s.inline&&(this.render(),this.bind(),this.isShown=!0),this.ready=!0,nt(s.ready)&&yt(t,j,s.ready,{once:!0}),!1!==xt(t,j)?this.ready&&s.inline&&this.view(this.index):this.ready=!1)}}])&&o(t.prototype,e),n&&o(t,n),i}();return st(n.prototype,It,r,t,St,Ot),n}); \ No newline at end of file diff --git a/maixpy/static/search_index/index.json b/maixpy/static/search_index/index.json new file mode 100644 index 00000000..3442e24d --- /dev/null +++ b/maixpy/static/search_index/index.json @@ -0,0 +1 @@ +{"/api/":["MaixPy API Reference","/maixpy/static/search_index/index_0.json"],"/doc/zh/":["MaixPy 中文文档","/maixpy/static/search_index/index_1.json"],"/doc/en/":["MaixPy English Documentation","/maixpy/static/search_index/index_2.json"],"/":["MaixPy 页面","/maixpy/static/search_index/index_3.json"],"/en/":["MaixPy Pages","/maixpy/static/search_index/index_4.json"]} \ No newline at end of file diff --git a/maixpy/static/search_index/index_0.json b/maixpy/static/search_index/index_0.json new file mode 100644 index 00000000..a6c4d6a2 --- /dev/null +++ b/maixpy/static/search_index/index_0.json @@ -0,0 +1 @@ +{"/maixpy/api/maix/audio.html":{"title":"maix.audio","content":" title: maix.audio maix.audio module > You can use `maix.audio` to access this module with MaixPy > This module is generated from [MaixCDK](https://github.com/sipeed/MaixCDK) ## Module No module ## Enum ### Format item doc **brief** Audio type **values** **FMT_NONE**: format invalid
    **FMT_S8**: unsigned 8 bits
    **FMT_S16_LE**: signed 16 bits, little endian
    **FMT_S32_LE**: signed 32 bits, little endian
    **FMT_S16_BE**: signed 16 bits, big endian
    **FMT_S32_BE**: signed 32 bits, big endian
    **FMT_U8**: unsigned 8 bits
    **FMT_U16_LE**: unsigned 16 bits, little endian
    **FMT_U32_LE**: unsigned 32 bits, little endian
    **FMT_U16_BE**: unsigned 16 bits, big endian
    **FMT_U32_BE**: unsigned 32 bits, big endian
    **C++ defination code**: ```cpp enum Format { FMT_NONE 0, // format invalid FMT_S8, // unsigned 8 bits FMT_S16_LE, // signed 16 bits, little endian FMT_S32_LE, // signed 32 bits, little endian FMT_S16_BE, // signed 16 bits, big endian FMT_S32_BE, // signed 32 bits, big endian FMT_U8, // unsigned 8 bits FMT_U16_LE, // unsigned 16 bits, little endian FMT_U32_LE, // unsigned 32 bits, little endian FMT_U16_BE, // unsigned 16 bits, big endian FMT_U32_BE, // unsigned 32 bits, big endian } ``` ## Variable ## Function ## Class ### Recorder item doc **brief** Recorder class **C++ defination code**: ```cpp class Recorder ``` #### \\_\\_init\\_\\_ item doc **type** func **brief** Construct a new Recorder object **param** **path**: record path. the path determines the location where you save the file, if path is none, the audio module will not save file.
    **sample_rate**: record sample rate, default is 48000(48KHz), means 48000 samples per second.
    **format**: record sample format, default is audio::Format::FMT_S16_LE, means sampling 16 bits at a time and save as signed 16 bits, little endian. see @audio::Format
    **channel**: record sample channel, default is 1, means 1 channel sampling at the same time
    **static** False **C++ defination code**: ```cpp Recorder(std::string path std::string(), int sample_rate 48000, audio::Format format audio::Format::FMT_S16_LE, int channel 1) ``` #### volume item doc **type** func **brief** Set/Get record volume **param** **value**: volume value, If you use this parameter, audio will set the value to volume,
    if you don't, it will return the current volume.
    **return** the current volume **static** False **C++ defination code**: ```cpp int volume(int value 1) ``` #### record item doc **type** func **brief** Record, Read all cached data in buffer and return. **param** **record_ms**: record time. unit: ms
    **sample_rate**: audio sample rate
    **format**: audio sample format
    **channel**: audio sample channel
    **return** pcm data. datatype @see Bytes. If you pass in record_ms parameter, the return value is an empty Bytes object. **static** False **C++ defination code**: ```cpp maix::Bytes *record(int record_ms 1) ``` #### finish item doc **type** func **brief** Finish the record, if you have passed in the path, this api will save the audio data to file. **return** error code, err::ERR_NONE means success, others means failed **static** False **C++ defination code**: ```cpp err::Err finish() ``` #### sample\\_rate item doc **type** func **brief** Get sample rate **return** returns sample rate **static** False **C++ defination code**: ```cpp int sample_rate() ``` #### format item doc **type** func **brief** Get sample format **return** returns sample format **static** False **C++ defination code**: ```cpp audio::Format format() ``` #### channel item doc **type** func **brief** Get sample channel **return** returns sample channel **static** False **C++ defination code**: ```cpp int channel() ``` ### Player item doc **brief** Player class **C++ defination code**: ```cpp class Player ``` #### \\_\\_init\\_\\_ item doc **type** func **brief** Construct a new Player object **param** **path**: player path. the path determines the location where you save the file, if path is none, the audio module will not save file.
    **sample_rate**: player sample rate, default is 48000(48KHz), means 48000 samples per second.
    **format**: player sample format, default is audio::Format::FMT_S16_LE, means sampling 16 bits at a time and save as signed 16 bits, little endian. see @audio::Format
    **channel**: player sample channel, default is 1, means 1 channel sampling at the same time
    **static** False **C++ defination code**: ```cpp Player(std::string path std::string(), int sample_rate 48000, audio::Format format audio::Format::FMT_S16_LE, int channel 1) ``` #### volume item doc **type** func **brief** Set/Get player volume(Not support now) **param** **value**: volume value, If you use this parameter, audio will set the value to volume,
    if you don't, it will return the current volume.
    **return** the current volume **static** False **C++ defination code**: ```cpp int volume(int value 1) ``` #### play item doc **type** func **brief** Play **param** **data**: audio data, must be raw data
    **return** error code, err::ERR_NONE means success, others means failed **static** False **C++ defination code**: ```cpp err::Err play(maix::Bytes *data maix::audio::Player::NoneBytes) ``` #### sample\\_rate item doc **type** func **brief** Get sample rate **return** returns sample rate **static** False **C++ defination code**: ```cpp int sample_rate() ``` #### format item doc **type** func **brief** Get sample format **return** returns sample format **static** False **C++ defination code**: ```cpp audio::Format format() ``` #### channel item doc **type** func **brief** Get sample channel **return** returns sample channel **static** False **C++ defination code**: ```cpp int channel() ```"},"/maixpy/api/maix/sys.html":{"title":"maix.sys","content":" title: maix.sys maix.sys module > You can use `maix.sys` to access this module with MaixPy > This module is generated from [MaixCDK](https://github.com/sipeed/MaixCDK) ## Module No module ## Enum ## Variable ## Function ### os\\_version ```python def os_version() > str ``` item doc **brief** Get system version **return** version string, e.g. \"2024.4.1 13af4b\" **C++ defination code**: ```cpp std::string os_version() ``` ### device\\_name ```python def device_name() > str ``` item doc **brief** Get device name **return** device name, e.g. \"MaixCAM\" **C++ defination code**: ```cpp std::string device_name() ``` ### host\\_name ```python def host_name() > str ``` item doc **brief** Get host name **return** host name, e.g. \"maixcam 2f9f\" **C++ defination code**: ```cpp std::string host_name() ``` ### host\\_domain ```python def host_domain() > str ``` item doc **brief** Get host domain **return** host domain, e.g. \"maixcam 2f9f.local\" **C++ defination code**: ```cpp std::string host_domain() ``` ### ip\\_address ```python def ip_address() > dict[str, str] ``` item doc **brief** Get ip address **return** ip address, dict type, e.g. {\"eth0\": \"192.168.0.195\", \"wlan0\": \"192.168.0.123\", \"usb0\": \"10.47.159.1\"} **C++ defination code**: ```cpp std::map ip_address() ``` ### mac\\_address ```python def mac_address() > dict[str, str] ``` item doc **brief** Get mac address **return** mac address, dict type, e.g. {\"eth0\": \"00:0c:29:2f:9f:00\", \"wlan0\": \"00:0c:29:2f:9f:01\", \"usb0\": \"00:0c:29:2f:9f:02\"} **C++ defination code**: ```cpp std::map mac_address() ``` ### device\\_key ```python def device_key() > str ``` item doc **brief** Get device key, can be unique id of device **return** device key, 32 bytes hex string, e.g. \"1234567890abcdef1234567890abcdef\" **C++ defination code**: ```cpp std::string device_key() ``` ### memory\\_info ```python def memory_info() > dict[str, int] ``` item doc **brief** Get memory info **return** memory info, dict type, e.g. {\"total\": 1024, \"used\": 512, \"hw_total\": 256*1024*1024}
    total: total memory size in Byte.
    used: used memory size in Byte.
    hw_total: total memory size in Byte of hardware, the total < hw_total,
    OS kernel may reserve some memory for some hardware like camera, npu, display etc. **C++ defination code**: ```cpp std::map memory_info() ``` ### bytes\\_to\\_human ```python def bytes_to_human(bytes: int, precision: int 2, base: int 1024, unit: str 'B', sep: str ' ') > str ``` item doc **brief** Bytes to human readable string **param** **bytes:**: bytes size,e.g. 1234B 1234/1024 1.205 KB
    **precision:**: decimal precision, default 2
    **base:**: base number, default 1024
    **unit:**: unit string, e.g. \"B\"
    **sep:**: separator string, e.g. \" \"
    **return** human readable string, e.g. \"1.21 KB\" **C++ defination code**: ```cpp std::string bytes_to_human(unsigned long long bytes, int precision 2, int base 1024, const std::string &unit \"B\", const std::string &sep \" \") ``` ### cpu\\_freq ```python def cpu_freq() > dict[str, int] ``` item doc **brief** Get CPU frequency **return** CPU frequency, dict type, e.g. {\"cpu0\": 1000000000, \"cpu1\": 1000000000} **C++ defination code**: ```cpp std::map cpu_freq() ``` ### cpu\\_temp ```python def cpu_temp() > dict[str, float] ``` item doc **brief** Get CPU temperature **return** CPU temperature, unit dgree, dict type, e.g. {\"cpu\": 50.0, \"cpu0\": 50, \"cpu1\": 50} **C++ defination code**: ```cpp std::map cpu_temp() ``` ### cpu\\_usage ```python def cpu_usage() > dict[str, float] ``` item doc **brief** Get CPU usage **return** CPU usage, dict type, e.g. {\"cpu\": 50.0, \"cpu0\": 50, \"cpu1\": 50} **C++ defination code**: ```cpp std::map cpu_usage() ``` ### npu\\_freq ```python def npu_freq() > dict[str, int] ``` item doc **brief** Get NPU frequency **return** NPU frequency, dict type, e.g. {\"npu0\": 500000000} **C++ defination code**: ```cpp std::map npu_freq() ``` ### disk\\_usage ```python def disk_usage(path: str '/') > dict[str, int] ``` item doc **brief** Get disk usage **param** **path:**: disk path, default \"/\"
    **return** disk usage, dict type, e.g. {\"total\": 1024, \"used\": 512} **C++ defination code**: ```cpp std::map disk_usage(const std::string &path \"/\") ``` ### disk\\_partitions ```python def disk_partitions(only_disk: bool True) > list[dict[str, str]] ``` item doc **brief** Get disk partition and mount point info **param** **only_disk**: only return real disk, tempfs sysfs etc. not return, default true.
    **return** disk partition and mount point info, list type, e.g. [{\"device\": \"/dev/mmcblk0p1\", \"mountpoint\": \"/mnt/sdcard\", \"fstype\": \"vfat\"}] **C++ defination code**: ```cpp std::vector> disk_partitions(bool only_disk true) ``` ### poweroff ```python def poweroff() > None ``` item doc **brief** Power off device **C++ defination code**: ```cpp void poweroff() ``` ### reboot ```python def reboot() > None ``` item doc **brief** Power off device and power on **C++ defination code**: ```cpp void reboot() ``` ## Class"},"/maixpy/api/maix/tensor.html":{"title":"maix.tensor","content":" title: maix.tensor maix.tensor module > You can use `maix.tensor` to access this module with MaixPy > This module is generated from [MaixCDK](https://github.com/sipeed/MaixCDK) ## Module No module ## Enum ### DType item doc **brief** Tensor data types **values** **UINT8**:
    **INT8**:
    **UINT16**:
    **INT16**:
    **UINT32**:
    **INT32**:
    **FLOAT16**:
    **FLOAT32**:
    **FLOAT64**:
    **BOOL**:
    **DTYPE_MAX**:
    **C++ defination code**: ```cpp enum DType { UINT8 0, INT8, UINT16, INT16, UINT32, INT32, FLOAT16, FLOAT32, FLOAT64, BOOL, // STRING, // OBJECT, DTYPE_MAX } ``` ## Variable ### dtype\\_size item doc **brief** Tensor data type size in bytes **attention** It's a copy of this variable in MaixPy,
    so change it in C++ (e.g. update var in hello function) will not take effect the var inMaixPy.
    So we add const for this var to avoid this mistake. **value** **{
    1, // UINT8
    1, // INT8
    2, // UINT16
    2, // INT16
    4, // UINT32
    4, // INT32
    2, // FLOAT16
    4, // FLOAT32
    8, // FLOAT64
    1, // BOOL
    // 1, // STRING
    // 1, // OBJECT
    0
    }** **readonly** True **C++ defination code**: ```cpp const std::vector dtype_size { 1, // UINT8 1, // INT8 2, // UINT16 2, // INT16 4, // UINT32 4, // INT32 2, // FLOAT16 4, // FLOAT32 8, // FLOAT64 1, // BOOL // 1, // STRING // 1, // OBJECT 0 } ``` ### dtype\\_name item doc **brief** Tensor data type name **value** **{
    \"uint8\",
    \"int8\",
    \"uint16\",
    \"int16\",
    \"uint32\",
    \"int32\",
    \"float16\",
    \"float32\",
    \"float64\",
    \"bool\",
    // \"string\",
    // \"object\",
    \"invalid\"
    }** **readonly** True **C++ defination code**: ```cpp const std::vector dtype_name { \"uint8\", \"int8\", \"uint16\", \"int16\", \"uint32\", \"int32\", \"float16\", \"float32\", \"float64\", \"bool\", // \"string\", // \"object\", \"invalid\" } ``` ## Function ## Class ### Tensor item doc **brief** Tensor class **C++ defination code**: ```cpp class Tensor ``` #### \\_\\_init\\_\\_ item doc **type** func **brief** Tensor constructor **param** **shape**: tensor shape, a int list
    **dtype**: tensor element data type, see DType of this module
    **data**: pointer to data content, can be nullptr, it will automatically alloc memory
    and detroy it when this object is destroyed
    **static** False **C++ defination code**: ```cpp Tensor(std::vector shape, tensor::DType dtype, void *data nullptr) ``` #### to\\_str item doc **type** func **brief** To string **static** False **C++ defination code**: ```cpp std::string to_str() ``` #### \\_\\_str\\_\\_ item doc **type** func **brief** To string **static** False **C++ defination code**: ```cpp std::string __str__() ``` #### shape item doc **type** func **brief** get tensor shape **return** tensor shape, a int list **static** False **C++ defination code**: ```cpp std::vector shape() ``` #### expand\\_dims item doc **type** func **brief** expand tensor shape **param** **axis**: axis to expand
    **static** False **C++ defination code**: ```cpp void expand_dims(int axis) ``` #### reshape item doc **type** func **brief** reshape tensor shape, if size not match, it will throw an err::Exception **param** **shape**: new shape
    **static** False **C++ defination code**: ```cpp void reshape(std::vector shape) ``` #### flatten item doc **type** func **brief** Flatten tensor shape to 1D **static** False **C++ defination code**: ```cpp void flatten() ``` #### dtype item doc **type** func **brief** get tensor data type **return** tensor data type, see DType of this module **static** False **C++ defination code**: ```cpp tensor::DType dtype() ``` #### argmax item doc **type** func **brief** argmax of tensor **param** **axis**: By default, the index is into the flattened array, otherwise along the specified axis., wrong axis will throw an err::Exception
    **return** argmax result, you need to delete it after use in C++. **static** False **C++ defination code**: ```cpp tensor::Tensor *argmax(int axis 0xffff) ``` #### argmax1 item doc **type** func **brief** argmax1, flattened data max index **return** argmax result, int type **static** False **C++ defination code**: ```cpp int argmax1() ``` ### Tensors item doc **brief** Tensors **C++ defination code**: ```cpp class Tensors ``` #### \\_\\_init\\_\\_ ```python def __init__(self) > None ``` item doc **type** func **brief** Constructor of Tensors **static** False **C++ defination code**: ```cpp Tensors() ``` #### add\\_tensor ```python def add_tensor(self, key: str, tensor: Tensor, copy: bool, auto_delete: bool) > None ``` item doc **type** func **brief** Add tensor **static** False **C++ defination code**: ```cpp void add_tensor(const std::string &key, tensor::Tensor *tensor, bool copy, bool auto_delete) ``` #### rm\\_tensor ```python def rm_tensor(self, key: str) > None ``` item doc **type** func **brief** Remove tensor **static** False **C++ defination code**: ```cpp void rm_tensor(const std::string &key) ``` #### get\\_tensor ```python def get_tensor(self, key: str) > Tensor ``` item doc **type** func **brief** Get tensor by key **static** False **C++ defination code**: ```cpp tensor::Tensor *get_tensor(const std::string &key) ``` #### \\_\\_getitem\\_\\_ ```python def __getitem__(self, key: str) > Tensor ``` item doc **type** func **brief** Operator [] **static** False **C++ defination code**: ```cpp tensor::Tensor *operator[](const std::string &key) ``` #### \\_\\_len\\_\\_ ```python def __len__(self) > int ``` item doc **type** func **brief** Size **static** False **C++ defination code**: ```cpp size_t size() ``` #### get\\_names ```python def get_names(self) > list[str] ``` item doc **type** func **brief** Get names **static** False **C++ defination code**: ```cpp std::vector get_names() ``` #### tensors item doc **type** var **brief** Tensors data, dict type **static** False **readonly** False **C++ defination code**: ```cpp std::map tensors ```"},"/maixpy/api/maix/i18n.html":{"title":"maix.i18n","content":" title: maix.i18n maix.i18n module > You can use `maix.i18n` to access this module with MaixPy > This module is generated from [MaixCDK](https://github.com/sipeed/MaixCDK) ## Module No module ## Enum ## Variable ### locales item doc **brief** i18n locales list **value** **{
    \"en\",
    \"zh\",
    \"zh tw\",
    \"ja\"
    }** **readonly** False **C++ defination code**: ```cpp static std::vector locales { \"en\", \"zh\", \"zh tw\", \"ja\" } ``` ### names item doc **brief** i18n language names list **value** **{
    \"English\",
    \"简体中文\",
    \"繁體中文\",
    \"日本語\"
    }** **readonly** True **C++ defination code**: ```cpp const static std::vector names { \"English\", \"简体中文\", \"繁體中文\", \"日本語\" } ``` ## Function ### get\\_locale ```python def get_locale(self) > str ``` item doc **brief** Get system config of locale. **return** language locale, e.g. en, zh, zh_CN, zh_TW, etc. **C++ defination code**: ```cpp string get_locale() ``` ### get\\_language\\_name item doc **brief** Get system config of language name. **return** language name, e.g. English, 简体中文, 繁體中文, etc. **C++ defination code**: ```cpp string get_language_name() ``` ## Class ### Trans item doc **brief** Translate helper class. **C++ defination code**: ```cpp class Trans ``` #### \\_\\_init\\_\\_ ```python def __init__(self, locales_dict: dict[str, dict[str, str]]) > None ``` item doc **type** func **brief** Translate helper class constructor.\\nBy default locale is get by `i18n.get_locale()` function which set by system settings.\\nBut you can also manually set by `set_locale` function temporarily. **param** **locales_dict**: locales dict, e.g. {\"zh\": {\"Confirm\": \"确认\", \"OK\": \"好的\"}, \"en\": {\"Confirm\": \"Confirm\", \"OK\": \"OK\"}}
    **static** False **C++ defination code**: ```cpp Trans(const std::map> &locales_dict) ``` #### tr ```python def tr(self, key: str, locale: str '') > str ``` item doc **type** func **brief** Translate string by key. **param** **key**: string key, e.g. \"Confirm\"
    **locale**: locale name, if not assign, use default locale set by system settings or set_locale function.
    **return** translated string, if find translation, return it, or return key, e.g. \"确认\", \"Confirm\", etc. **static** False **C++ defination code**: ```cpp string tr(const string &key, const string locale \"\") ``` #### set\\_locale ```python def set_locale(self, locale: str) > None ``` item doc **type** func **brief** Set locale temporarily, will not affect system settings. **param** **locale**: locale name, e.g. \"zh\", \"en\", etc. @see maix.i18n.locales
    **static** False **C++ defination code**: ```cpp void set_locale(const string &locale) ``` #### get\\_locale ```python def get_locale(self) > str ``` item doc **type** func **brief** Get current locale. **return** locale name, e.g. \"zh\", \"en\", etc. @see maix.i18n.locales **static** False **C++ defination code**: ```cpp string get_locale() ```"},"/maixpy/api/maix/rtsp.html":{"title":"maix.rtsp","content":" title: maix.rtsp maix.rtsp module > You can use `maix.rtsp` to access this module with MaixPy > This module is generated from [MaixCDK](https://github.com/sipeed/MaixCDK) ## Module No module ## Enum ### RtspStreamType item doc **brief** The stream type of rtsp **values** **RTSP_STREAM_NONE**: format invalid
    **RTSP_STREAM_H265**:
    **C++ defination code**: ```cpp enum RtspStreamType { RTSP_STREAM_NONE 0, // format invalid RTSP_STREAM_H265, } ``` ## Variable ## Function ## Class ### Region item doc **brief** Region class **C++ defination code**: ```cpp class Region ``` #### \\_\\_init\\_\\_ ```python def __init__(self, x: int, y: int, width: int, height: int, format: maix.image.Format, camera: maix.camera.Camera) > None ``` item doc **type** func **brief** Construct a new Region object **param** **x**: region coordinate x
    **y**: region coordinate y
    **width**: region width
    **height**: region height
    **format**: region format
    **camera**: bind region to camera
    **static** False **C++ defination code**: ```cpp Region(int x, int y, int width, int height, image::Format format, camera::Camera *camera) ``` #### get\\_canvas ```python def get_canvas(self) > maix.image.Image ``` item doc **type** func **brief** Return an image object from region **return** image object **static** False **C++ defination code**: ```cpp image::Image *get_canvas() ``` #### update\\_canvas ```python def update_canvas(self) > maix.err.Err ``` item doc **type** func **brief** Update canvas **return** error code **static** False **C++ defination code**: ```cpp err::Err update_canvas() ``` ### Rtsp item doc **brief** Rtsp class **C++ defination code**: ```cpp class Rtsp ``` #### \\_\\_init\\_\\_ item doc **type** func **brief** Construct a new Video object **param** **ip**: rtsp ip
    **port**: rtsp port
    **fps**: rtsp fps
    **stream_type**: rtsp stream type
    **static** False **C++ defination code**: ```cpp Rtsp(std::string ip std::string(), int port 8554, int fps 30, rtsp::RtspStreamType stream_type rtsp::RtspStreamType::RTSP_STREAM_H265) ``` #### start item doc **type** func **brief** start rtsp **return** error code, err::ERR_NONE means success, others means failed **static** False **C++ defination code**: ```cpp err::Err start() ``` #### start (overload 1) item doc **type** func **brief** stop rtsp **return** error code, err::ERR_NONE means success, others means failed **static** False **C++ defination code**: ```cpp err::Err stop() ``` #### bind\\_camera item doc **type** func **brief** Bind camera **param** **camera**: camera object
    **return** error code, err::ERR_NONE means success, others means failed **static** False **C++ defination code**: ```cpp err::Err bind_camera(camera::Camera *camera) ``` #### write item doc **type** func **brief** Write data to rtsp **param** **type**: rtsp stream type
    **data**: rtsp stream data
    **fps**: rtsp stream data size
    **return** error code, err::ERR_NONE means success, others means failed **static** False **C++ defination code**: ```cpp err::Err write(video::Frame &stream) ``` #### get\\_url item doc **type** func **brief** Get url of rtsp **return** url of rtsp **static** False **C++ defination code**: ```cpp std::string get_url() ``` #### to\\_camera item doc **type** func **brief** Get camera object from rtsp **return** camera object **static** False **C++ defination code**: ```cpp camera::Camera *to_camera() ``` #### rtsp\\_is\\_start item doc **type** func **brief** return rtsp start status **return** true means rtsp is start, false means rtsp is stop. **static** False **C++ defination code**: ```cpp bool rtsp_is_start() ``` #### add\\_region item doc **type** func **brief** return a region object, you can draw image on the region. **param** **x**: region coordinate x
    **y**: region coordinate y
    **width**: region width
    **height**: region height
    **format**: region format, support Format::FMT_BGRA8888 only
    **return** the reigon object **static** False **C++ defination code**: ```cpp rtsp::Region *add_region(int x, int y, int width, int height, image::Format format image::Format::FMT_BGRA8888) ``` #### update\\_region item doc **type** func **brief** update and show region **return** error code **static** False **C++ defination code**: ```cpp err::Err update_region(rtsp::Region ®ion) ```"},"/maixpy/api/maix/peripheral.html":{"title":"maix.peripheral","content":" title: maix.peripheral Chip's peripheral driver > You can use `maix.peripheral` to access this module with MaixPy > This module is generated from [MaixCDK](https://github.com/sipeed/MaixCDK) ## Module module brief [adc](./peripheral/adc.html) maix.peripheral.adc module [spi](./peripheral/spi.html) maix.peripheral.spi module [uart](./peripheral/uart.html) maix uart peripheral driver [key](./peripheral/key.html) maix.peripheral.key module [i2c](./peripheral/i2c.html) maix.peripheral.i2c module [pinmap](./peripheral/pinmap.html) maix.peripheral.pinmap module [timer](./peripheral/timer.html) maix.peripheral.timer module [pwm](./peripheral/pwm.html) maix.peripheral.pwm module [gpio](./peripheral/gpio.html) maix.peripheral.gpio module [wdt](./peripheral/wdt.html) maix.peripheral.wdt module ## Enum ## Variable ## Function ## Class"},"/maixpy/api/maix/peripheral/timer.html":{"title":"maix.peripheral.timer","content":" title: maix.peripheral.timer maix.peripheral.timer module > You can use `maix.peripheral.timer` to access this module with MaixPy > This module is generated from [MaixCDK](https://github.com/sipeed/MaixCDK) ## Module No module ## Enum ## Variable ## Function ## Class ### TIMER item doc **brief** Peripheral timer class **C++ defination code**: ```cpp class TIMER ``` #### \\_\\_init\\_\\_ item doc **type** func **brief** TIMER constructor **static** False **C++ defination code**: ```cpp TIMER() ```"},"/maixpy/api/maix/peripheral/pinmap.html":{"title":"maix.peripheral.pinmap","content":" title: maix.peripheral.pinmap maix.peripheral.pinmap module > You can use `maix.peripheral.pinmap` to access this module with MaixPy > This module is generated from [MaixCDK](https://github.com/sipeed/MaixCDK) ## Module No module ## Enum ## Variable ## Function ### get\\_pins ```python def get_pins() > list[str] ``` item doc **brief** Get all pins of devices **return** pin name list, string type. **C++ defination code**: ```cpp std::vector get_pins() ``` ### get\\_pin\\_functions ```python def get_pin_functions(pin: str) > list[str] ``` item doc **brief** Get all function of a pin **param** **pin**: pin name, string type.
    **return** function list, function name is string type. **throw** If pin name error will throwout err.Err.ERR_ARGS error. **C++ defination code**: ```cpp std::vector get_pin_functions(const std::string &pin) ``` ### set\\_pin\\_function ```python def set_pin_function(pin: str, func: str) > maix.err.Err ``` item doc **brief** Set function of a pin **param** **pin**: pin name, string type.
    **func**: which function should this pin use.
    **return** if set ok, will return err.Err.ERR_NONE, else error occurs. **C++ defination code**: ```cpp err::Err set_pin_function(const std::string &pin, const std::string &func) ``` ## Class"},"/maixpy/api/maix/peripheral/i2c.html":{"title":"maix.peripheral.i2c","content":" title: maix.peripheral.i2c maix.peripheral.i2c module > You can use `maix.peripheral.i2c` to access this module with MaixPy > This module is generated from [MaixCDK](https://github.com/sipeed/MaixCDK) ## Module No module ## Enum ### AddrSize item doc **brief** Address size enum **values** **SEVEN_BIT**: 7 bit address mode
    **TEN_BIT**: 10 bit address mode
    **C++ defination code**: ```cpp enum AddrSize { SEVEN_BIT 7, // 7 bit address mode TEN_BIT 10 // 10 bit address mode } ``` ### Mode item doc **brief** I2C mode enum **values** **MASTER**: master mode
    **SLAVE**: slave mode
    **C++ defination code**: ```cpp enum Mode { MASTER 0x00, // master mode SLAVE 0x01 // slave mode } ``` ## Variable ## Function ### list\\_devices item doc **brief** Get supported i2c bus devices. **return** i2c bus devices list, int type, is the i2c bus id. **C++ defination code**: ```cpp std::vector list_devices() ``` ## Class ### I2C item doc **brief** Peripheral i2c class **C++ defination code**: ```cpp class I2C ``` #### \\_\\_init\\_\\_ item doc **type** func **brief** I2C Device constructor\\nthis constructor will be export to MaixPy as _maix.example.Example.__init__ **param** **id**: direction [in], i2c bus id, int type, e.g. 0, 1, 2
    **freq**: direction [in], i2c clock, int type, default is 100000(100kbit/s), will auto set fast mode if freq > 100000.
    **mode**: direction [in], mode of i2c, i2c.Mode.SLAVE or i2c.Mode.MASTER.
    **addr_size**: direction [in], address length of i2c, i2c.AddrSize.SEVEN_BIT or i2c.AddrSize.TEN_BIT.
    **throw** err::Exception if open i2c device failed. **static** False **C++ defination code**: ```cpp I2C(int id, i2c::Mode mode, int freq 100000, i2c::AddrSize addr_size i2c::AddrSize::SEVEN_BIT) ``` #### scan item doc **type** func **brief** scan all i2c salve address on the bus **return** the list of i2c slave address, int list type. **static** False **C++ defination code**: ```cpp std::vector scan() ``` #### writeto item doc **type** func **brief** write data to i2c slave **param** **addr**: direction [in], i2c slave address, int type
    **data**: direction [in], data to write, bytes type.
    Note: The range of value should be in [0,255].
    **return** if success, return the length of written data, error occurred will return err::Err. **static** False **C++ defination code**: ```cpp int writeto(int addr, const Bytes &data) ``` #### readfrom item doc **type** func **brief** read data from i2c slave **param** **addr**: direction [in], i2c slave address, int type
    **len**: direction [in], data length to read, int type
    **return** the list of data read from i2c slave, bytes type, you should delete it after use in C++.
    If read failed, return nullptr in C++, None in MaixPy. **static** False **C++ defination code**: ```cpp Bytes* readfrom(int addr, int len) ``` #### writeto\\_mem item doc **type** func **brief** write data to i2c slave's memory address **param** **addr**: direction [in], i2c slave address, int type
    **mem_addr**: direction [in], memory address want to write, int type.
    **data**: direction [in], data to write, bytes type.
    **mem_addr_size**: direction [in], memory address size, default is 8.
    **mem_addr_le**: direction [in], memory address little endian, default is false, that is send high byte first.
    **return** data length written if success, error occurred will return err::Err. **static** False **C++ defination code**: ```cpp int writeto_mem(int addr, int mem_addr, const Bytes &data, int mem_addr_size 8, bool mem_addr_le false) ``` #### readfrom\\_mem item doc **type** func **brief** read data from i2c slave **param** **addr**: direction [in], i2c slave address, int type
    **mem_addr**: direction [in], memory address want to read, int type.
    **len**: direction [in], data length to read, int type
    **mem_addr_size**: direction [in], memory address size, default is 8.
    **mem_addr_le**: direction [in], memory address little endian, default is false, that is send high byte first.
    **return** the list of data read from i2c slave, bytes type, you should delete it after use in C++.
    If read failed, return nullptr in C++, None in MaixPy. **static** False **C++ defination code**: ```cpp Bytes* readfrom_mem(int addr, int mem_addr, int len, int mem_addr_size 8, bool mem_addr_le false) ```"},"/maixpy/api/maix/peripheral/pwm.html":{"title":"maix.peripheral.pwm","content":" title: maix.peripheral.pwm maix.peripheral.pwm module > You can use `maix.peripheral.pwm` to access this module with MaixPy > This module is generated from [MaixCDK](https://github.com/sipeed/MaixCDK) ## Module No module ## Enum ## Variable ## Function ## Class ### PWM item doc **brief** Peripheral pwm class **C++ defination code**: ```cpp class PWM ``` #### \\_\\_init\\_\\_ item doc **type** func **brief** PWM constructor **param** **pin**: direction [in], pwm id, int type, like 0, 1, 2 etc.
    **freq**: direction [in], pwm frequency, unit: Hz. int type. default is 1000
    **duty**: direction [in], pwm duty. double type. range is [0, 100], default is 0.
    **enable**: direction [in], enable pwm output right now. bool type. default is true, if false, you need to call enable() to enable pwm output.
    **duty_val**: direction [in], pwm duty value, int type. default 1 means not set and auto calculate by freq and duty.
    This arg directly set pwm duty value, if set, will ignore duty arg.
    duty_val duty / 100 * T_ns, T_ns 1 / freq * 1000000000.
    **throw** If args error or init pwm failed, will throw err::Exception **static** False **C++ defination code**: ```cpp PWM(int id, int freq 1000, double duty 0, bool enable true, int duty_val 1) ``` #### duty item doc **type** func **brief** get or set pwm duty **param** **duty**: direction [in], pwm duty, double type, value in [0, 100], default 1 means only read.
    **return** current duty, float type, if set and set failed will return err::Err **static** False **C++ defination code**: ```cpp double duty(double duty 1) ``` #### duty\\_val item doc **type** func **brief** set pwm duty value **param** **duty_val**: direction [in], pwm duty value. int type. default is 1
    duty_val > 0 means set duty_val
    duty_val 1 or not set, return current duty_val
    **return** int type
    when get duty_val, return current duty_val, else return err::Err code. **static** False **C++ defination code**: ```cpp int duty_val(int duty_val 1) ``` #### freq item doc **type** func **brief** get or set pwm frequency **param** **freq**: direction [in], pwm frequency. int type. default is 1
    freq > 0, set freq
    freq 1 or not set, return current freq
    **return** int type, current freq, if set and set failed will return err::Err **static** False **C++ defination code**: ```cpp int freq(int freq 1) ``` #### enable item doc **type** func **brief** set pwm enable **return** err::Err type, err.Err.ERR_NONE means success **static** False **C++ defination code**: ```cpp err::Err enable() ``` #### disable item doc **type** func **brief** set pwm disable **return** err::Err type, err.Err.ERR_NONE means success **static** False **C++ defination code**: ```cpp err::Err disable() ``` #### is\\_enabled item doc **type** func **brief** get pwm enable status **return** bool type, true means enable, false means disable **static** False **C++ defination code**: ```cpp bool is_enabled() ```"},"/maixpy/api/maix/peripheral/spi.html":{"title":"maix.peripheral.spi","content":" title: maix.peripheral.spi maix.peripheral.spi module > You can use `maix.peripheral.spi` to access this module with MaixPy > This module is generated from [MaixCDK](https://github.com/sipeed/MaixCDK) ## Module No module ## Enum ### Mode item doc **brief** SPI mode enum **values** **MASTER**: spi master mode
    **SLAVE**: spi slave mode
    **C++ defination code**: ```cpp enum Mode { MASTER 0x0, // spi master mode SLAVE 0x1, // spi slave mode } ``` ## Variable ## Function ## Class ### SPI item doc **brief** Peripheral spi class **C++ defination code**: ```cpp class SPI ``` #### \\_\\_init\\_\\_ item doc **type** func **brief** SPI constructor **param** **id**: direction [in], spi bus id, int type
    **freq**: direction [in], freq of spi, int type
    **soft_cs**: direction [in], not use hardware cs, bool type, if set true, you can operate cs pin use gpio manually.
    **mode**: direction [in], mode of spi, spi.Mode type, spi.Mode.MASTER or spi.Mode.SLAVE.
    **polarity**: direction [in], polarity of spi, 0 means idle level of clock is low, 1 means high, int type, default is 0.
    **phase**: direction [in], phase of spi, 0 means data is captured on the first edge of the SPI clock cycle, 1 means second, int type, default is 0.
    **bits**: direction [in], bits of spi, int type, default is 8.
    **cs**: direction [in], cs pin number, int type, default is 0, if SPI support multi hardware cs, you can set it to other value.
    **static** False **C++ defination code**: ```cpp SPI(int id, spi::Mode mode, int freq, bool soft_cs false, int polarity 0, int phase 0, int bits 8, int cs 0) ``` #### read item doc **type** func **brief** read data from spi **param** **length**: direction [in], read length, int type
    **return** bytes data, Bytes type in C++, bytes type in MaixPy. You need to delete it manually after use in C++. **static** False **C++ defination code**: ```cpp Bytes *read(int length) ``` #### write\\_read item doc **type** func **brief** write data to spi and read data from spi at the same time. **param** **data**: direction [in], data to write, Bytes type in C++, bytes type in MaixPy
    **read_len**: direction [in], read length, int type, should > 0.
    **return** read data, Bytes type in C++, bytes type in MaixPy. You need to delete it manually after use in C++. **static** False **C++ defination code**: ```cpp Bytes *write_read(Bytes *data, int read_len) ``` #### is\\_busy item doc **type** func **brief** get busy status of spi **return** busy status, bool type **static** False **C++ defination code**: ```cpp bool is_busy() ```"},"/maixpy/api/maix/peripheral/key.html":{"title":"maix.peripheral.key","content":" title: maix.peripheral.key maix.peripheral.key module > You can use `maix.peripheral.key` to access this module with MaixPy > This module is generated from [MaixCDK](https://github.com/sipeed/MaixCDK) ## Module No module ## Enum ### Keys item doc **brief** Keys enum, id the same as linux input.h(input event codes.h) **values** **KEY_NONE**:
    **KEY_ESC**:
    **KEY_OK**:
    **KEY_OPTION**:
    **KEY_NEXT**:
    **KEY_PREV**:
    **C++ defination code**: ```cpp enum Keys{ KEY_NONE 0x000, KEY_ESC 0x001, KEY_OK 0x160, KEY_OPTION 0x165, KEY_NEXT 0x197, KEY_PREV 0x19c } ``` ### State item doc **brief** Key state enum **values** **KEY_RELEASED**:
    **KEY_PRESSED**:
    **C++ defination code**: ```cpp enum State{ KEY_RELEASED 0, KEY_PRESSED 1, } ``` ## Variable ## Function ### add\\_default\\_listener item doc **brief** Add default listener, if you want to exit app when press ok button, you can just call this function.\\nThis function is auto called in MaixPy' startup code, so you don't need to call it in MaixPy.\\nCreate Key object will auto call rm_default_listener() to cancel the default ok button function.\\nWhen ok button pressed, a SIGINT signal will be raise and call app.set_exit_flag(True). **C++ defination code**: ```cpp void add_default_listener() ``` ### rm\\_default\\_listener item doc **brief** Remove default listener, if you want to cancel the default ok button function(exit app), you can just call this function. **C++ defination code**: ```cpp void rm_default_listener() ``` ## Class ### Key item doc **brief** Key input class **C++ defination code**: ```cpp class Key ``` #### \\_\\_init\\_\\_ ```python def __init__(self, callback: typing.Callable[[int, int], None] None, open: bool True) > None ``` item doc **type** func **brief** Key Device constructor **param** **callback**: When key triggered and callback is not empty(empty In MaixPy is None, in C++ is nullptr),
    callback will be called with args key(key.Keys) and value(key.State).
    If set to null, you can get key value by read() function.
    This callback called in a standalone thread, so you can block a while in callback, and you should be carefully when operate shared data.
    **open**: auto open device in constructor, if false, you need call open() to open device
    **static** False **C++ defination code**: ```cpp Key(std::function callback nullptr, bool open true) ``` #### open ```python def open(self) > maix.err.Err ``` item doc **type** func **brief** Open(Initialize) key device, if already opened, will close first and then open. **return** err::Err type, err.Err.ERR_NONE means success **static** False **C++ defination code**: ```cpp err::Err open() ``` #### close ```python def close(self) > maix.err.Err ``` item doc **type** func **brief** Close key device **return** err::Err type, err.Err.ERR_NONE means success **static** False **C++ defination code**: ```cpp err::Err close() ``` #### is\\_opened ```python def is_opened(self) > bool ``` item doc **type** func **brief** Check key device is opened **return** bool type, true means opened, false means closed **static** False **C++ defination code**: ```cpp bool is_opened() ``` #### read ```python def read(self) > tuple[int, int] ``` item doc **type** func **brief** Read key input, and return key and value, if callback is set, DO NOT call this function manually. **return** list type, first is key(maix.key.Keys), second is value(maix.key.State), if no key input, return [0, 0] **throw** If read failed, will throw maix.err.Exception. **static** False **C++ defination code**: ```cpp std::pair read() ```"},"/maixpy/api/maix/peripheral/uart.html":{"title":"maix.peripheral.uart","content":" title: maix.peripheral.uart maix uart peripheral driver > You can use `maix.peripheral.uart` to access this module with MaixPy > This module is generated from [MaixCDK](https://github.com/sipeed/MaixCDK) ## Module No module ## Enum ### PARITY item doc **brief** uart parity enum **values** **PARITY_NONE**: no parity
    **PARITY_ODD**: odd parity
    **PARITY_EVEN**: even parity
    **PARITY_MAX**:
    **C++ defination code**: ```cpp enum PARITY { PARITY_NONE 0x00, // no parity PARITY_ODD 0x01, // odd parity PARITY_EVEN 0x02, // even parity PARITY_MAX } ``` ### STOP item doc **brief** uart stop bits **values** **STOP_1**: 1 stop bit
    **STOP_2**: 2 stop bits
    **STOP_1_5**: 1.5 stop bits
    **STOP_MAX**:
    **C++ defination code**: ```cpp enum STOP { STOP_1 0x01, // 1 stop bit STOP_2 0x02, // 2 stop bits STOP_1_5 0x03, // 1.5 stop bits STOP_MAX } ``` ### BITS item doc **brief** uart stop bits **values** **BITS_5**: 5 data bits
    **BITS_6**: 6 data bits
    **BITS_7**: 7 data bits
    **BITS_8**: 8 data bits
    **BITS_MAX**:
    **C++ defination code**: ```cpp enum BITS { BITS_5 5, // 5 data bits BITS_6 6, // 6 data bits BITS_7 7, // 7 data bits BITS_8 8, // 8 data bits BITS_MAX } ``` ### FLOW\\_CTRL item doc **brief** uart flow control **values** **FLOW_CTRL_NONE**: no flow control
    **FLOW_CTRL_HW**: hardware flow control
    **FLOW_CTRL_MAX**:
    **C++ defination code**: ```cpp enum FLOW_CTRL { FLOW_CTRL_NONE 0, // no flow control FLOW_CTRL_HW 1, // hardware flow control FLOW_CTRL_MAX } ``` ## Variable ## Function ### list\\_devices item doc **brief** Get supported uart ports. **return** uart ports list, string type. **C++ defination code**: ```cpp std::vector list_devices() ``` ## Class ### UART item doc **brief** maix uart peripheral driver **C++ defination code**: ```cpp class UART : public comm::CommBase ``` #### \\_\\_init\\_\\_ ```python def __init__(self, port: str '', baudrate: int 115200, databits: BITS ..., parity: PARITY ..., stopbits: STOP ..., flow_ctrl: FLOW_CTRL ...) > None ``` item doc **type** func **brief** UART constructor. You need to call open() to open the device. **param** **port**: uart port. string type, can get it by uart.list_devices().
    If empty, will not open device in constructor, default empty.
    if not empty, will auto open device in constructor, open fail will throw err.Exception.
    **baudrate**: baudrate of uart. int type, default 115200.
    **databits**: databits, values @see uart.DATA_BITS
    **parity**: parity, values @see uart.PARITY
    **stopbits**: stopbits, values @see uart.STOP_BITS
    **flow_control**: flow_control, values @see uart.FLOW_CTRL
    **static** False **C++ defination code**: ```cpp UART(const std::string &port \"\", int baudrate 115200, uart::BITS databits uart::BITS_8, uart::PARITY parity uart::PARITY_NONE, uart::STOP stopbits uart::STOP_1, uart::FLOW_CTRL flow_ctrl uart::FLOW_CTRL_NONE) ``` #### set\\_port ```python def set_port(self, port: str) > maix.err.Err ``` item doc **type** func **brief** Set port **param** **port**: uart port. string type, can get it by uart.list_devices().
    **return** set port error code, err.Err type. **static** False **C++ defination code**: ```cpp err::Err set_port(const std::string &port) ``` #### get\\_port ```python def get_port(self) > str ``` item doc **type** func **brief** Get port **return** uart port, string type. **static** False **C++ defination code**: ```cpp std::string get_port() ``` #### set\\_baudrate ```python def set_baudrate(self, baudrate: int) > maix.err.Err ``` item doc **type** func **brief** Set baud rate **param** **baudrate**: baudrate of uart. int type, default 115200.
    **return** set baud rate error code, err.Err type. **static** False **C++ defination code**: ```cpp err::Err set_baudrate(int baudrate) ``` #### get\\_baudrate ```python def get_baudrate(self) > int ``` item doc **type** func **brief** Get baud rate **return** baud rate, int type. **static** False **C++ defination code**: ```cpp int get_baudrate() ``` #### open ```python def open(self) > maix.err.Err ``` item doc **type** func **brief** Open uart device, before open, port must be set in constructor or by set_port().\\nIf already opened, do nothing and return err.ERR_NONE. **return** open device error code, err.Err type. **static** False **C++ defination code**: ```cpp err::Err open() ``` #### is\\_open ```python def is_open(self) > bool ``` item doc **type** func **brief** Check if device is opened. **return** true if opened, false if not opened. **static** False **C++ defination code**: ```cpp bool is_open() ``` #### close ```python def close(self) > maix.err.Err ``` item doc **type** func **brief** Close uart device, if already closed, do nothing and return err.ERR_NONE. **return** close device error code, err.Err type. **static** False **C++ defination code**: ```cpp err::Err close() ``` #### write\\_str ```python def write_str(self, str: str) > int ``` item doc **type** func **brief** Send string data **param** **str**: string data
    **return** sent data length, < 0 means error, value is err.Err. **static** False **C++ defination code**: ```cpp int write_str(const std::string &str) ``` #### write ```python def write(self, data: maix.Bytes(bytes)) > int ``` item doc **type** func **brief** Send data to uart **param** **data**: direction [in], data to send, bytes type. If you want to send str type, use str.encode() to convert.
    **return** sent length, int type, if < 0 means error, value is err.Err. **static** False **C++ defination code**: ```cpp int write(Bytes &data) ``` #### available ```python def available(self, timeout: int 0) > int ``` item doc **type** func **brief** Check if data available or wait data available. **param** **timeout**: unit ms, timeout to wait data, default 0.
    0 means check data available and return immediately,
    > 0 means wait until data available or timeout.
    1 means wait until data available.
    **return** available data number, 0 if timeout or no data, <0 if error, value is err.Err, can be err::ERR_IO, err::ERR_CANCEL, err::ERR_NOT_OPEN. **throw** err.Exception if fatal error. **static** False **C++ defination code**: ```cpp int available(int timeout 0) ``` #### read ```python def read(*args, **kwargs) ``` item doc **type** func **brief** Recv data from uart **param** **len**: max data length want to receive, default 1.
    1 means read data in uart receive buffer.
    >0 means read len data want to receive.
    other values is invalid.
    **timeout**: unit ms, timeout to receive data, default 0.
    0 means read data in uart receive buffer and return immediately,
    1 means block until read len data,
    >0 means block until read len data or timeout.
    **return** received data, bytes type.
    Attention, you need to delete the returned object yourself in C++. **static** False **C++ defination code**: ```cpp Bytes *read(int len 1, int timeout 0) ``` #### readline ```python def readline(*args, **kwargs) ``` item doc **type** func **brief** Read line from uart, that is read until '\\n' or '\\r\\n'. **param** **timeout**: unit ms, timeout to receive data, default 1 means block until read '\\n' or '\\r\\n'.
    > 0 means block until read '\\n' or '\\r\\n' or timeout.
    **return** received data, bytes type. If timeout will return the current received data despite not read '\\n' or '\\r\\n'.
    e.g. If we want to read b'123\\n', but when we only read b'12', timeout, then return b'12'. **static** False **C++ defination code**: ```cpp Bytes *readline(int timeout 1) ```"},"/maixpy/api/maix/peripheral/gpio.html":{"title":"maix.peripheral.gpio","content":" title: maix.peripheral.gpio maix.peripheral.gpio module > You can use `maix.peripheral.gpio` to access this module with MaixPy > This module is generated from [MaixCDK](https://github.com/sipeed/MaixCDK) ## Module No module ## Enum ### Mode item doc **brief** GPIO mode **values** **IN**: input mode
    **OUT**: output mode
    **OUT_OD**: output open drain mode
    **MODE_MAX**:
    **C++ defination code**: ```cpp enum Mode { IN 0x01, // input mode OUT 0x02, // output mode OUT_OD 0x03, // output open drain mode MODE_MAX } ``` ### Pull item doc **brief** GPIO pull mode **values** **PULL_NONE**: pull none mode
    **PULL_UP**: pull up mode
    **PULL_DOWN**: pull down mode
    **PULL_MAX**:
    **C++ defination code**: ```cpp enum Pull { PULL_NONE 0x00, // pull none mode PULL_UP 0x01, // pull up mode PULL_DOWN 0x02, // pull down mode PULL_MAX } ``` ## Variable ## Function ## Class ### GPIO item doc **brief** Peripheral gpio class **C++ defination code**: ```cpp class GPIO ``` #### \\_\\_init\\_\\_ ```python def __init__(self, pin: str, mode: Mode ..., pull: Pull ...) > None ``` item doc **type** func **brief** GPIO constructor **param** **pin**: direction [in], gpio pin name, string type the same as board's pin name, e.g. \"B14\" or \"GPIOB14\", or number string like \"10\" if board no gpiochipe name.
    **mode**: direction [in], gpio mode. gpio.Mode type, default is gpio.Mode.IN (input) mode.
    **pull**: direction [in], gpio pull. gpio.Pull type, default is gpio.Pull.PULL_NONE (pull none) mode.
    For input mode, this will set gpio default status(value), if set to gpio.Pull.PULL_NONE, gpio value will be floating.
    For output mode, this will set gpio default status(value), if set to gpio.Pull.PULL_UP, gpio value will be 1, else 0.
    **throw** err::Exception if open gpio device failed. **static** False **C++ defination code**: ```cpp GPIO(std::string pin, gpio::Mode mode gpio::Mode::IN, gpio::Pull pull gpio::Pull::PULL_NONE) ``` #### value ```python def value(self, value: int 1) > int ``` item doc **type** func **brief** set and get gpio value **param** **value**: direction [in], gpio value. int type.
    0, means write gpio to low level
    1, means write gpio to high level
    1, means read gpio value, not set
    **return** int type, return gpio value, can be 0 or 1 **static** False **C++ defination code**: ```cpp int value(int value 1) ``` #### high ```python def high(self) > None ``` item doc **type** func **brief** set gpio high (value to 1) **static** False **C++ defination code**: ```cpp void high() ``` #### low ```python def low(self) > None ``` item doc **type** func **brief** set gpio low (value to 0) **static** False **C++ defination code**: ```cpp void low() ``` #### toggle ```python def toggle(self) > None ``` item doc **type** func **brief** gpio toggle **static** False **C++ defination code**: ```cpp void toggle() ```"},"/maixpy/api/maix/peripheral/adc.html":{"title":"maix.peripheral.adc","content":" title: maix.peripheral.adc maix.peripheral.adc module > You can use `maix.peripheral.adc` to access this module with MaixPy > This module is generated from [MaixCDK](https://github.com/sipeed/MaixCDK) ## Module No module ## Enum ## Variable ### RES\\_BIT\\_8 item doc **brief** 8 bit resolution, supported by the actual hardware **value** **8** **readonly** True **C++ defination code**: ```cpp const int RES_BIT_8 8 ``` ### RES\\_BIT\\_10 item doc **brief** 10 bit resolution, supported by the actual hardware **value** **10** **readonly** True **C++ defination code**: ```cpp const int RES_BIT_10 10 ``` ### RES\\_BIT\\_12 item doc **brief** 12 bit resolution, supported by the actual hardware **value** **12** **readonly** True **C++ defination code**: ```cpp const int RES_BIT_12 12 ``` ### RES\\_BIT\\_16 item doc **brief** 16 bit resolution, supported by the actual hardware **value** **16** **readonly** True **C++ defination code**: ```cpp const int RES_BIT_16 16 ``` ## Function ## Class ### ADC item doc **brief** Peripheral adc class **C++ defination code**: ```cpp class ADC ``` #### \\_\\_init\\_\\_ ```python def __init__(self, pin: int, resolution: int, vref: float 1) > None ``` item doc **type** func **brief** ADC constructor **param** **pin**: direction [in], adc pin, int type
    **resolution**: direction [in], adc resolution. default is 1, means use default resolution
    option:
    resolution adc.RES_BIT_8, means 8 bit resolution
    resolution adc.RES_BIT_10, means 10 bit resolution
    resolution adc.RES_BIT_12, means 12 bit resolution
    resolution adc.RES_BIT_16, means 16 bit resolution
    the default resolution is determined by actual hardware.
    **vref**: direction [in], adc refer voltage. default is 1, means use default refer voltage.
    the default vref is determined by actual hardware. range: [0.0, 10.0]
    **static** False **C++ defination code**: ```cpp ADC(int pin, int resolution, float vref 1) ``` #### read ```python def read(self) > int ``` item doc **type** func **brief** read adc value **return** adc data, int type
    if resolution is 8 bit, return value range is [0, 255]
    if resolution is 10 bit, return value range is [0, 1023]
    if resolution is 12 bit, return value range is [0, 4095]
    if resolution is 16 bit, return value range is [0, 65535] **static** False **C++ defination code**: ```cpp int read() ``` #### read\\_vol ```python def read_vol(self) > float ``` item doc **type** func **brief** read adc voltage **return** adc voltage, float type。the range is [0.0, vref] **static** False **C++ defination code**: ```cpp float read_vol() ```"},"/maixpy/api/maix/peripheral/wdt.html":{"title":"maix.peripheral.wdt","content":" title: maix.peripheral.wdt maix.peripheral.wdt module > You can use `maix.peripheral.wdt` to access this module with MaixPy > This module is generated from [MaixCDK](https://github.com/sipeed/MaixCDK) ## Module No module ## Enum ## Variable ## Function ## Class ### WDT item doc **brief** Peripheral wdt class **C++ defination code**: ```cpp class WDT ``` #### \\_\\_init\\_\\_ item doc **type** func **brief** WDT constructor, after construct, the wdt will auto start. **param** **id**: direction [in], id of wdt, int type
    **feed_ms**: direction [in], feed interval, int type, unit is ms, you must feed wdt in this interval, or system will restart.
    **static** False **C++ defination code**: ```cpp WDT(int id, int feed_ms) ``` #### feed item doc **type** func **brief** feed wdt **return** error code, if feed success, return err::ERR_NONE **static** False **C++ defination code**: ```cpp int feed() ``` #### stop item doc **type** func **brief** stop wdt **static** False **C++ defination code**: ```cpp int stop() ``` #### restart item doc **type** func **brief** restart wdt, stop and start watchdog timer. **static** False **C++ defination code**: ```cpp int restart() ```"},"/maixpy/api/maix/example.html":{"title":"maix.example","content":" title: maix.example example module, this will be maix.example module in MaixPy, maix::example namespace in MaixCDK > You can use `maix.example` to access this module with MaixPy > This module is generated from [MaixCDK](https://github.com/sipeed/MaixCDK) ## Module No module ## Enum ### Kind item doc **brief** Example enum **values** **KIND_NONE**: Kind none, value always 0, other enum value will auto increase
    **KIND_DOG**: Kind dog
    **KIND_CAT**: Kind cat, value is auto generated according to KING_DOG
    **KIND_BIRD**:
    **KIND_MAX**: Max Kind quantity
    You can get max Kind value by KIND_MAX 1
    **C++ defination code**: ```cpp enum Kind { KIND_NONE 0, /** Kind none, value always 0, other enum value will auto increase */ KIND_DOG, /** Kind dog*/ KIND_CAT, // Kind cat, value is auto generated according to KING_DOG KIND_BIRD, KIND_MAX /* Max Kind quantity, You can get max Kind value by KIND_MAX 1 */ } ``` ## Variable ### var1 item doc **brief** Example module variable **attention** It's a copy of this variable in MaixPy,
    so change it in C++ (e.g. update var in hello function) will not take effect the var inMaixPy.
    So we add const for this var to avoid this mistake. **value** **\"Sipeed\"** **readonly** True **C++ defination code**: ```cpp const std::string var1 \"Sipeed\" ``` ### list\\_var item doc **brief** Tensor data type size in bytes **attention** **1**. DO NOT use C/C++ array directly for python API, the python wrapper not support it.
    Use std::vector instead.
    **2**. It's a copy of this variable in MaixPy,
    so change it in C++ (e.g. update var in hello function) will not take effect the var inMaixPy.
    So we add const for this var to avoid this mistake.
    **value** **{
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9}** **readonly** True **C++ defination code**: ```cpp const std::vector list_var { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9} ``` ### test\\_var item doc **brief** Example module variable test_var **attention** It's a copy of this variable in MaixPy, so if you change it in C++, it will not take effect in MaixPy.
    And change it in MaixPy will not take effect in C++ as well !!!
    If you want to use vars shared between C++ and MaixPy, you can create a class and use its member. **value** **100** **readonly** False **C++ defination code**: ```cpp int test_var 100 ``` ## Function ### hello ```python def hello(name: str) > str ``` item doc **brief** say hello to someone **param** **name**: direction [in], name of someone, string type
    **return** string type, content is hello + name **C++ defination code**: ```cpp std::string hello(std::string name) ``` ### change\\_arg\\_name item doc **brief** Change arg name example **param** **e**: Example object
    **return** same as arg **C++ defination code**: ```cpp example::Example *change_arg_name(example::Example *e) ``` ### change\\_arg\\_name2 ```python def change_arg_name2(e: Example) > None ``` item doc **brief** Change arg name example **param** **e**: Example object
    **C++ defination code**: ```cpp void change_arg_name2(example::Example &e) ``` ## Class ### Test item doc **brief** Test class **C++ defination code**: ```cpp class Test ``` #### \\_\\_init\\_\\_ ```python def __init__(self) > None ``` item doc **type** func **brief** Test constructor **static** False **C++ defination code**: ```cpp Test() ``` ### Example item doc **brief** Example class\\nthis class will be export to MaixPy as maix.example.Example **C++ defination code**: ```cpp class Example ``` #### \\_\\_init\\_\\_ ```python def __init__(self, name: str, age: int 18, pet: Kind ...) > None ``` item doc **type** func **brief** Example constructor\\nthis constructor will be export to MaixPy as maix.example.Example.__init__ **param** **name**: direction [in], name of Example, string type
    **age**: direction [in], age of Example, int type, default is 18, value range is [0, 100]
    **attention** to make auto generate code work, param Kind should with full namespace name `example::Kind` instead of `Kind`,
    namespace `maix` can be ignored. **static** False **C++ defination code**: ```cpp Example(std::string &name, int age 18, example::Kind pet example::KIND_NONE) ``` #### get\\_name ```python def get_name(self) > str ``` item doc **type** func **brief** get name of Example\\nyou can also get name by property `name`. **return** name of Example, string type **static** False **C++ defination code**: ```cpp std::string get_name() ``` #### get\\_age ```python def get_age(self) > int ``` item doc **type** func **brief** get age of Example **return** age of Example, int type, value range is [0, 100] **static** False **C++ defination code**: ```cpp int get_age() ``` #### set\\_name ```python def set_name(self, name: str) > None ``` item doc **type** func **brief** set name of Example **param** **name**: name of Example, string type
    **static** False **C++ defination code**: ```cpp void set_name(std::string name) ``` #### set\\_age ```python def set_age(self, age: int) > None ``` item doc **type** func **brief** set age of Example **param** **age**: age of Example, int type, value range is [0, 100]
    **static** False **C++ defination code**: ```cpp void set_age(int age) ``` #### set\\_pet ```python def set_pet(self, pet: Kind) > None ``` item doc **type** func **brief** Example enum member **attention** **static** False **C++ defination code**: ```cpp void set_pet(example::Kind pet) ``` #### get\\_pet ```python def get_pet(self) > Kind ``` item doc **type** func **brief** Example enum member **static** False **C++ defination code**: ```cpp example::Kind get_pet() ``` #### get\\_list ```python def get_list(self, in: list[int]) > list[int] ``` item doc **type** func **brief** get list example **param** **in**: direction [in], input list, items are int type.
    In MaixPy, you can pass list or tuple to this API
    **return** list, items are int type, content is [1, 2, 3] + in. Alloc item, del in MaixPy will auto free memory. **static** False **C++ defination code**: ```cpp std::vector *get_list(std::vector in) ``` #### get\\_dict ```python def get_dict(self, in: dict[str, int]) > dict[str, int] ``` item doc **type** func **brief** Example dict API **param** **in**: direction [in], input dict, key is string type, value is int type.
    In MaixPy, you can pass `dict` to this API
    **return** dict, key is string type, value is int type, content is {\"a\": 1} + in
    In MaixPy, return type is `dict` object **static** False **C++ defination code**: ```cpp std::map get_dict(std::map &in) ``` #### hello ```python def hello(name: str) > str ``` item doc **type** func **brief** say hello to someone **param** **name**: name of someone, string type
    **return** string type, content is Example::hello_str + name **static** True **C++ defination code**: ```cpp static std::string hello(std::string name) ``` #### hello\\_bytes ```python def hello_bytes(*args, **kwargs) ``` item doc **type** func **brief** param is bytes example **param** **bytes**: bytes type param
    **return** bytes type, return value is bytes changed value **static** True **C++ defination code**: ```cpp static Bytes *hello_bytes(Bytes &bytes) ``` #### callback ```python def callback(cb: typing.Callable[[int, int], int]) > int ``` item doc **type** func **brief** Callback example **param** **cb**: callback function, param is two int type, return is int type
    **return** int type, return value is cb(1, 2) **static** True **C++ defination code**: ```cpp static int callback(std::function cb) ``` #### hello\\_dict ```python def hello_dict(dict: dict[str, int]) > dict[str, int] ``` item doc **type** func **brief** Dict param example **param** **dict**: dict type param, key is string type, value is int type
    **static** True **C++ defination code**: ```cpp static std::map *hello_dict(std::map *dict) ``` #### name item doc **type** var **brief** name member of Example **static** False **readonly** False **C++ defination code**: ```cpp std::string name ``` #### age item doc **type** var **brief** age member of Example, value range should be [0, 100] **static** False **readonly** False **C++ defination code**: ```cpp int age ``` #### hello\\_str item doc **type** var **brief** hello_str member of Example, default value is \\\"hello \\\" **static** True **readonly** False **C++ defination code**: ```cpp static std::string hello_str ``` #### var1 item doc **type** var **brief** Example module readonly variable **static** False **readonly** True **C++ defination code**: ```cpp const std::string var1 \"Example.var1\" ``` #### var2 item doc **type** var **brief** Example module readonly variable **static** False **readonly** True **C++ defination code**: ```cpp std::string var2 \"Example.var2\" ``` #### dict\\_test ```python def dict_test() > dict[str, Test] ``` item doc **type** func **brief** dict_test, return dict type, and element is pointer type(alloc in C++).\\nHere when the returned Tensor object will auto delete by Python GC. **static** True **C++ defination code**: ```cpp static std::map *dict_test() ```"},"/maixpy/api/maix/touchscreen.html":{"title":"maix.touchscreen","content":" title: maix.touchscreen maix.touchscreen module > You can use `maix.touchscreen` to access this module with MaixPy > This module is generated from [MaixCDK](https://github.com/sipeed/MaixCDK) ## Module No module ## Enum ## Variable ## Function ## Class ### TouchScreen item doc **brief** TouchScreen class **C++ defination code**: ```cpp class TouchScreen ``` #### \\_\\_init\\_\\_ item doc **type** func **brief** Construct a new TouchScreen object **param** **device**: touchscreen device path, you can get devices by list_devices method, by default(value is NULL(None in MaixPy)) means the first device
    **open**: If true, touchscreen will automatically call open() after creation. default is true.
    **static** False **C++ defination code**: ```cpp TouchScreen(const std::string &device \"\", bool open true) ``` #### open item doc **type** func **brief** open touchscreen device **return** error code, err::ERR_NONE means success, others means failed **static** False **C++ defination code**: ```cpp err::Err open() ``` #### close item doc **type** func **brief** close touchscreen device **return** error code, err::ERR_NONE means success, others means failed **static** False **C++ defination code**: ```cpp err::Err close() ``` #### read item doc **type** func **brief** read touchscreen device **attention** This method will discard same event in buffer, that is:
    if too many move event in buffer when call this method, it will only return the last one,
    and if read pressed or released event, it will return immediately. **return** Returns a list include x, y, pressed state **static** False **C++ defination code**: ```cpp std::vector read() ``` #### read (overload 1) item doc **type** func **brief** read touchscreen device **attention** This method will return immediately if have event, so it's better to use available() to check if have more event in buffer,
    or too much event in buffer when your program call this read() interval is too long will make your program slow. **return** Returns a list include x, y, pressed state **static** False **C++ defination code**: ```cpp std::vector read0() ``` #### available item doc **type** func **brief** If we need to read from touchscreen, for event driven touchscreen means have event or not **param** **timeout**: 1 means block, 0 means no block, >0 means timeout, default is 0, unit is ms.
    **return** true if need to read(have event), false if not **static** False **C++ defination code**: ```cpp bool available(int timeout 0) ``` #### is\\_opened item doc **type** func **brief** Check if touchscreen is opened **return** true if touchscreen is opened, false if not **static** False **C++ defination code**: ```cpp bool is_opened() ```"},"/maixpy/api/maix/util.html":{"title":"maix.util","content":" title: maix.util maix.util module > You can use `maix.util` to access this module with MaixPy > This module is generated from [MaixCDK](https://github.com/sipeed/MaixCDK) ## Module No module ## Enum ## Variable ## Function ### disable\\_kernel\\_debug ```python def disable_kernel_debug() > None ``` item doc **brief** disable the kernel debug **C++ defination code**: ```cpp void disable_kernel_debug() ``` ### enable\\_kernel\\_debug ```python def enable_kernel_debug() > None ``` item doc **brief** disable the kernel debug **C++ defination code**: ```cpp void enable_kernel_debug() ``` ## Class"},"/maixpy/api/maix/err.html":{"title":"maix.err","content":" title: maix.err maix.err module > You can use `maix.err` to access this module with MaixPy > This module is generated from [MaixCDK](https://github.com/sipeed/MaixCDK) ## Module No module ## Enum ### Err item doc **brief** Maix Error code **values** **ERR_NONE**: No error
    **ERR_ARGS**: Invalid arguments
    **ERR_NO_MEM**: No memory
    **ERR_NOT_IMPL**: Not implemented
    **ERR_NOT_READY**: Not ready
    **ERR_NOT_INIT**: Not initialized
    **ERR_NOT_OPEN**: Not opened
    **ERR_NOT_PERMIT**: Not permitted
    **ERR_REOPEN**: Re open
    **ERR_BUSY**: Busy
    **ERR_READ**: Read error
    **ERR_WRITE**: Write error
    **ERR_TIMEOUT**: Timeout
    **ERR_RUNTIME**: Runtime error
    **ERR_IO**: IO error
    **ERR_NOT_FOUND**: Not found
    **ERR_ALREAY_EXIST**: Already exist
    **ERR_BUFF_FULL**: Buffer full
    **ERR_BUFF_EMPTY**: Buffer empty
    **ERR_CANCEL**: Cancel
    **ERR_OVERFLOW**: Overflow
    **ERR_MAX**:
    **C++ defination code**: ```cpp enum Err { // !!! fixed error code, DO NOT change number already defined, only append new error code ERR_NONE 0, // No error ERR_ARGS , // Invalid arguments ERR_NO_MEM , // No memory ERR_NOT_IMPL , // Not implemented ERR_NOT_READY , // Not ready ERR_NOT_INIT , // Not initialized ERR_NOT_OPEN , // Not opened ERR_NOT_PERMIT , // Not permitted ERR_REOPEN , // Re open ERR_BUSY , // Busy ERR_READ , // Read error ERR_WRITE , // Write error ERR_TIMEOUT , // Timeout ERR_RUNTIME , // Runtime error ERR_IO , // IO error ERR_NOT_FOUND , // Not found ERR_ALREAY_EXIST , // Already exist ERR_BUFF_FULL , // Buffer full ERR_BUFF_EMPTY , // Buffer empty ERR_CANCEL , // Cancel ERR_OVERFLOW , // Overflow ERR_MAX, } ``` ## Variable ## Function ### to\\_str ```python def to_str(e: Err) > str ``` item doc **brief** Error code to string **param** **e**: direction [in], error code, err::Err type
    **return** error string **C++ defination code**: ```cpp std::string to_str(err::Err e) ``` ### get\\_error ```python def get_error() > str ``` item doc **brief** get last error string **return** error string **C++ defination code**: ```cpp std::string& get_error() ``` ### set\\_error ```python def set_error(str: str) > None ``` item doc **brief** set last error string **param** **str**: direction [in], error string
    **C++ defination code**: ```cpp void set_error(const std::string &str) ``` ### check\\_raise ```python def check_raise(e: Err, msg: str '') > None ``` item doc **brief** Check error code, if not ERR_NONE, raise err.Exception **param** **e**: direction [in], error code, err::Err type
    **msg**: direction [in], error message
    **C++ defination code**: ```cpp void check_raise(err::Err e, const std::string &msg \"\") ``` ### check\\_bool\\_raise ```python def check_bool_raise(ok: bool, msg: str '') > None ``` item doc **brief** Check condition, if false, raise err.Exception **param** **ok**: direction [in], condition, if true, do nothing, if false, raise err.Exception
    **msg**: direction [in], error message
    **C++ defination code**: ```cpp void check_bool_raise(bool ok, const std::string &msg \"\") ``` ### check\\_null\\_raise ```python def check_null_raise(ptr: capsule, msg: str '') > None ``` item doc **brief** Check NULL pointer, if NULL, raise exception **param** **ptr**: direction [in], pointer
    **msg**: direction [in], error message
    **C++ defination code**: ```cpp void check_null_raise(void *ptr, const std::string &msg \"\") ``` ## Class ### Exception item doc **brief** Maix Exception **C++ defination code**: ```cpp class Exception : public std::exception ```"},"/maixpy/api/maix/video.html":{"title":"maix.video","content":" title: maix.video maix.video module > You can use `maix.video` to access this module with MaixPy > This module is generated from [MaixCDK](https://github.com/sipeed/MaixCDK) ## Module No module ## Enum ### VideoType item doc **brief** Video type **values** **VIDEO_NONE**: format invalid
    **VIDEO_ENC_H265_CBR**:
    **VIDEO_ENC_MP4_CBR**:
    **VIDEO_DEC_H265_CBR**:
    **VIDEO_DEC_MP4_CBR**:
    **C++ defination code**: ```cpp enum VideoType { VIDEO_NONE 0, // format invalid VIDEO_ENC_H265_CBR, VIDEO_ENC_MP4_CBR, VIDEO_DEC_H265_CBR, VIDEO_DEC_MP4_CBR, } ``` ## Variable ## Function ## Class ### Frame item doc **brief** Frame class **C++ defination code**: ```cpp class Frame ``` ### Packet item doc **brief** Packet class **C++ defination code**: ```cpp class Packet ``` #### \\_\\_init\\_\\_ item doc **type** func **brief** Packet number (pair of numerator and denominator). **param** **data**: src data pointer, use pointers directly without copying.
    Note: this object will try to free this memory
    **len**: data len
    **pts**: presentation time stamp. unit: time_base
    **dts**: decoding time stamp. unit: time_base
    **duration**: packet display time. unit: time_base
    **static** False **C++ defination code**: ```cpp Packet(uint8_t *data, int len, uint64_t pts 1, uint64_t dts 1, int64_t duration 0) ``` #### get item doc **type** func **brief** Get raw data of packet **return** raw data **static** False **C++ defination code**: ```cpp std::vector get() ``` #### data item doc **type** func **brief** Get raw data of packet **return** raw data **static** False **C++ defination code**: ```cpp uint8_t *data() ``` #### data\\_size item doc **type** func **brief** Get raw data size of packet **return** size of raw data **static** False **C++ defination code**: ```cpp size_t data_size() ``` #### is\\_valid item doc **type** func **brief** Check packet is valid **return** true, packet is valid; false, packet is invalid **static** False **C++ defination code**: ```cpp bool is_valid() ``` #### set\\_pts item doc **type** func **brief** Set pts **param** **pts**: presentation time stamp. unit: time_base
    **return** true, packet is valid; false, packet is invalid **static** False **C++ defination code**: ```cpp void set_pts(uint64_t pts) ``` #### set\\_dts item doc **type** func **brief** Set dts **param** **dts**: decoding time stamp. unit: time_base
    **return** true, packet is valid; false, packet is invalid **static** False **C++ defination code**: ```cpp void set_dts(uint64_t dts) ``` #### set\\_duration item doc **type** func **brief** Set duration **param** **duration**: packet display time. unit: time_base
    **return** true, packet is valid; false, packet is invalid **static** False **C++ defination code**: ```cpp void set_duration(uint64_t duration) ``` ### Video item doc **brief** Video class **C++ defination code**: ```cpp class Video ``` #### \\_\\_init\\_\\_ ```python def __init__(self, path: str '', width: int 2560, height: int 1440, format: maix.image.Format ..., time_base: int 30, framerate: int 30, capture: bool False, open: bool True) > None ``` item doc **type** func **brief** Construct a new Video object **param** **path**: video path. the path determines the location where you load or save the file, if path is none, the video module will not save or load file.
    xxx.h265 means video format is H265, xxx.mp4 means video format is MP4
    **width**: picture width. this value may be set automatically. default is 2560.
    **height**: picture height. this value may be set automatically. default is 1440.
    **format**: picture pixel format. this value may be set automatically. default is FMT_YVU420SP.
    **time_base**: frame time base. time_base default is 30, means 1/30 ms
    **framerate**: frame rate. framerate default is 30, means 30 frames per second
    for video. 1/time_base is not the average frame rate if the frame rate is not constant.
    **capture**: enable capture, if true, you can use capture() function to get an image object
    **open**: If true, video will automatically call open() after creation. default is true.
    **static** False **C++ defination code**: ```cpp Video(std::string path std::string(), int width 2560, int height 1440, image::Format format image::Format::FMT_YVU420SP, int time_base 30, int framerate 30, bool capture false, bool open true) ``` #### open ```python def open(self, path: str '', fps: float 30.0) > maix.err.Err ``` item doc **type** func **brief** Open video and run **param** **path**: video path. the path determines the location where you load or save the file, if path is none, the video module will not save or load file.
    xxx.h265 means video format is H265, xxx.mp4 means video format is MP4
    **fps**: video fps
    **return** error code, err::ERR_NONE means success, others means failed **static** False **C++ defination code**: ```cpp err::Err open(std::string path std::string(), double fps 30.0) ``` #### close ```python def close(self) > None ``` item doc **type** func **brief** Close video **static** False **C++ defination code**: ```cpp void close() ``` #### bind\\_camera ```python def bind_camera(self, camera: maix.camera.Camera) > maix.err.Err ``` item doc **type** func **brief** Bind camera **param** **camera**: camera object
    **return** error code, err::ERR_NONE means success, others means failed **static** False **C++ defination code**: ```cpp err::Err bind_camera(camera::Camera *camera) ``` #### encode ```python def encode(self, img: maix.image.Image ...) > Packet ``` item doc **type** func **brief** Encode image. **param** **img**: the image will be encode.
    if the img is NULL, this function will try to get image from camera, you must use bind_camera() function to bind the camera.
    **return** encode result **static** False **C++ defination code**: ```cpp video::Packet *encode(image::Image *img maix::video::Video::NoneImage) ``` #### decode ```python def decode(self, frame: Frame None) > maix.image.Image ``` item doc **type** func **brief** Decode frame **param** **frame**: the frame will be decode
    **return** decode result **static** False **C++ defination code**: ```cpp image::Image *decode(video::Frame *frame nullptr) ``` #### finish ```python def finish(self) > maix.err.Err ``` item doc **type** func **brief** Encode or decode finish **return** error code **static** False **C++ defination code**: ```cpp err::Err finish() ``` #### capture ```python def capture(self) > maix.image.Image ``` item doc **type** func **brief** Capture image **attention** Each time encode is called, the last captured image will be released. **return** error code **static** False **C++ defination code**: ```cpp image::Image *capture() ``` #### is\\_recording ```python def is_recording(self) > bool ``` item doc **type** func **brief** Check if video is recording **return** true if video is recording, false if not **static** False **C++ defination code**: ```cpp bool is_recording() ``` #### is\\_opened ```python def is_opened(self) > bool ``` item doc **type** func **brief** Check if video is opened **return** true if video is opened, false if not **static** False **C++ defination code**: ```cpp bool is_opened() ``` #### is\\_closed ```python def is_closed(self) > bool ``` item doc **type** func **brief** check video device is closed or not **return** closed or not, bool type **static** False **C++ defination code**: ```cpp bool is_closed() ``` #### width ```python def width(self) > int ``` item doc **type** func **brief** Get video width **return** video width **static** False **C++ defination code**: ```cpp int width() ``` #### height ```python def height(self) > int ``` item doc **type** func **brief** Get video height **return** video height **static** False **C++ defination code**: ```cpp int height() ```"},"/maixpy/api/maix/nn/F.html":{"title":"maix.nn.F","content":" title: maix.nn.F maix.nn.F module > You can use `maix.nn.F` to access this module with MaixPy > This module is generated from [MaixCDK](https://github.com/sipeed/MaixCDK) ## Module No module ## Enum ## Variable ## Function ### softmax ```python def softmax(tensor: maix.tensor.Tensor, replace: bool) > maix.tensor.Tensor ``` item doc **brief** Softmax, only support 1D tensor, multi dimension tensor will be treated as 1D tensor **param** **tensor**: input tensor
    **replace**: change input tensor data directly, if not, will create a new tensor
    **throw** If arg error, will raise err.Exception error **return** output tensor, if arg replace is true, return the arg tensor's address.
    If not replace, return a new object, so In C++, you should delete it manually in this case! **C++ defination code**: ```cpp tensor::Tensor *softmax(tensor::Tensor *tensor, bool replace) ``` ## Class"},"/maixpy/api/maix/network.html":{"title":"maix.network","content":" title: maix.network maix.network module > You can use `maix.network` to access this module with MaixPy > This module is generated from [MaixCDK](https://github.com/sipeed/MaixCDK) ## Module module brief [wifi](./network/wifi.html) maix.network.wifi module ## Enum ## Variable ## Function ### have\\_network ```python def have_network() > bool ``` item doc **brief** Return if device have network(WiFi/Eth etc.) **return** True if have network, else False. **C++ defination code**: ```cpp bool have_network() ``` ## Class"},"/maixpy/api/maix/nn.html":{"title":"maix.nn","content":" title: maix.nn maix.nn module > You can use `maix.nn` to access this module with MaixPy > This module is generated from [MaixCDK](https://github.com/sipeed/MaixCDK) ## Module module brief [F](./nn/F.html) maix.nn.F module ## Enum ## Variable ## Function ## Class ### Object item doc **brief** Object for detect result **C++ defination code**: ```cpp class Object ``` #### \\_\\_init\\_\\_ item doc **type** func **brief** Constructor of Object for detect result **param** **x**: left top x
    **y**: left top y
    **w**: width
    **h**: height
    **class_id**: class id
    **score**: score
    **static** False **C++ defination code**: ```cpp Object(int x 0, int y 0, int w 0, int h 0, int class_id 0, float score 0) ``` #### \\_\\_str\\_\\_ item doc **type** func **brief** Object info to string **return** Object info string **static** False **C++ defination code**: ```cpp std::string to_str() ``` #### x item doc **type** var **brief** Object left top coordinate x **static** False **readonly** False **C++ defination code**: ```cpp int x ``` #### y item doc **type** var **brief** Object left top coordinate y **static** False **readonly** False **C++ defination code**: ```cpp int y ``` #### w item doc **type** var **brief** Object width **static** False **readonly** False **C++ defination code**: ```cpp int w ``` #### h item doc **type** var **brief** Object height **static** False **readonly** False **C++ defination code**: ```cpp int h ``` #### class\\_id item doc **type** var **brief** Object class id **static** False **readonly** False **C++ defination code**: ```cpp int class_id ``` #### score item doc **type** var **brief** Object score **static** False **readonly** False **C++ defination code**: ```cpp float score ``` ### YOLOv5 item doc **brief** YOLOv5 class **C++ defination code**: ```cpp class YOLOv5 ``` #### \\_\\_init\\_\\_ item doc **type** func **brief** Constructor of YOLOv5 class **param** **model**: model path, default empty, you can load model later by load function.
    **throw** If model arg is not empty and load failed, will throw err::Exception. **static** False **C++ defination code**: ```cpp YOLOv5(const string &model \"\") ``` #### load ```python def load(self, model: str) > maix.err.Err ``` item doc **type** func **brief** Load model from file **param** **model**: Model path want to load
    **return** err::Err **static** False **C++ defination code**: ```cpp err::Err load(const string &model) ``` #### detect item doc **type** func **brief** Detect objects from image **param** **img**: Image want to detect, if image's size not match model input's, will auto resize with fit method.
    **conf_th**: Confidence threshold, default 0.5.
    **iou_th**: IoU threshold, default 0.45.
    **fit**: Resize method, default image.Fit.FIT_CONTAIN.
    **throw** If image format not match model input format, will throw err::Exception. **return** Object list. In C++, you should delete it after use. **static** False **C++ defination code**: ```cpp std::vector *detect(image::Image &img, float conf_th 0.5, float iou_th 0.45, maix::image::Fit fit maix::image::FIT_CONTAIN) ``` #### input\\_size ```python def input_size(self) > maix.image.Size ``` item doc **type** func **brief** Get model input size **return** model input size **static** False **C++ defination code**: ```cpp image::Size input_size() ``` #### input\\_width ```python def input_width(self) > int ``` item doc **type** func **brief** Get model input width **return** model input size of width **static** False **C++ defination code**: ```cpp int input_width() ``` #### input\\_height ```python def input_height(self) > int ``` item doc **type** func **brief** Get model input height **return** model input size of height **static** False **C++ defination code**: ```cpp int input_height() ``` #### input\\_format ```python def input_format(self) > maix.image.Format ``` item doc **type** func **brief** Get input image format **return** input image format, image::Format type. **static** False **C++ defination code**: ```cpp image::Format input_format() ``` #### labels item doc **type** var **brief** Labels list **static** False **readonly** False **C++ defination code**: ```cpp std::vector labels ``` #### label\\_path item doc **type** var **brief** Label file path **static** False **readonly** False **C++ defination code**: ```cpp std::string label_path ``` #### mean item doc **type** var **brief** Get mean value, list type **static** False **readonly** False **C++ defination code**: ```cpp std::vector mean ``` #### scale item doc **type** var **brief** Get scale value, list type **static** False **readonly** False **C++ defination code**: ```cpp std::vector scale ``` #### anchors item doc **type** var **brief** Get anchors **static** False **readonly** False **C++ defination code**: ```cpp std::vector anchors ``` ### Classifier item doc **brief** Classifier **C++ defination code**: ```cpp class Classifier ``` #### \\_\\_init\\_\\_ ```python def __init__(self, model: str '') > None ``` item doc **type** func **brief** Construct a new Classifier object **param** **model**: MUD model path, if empty, will not load model, you can call load() later.
    if not empty, will load model and will raise err::Exception if load failed.
    **static** False **C++ defination code**: ```cpp Classifier(const string &model \"\") ``` #### load ```python def load(self, model: str) > maix.err.Err ``` item doc **type** func **brief** Load model from file, model format is .mud,\\nMUD file should contain [extra] section, have key values:\\n model_type: classifier\\n input_type: rgb or bgr\\n mean: 123.675, 116.28, 103.53\\n scale: 0.017124753831663668, 0.01750700280112045, 0.017429193899782137\\n labels: imagenet_classes.txt **param** **model**: MUD model path
    **return** error code, if load failed, return error code **static** False **C++ defination code**: ```cpp err::Err load(const string &model) ``` #### classify ```python def classify(self, img: maix.image.Image, softmax: bool True) > list[tuple[int, float]] ``` item doc **type** func **brief** Forward image to model, get result. Only for image input, use classify_raw for tensor input. **param** **img**: image, format should match model input_type, or will raise err.Exception
    **softmax**: if true, will do softmax to result, or will return raw value
    **throw** If error occurred, will raise err::Exception, you can find reason in log, mostly caused by args error or hardware error. **return** result, a list of (label, score). In C++, you need to delete it after use. **static** False **C++ defination code**: ```cpp std::vector> *classify(image::Image &img, bool softmax true) ``` #### classify\\_raw ```python def classify_raw(self, data: maix.tensor.Tensor, softmax: bool True) > list[tuple[int, float]] ``` item doc **type** func **brief** Forward tensor data to model, get result **param** **data**: tensor data, format should match model input_type, or will raise err.Excetion
    **softmax**: if true, will do softmax to result, or will return raw value
    **throw** If error occurred, will raise err::Exception, you can find reason in log, mostly caused by args error or hardware error. **return** result, a list of (label, score). In C++, you need to delete it after use. **static** False **C++ defination code**: ```cpp std::vector> *classify_raw(tensor::Tensor &data, bool softmax true) ``` #### input\\_size ```python def input_size(self) > maix.image.Size ``` item doc **type** func **brief** Get model input size, only for image input **return** model input size **static** False **C++ defination code**: ```cpp image::Size input_size() ``` #### input\\_width ```python def input_width(self) > int ``` item doc **type** func **brief** Get model input width, only for image input **return** model input size of width **static** False **C++ defination code**: ```cpp int input_width() ``` #### input\\_height ```python def input_height(self) > int ``` item doc **type** func **brief** Get model input height, only for image input **return** model input size of height **static** False **C++ defination code**: ```cpp int input_height() ``` #### input\\_format ```python def input_format(self) > maix.image.Format ``` item doc **type** func **brief** Get input image format, only for image input **return** input image format, image::Format type. **static** False **C++ defination code**: ```cpp image::Format input_format() ``` #### input\\_shape ```python def input_shape(self) > list[int] ``` item doc **type** func **brief** Get input shape, if have multiple input, only return first input shape **return** input shape, list type **static** False **C++ defination code**: ```cpp std::vector input_shape() ``` #### labels item doc **type** var **brief** Labels list **static** False **readonly** False **C++ defination code**: ```cpp std::vector labels ``` #### label\\_path item doc **type** var **brief** Label file path **static** False **readonly** False **C++ defination code**: ```cpp std::string label_path ``` #### mean item doc **type** var **brief** Get mean value, list type **static** False **readonly** False **C++ defination code**: ```cpp std::vector mean ``` #### scale item doc **type** var **brief** Get scale value, list type **static** False **readonly** False **C++ defination code**: ```cpp std::vector scale ``` ### MUD item doc **brief** MUD(model universal describe file) class **C++ defination code**: ```cpp class MUD ``` #### \\_\\_init\\_\\_ ```python def __init__(self, model_path: str None) > None ``` item doc **type** func **brief** MUD constructor **param** **model_path**: direction [in], model file path, model format can be MUD(model universal describe file) file.
    If model_path set, will load model from file, load failed will raise err.Exception.
    If model_path not set, you can load model later by load function.
    **static** False **C++ defination code**: ```cpp MUD(const char *model_path nullptr) ``` #### load ```python def load(self, model: str) > maix.err.Err ``` item doc **type** func **brief** Load model from file **param** **model_path**: direction [in], model file path, model format can be MUD(model universal describe file) file.
    **return** error code, if load success, return err::ERR_NONE **static** False **C++ defination code**: ```cpp err::Err load(const std::string &model_path) ``` #### type item doc **type** var **brief** Model type, string type **static** False **readonly** False **C++ defination code**: ```cpp std::string type ``` #### items item doc **type** var **brief** Model config items, different model type has different config items **static** False **readonly** False **C++ defination code**: ```cpp std::map> items ``` ### LayerInfo item doc **brief** NN model layer info **C++ defination code**: ```cpp class LayerInfo ``` #### \\_\\_init\\_\\_ item doc **type** func **brief** LayerInfo constructor **param** **name**: direction [in], layer name
    **dtype**: direction [in], layer data type
    **shape**: direction [in], layer shape
    **static** False **C++ defination code**: ```cpp LayerInfo(const std::string &name \"\", tensor::DType dtype tensor::DType::FLOAT32, std::vector shape std::vector()) ``` #### name item doc **type** var **brief** Layer name **static** False **readonly** False **C++ defination code**: ```cpp std::string name ``` #### dtype item doc **type** var **brief** Layer data type **attention** If model is quantized, this is the real quantized data type like int8 float16,
    in most scene, inputs and outputs we actually use float32 in API like forward. **static** False **readonly** False **C++ defination code**: ```cpp tensor::DType dtype ``` #### shape item doc **type** var **brief** Layer shape **static** False **readonly** False **C++ defination code**: ```cpp std::vector shape ``` #### to\\_str item doc **type** func **brief** To string **static** False **C++ defination code**: ```cpp std::string to_str() ``` #### \\_\\_str\\_\\_ ```python def __str__(self) > str ``` item doc **type** func **brief** To string **static** False **C++ defination code**: ```cpp std::string __str__() ``` ### NN item doc **brief** Neural network class **C++ defination code**: ```cpp class NN ``` #### \\_\\_init\\_\\_ item doc **type** func **brief** Neural network constructor **param** **model**: direction [in], model file path, model format can be MUD(model universal describe file) file.
    If model_path set, will load model from file, load failed will raise err.Exception.
    If model_path not set, you can load model later by load function.
    **static** False **C++ defination code**: ```cpp NN(const std::string &model \"\") ``` #### load ```python def load(self, model: str) > maix.err.Err ``` item doc **type** func **brief** Load model from file **param** **model**: direction [in], model file path, model format can be MUD(model universal describe file) file.
    **return** error code, if load success, return err::ERR_NONE **static** False **C++ defination code**: ```cpp err::Err load(const std::string &model) ``` #### loaded item doc **type** func **brief** Is model loaded **return** true if model loaded, else false **static** False **C++ defination code**: ```cpp bool loaded() ``` #### inputs\\_info item doc **type** func **brief** Get model input layer info **return** input layer info **static** False **C++ defination code**: ```cpp std::vector inputs_info() ``` #### outputs\\_info item doc **type** func **brief** Get model output layer info **return** output layer info **static** False **C++ defination code**: ```cpp std::vector outputs_info() ``` #### extra\\_info item doc **type** func **brief** Get model extra info define in MUD file **return** extra info, dict type, key value object, attention: key and value are all string type. **static** False **C++ defination code**: ```cpp std::map extra_info() ``` #### forward item doc **type** func **brief** forward run model, get output of model,\\nthis is specially for MaixPy, not efficient, but easy to use in MaixPy **param** **input**: direction [in], input tensor
    **return** output tensor. In C++, you should manually delete tensors in return value and return value. **static** False **C++ defination code**: ```cpp tensor::Tensors *forward(tensor::Tensors &inputs) ``` #### forward\\_image item doc **type** func **brief** forward model, param is image **param** **img**: input image
    **mean**: mean value, a list type, e.g. [0.485, 0.456, 0.406], default is empty list means not normalize.
    **scale**: scale value, a list type, e.g. [1/0.229, 1/0.224, 1/0.225], default is empty list means not normalize.
    **fit**: fit mode, if the image size of input not equal to model's input, it will auto resize use this fit method,
    default is image.Fit.FIT_FILL for easy coordinate calculation, but for more accurate result, use image.Fit.FIT_CONTAIN is better.
    **copy_result**: If set true, will copy result to a new variable; else will use a internal memory, you can only use it until to the next forward.
    Default true to avoid problems, you can set it to false manually to make speed faster.
    **return** output tensor. In C++, you should manually delete tensors in return value and return value. **static** False **C++ defination code**: ```cpp tensor::Tensors *forward_image(image::Image &img, std::vector mean std::vector(), std::vector scale std::vector(), image::Fit fit image::Fit::FIT_FILL, bool copy_result true) ```"},"/maixpy/api/maix/display.html":{"title":"maix.display","content":" title: maix.display maix.display module, control display device and show image on it > You can use `maix.display` to access this module with MaixPy > This module is generated from [MaixCDK](https://github.com/sipeed/MaixCDK) ## Module No module ## Enum ## Variable ## Function ### send\\_to\\_maixvision item doc **brief** Send image to MaixVision work station if connected.\\nIf you want to debug your program an don't want to initialize display, use this method. **param** **img**: image to send, image.Image object
    **C++ defination code**: ```cpp void send_to_maixvision(image::Image &img) ``` ## Class ### Display item doc **brief** Display class **C++ defination code**: ```cpp class Display ``` #### \\_\\_init\\_\\_ ```python def __init__(self, width: int 1, height: int 1, format: maix.image.Format ..., device: str None, open: bool True) > None ``` item doc **type** func **brief** Construct a new Display object **param** **width**: display width, by default(value is 1) means auto detect,
    if width > max device supported width, will auto set to max device supported width
    **height**: display height, by default(value is 1) means auto detect,
    if height > max device supported height, will auto set to max device supported height
    **device**: display device name, you can get devices by list_devices method, by default(value is NULL(None in MaixPy)) means the first device
    **open**: If true, display will automatically call open() after creation. default is true.
    **static** False **C++ defination code**: ```cpp Display(int width 1, int height 1, image::Format format image::FMT_RGB888, const char *device nullptr, bool open true) ``` #### width ```python def width(self) > int ``` item doc **type** func **brief** Get display width **return** width **static** False **C++ defination code**: ```cpp int width() ``` #### height ```python def height(self) > int ``` item doc **type** func **brief** Get display height **param** **ch**: channel to get, by default(value is 0) means the first channel
    **return** height **static** False **C++ defination code**: ```cpp int height() ``` #### size ```python def size(self) > list[int] ``` item doc **type** func **brief** Get display size **param** **ch**: channel to get, by default(value is 0) means the first channel
    **return** size A list type in MaixPy, [width, height] **static** False **C++ defination code**: ```cpp std::vector size() ``` #### format ```python def format(self) > maix.image.Format ``` item doc **type** func **brief** Get display format **return** format **static** False **C++ defination code**: ```cpp image::Format format() ``` #### open ```python def open(self, width: int 1, height: int 1, format: maix.image.Format ...) > maix.err.Err ``` item doc **type** func **brief** open display device, if already opened, will return err.ERR_NONE. **param** **width**: display width, default is 1, means auto, mostly means max width of display support
    **height**: display height, default is 1, means auto, mostly means max height of display support
    **format**: display output format, default is RGB888
    **return** error code **static** False **C++ defination code**: ```cpp err::Err open(int width 1, int height 1, image::Format format image::FMT_INVALID) ``` #### close ```python def close(self) > maix.err.Err ``` item doc **type** func **brief** close display device **return** error code **static** False **C++ defination code**: ```cpp err::Err close() ``` #### add\\_channel ```python def add_channel(self, width: int 1, height: int 1, format: maix.image.Format ..., open: bool True) > Display ``` item doc **type** func **brief** Add a new channel and return a new Display object, you can use close() to close this channel. **param** **width**: display width, default is 1, means auto, mostly means max width of display support
    **height**: display height, default is 1, means auto, mostly means max height of display support
    **format**: display output format, default is RGB888
    **open**: If true, display will automatically call open() after creation. default is true.
    **return** new Display object **static** False **C++ defination code**: ```cpp display::Display *add_channel(int width 1, int height 1, image::Format format image::FMT_RGB888, bool open true) ``` #### is\\_opened ```python def is_opened(self) > bool ``` item doc **type** func **brief** check display device is opened or not **return** opened or not, bool type **static** False **C++ defination code**: ```cpp bool is_opened() ``` #### is\\_closed ```python def is_closed(self) > bool ``` item doc **type** func **brief** check display device is closed or not **return** closed or not, bool type **static** False **C++ defination code**: ```cpp bool is_closed() ``` #### show ```python def show(self, img: maix.image.Image, fit: maix.image.Fit ...) > maix.err.Err ``` item doc **type** func **brief** show image on display device, and will also send to MaixVision work station if connected. **param** **img**: image to show, image.Image object,
    if the size of image smaller than display size, will show in the center of display;
    if the size of image bigger than display size, will auto resize to display size and keep ratio, fill blank with black color.
    **fit**: image in screen fit mode, by default(value is image.FIT_CONTAIN), @see image.Fit for more details
    e.g. image.FIT_CONTAIN means resize image to fit display size and keep ratio, fill blank with black color.
    **return** error code **static** False **C++ defination code**: ```cpp err::Err show(image::Image &img, image::Fit fit image::FIT_CONTAIN) ``` #### device ```python def device(self) > str ``` item doc **type** func **brief** Get display device path **return** display device path **static** False **C++ defination code**: ```cpp std::string device() ``` #### set\\_backlight ```python def set_backlight(self, value: float) > None ``` item doc **type** func **brief** Set display backlight **param** **value**: backlight value, float type, range is [0, 100]
    **static** False **C++ defination code**: ```cpp void set_backlight(float value) ``` #### get\\_backlight ```python def get_backlight(self) > float ``` item doc **type** func **brief** Get display backlight **return** value backlight value, float type, range is [0, 100] **static** False **C++ defination code**: ```cpp float get_backlight() ``` #### set\\_hmirror ```python def set_hmirror(self, en: bool) > maix.err.Err ``` item doc **type** func **brief** Set display mirror **param** **en**: enable/disable mirror
    **static** False **C++ defination code**: ```cpp err::Err set_hmirror(bool en) ``` #### set\\_vflip ```python def set_vflip(self, en: bool) > maix.err.Err ``` item doc **type** func **brief** Set display flip **param** **en**: enable/disable flip
    **static** False **C++ defination code**: ```cpp err::Err set_vflip(bool en) ```"},"/maixpy/api/index.html":{"title":"MaixPy API -- Maix AI machine vision platform Python API","content":" title: MaixPy API Maix AI machine vision platform Python API **You can read API doc at [MaixPy API on Sipeed Wiki](https://wiki.sipeed.com/maixpy/api/index.html)** If you want to preview API doc offline, build MaixPy, and API doc will be generated in `MaixPy/docs/api/` directory. > For MaixPy developer: This API documentation is generated from the source code, DO NOT edit this file manually! MaixPy API documentation, modules: module brief [maix.err](./maix/err.html) maix.err module [maix.tensor](./maix/tensor.html) maix.tensor module [maix.image](./maix/image.html) maix.image module, image related definition and functions [maix.camera](./maix/camera.html) maix.camera module, access camera device and get image from it [maix.display](./maix/display.html) maix.display module, control display device and show image on it [maix.video](./maix/video.html) maix.video module [maix.touchscreen](./maix/touchscreen.html) maix.touchscreen module [maix.rtsp](./maix/rtsp.html) maix.rtsp module [maix.network](./maix/network.html) maix.network module [maix.comm](./maix/comm.html) maix.comm module [maix.peripheral](./maix/peripheral.html) Chip's peripheral driver [maix.util](./maix/util.html) maix.util module [maix.time](./maix/time.html) maix.time module [maix.app](./maix/app.html) maix.app module [maix.example](./maix/example.html) example module, this will be maix.example module in MaixPy, maix::example namespace in MaixCDK [maix.i18n](./maix/i18n.html) maix.i18n module [maix.fs](./maix/fs.html) maix.fs module [maix.protocol](./maix/protocol.html) maix.protocol module [maix.sys](./maix/sys.html) maix.sys module [maix.thread](./maix/thread.html) maix.thread module [maix.nn](./maix/nn.html) maix.nn module [maix.audio](./maix/audio.html) maix.audio module "},"/maixpy/api/maix/fs.html":{"title":"maix.fs","content":" title: maix.fs maix.fs module > You can use `maix.fs` to access this module with MaixPy > This module is generated from [MaixCDK](https://github.com/sipeed/MaixCDK) ## Module No module ## Enum ### SEEK item doc **brief** SEEK enums **values** **SEEK_SET**: Seek from beginning of file.
    **SEEK_CUR**: Seek from current position.
    **SEEK_END**: Seek from end of file.
    **C++ defination code**: ```cpp enum SEEK { SEEK_SET 0, // Seek from beginning of file. SEEK_CUR 1, // Seek from current position. SEEK_END 2, // Seek from end of file. } ``` ## Variable ## Function ### isabs ```python def isabs(path: str) > bool ``` item doc **brief** Check if the path is absolute path **param** **path**: path to check
    **return** true if path is absolute path **C++ defination code**: ```cpp bool isabs(const std::string &path) ``` ### isdir ```python def isdir(path: str) > bool ``` item doc **brief** Check if the path is a directory, if not exist, throw exception **param** **path**: path to check
    **return** true if path is a directory **C++ defination code**: ```cpp bool isdir(const std::string &path) ``` ### isfile ```python def isfile(path: str) > bool ``` item doc **brief** Check if the path is a file, if not exist, throw exception **param** **path**: path to check
    **return** true if path is a file **C++ defination code**: ```cpp bool isfile(const std::string &path) ``` ### islink ```python def islink(path: str) > bool ``` item doc **brief** Check if the path is a link, if not exist, throw exception **param** **path**: path to check
    **return** true if path is a link **C++ defination code**: ```cpp bool islink(const std::string &path) ``` ### symlink ```python def symlink(src: str, link: str, force: bool False) > maix.err.Err ``` item doc **brief** Create soft link **param** **src**: real file path
    **link**: link file path
    **force**: force link, if already have link file, will delet it first then create.
    **C++ defination code**: ```cpp err::Err symlink(const std::string &src, const std::string &link, bool force false) ``` ### exists ```python def exists(path: str) > bool ``` item doc **brief** Check if the path exists **param** **path**: path to check
    **return** true if path exists **C++ defination code**: ```cpp bool exists(const std::string &path) ``` ### mkdir ```python def mkdir(path: str, exist_ok: bool True, recursive: bool True) > maix.err.Err ``` item doc **brief** Create a directory recursively **param** **path**: path to create
    **exist_ok**: if true, also return true if directory already exists
    **recursive**: if true, create directory recursively, otherwise, only create one directory, default is true
    **return** err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed **C++ defination code**: ```cpp err::Err mkdir(const std::string &path, bool exist_ok true, bool recursive true) ``` ### rmdir ```python def rmdir(path: str, recursive: bool False) > maix.err.Err ``` item doc **brief** Remove a directory **param** **path**: path to remove
    **recursive**: if true, remove directory recursively, otherwise, only remove empty directory, default is false
    **return** err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed **C++ defination code**: ```cpp err::Err rmdir(const std::string &path, bool recursive false) ``` ### remove ```python def remove(path: str) > maix.err.Err ``` item doc **brief** Remove a file **param** **path**: path to remove
    **return** err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed **C++ defination code**: ```cpp err::Err remove(const std::string &path) ``` ### rename ```python def rename(src: str, dst: str) > maix.err.Err ``` item doc **brief** Rename a file or directory **param** **src**: source path
    **dst**: destination path, if destination dirs not exist, will auto create
    **return** err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed **C++ defination code**: ```cpp err::Err rename(const std::string &src, const std::string &dst) ``` ### sync ```python def sync() > None ``` item doc **brief** Sync files, ensure they're wrriten to disk from RAM **C++ defination code**: ```cpp void sync() ``` ### getsize ```python def getsize(path: str) > int ``` item doc **brief** Get file size **param** **path**: path to get size
    **return** file size if success, err::Err code if failed **C++ defination code**: ```cpp int getsize(const std::string &path) ``` ### dirname ```python def dirname(path: str) > str ``` item doc **brief** Get directory name of path **param** **path**: path to get dirname
    **return** dirname if success, empty string if failed **C++ defination code**: ```cpp std::string dirname(const std::string &path) ``` ### basename ```python def basename(path: str) > str ``` item doc **brief** Get base name of path **param** **path**: path to get basename
    **return** basename if success, empty string if failed **C++ defination code**: ```cpp std::string basename(const std::string &path) ``` ### abspath ```python def abspath(path: str) > str ``` item doc **brief** Get absolute path **param** **path**: path to get absolute path
    **return** absolute path if success, empty string if failed **C++ defination code**: ```cpp std::string abspath(const std::string &path) ``` ### getcwd ```python def getcwd() > str ``` item doc **brief** Get current working directory **return** current working directory absolute path **C++ defination code**: ```cpp std::string getcwd() ``` ### realpath ```python def realpath(path: str) > str ``` item doc **brief** Get realpath of path **param** **path**: path to get realpath
    **return** realpath if success, empty string if failed **C++ defination code**: ```cpp std::string realpath(const std::string &path) ``` ### splitext ```python def splitext(path: str) > str ``` item doc **brief** Get file extension **param** **path**: path to get extension
    **return** extension if success, empty string if failed **C++ defination code**: ```cpp std::string splitext(const std::string &path) ``` ### listdir ```python def listdir(path: str, recursive: bool False, full_path: bool False) > list[str] ``` item doc **brief** List files in directory **param** **path**: path to list
    **recursive**: if true, list recursively, otherwise, only list current directory, default is false
    **full_path**: if true, return full path, otherwise, only return basename, default is false
    **return** files list if success, nullptr if failed, you should manually delete it in C++. **C++ defination code**: ```cpp std::vector *listdir(const std::string &path, bool recursive false, bool full_path false) ``` ### open ```python def open(self, path: str, mode: str) > maix.err.Err ``` item doc **brief** Open a file, and return a File object **param** **path**: path to open
    **mode**: open mode, support \"r\", \"w\", \"a\", \"r+\", \"w+\", \"a+\", \"rb\", \"wb\", \"ab\", \"rb+\", \"wb+\", \"ab+\"
    **return** File object if success(need to delete object manually in C/C++), nullptr if failed **C++ defination code**: ```cpp fs::File *open(const std::string &path, const std::string &mode) ``` ### tempdir ```python def tempdir() > str ``` item doc **brief** Get temp files directory **return** temp files directory **C++ defination code**: ```cpp std::string tempdir() ``` ## Class ### File item doc **brief** File read write ops **C++ defination code**: ```cpp class File ``` #### \\_\\_init\\_\\_ ```python def __init__(self) > None ``` item doc **type** func **brief** Construct File object **static** False **C++ defination code**: ```cpp File() ``` #### open ```python def open(self, path: str, mode: str) > maix.err.Err ``` item doc **type** func **brief** Open a file **param** **path**: path to open
    **mode**: open mode, support \"r\", \"w\", \"a\", \"r+\", \"w+\", \"a+\", \"rb\", \"wb\", \"ab\", \"rb+\", \"wb+\", \"ab+\"
    **return** err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed **static** False **C++ defination code**: ```cpp err::Err open(const std::string &path, const std::string &mode) ``` #### close ```python def close(self) > None ``` item doc **type** func **brief** Close a file **static** False **C++ defination code**: ```cpp void close() ``` #### read ```python def read(self, size: int) > list[int] ``` item doc **type** func **brief** Read data from file API2 **param** **size**: max read size
    **return** bytes data if success(need delete manually in C/C++), nullptr if failed **static** False **C++ defination code**: ```cpp std::vector *read(int size) ``` #### readline ```python def readline(self) > str ``` item doc **type** func **brief** Read line from file **return** line if success, empty string if failed. You need to delete the returned object manually in C/C++. **static** False **C++ defination code**: ```cpp std::string *readline() ``` #### write ```python def write(self, buf: list[int]) > int ``` item doc **type** func **brief** Write data to file API2 **param** **buf**: buffer to write
    **return** write size if success, err::Err code if failed **static** False **C++ defination code**: ```cpp int write(const std::vector &buf) ``` #### seek ```python def seek(self, offset: int, whence: int) > int ``` item doc **type** func **brief** Seek file position **param** **offset**: offset to seek
    **whence**: @see maix.fs.SEEK
    **return** new position if success, err::Err code if failed **static** False **C++ defination code**: ```cpp int seek(int offset, int whence) ``` #### tell ```python def tell(self) > int ``` item doc **type** func **brief** Get file position **return** file position if success, err::Err code if failed **static** False **C++ defination code**: ```cpp int tell() ``` #### flush ```python def flush(self) > maix.err.Err ``` item doc **type** func **brief** Flush file **return** err::ERR_NONE(err.Err.ERR_NONE in MaixPy) if success, other error code if failed **static** False **C++ defination code**: ```cpp err::Err flush() ```"},"/maixpy/api/maix/image.html":{"title":"maix.image","content":" title: maix.image maix.image module, image related definition and functions > You can use `maix.image` to access this module with MaixPy > This module is generated from [MaixCDK](https://github.com/sipeed/MaixCDK) ## Module No module ## Enum ### Format item doc **brief** Image formats **attention** for developers, update this enum will also need to update the fmt_size in maix_image.cpp **values** **FMT_RGB888**: RGBRGB...RGB, R at the lowest address
    **FMT_BGR888**: BGRBGR...BGR, B at the lowest address
    **FMT_RGBA8888**: RGBARGBA...RGBA, R at the lowest address
    **FMT_BGRA8888**: BGRABGRA...BGRA, B at the lowest address
    **FMT_RGB565**:
    **FMT_BGR565**:
    **FMT_YUV422SP**: YYY...UVUVUV...UVUV
    **FMT_YUV422P**: YYY...UUU...VVV
    **FMT_YVU420SP**: YYY...VUVUVU...VUVU, NV21
    **FMT_YUV420SP**: YYY...UVUVUV...UVUV, NV12
    **FMT_YVU420P**: YYY...VVV...UUU
    **FMT_YUV420P**: YYY...UUU...VVV
    **FMT_GRAYSCALE**:
    **FMT_UNCOMPRESSED_MAX**:
    **FMT_COMPRESSED_MIN**:
    **FMT_JPEG**:
    **FMT_PNG**:
    **FMT_COMPRESSED_MAX**:
    **FMT_INVALID**: format not valid
    **C++ defination code**: ```cpp enum Format { FMT_RGB888 0, // RGBRGB...RGB, R at the lowest address FMT_BGR888, // BGRBGR...BGR, B at the lowest address FMT_RGBA8888, // RGBARGBA...RGBA, R at the lowest address FMT_BGRA8888, // BGRABGRA...BGRA, B at the lowest address FMT_RGB565, FMT_BGR565, FMT_YUV422SP, // YYY...UVUVUV...UVUV FMT_YUV422P, // YYY...UUU...VVV FMT_YVU420SP, // YYY...VUVUVU...VUVU, NV21 FMT_YUV420SP, // YYY...UVUVUV...UVUV, NV12 FMT_YVU420P, // YYY...VVV...UUU FMT_YUV420P, // YYY...UUU...VVV FMT_GRAYSCALE, FMT_UNCOMPRESSED_MAX, // compressed format below, not compressed should define upper FMT_COMPRESSED_MIN, FMT_JPEG, FMT_PNG, FMT_COMPRESSED_MAX, FMT_INVALID 0xFF // format not valid } ``` ### Fit item doc **brief** Object fit method **values** **FIT_NONE**: no object fit, keep original
    **FIT_FILL**: width to new width, height to new height, may be stretch
    **FIT_CONTAIN**: keep aspect ratio, fill blank area with black color
    **FIT_COVER**: keep aspect ratio, crop image to fit new size
    **FIT_MAX**:
    **C++ defination code**: ```cpp enum Fit { FIT_NONE 1, // no object fit, keep original FIT_FILL 0, // width to new width, height to new height, may be stretch FIT_CONTAIN, // keep aspect ratio, fill blank area with black color FIT_COVER, // keep aspect ratio, crop image to fit new size FIT_MAX } ``` ### ResizeMethod item doc **brief** Resize method **values** **NEAREST**:
    **BILINEAR**:
    **BICUBIC**:
    **AREA**:
    **LANCZOS**:
    **HAMMING**:
    **RESIZE_METHOD_MAX**:
    **C++ defination code**: ```cpp enum ResizeMethod { NEAREST 0, BILINEAR, BICUBIC, AREA, LANCZOS, HAMMING, RESIZE_METHOD_MAX } ``` ### ApriltagFamilies item doc **brief** Family of apriltag **values** **TAG16H5**:
    **TAG25H7**:
    **TAG25H9**:
    **TAG36H10**:
    **TAG36H11**:
    **ARTOOLKIT**:
    **C++ defination code**: ```cpp enum ApriltagFamilies { TAG16H5 1, TAG25H7 2, TAG25H9 4, TAG36H10 8, TAG36H11 16, ARTOOLKIT 32 } ``` ### TemplateMatch item doc **brief** Template match method **values** **SEARCH_EX**: Exhaustive search
    **SEARCH_DS**: Diamond search
    **C++ defination code**: ```cpp enum TemplateMatch { SEARCH_EX, // Exhaustive search SEARCH_DS, // Diamond search } ``` ### CornerDetector item doc **brief** CornerDetector class **values** **CORNER_FAST**:
    **CORNER_AGAST**:
    **C++ defination code**: ```cpp enum CornerDetector { CORNER_FAST, CORNER_AGAST } ``` ### EdgeDetector item doc **brief** EdgeDetector class **values** **EDGE_CANNY**:
    **EDGE_SIMPLE**:
    **C++ defination code**: ```cpp enum EdgeDetector { EDGE_CANNY, EDGE_SIMPLE, } ``` ## Variable ### fmt\\_size item doc **brief** Image format size in bytes **attention** It's a copy of this variable in MaixPy,
    so change it in C++ (e.g. update var in hello function) will not take effect the var inMaixPy.
    So we add const for this var to avoid this mistake. **value** **{
    3,
    3,
    4,
    4,
    2,
    2,
    2,
    2,
    1.5,
    1.5,
    1.5,
    1.5,
    1,
    0,
    0,
    0,
    0,
    0
    }** **readonly** True **C++ defination code**: ```cpp const std::vector fmt_size { 3, 3, 4, 4, 2, 2, 2, 2, 1.5, 1.5, 1.5, 1.5, 1, 0, 0, 0, 0, 0 } ``` ### fmt\\_names item doc **brief** Image format string **value** **{
    \"RGB888\",
    \"BGR888\",
    \"RGBA8888\",
    \"BGRA8888\",
    \"RGB565\",
    \"BGR565\",
    \"YUV422SP\",
    \"YUV422P\",
    \"YVU420SP\",
    \"YUV420SP\",
    \"YVU420P\"
    \"YUV420P\",
    \"GRAYSCALE\",
    \"MAX\"}** **readonly** True **C++ defination code**: ```cpp const std::vector fmt_names { \"RGB888\", \"BGR888\", \"RGBA8888\", \"BGRA8888\", \"RGB565\", \"BGR565\", \"YUV422SP\", \"YUV422P\", \"YVU420SP\", \"YUV420SP\", \"YVU420P\" \"YUV420P\", \"GRAYSCALE\", \"MAX\"} ``` ### COLOR\\_WHITE item doc **brief** Predefined color white **value** **image::Color::from_rgb(255, 255, 255)** **readonly** True **C++ defination code**: ```cpp const image::Color COLOR_WHITE image::Color::from_rgb(255, 255, 255) ``` ### COLOR\\_BLACK item doc **brief** Predefined color black **value** **image::Color::from_rgb(0, 0, 0)** **readonly** True **C++ defination code**: ```cpp const image::Color COLOR_BLACK image::Color::from_rgb(0, 0, 0) ``` ### COLOR\\_RED item doc **brief** Predefined color red **value** **image::Color::from_rgb(255, 0, 0)** **readonly** True **C++ defination code**: ```cpp const image::Color COLOR_RED image::Color::from_rgb(255, 0, 0) ``` ### COLOR\\_GREEN item doc **brief** Predefined color green **value** **image::Color::from_rgb(0, 255, 0)** **readonly** True **C++ defination code**: ```cpp const image::Color COLOR_GREEN image::Color::from_rgb(0, 255, 0) ``` ### COLOR\\_BLUE item doc **brief** Predefined color blue **value** **image::Color::from_rgb(0, 0, 255)** **readonly** True **C++ defination code**: ```cpp const image::Color COLOR_BLUE image::Color::from_rgb(0, 0, 255) ``` ### COLOR\\_YELLOW item doc **brief** Predefined color yellow **value** **image::Color::from_rgb(255, 255, 0)** **readonly** True **C++ defination code**: ```cpp const image::Color COLOR_YELLOW image::Color::from_rgb(255, 255, 0) ``` ### COLOR\\_PURPLE item doc **brief** Predefined color purple **value** **image::Color::from_rgb(143, 0, 255)** **readonly** True **C++ defination code**: ```cpp const image::Color COLOR_PURPLE image::Color::from_rgb(143, 0, 255) ``` ### COLOR\\_ORANGE item doc **brief** Predefined color orange **value** **image::Color::from_rgb(255, 127, 0)** **readonly** True **C++ defination code**: ```cpp const image::Color COLOR_ORANGE image::Color::from_rgb(255, 127, 0) ``` ### COLOR\\_GRAY item doc **brief** Predefined color gray **value** **image::Color::from_rgb(127, 127, 127)** **readonly** True **C++ defination code**: ```cpp const image::Color COLOR_GRAY image::Color::from_rgb(127, 127, 127) ``` ## Function ### load ```python def load(path: str, format: Format ...) > Image ``` item doc **brief** Load image from file, and convert to Image object **param** **path**: image file path
    **format**: read as this format, if not match, will convert to this format, by default is RGB888
    **return** Image object **C++ defination code**: ```cpp image::Image *load(const char *path, image::Format format image::Format::FMT_RGB888) ``` ### from\\_bytes ```python def from_bytes(width: int, height: int, format: Format, data: maix.Bytes(bytes), copy: bool True) > Image ``` item doc **brief** Create image from bytes **param** **width**: image width
    **height**: image height
    **format**: image format
    **data**: image data, if data is None, will malloc memory for image data
    If the image is in jpeg format, data must be filled in.
    **copy**: if true and data is not None, will copy data to new buffer, else will use data directly. default is true to avoid memory leak.
    Use it carefully!!!
    **return** Image object **C++ defination code**: ```cpp image::Image *from_bytes(int width, int height, image::Format format, Bytes *data, bool copy true) ``` ### load\\_font ```python def load_font(name: str, path: str, size: int 16) > maix.err.Err ``` item doc **brief** Load font from file **param** **name**: font name, used to identify font
    **path**: font file path, support ttf, ttc, otf
    **size**: font size, font height, by default is 16
    **return** error code, err::ERR_NONE is ok, other is error **C++ defination code**: ```cpp err::Err load_font(const std::string &name, const char *path, int size 16) ``` ### set\\_default\\_font item doc **brief** Set default font, if not call this method, default is hershey_plain **param** **name**: font name, supported names can be get by fonts()
    **return** error code, err::ERR_NONE is ok, other is error **C++ defination code**: ```cpp err::Err set_default_font(const std::string &name) ``` ### fonts ```python def fonts() > list[str] ``` item doc **brief** Get all loaded fonts **return** all loaded fonts, string list type **C++ defination code**: ```cpp std::vector *fonts() ``` ### string\\_size ```python def string_size(string: str, scale: float 1, thickness: int 1, font: str '') > Size ``` item doc **brief** Get text rendered width and height **param** **string**: text content
    **scale**: font scale, by default(value is 1)
    **thickness**: text thickness(line width), by default(value is 1)
    **return** text rendered width and height, [width, height] **C++ defination code**: ```cpp image::Size string_size(std::string string, float scale 1, int thickness 1, const std::string &font \"\") ``` ### cv2image item doc **brief** OpenCV Mat(numpy array object) to Image object **param** **array**: numpy array object, must be a 3 dim or 2 dim continuous array with shape hwc or hw
    **return** Image object **C++ defination code**: ```cpp image::Image *cv2image(py::array_t array, bool bgr true, bool copy true) ``` ### image2cv ```python def image2cv(img: Image, bgr: bool True, copy: bool True) > numpy.ndarray[numpy.uint8] ``` item doc **brief** Image object to OpenCV Mat(numpy array object) **param** **img**: Image object
    **return** numpy array object **C++ defination code**: ```cpp py::array_t image2cv(image::Image *img, bool bgr true, bool copy true) ``` ## Class ### Size item doc **brief** Image size type **C++ defination code**: ```cpp class Size ``` #### \\_\\_init\\_\\_ ```python def __init__(self, width: int 0, height: int 0) > None ``` item doc **type** func **brief** Construct a new Size object **param** **width**: image width
    **height**: image height
    **static** False **C++ defination code**: ```cpp Size(int width 0, int height 0) ``` #### width ```python def width(self, width: int 1) > int ``` item doc **type** func **brief** width of size **param** **width**: set new width, if not set, only return current width
    **static** False **C++ defination code**: ```cpp int width(int width 1) ``` #### height ```python def height(self, height: int 1) > int ``` item doc **type** func **brief** height of size **param** **height**: set new height, if not set, only return current height
    **static** False **C++ defination code**: ```cpp int height(int height 1) ``` #### \\_\\_getitem\\_\\_ ```python def __getitem__(self, index: int) > int ``` item doc **type** func **brief** Subscript operator **param** **index**: 0 for width, 1 for height
    **return** int& width or height **static** False **C++ defination code**: ```cpp int &operator[](int index) ``` #### \\_\\_str\\_\\_ ```python def __str__(self) > str ``` item doc **type** func **brief** to string **static** False **C++ defination code**: ```cpp std::string __str__() ``` ### Line item doc **brief** Line class **C++ defination code**: ```cpp class Line ``` #### \\_\\_init\\_\\_ item doc **type** func **brief** Line constructor **param** **x1**: coordinate x1 of the straight line
    **y1**: coordinate y1 of the straight line
    **x2**: coordinate x2 of the straight line
    **y2**: coordinate y2 of the straight line
    **magnitude**: magnitude of the straight line after Hough transformation
    **theta**: angle of the straight line after Hough transformation
    **rho**: p value of the straight line after Hough transformation
    **static** False **C++ defination code**: ```cpp Line(int x1, int y1, int x2, int y2, int magnitude 0, int theta 0, int rho 0) ``` #### \\_\\_getitem\\_\\_ item doc **type** func **brief** Subscript operator **param** **index [0]**: get x1 of line
    [1] get y1 of line
    [2] get x2 of line
    [3] get y2 of line
    [4] get length of line
    [5] get magnitude of the straight line after Hough transformation
    [6] get angle of the straight line after Hough transformation (0 179 degrees)
    [7] get p value of the straight line after Hough transformation
    **return** int& **static** False **C++ defination code**: ```cpp int &__getitem__(int index) ``` #### x1 item doc **type** func **brief** get x1 of line **return** return x1 of the line, type is int **static** False **C++ defination code**: ```cpp int x1() ``` #### y1 item doc **type** func **brief** get y1 of line **return** return y1 of the line, type is int **static** False **C++ defination code**: ```cpp int y1() ``` #### x2 item doc **type** func **brief** get x2 of line **return** return x2 of the line, type is int **static** False **C++ defination code**: ```cpp int x2() ``` #### y2 item doc **type** func **brief** get y2 of line **return** return y2 of the line, type is int **static** False **C++ defination code**: ```cpp int y2() ``` #### length item doc **type** func **brief** get length of line **return** return length of the line, type is int **static** False **C++ defination code**: ```cpp int length() ``` #### magnitude item doc **type** func **brief** get magnitude of the straight line after Hough transformation **return** return magnitude, type is int **static** False **C++ defination code**: ```cpp int magnitude() ``` #### theta item doc **type** func **brief** get angle of the straight line after Hough transformation (0 179 degrees) **return** return angle, type is int **static** False **C++ defination code**: ```cpp int theta() ``` #### rho item doc **type** func **brief** get p value of the straight line after Hough transformation **return** return p value, type is int **static** False **C++ defination code**: ```cpp int rho() ``` ### Rect item doc **brief** Rect class **C++ defination code**: ```cpp class Rect ``` #### \\_\\_init\\_\\_ ```python def __init__(self, corners: list[list[int]], x: int, y: int, w: int, h: int, magnitude: int 0) > None ``` item doc **type** func **brief** Rect constructor **param** **corners**: corners of rect
    **x**: coordinate x of the straight line
    **y**: coordinate y of the straight line
    **w**: coordinate w of the straight line
    **h**: coordinate h of the straight line
    **magnitude**: magnitude of the straight line after Hough transformation
    **static** False **C++ defination code**: ```cpp Rect(std::vector> &corners, int x, int y, int w, int h, int magnitude 0) ``` #### \\_\\_getitem\\_\\_ ```python def __getitem__(self, index: int) > int ``` item doc **type** func **brief** Subscript operator **param** **index [0]**: get x of rect
    [1] get y of rect
    [2] get w of rect
    [3] get h of rect
    [4] get magnitude of the straight line after Hough transformation
    **return** int& **static** False **C++ defination code**: ```cpp int &__getitem__(int index) ``` #### corners ```python def corners(self) > list[list[int]] ``` item doc **type** func **brief** get corners of rect **return** return the coordinate of the rect. **static** False **C++ defination code**: ```cpp std::vector> corners() ``` #### rect ```python def rect(self) > list[int] ``` item doc **type** func **brief** get rectangle of rect **return** return the rectangle of the rect. format is {x, y, w, h}, type is std::vector **static** False **C++ defination code**: ```cpp std::vector rect() ``` #### x ```python def x(self) > int ``` item doc **type** func **brief** get x of rect **return** return x of the rect, type is int **static** False **C++ defination code**: ```cpp int x() ``` #### y ```python def y(self) > int ``` item doc **type** func **brief** get y of rect **return** return y of the rect, type is int **static** False **C++ defination code**: ```cpp int y() ``` #### w ```python def w(self) > int ``` item doc **type** func **brief** get w of rect **return** return w of the rect, type is int **static** False **C++ defination code**: ```cpp int w() ``` #### h ```python def h(self) > int ``` item doc **type** func **brief** get h of rect **return** return h of the rect, type is int **static** False **C++ defination code**: ```cpp int h() ``` #### magnitude ```python def magnitude(self) > int ``` item doc **type** func **brief** get magnitude of the straight line after Hough transformation **return** return magnitude, type is int **static** False **C++ defination code**: ```cpp int magnitude() ``` ### Circle item doc **brief** circle class **C++ defination code**: ```cpp class Circle ``` #### \\_\\_init\\_\\_ ```python def __init__(self, x: int, y: int, r: int, magnitude: int) > None ``` item doc **type** func **brief** Circle constructor **param** **x**: coordinate x of the circle
    **y**: coordinate y of the circle
    **r**: coordinate r of the circle
    **magnitude**: coordinate y2 of the straight line
    **static** False **C++ defination code**: ```cpp Circle(int x, int y, int r, int magnitude) ``` #### \\_\\_getitem\\_\\_ ```python def __getitem__(self, index: int) > int ``` item doc **type** func **brief** Subscript operator **param** **index [0]**: get x of circle
    [1] get y of circle
    [2] get r of circle
    [3] get magnitude of the circle after Hough transformation
    **return** int& **static** False **C++ defination code**: ```cpp int &__getitem__(int index) ``` #### x ```python def x(self) > int ``` item doc **type** func **brief** get x of circle **return** return x of the circle, type is int **static** False **C++ defination code**: ```cpp int x() ``` #### y ```python def y(self) > int ``` item doc **type** func **brief** get y of circle **return** return y of the circle, type is int **static** False **C++ defination code**: ```cpp int y() ``` #### r ```python def r(self) > int ``` item doc **type** func **brief** get r of circle **return** return r of the circle, type is int **static** False **C++ defination code**: ```cpp int r() ``` #### magnitude ```python def magnitude(self) > int ``` item doc **type** func **brief** get magnitude of the circle after Hough transformation **return** return magnitude, type is int **static** False **C++ defination code**: ```cpp int magnitude() ``` ### Blob item doc **brief** Blob class **C++ defination code**: ```cpp class Blob ``` #### \\_\\_init\\_\\_ item doc **type** func **brief** Blob constructor **param** **rect**: blob rect, type is std::vector
    **corners**: blob corners, type is std::vector>
    **mini_corners**: blob mini_corners, type is std::vector>
    **cx**: blob center x, type is float
    **cy**: blob center y, type is float
    **pixels**: blob pixels, type is int
    **rotation**: blob rotation, type is float
    **code**: blob code, type is int
    **count**: blob count, type is int
    **perimeter**: blob perimeter, type is int
    **roundness**: blob roundness, type is float
    **x_hist_bins**: blob x_hist_bins, type is std::vector
    **y_hist_bins**: blob y_hist_bins, type is std::vector
    **static** False **C++ defination code**: ```cpp Blob(std::vector &rect, std::vector> &corners, std::vector> &mini_corners,float cx, float cy, int pixels, float rotation, int code, int count, int perimeter, float roundness, std::vector &x_hist_bins, std::vector &y_hist_bins) ``` #### \\_\\_getitem\\_\\_ item doc **type** func **brief** Subscript operator **param** **index [0]**: Returns the blob’s bounding box x coordinate
    [1] Returns the blob’s bounding box y coordinate
    [2] Returns the blob’s bounding box w coordinate
    [3] Returns the blob’s bounding box h coordinate
    [4] Returns the number of pixels that are part of this blob
    [5] Returns the centroid x position of the blob
    [6] Returns the centroid y position of the blob
    **return** int& width or height **static** False **C++ defination code**: ```cpp int &__getitem__(int index) ``` #### corners item doc **type** func **brief** get blob corners **return** Returns a list of 4 (x,y) tuples of the 4 corners of the object.
    (x0, y0)___________(x1, y1)



    ___________
    (x3, y3) (x2, y2)
    note: the order of corners may change **static** False **C++ defination code**: ```cpp std::vector> corners() ``` #### mini\\_corners item doc **type** func **brief** get blob mini corners **return** Returns a list of 4 (x,y) tuples of the 4 corners than bound the min area rectangle of the blob.
    (x0, y0)___________(x1, y1)



    ___________
    (x3, y3) (x2, y2)
    note: the order of corners may change **static** False **C++ defination code**: ```cpp std::vector> mini_corners() ``` #### rect item doc **type** func **brief** get blob rect **return** Returns the center coordinates and width and height of the rectangle. format is (x, y, w, h)
    w
    (x, y) ___________

    h

    ___________ **static** False **C++ defination code**: ```cpp std::vector rect() ``` #### x item doc **type** func **brief** get blob x of the upper left coordinate **return** Returns the x coordinate of the upper left corner of the rectangle. **static** False **C++ defination code**: ```cpp int x() ``` #### y item doc **type** func **brief** get blob y of the upper left coordinate **return** Returns the y coordinate of the upper left corner of the rectangle. **static** False **C++ defination code**: ```cpp int y() ``` #### w item doc **type** func **brief** get blob width **return** Returns the blob’s bounding box w coordinate **static** False **C++ defination code**: ```cpp int w() ``` #### h item doc **type** func **brief** get blob height **return** Returns the blob’s bounding box h coordinate **static** False **C++ defination code**: ```cpp int h() ``` #### pixels item doc **type** func **brief** get blob pixels **return** Returns the number of pixels that are part of this blob. **static** False **C++ defination code**: ```cpp int pixels() ``` #### cx item doc **type** func **brief** get blob center x **return** Returns the centroid x position of the blob **static** False **C++ defination code**: ```cpp int cx() ``` #### cy item doc **type** func **brief** get blob center y **return** Returns the centroid y position of the blob **static** False **C++ defination code**: ```cpp int cy() ``` #### cxf item doc **type** func **brief** get blob center x **return** Returns the centroid x position of the blob **static** False **C++ defination code**: ```cpp float cxf() ``` #### cyf item doc **type** func **brief** get blob center y **return** Returns the centroid y position of the blob **static** False **C++ defination code**: ```cpp float cyf() ``` #### rotation item doc **type** func **brief** get blob rotation **return** Returns the rotation of the blob in radians (float). If the blob is like a pencil or pen this value will be unique for 0 180 degrees. **static** False **C++ defination code**: ```cpp float rotation() ``` #### rotation\\_rad item doc **type** func **brief** get blob rotation_rad **return** Returns the rotation of the blob in radians **static** False **C++ defination code**: ```cpp float rotation_rad() ``` #### rotation\\_deg item doc **type** func **brief** get blob rotation_deg **return** Returns the rotation of the blob in degrees. **static** False **C++ defination code**: ```cpp int rotation_deg() ``` #### code item doc **type** func **brief** get blob code **return** Returns a 32 bit binary number with a bit set in it for each color threshold that’s part of this blob **static** False **C++ defination code**: ```cpp int code() ``` #### count item doc **type** func **brief** get blob count **return** Returns the number of blobs merged into this blob. **static** False **C++ defination code**: ```cpp int count() ``` #### perimeter item doc **type** func **brief** get blob merge_cnt **return** Returns the number of pixels on this blob’s perimeter. **static** False **C++ defination code**: ```cpp int perimeter() ``` #### roundness item doc **type** func **brief** get blob roundness **return** Returns a value between 0 and 1 representing how round the object is **static** False **C++ defination code**: ```cpp float roundness() ``` #### elongation item doc **type** func **brief** get blob elongation **returnReturns** a value between 0 and 1 representing how long (not round) the object is **static** False **C++ defination code**: ```cpp float elongation() ``` #### area item doc **type** func **brief** get blob area **return** Returns the area of the bounding box around the blob **static** False **C++ defination code**: ```cpp int area() ``` #### density item doc **type** func **brief** get blob density **return** Returns the density ratio of the blob **static** False **C++ defination code**: ```cpp float density() ``` #### extent item doc **type** func **brief** Alias for blob.density() **return** Returns the density ratio of the blob **static** False **C++ defination code**: ```cpp float extent() ``` #### compactness item doc **type** func **brief** get blob compactness **return** Returns the compactness ratio of the blob **static** False **C++ defination code**: ```cpp float compactness() ``` #### solidity item doc **type** func **brief** get blob solidity **return** Returns the solidity ratio of the blob **static** False **C++ defination code**: ```cpp float solidity() ``` #### convexity item doc **type** func **brief** get blob convexity **return** Returns a value between 0 and 1 representing how convex the object is **static** False **C++ defination code**: ```cpp float convexity() ``` #### x\\_hist\\_bins item doc **type** func **brief** get blob x_hist_bins **return** Returns the x_hist_bins of the blob **static** False **C++ defination code**: ```cpp std::vector x_hist_bins() ``` #### y\\_hist\\_bins item doc **type** func **brief** get blob y_hist_bins **return** Returns the y_hist_bins of the blob **static** False **C++ defination code**: ```cpp std::vector y_hist_bins() ``` #### major\\_axis\\_line item doc **type** func **brief** get blob major_axis_line **return** Returns a line tuple (x1, y1, x2, y2) of the minor axis of the blob. **static** False **C++ defination code**: ```cpp std::vector major_axis_line() ``` #### minor\\_axis\\_line item doc **type** func **brief** get blob minor_axis_line **return** Returns a line tuple (x1, y1, x2, y2) of the minor axis of the blob. **static** False **C++ defination code**: ```cpp std::vector minor_axis_line() ``` #### enclosing\\_circle item doc **type** func **brief** get blob enclosing_circle **return** Returns a circle tuple (x, y, r) of the circle that encloses the min area rectangle of a blob. **static** False **C++ defination code**: ```cpp std::vector enclosing_circle() ``` #### enclosed\\_ellipse item doc **type** func **brief** get blob enclosed_ellipse **return** Returns an ellipse tuple (x, y, rx, ry, rotation) of the ellipse that fits inside of the min area rectangle of a blob. **static** False **C++ defination code**: ```cpp std::vector enclosed_ellipse() ``` ### QRCode item doc **brief** QRCode class **C++ defination code**: ```cpp class QRCode ``` #### \\_\\_init\\_\\_ item doc **type** func **brief** QRCode constructor **param** **rect**: rect of corners, type is std::vector
    **corners**: corners of QRCode
    **payload**: payload of the QRCode
    **version**: version of the QRCode
    **ecc_level**: ecc_level of the QRCode
    **mask**: mask of the QRCode
    **data_type**: data_type of the QRCode
    **eci**: eci of the QRCode
    **static** False **C++ defination code**: ```cpp QRCode(std::vector &rect, std::vector> &corners, std::string &payload, int version, int ecc_level, int mask, int data_type, int eci) ``` #### \\_\\_getitem\\_\\_ item doc **type** func **brief** Subscript operator **param** **index [0]**: Returns the qrcode’s bounding box x coordinate
    [1] Returns the qrcode’s bounding box y coordinate
    [2] Returns the qrcode’s bounding box w coordinate
    [3] Returns the qrcode’s bounding box h coordinate
    [4] Not support this index, try to use payload() method
    [5] Returns the version of qrcode
    [6] Returns the error correction level of qrcode
    [7] Returns the mask of qrcode
    [8] Returns the datatype of qrcode
    [9] Returns the eci of qrcode
    **return** int& **static** False **C++ defination code**: ```cpp int &__getitem__(int index) ``` #### corners item doc **type** func **brief** get coordinate of QRCode **return** return the coordinate of the QRCode. **static** False **C++ defination code**: ```cpp std::vector> corners() ``` #### rect item doc **type** func **brief** get rectangle of QRCode **return** return the rectangle of the QRCode. format is {x, y, w, h}, type is std::vector **static** False **C++ defination code**: ```cpp std::vector rect() ``` #### x item doc **type** func **brief** get x of QRCode **return** return x of the QRCode, type is int **static** False **C++ defination code**: ```cpp int x() ``` #### y item doc **type** func **brief** get y of QRCode **return** return y of the QRCode, type is int **static** False **C++ defination code**: ```cpp int y() ``` #### w item doc **type** func **brief** get w of QRCode **return** return w of the QRCode, type is int **static** False **C++ defination code**: ```cpp int w() ``` #### h item doc **type** func **brief** get h of QRCode **return** return h of the QRCode, type is int **static** False **C++ defination code**: ```cpp int h() ``` #### payload item doc **type** func **brief** get QRCode payload **return** return area of the QRCode **static** False **C++ defination code**: ```cpp std::string payload() ``` #### version item doc **type** func **brief** get QRCode version **return** return version of the QRCode **static** False **C++ defination code**: ```cpp int version() ``` #### ecc\\_level item doc **type** func **brief** get QRCode error correction level **return** return error correction level of the QRCode **static** False **C++ defination code**: ```cpp int ecc_level() ``` #### mask item doc **type** func **brief** get QRCode mask **return** return mask of the QRCode **static** False **C++ defination code**: ```cpp int mask() ``` #### data\\_type item doc **type** func **brief** get QRCode dataType **return** return mask of the QRCode **static** False **C++ defination code**: ```cpp int data_type() ``` #### eci item doc **type** func **brief** get QRCode eci **return** return data of the QRCode **static** False **C++ defination code**: ```cpp int eci() ``` #### is\\_numeric item doc **type** func **brief** check QRCode is numeric **return** return true if the result type of the QRCode is numeric **static** False **C++ defination code**: ```cpp bool is_numeric() ``` #### is\\_alphanumeric item doc **type** func **brief** check QRCode is alphanumeric **return** return true if the result type of the QRCode is alphanumeric **static** False **C++ defination code**: ```cpp bool is_alphanumeric() ``` #### is\\_binary item doc **type** func **brief** check QRCode is binary **return** return true if the result type of the QRCode is binary **static** False **C++ defination code**: ```cpp bool is_binary() ``` #### is\\_kanji item doc **type** func **brief** check QRCode is kanji **return** return true if the result type of the QRCode is kanji **static** False **C++ defination code**: ```cpp bool is_kanji() ``` ### AprilTag item doc **brief** AprilTag class **C++ defination code**: ```cpp class AprilTag ``` #### \\_\\_init\\_\\_ ```python def __init__(self, rect: list[int], corners: list[list[int]], id: int, famliy: int, centroid_x: float, centroid_y: float, rotation: float, decision_margin: float, hamming: int, goodness: float, x_translation: float, y_translation: float, z_translation: float, x_rotation: float, y_rotation: float, z_rotation: float) > None ``` item doc **type** func **brief** AprilTag constructor **param** **rect**: Inlucdes the top left corner and the width and height of the rectangle. format is {x, y, w, h}, type is std::vector
    **corners**: Includes the four corners of the rectangle. format is {{x0, y0}, {x1, y1}, {x2, y2}, {x3, y3}}, type is std::vector>
    **id**: The id of the AprilTag
    **famliy**: The family of the AprilTag
    **centroid_x**: The x coordinate of the center of the AprilTag
    **centroid_y**: The y coordinate of the center of the AprilTag
    **rotation**: The rotation of the AprilTag
    **decision_margin**: The decision_margin of the AprilTag
    **hamming**: The hamming of the AprilTag
    **goodness**: The goodness of the AprilTag
    **x_translation**: The x_translation of the AprilTag
    **y_translation**: The y_translation of the AprilTag
    **z_translation**: The z_translation of the AprilTag
    **x_rotation**: The x_rotation of the AprilTag
    **y_rotation**: The y_rotation of the AprilTag
    **z_rotation**: The z_rotation of the AprilTag
    **static** False **C++ defination code**: ```cpp AprilTag(std::vector &rect, std::vector> &corners, int id, int famliy, float centroid_x, float centroid_y, float rotation, float decision_margin, int hamming, float goodness, float x_translation, float y_translation, float z_translation, float x_rotation, float y_rotation, float z_rotation) ``` #### \\_\\_getitem\\_\\_ ```python def __getitem__(self, index: int) > int ``` item doc **type** func **brief** Subscript operator **param** **index [0]**: Returns the apriltag’s bounding box x coordinate
    [1] Returns the apriltag’s bounding box y coordinate
    [2] Returns the apriltag’s bounding box w coordinate
    [3] Returns the apriltag’s bounding box h coordinate
    [4] Returns the apriltag’s id
    [5] Returns the apriltag’s family
    [6] Not support
    [7] Not support
    [8] Not support
    [9] Not support
    [10] Returns the apriltag’s hamming
    [11] Not support
    [12] Not support
    [13] Not support
    [14] Not support
    [15] Not support
    [16] Not support
    [17] Not support
    **return** int& **static** False **C++ defination code**: ```cpp int &__getitem__(int index) ``` #### corners ```python def corners(self) > list[list[int]] ``` item doc **type** func **brief** get coordinate of AprilTag **return** return the coordinate of the AprilTag. **static** False **C++ defination code**: ```cpp std::vector> corners() ``` #### rect ```python def rect(self) > list[int] ``` item doc **type** func **brief** get rectangle of AprilTag **return** return the rectangle of the AprilTag. format is {x, y, w, h}, type is std::vector **static** False **C++ defination code**: ```cpp std::vector rect() ``` #### x ```python def x(self) > int ``` item doc **type** func **brief** get x of AprilTag **return** return x of the AprilTag, type is int **static** False **C++ defination code**: ```cpp int x() ``` #### y ```python def y(self) > int ``` item doc **type** func **brief** get y of AprilTag **return** return y of the AprilTag, type is int **static** False **C++ defination code**: ```cpp int y() ``` #### w ```python def w(self) > int ``` item doc **type** func **brief** get w of AprilTag **return** return w of the AprilTag, type is int **static** False **C++ defination code**: ```cpp int w() ``` #### h ```python def h(self) > int ``` item doc **type** func **brief** get h of AprilTag **return** return h of the AprilTag, type is int **static** False **C++ defination code**: ```cpp int h() ``` #### id ```python def id(self) > int ``` item doc **type** func **brief** get id of AprilTag **return** return id of the AprilTag, type is int **static** False **C++ defination code**: ```cpp int id() ``` #### family ```python def family(self) > int ``` item doc **type** func **brief** get family of AprilTag **return** return family of the AprilTag, type is int **static** False **C++ defination code**: ```cpp int family() ``` #### cx ```python def cx(self) > int ``` item doc **type** func **brief** get cx of AprilTag **return** return cx of the AprilTag, type is int **static** False **C++ defination code**: ```cpp int cx() ``` #### cxf ```python def cxf(self) > float ``` item doc **type** func **brief** get cxf of AprilTag **return** return cxf of the AprilTag, type is float **static** False **C++ defination code**: ```cpp float cxf() ``` #### cy ```python def cy(self) > int ``` item doc **type** func **brief** get cy of AprilTag **return** return cy of the AprilTag, type is int **static** False **C++ defination code**: ```cpp int cy() ``` #### cyf ```python def cyf(self) > float ``` item doc **type** func **brief** get cyf of AprilTag **return** return cyf of the AprilTag, type is float **static** False **C++ defination code**: ```cpp float cyf() ``` #### rotation ```python def rotation(self) > float ``` item doc **type** func **brief** get rotation of AprilTag **return** return rotation of the AprilTag, type is float **static** False **C++ defination code**: ```cpp float rotation() ``` #### decision\\_margin ```python def decision_margin(self) > float ``` item doc **type** func **brief** Get decision_margin of AprilTag **return** Returns the quality of the apriltag match (0.0 1.0) where 1.0 is the best. **static** False **C++ defination code**: ```cpp float decision_margin() ``` #### hamming ```python def hamming(self) > int ``` item doc **type** func **brief** get hamming of AprilTag **return** Returns the number of accepted bit errors for this tag.
    return 0, means 0 bit errors will be accepted.
    1 is TAG25H7, means up to 1 bit error may be accepted
    2 is TAG25H9, means up to 3 bit errors may be accepted
    3 is TAG36H10, means up to 3 bit errors may be accepted
    4 is TAG36H11, means up to 4 bit errors may be accepted
    5 is ARTOOLKIT, means 0 bit errors will be accepted **static** False **C++ defination code**: ```cpp int hamming() ``` #### goodness ```python def goodness(self) > float ``` item doc **type** func **brief** get goodness of AprilTag **return** return goodness of the AprilTag, type is float
    Note: This value is always 0.0 for now. **static** False **C++ defination code**: ```cpp float goodness() ``` #### x\\_translation ```python def x_translation(self) > float ``` item doc **type** func **brief** get x_translation of AprilTag **return** return x_translation of the AprilTag, type is float **static** False **C++ defination code**: ```cpp float x_translation() ``` #### y\\_translation ```python def y_translation(self) > float ``` item doc **type** func **brief** get y_translation of AprilTag **return** return y_translation of the AprilTag, type is float **static** False **C++ defination code**: ```cpp float y_translation() ``` #### z\\_translation ```python def z_translation(self) > float ``` item doc **type** func **brief** get z_translation of AprilTag **return** return z_translation of the AprilTag, type is float **static** False **C++ defination code**: ```cpp float z_translation() ``` #### x\\_rotation ```python def x_rotation(self) > float ``` item doc **type** func **brief** get x_rotation of AprilTag **return** return x_rotation of the AprilTag, type is float **static** False **C++ defination code**: ```cpp float x_rotation() ``` #### y\\_rotation ```python def y_rotation(self) > float ``` item doc **type** func **brief** get y_rotation of AprilTag **return** return y_rotation of the AprilTag, type is float **static** False **C++ defination code**: ```cpp float y_rotation() ``` #### z\\_rotation ```python def z_rotation(self) > float ``` item doc **type** func **brief** get z_rotation of AprilTag **return** return z_rotation of the AprilTag, type is float **static** False **C++ defination code**: ```cpp float z_rotation() ``` ### DataMatrix item doc **brief** DataMatrix class **C++ defination code**: ```cpp class DataMatrix ``` #### \\_\\_init\\_\\_ item doc **type** func **brief** DataMatrix constructor **param** **rect**: Inlucdes the top left corner and the width and height of the rectangle. format is {x, y, w, h}, type is std::vector
    **corners**: Includes the four corners of the rectangle. format is {{x0, y0}, {x1, y1}, {x2, y2}, {x3, y3}}, type is std::vector>
    **payload**: The payload of the DataMatrix
    **rotation**: The rotation of the DataMatrix
    **rows**: The rows of the DataMatrix
    **columns**: The columns of the DataMatrix
    **capacity**: The capacity of the DataMatrix
    **padding**: The padding of the DataMatrix
    **static** False **C++ defination code**: ```cpp DataMatrix(std::vector &rect, std::vector> &corners, std::string &payload, float rotation, int rows, int columns, int capacity, int padding) ``` #### \\_\\_getitem\\_\\_ item doc **type** func **brief** Subscript operator **param** **index [0]**: get x of DataMatrix
    [1] get y of DataMatrix
    [2] get w of DataMatrix
    [3] get h of DataMatrix
    [4] Not support this index, try to use payload() method
    [5] Not support this index, try to use rotation() method
    [6] get rows of DataMatrix
    [7] get columns of DataMatrix
    [8] get capacity of DataMatrix
    [9] get padding of DataMatrix
    **return** int& **static** False **C++ defination code**: ```cpp int &__getitem__(int index) ``` #### corners item doc **type** func **brief** get coordinate of DataMatrix **return** return the coordinate of the DataMatrix. **static** False **C++ defination code**: ```cpp std::vector> corners() ``` #### rect item doc **type** func **brief** get rectangle of DataMatrix **return** return the rectangle of the DataMatrix. format is {x, y, w, h}, type is std::vector **static** False **C++ defination code**: ```cpp std::vector rect() ``` #### x item doc **type** func **brief** get x of DataMatrix **return** return x of the DataMatrix, type is int **static** False **C++ defination code**: ```cpp int x() ``` #### y item doc **type** func **brief** get y of DataMatrix **return** return y of the DataMatrix, type is int **static** False **C++ defination code**: ```cpp int y() ``` #### w item doc **type** func **brief** get w of DataMatrix **return** return w of the DataMatrix, type is int **static** False **C++ defination code**: ```cpp int w() ``` #### h item doc **type** func **brief** get h of DataMatrix **return** return h of the DataMatrix, type is int **static** False **C++ defination code**: ```cpp int h() ``` #### payload item doc **type** func **brief** get payload of DataMatrix **return** return payload of the DataMatrix, type is std::string **static** False **C++ defination code**: ```cpp std::string payload() ``` #### rotation item doc **type** func **brief** get rotation of DataMatrix **return** return rotation of the DataMatrix, type is float **static** False **C++ defination code**: ```cpp float rotation() ``` #### rows item doc **type** func **brief** get rows of DataMatrix **return** return rows of the DataMatrix, type is int **static** False **C++ defination code**: ```cpp int rows() ``` #### columns item doc **type** func **brief** get columns of DataMatrix **return** return columns of the DataMatrix, type is int **static** False **C++ defination code**: ```cpp int columns() ``` #### capacity item doc **type** func **brief** get capacity of DataMatrix **return** returns how many characters could fit in this data matrix, type is int **static** False **C++ defination code**: ```cpp int capacity() ``` #### padding item doc **type** func **brief** get padding of DataMatrix **return** returns how many unused characters are in this data matrix, type is int **static** False **C++ defination code**: ```cpp int padding() ``` ### BarCode item doc **brief** BarCode class **C++ defination code**: ```cpp class BarCode ``` #### \\_\\_init\\_\\_ ```python def __init__(self, rect: list[int], corners: list[list[int]], payload: str, type: int, rotation: float, quality: int) > None ``` item doc **type** func **brief** BarCode constructor **param** **rect**: Inlucdes the top left corner and the width and height of the rectangle. format is {x, y, w, h}, type is std::vector
    **corners**: Includes the four corners of the rectangle. format is {{x0, y0}, {x1, y1}, {x2, y2}, {x3, y3}}, type is std::vector>
    **payload**: The payload of the BarCode
    **type**: The type of the BarCode
    **rotation**: The rotation of the BarCode
    **quality**: The quality of the BarCode
    **static** False **C++ defination code**: ```cpp BarCode(std::vector &rect, std::vector> &corners, std::string &payload, int type, float rotation, int quality) ``` #### \\_\\_getitem\\_\\_ ```python def __getitem__(self, index: int) > int ``` item doc **type** func **brief** Subscript operator **param** **index [0]**: get x of BarCode
    [1] get y of BarCode
    [2] get w of BarCode
    [3] get h of BarCode
    [4] Not support this index, try to use payload() method
    [5] get type of BarCode
    [6] Not support this index, try to use rotation() method
    [7] get quality of BarCode
    **return** int& **static** False **C++ defination code**: ```cpp int &__getitem__(int index) ``` #### corners ```python def corners(self) > list[list[int]] ``` item doc **type** func **brief** get coordinate of BarCode **return** return the coordinate of the BarCode. **static** False **C++ defination code**: ```cpp std::vector> corners() ``` #### rect ```python def rect(self) > list[int] ``` item doc **type** func **brief** get rectangle of BarCode **return** return the rectangle of the BarCode. format is {x, y, w, h}, type is std::vector **static** False **C++ defination code**: ```cpp std::vector rect() ``` #### x ```python def x(self) > int ``` item doc **type** func **brief** get x of BarCode **return** return x of the BarCode, type is int **static** False **C++ defination code**: ```cpp int x() ``` #### y ```python def y(self) > int ``` item doc **type** func **brief** get y of BarCode **return** return y of the BarCode, type is int **static** False **C++ defination code**: ```cpp int y() ``` #### w ```python def w(self) > int ``` item doc **type** func **brief** get w of BarCode **return** return w of the BarCode, type is int **static** False **C++ defination code**: ```cpp int w() ``` #### h ```python def h(self) > int ``` item doc **type** func **brief** get h of BarCode **return** return h of the BarCode, type is int **static** False **C++ defination code**: ```cpp int h() ``` #### payload ```python def payload(self) > str ``` item doc **type** func **brief** get payload of BarCode **return** return payload of the BarCode, type is std::string **static** False **C++ defination code**: ```cpp std::string payload() ``` #### type ```python def type(self) > int ``` item doc **type** func **brief** get type of BarCode **return** return type of the BarCode, type is int **static** False **C++ defination code**: ```cpp int type() ``` #### rotation ```python def rotation(self) > float ``` item doc **type** func **brief** get rotation of BarCode **return** return rotation of the BarCode, type is float. FIXME: always return 0.0 **static** False **C++ defination code**: ```cpp float rotation() ``` #### quality ```python def quality(self) > int ``` item doc **type** func **brief** get quality of BarCode **return** return quality of the BarCode, type is int **static** False **C++ defination code**: ```cpp int quality() ``` ### Statistics item doc **brief** Statistics class **C++ defination code**: ```cpp class Statistics ``` #### \\_\\_init\\_\\_ item doc **type** func **brief** Statistics constructor **param** **format**: The statistics source image format
    **l_statistics**: The statistics of the L channel. format is {mean, median, mode, std_dev, min, max, lq, uq}, type is std::vector
    **a_statistics**: The statistics of the A channel. format is {mean, median, mode, std_dev, min, max, lq, uq}, type is std::vector
    **b_statistics**: The statistics of the B channel. format is {mean, median, mode, std_dev, min, max, lq, uq}, type is std::vector
    **static** False **C++ defination code**: ```cpp Statistics(image::Format format, std::vector &l_statistics, std::vector &a_statistics, std::vector &b_statistics) ``` #### \\_\\_getitem\\_\\_ item doc **type** func **brief** Subscript operator **param** **index**: array index
    **return** int& **static** False **C++ defination code**: ```cpp int &__getitem__(int index) ``` #### format item doc **type** func **brief** get format of Statistics source image **return** return format of the Statistics source image, type is image::Format **static** False **C++ defination code**: ```cpp image::Format format() ``` #### l\\_mean item doc **type** func **brief** get L channel mean **return** return L channel mean, type is int **static** False **C++ defination code**: ```cpp int l_mean() ``` #### l\\_median item doc **type** func **brief** get L channel median **return** return L channel median, type is int **static** False **C++ defination code**: ```cpp int l_median() ``` #### l\\_mode item doc **type** func **brief** get L channel mode **return** return L channel mode, type is int **static** False **C++ defination code**: ```cpp int l_mode() ``` #### l\\_std\\_dev item doc **type** func **brief** get L channel std_dev **return** return L channel std_dev, type is int **static** False **C++ defination code**: ```cpp int l_std_dev() ``` #### l\\_min item doc **type** func **brief** get L channel min **return** return L channel min, type is int **static** False **C++ defination code**: ```cpp int l_min() ``` #### l\\_max item doc **type** func **brief** get L channel max **return** return L channel max, type is int **static** False **C++ defination code**: ```cpp int l_max() ``` #### l\\_lq item doc **type** func **brief** get L channel lq **return** return L channel lq, type is int **static** False **C++ defination code**: ```cpp int l_lq() ``` #### l\\_uq item doc **type** func **brief** get L channel uq **return** return L channel uq, type is int **static** False **C++ defination code**: ```cpp int l_uq() ``` #### a\\_mean item doc **type** func **brief** get A channel mean **return** return A channel mean, type is int **static** False **C++ defination code**: ```cpp int a_mean() ``` #### a\\_median item doc **type** func **brief** get A channea median **return** return A channel median, type is int **static** False **C++ defination code**: ```cpp int a_median() ``` #### a\\_mode item doc **type** func **brief** get A channel mode **return** return A channel mode, type is int **static** False **C++ defination code**: ```cpp int a_mode() ``` #### a\\_std\\_dev item doc **type** func **brief** get A channel std_dev **return** return A channel std_dev, type is int **static** False **C++ defination code**: ```cpp int a_std_dev() ``` #### a\\_min item doc **type** func **brief** get A channel min **return** return A channel min, type is int **static** False **C++ defination code**: ```cpp int a_min() ``` #### a\\_max item doc **type** func **brief** get A channel max **return** return A channel max, type is int **static** False **C++ defination code**: ```cpp int a_max() ``` #### a\\_lq item doc **type** func **brief** get A channel lq **return** return A channel lq, type is int **static** False **C++ defination code**: ```cpp int a_lq() ``` #### a\\_uq item doc **type** func **brief** get A channel uq **return** return A channel uq, type is int **static** False **C++ defination code**: ```cpp int a_uq() ``` #### b\\_mean item doc **type** func **brief** get B channel mean **return** return B channel mean, type is int **static** False **C++ defination code**: ```cpp int b_mean() ``` #### b\\_median item doc **type** func **brief** get B channea median **return** return B channel median, type is int **static** False **C++ defination code**: ```cpp int b_median() ``` #### b\\_mode item doc **type** func **brief** get B channel mode **return** return B channel mode, type is int **static** False **C++ defination code**: ```cpp int b_mode() ``` #### b\\_std\\_dev item doc **type** func **brief** get B channel std_dev **return** return B channel std_dev, type is int **static** False **C++ defination code**: ```cpp int b_std_dev() ``` #### b\\_min item doc **type** func **brief** get B channel min **return** return B channel min, type is int **static** False **C++ defination code**: ```cpp int b_min() ``` #### b\\_max item doc **type** func **brief** get B channel max **return** return B channel max, type is int **static** False **C++ defination code**: ```cpp int b_max() ``` #### b\\_lq item doc **type** func **brief** get B channel lq **return** return B channel lq, type is int **static** False **C++ defination code**: ```cpp int b_lq() ``` #### b\\_uq item doc **type** func **brief** get B channel uq **return** return B channel uq, type is int **static** False **C++ defination code**: ```cpp int b_uq() ``` ### Displacement item doc **brief** Displacement class **C++ defination code**: ```cpp class Displacement ``` #### \\_\\_init\\_\\_ ```python def __init__(self, x_translation: float, y_translation: float, rotation: float, scale: float, response: float) > None ``` item doc **type** func **brief** Displacement constructor **param** **x_translation**: The x_translation of the Displacement
    **y_translation**: The y_translation of the Displacement
    **rotation**: The rotation of the Displacement
    **scale**: The scale of the Displacement
    **response**: The response of the Displacement
    **static** False **C++ defination code**: ```cpp Displacement(float x_translation, float y_translation, float rotation, float scale, float response) ``` #### \\_\\_getitem\\_\\_ ```python def __getitem__(self, index: int) > int ``` item doc **type** func **brief** Subscript operator **param** **index**: array index
    **return** int& **static** False **C++ defination code**: ```cpp int &__getitem__(int index) ``` #### x\\_translation ```python def x_translation(self) > float ``` item doc **type** func **brief** get x_translation of Displacement **return** return x_translation of the Displacement, type is float **static** False **C++ defination code**: ```cpp float x_translation() ``` #### y\\_translation ```python def y_translation(self) > float ``` item doc **type** func **brief** get y_translation of Displacement **return** return y_translation of the Displacement, type is float **static** False **C++ defination code**: ```cpp float y_translation() ``` #### rotation ```python def rotation(self) > float ``` item doc **type** func **brief** get rotation of Displacement **return** return rotation of the Displacement, type is float **static** False **C++ defination code**: ```cpp float rotation() ``` #### scale ```python def scale(self) > float ``` item doc **type** func **brief** get scale of Displacement **return** return scale of the Displacement, type is float **static** False **C++ defination code**: ```cpp float scale() ``` #### response ```python def response(self) > float ``` item doc **type** func **brief** get response of Displacement **return** return response of the Displacement, type is float **static** False **C++ defination code**: ```cpp float response() ``` ### LBPKeyPoint item doc **brief** LBPKeyPoint class **C++ defination code**: ```cpp class LBPKeyPoint ``` #### \\_\\_init\\_\\_ ```python def __init__(self, data: list[int]) > None ``` item doc **type** func **brief** LBPKeyPoint constructor **param** **data**: The data of the LBPKeyPoint
    **static** False **C++ defination code**: ```cpp LBPKeyPoint(std::valarray &data) ``` ### KeyPoint item doc **brief** KeyPoint class **C++ defination code**: ```cpp class KeyPoint ``` #### \\_\\_init\\_\\_ item doc **type** func **brief** KeyPoint constructor **param** **x**: The x of the KeyPoint
    **y**: The y of the KeyPoint
    **score**: The score of the KeyPoint
    **octave**: The octave of the KeyPoint
    **angle**: The angle of the KeyPoint
    **matched**: The matched of the KeyPoint
    **desc**: The desc of the KeyPoint
    **static** False **C++ defination code**: ```cpp KeyPoint(uint16_t x, uint16_t y, uint16_t score, uint16_t octave, uint16_t angle, uint16_t matched, std::vector &desc) ``` ### KPTMatch item doc **brief** KPTMatch class **C++ defination code**: ```cpp class KPTMatch ``` #### \\_\\_init\\_\\_ ```python def __init__(self, cx: int, cy: int, x: int, y: int, w: int, h: int, score: int, theta: int, match: int) > None ``` item doc **type** func **brief** KPTMatch constructor **param** **cx**: The cx of the KPTMatch
    **cy**: The cy of the KPTMatch
    **x**: The x of the KPTMatch
    **y**: The y of the KPTMatch
    **w**: The w of the KPTMatch
    **h**: The h of the KPTMatch
    **score**: The score of the KPTMatch
    **theta**: The theta of the KPTMatch
    **match**: The match of the KPTMatch
    **static** False **C++ defination code**: ```cpp KPTMatch(int cx, int cy, int x, int y, int w, int h, int score, int theta, int match) ``` ### ORBKeyPoint item doc **brief** ORBKeyPoint class **C++ defination code**: ```cpp class ORBKeyPoint ``` #### \\_\\_init\\_\\_ ```python def __init__(self, data: list[KeyPoint], threshold: int, normalized: bool) > None ``` item doc **type** func **brief** ORBKeyPoint constructor **param** **data**: The data of the ORBKeyPoint
    **threshold**: The threshold of the ORBKeyPoint
    **normalized**: The normalized of the ORBKeyPoint
    **static** False **C++ defination code**: ```cpp ORBKeyPoint(std::vector &data, int threshold, bool normalized) ``` #### get\\_data ```python def get_data(self) > list[KeyPoint] ``` item doc **type** func **brief** get data of ORBKeyPoint **return** return data of the ORBKeyPoint, type is std::vector **static** False **C++ defination code**: ```cpp std::vector get_data() ``` ### HaarCascade item doc **brief** HaarCascade class **C++ defination code**: ```cpp class HaarCascade ``` #### \\_\\_init\\_\\_ ```python def __init__(self) > None ``` item doc **type** func **brief** HaarCascade constructor **param** **data**: The data of the HaarCascade
    **threshold**: The threshold of the HaarCascade
    **normalized**: The normalized of the HaarCascade
    **static** False **C++ defination code**: ```cpp HaarCascade() ``` ### Color item doc **brief** Color class **C++ defination code**: ```cpp class Color ``` #### \\_\\_init\\_\\_ item doc **type** func **brief** Color constructor **param** **alpha**: alpha channel, value range: 0 ~ 1
    **static** False **C++ defination code**: ```cpp Color(uint8_t ch1, uint8_t ch2 0, uint8_t ch3 0, float alpha 0, image::Format format image::FMT_GRAYSCALE) ``` #### r item doc **type** var **brief** Color red channel **static** False **readonly** False **C++ defination code**: ```cpp uint8_t r ``` #### g item doc **type** var **brief** Color green channel **static** False **readonly** False **C++ defination code**: ```cpp uint8_t g ``` #### b item doc **type** var **brief** Color blue channel **static** False **readonly** False **C++ defination code**: ```cpp uint8_t b ``` #### alpha item doc **type** var **brief** Color alpha channel, value from 0.0 to 1.0, float value **static** False **readonly** False **C++ defination code**: ```cpp float alpha ``` #### gray item doc **type** var **brief** Color gray channel **static** False **readonly** False **C++ defination code**: ```cpp uint8_t gray ``` #### format item doc **type** var **brief** Color format **static** False **readonly** False **C++ defination code**: ```cpp image::Format format ``` #### hex item doc **type** func **brief** Get color's hex value **static** False **C++ defination code**: ```cpp uint32_t hex() ``` #### from\\_rgb item doc **type** func **brief** Create Color object from RGB channels **static** True **C++ defination code**: ```cpp static image::Color from_rgb(uint8_t r, uint8_t g, uint8_t b) ``` #### from\\_bgr item doc **type** func **brief** Create Color object from BGR channels **static** True **C++ defination code**: ```cpp static image::Color from_bgr(uint8_t b, uint8_t g, uint8_t r) ``` #### from\\_gray item doc **type** func **brief** Create Color object from gray channel **static** True **C++ defination code**: ```cpp static image::Color from_gray(uint8_t gray) ``` #### from\\_rgba item doc **type** func **brief** Create Color object from RGBA channels **param** **alpha**: alpha channel, float value, value range: 0 ~ 1
    **static** True **C++ defination code**: ```cpp static image::Color from_rgba(uint8_t r, uint8_t g, uint8_t b, float alpha) ``` #### from\\_bgra item doc **type** func **brief** Create Color object from BGRA channels **param** **alpha**: alpha channel, float value, value range: 0 ~ 1
    **static** True **C++ defination code**: ```cpp static image::Color from_bgra(uint8_t b, uint8_t g, uint8_t r, float alpha) ``` #### from\\_hex item doc **type** func **brief** Create Color object from hex value **param** **hex**: hex value, e.g. 0x0000FF00, lower address if first channel
    **format**: color format, @see image::Format
    **static** True **C++ defination code**: ```cpp static image::Color from_hex(uint32_t hex, image::Format &format) ``` #### to\\_format item doc **type** func **brief** Convert Color format **param** **format**: format want to convert to, @see image::Format, only support RGB888, BGR888, RGBA8888, BGRA8888, GRAYSCALE.
    **static** False **C++ defination code**: ```cpp void to_format(const image::Format &format) ``` #### to\\_format2 item doc **type** func **brief** Convert color format and return a new Color object **param** **format**: format want to convert to, @see image::Format, only support RGB888, BGR888, RGBA8888, BGRA8888, GRAYSCALE.
    **return** new Color object, you need to delete it manually in C++. **static** False **C++ defination code**: ```cpp image::Color *to_format2(const image::Format &format) ``` ### Image item doc **brief** Image class **C++ defination code**: ```cpp class Image ``` #### \\_\\_init\\_\\_ item doc **type** func **brief** Image constructor **param** **width**: image width, should > 0
    **height**: image height, should > 0
    **format**: image format @see image::Format
    **static** False **C++ defination code**: ```cpp Image(int width, int height, image::Format format image::Format::FMT_RGB888) ``` #### format item doc **type** func **brief** Get image's format **see** image.Format **static** False **C++ defination code**: ```cpp image::Format format() ``` #### size item doc **type** func **brief** Get image's size, [width, height] **static** False **C++ defination code**: ```cpp image::Size size() ``` #### data\\_size item doc **type** func **brief** Get image's data size **static** False **C++ defination code**: ```cpp int data_size() ``` #### width item doc **type** func **brief** Get image's width **static** False **C++ defination code**: ```cpp int width() ``` #### height item doc **type** func **brief** Get image's height **static** False **C++ defination code**: ```cpp int height() ``` #### data item doc **type** func **brief** Get image's data pointer.\\nIn MaixPy is capsule object. **static** False **C++ defination code**: ```cpp void *data() ``` #### \\_\\_str\\_\\_ item doc **type** func **brief** To string method **static** False **C++ defination code**: ```cpp std::string __str__() ``` #### to\\_str item doc **type** func **brief** To string method **static** False **C++ defination code**: ```cpp std::string to_str() ``` #### get\\_pixel item doc **type** func **brief** Get pixel of image **param** **x**: pixel's coordinate x. x must less than image's width
    **y**: pixel's coordinate y. y must less than image's height
    **rgbtuple**: switch return value method. rgbtuple decides whether to split the return or not. default is false.
    **return** pixel value,
    According to image format and rgbtuple, return different value:
    format is FMT_RGB888, rgbtuple is true, return [R, G, B]; rgbtuple is false, return [RGB]
    foramt is FMT_BGR888, rgbtuple is true, return [B, G, R]; rgbtuple is false, return [BGR]
    format is FMT_GRAYSCALE, return [GRAY]; **static** False **C++ defination code**: ```cpp std::vector get_pixel(int x, int y, bool rgbtuple false) ``` #### set\\_pixel item doc **type** func **brief** Set pixel of image **param** **x**: pixel's coordinate x. x must less than image's width
    **y**: pixel's coordinate y. y must less than image's height
    **pixel**: pixel value, according to image format and size of pixel, has different operation:
    format is FMT_RGB888, pixel size must be 1 or 3, if size is 1, will split pixel[0] to [R, G, B]; if size is 3, will use pixel directly
    format is FMT_BGR888, pixel size must be 1 or 3, if size is 1, will split pixel[0] to [B, G, R]; if size is 3, will use pixel directly
    format is FMT_GRAYSCALE, pixel size must be 1, will use pixel directly
    **return** error code, Err::ERR_NONE is ok, other is error **static** False **C++ defination code**: ```cpp err::Err set_pixel(int x, int y, std::vector pixel) ``` #### to\\_tensor item doc **type** func **brief** Convert Image object to tensor::Tensor object **param** **chw**: if true, the shape of tensor is [C, H, W], else [H, W, C]
    **copy**: if true, will alloc memory for tensor data, else will use the memory of Image object
    **return** tensor::Tensor object pointer, an allocated tensor object **static** False **C++ defination code**: ```cpp tensor::Tensor *to_tensor(bool chw false, bool copy true) ``` #### to\\_bytes item doc **type** func **brief** Get image's data and convert to array bytes **param** **copy**: if true, will alloc memory and copy data to new buffer,
    else will use the memory of Image object, delete bytes object will not affect Image object,
    but delete Image object will make bytes object invalid, it may cause program crash !!!!
    So use this param carefully.
    **return** image's data bytes, need be delete by caller in C++. **static** False **C++ defination code**: ```cpp Bytes *to_bytes(bool copy true) ``` #### to\\_format item doc **type** func **brief** Convert image to specific format **param** **format**: format want to convert to, @see image::Format, only support RGB888, BGR888, RGBA8888, BGRA8888, GRAYSCALE, JPEG.
    **return** new image object. Need be delete by caller in C++. **throw** err.Exception, if two images' format not support, **or already the format**, will raise exception **static** False **C++ defination code**: ```cpp image::Image *to_format(const image::Format &format) ``` #### to\\_jpeg item doc **type** func **brief** Convert image to jpeg **param** **quality**: the quality of jpg, default is 95. range is (50, 100].
    **return** new image object. Need be delete by caller in C++. **throw** err.Exception, if two images' format not support, **or already the format**, will raise exception **static** False **C++ defination code**: ```cpp image::Image *to_jpeg(int quality 95) ``` #### draw\\_image item doc **type** func **brief** Draw image on this image **param** **x**: left top corner of image point's coordinate x
    **y**: left top corner of image point's coordinate y
    **img**: image object to draw, the caller's channel must < the args' channel,
    e.g. caller is RGB888, args is RGBA8888, will throw exception, but caller is RGBA8888, args is RGB888 or RGBA8888 is ok
    **return** this image object self **static** False **C++ defination code**: ```cpp image::Image *draw_image(int x, int y, image::Image &img) ``` #### draw\\_rect item doc **type** func **brief** Fill rectangle color to image **param** **x**: left top corner of rectangle point's coordinate x
    **y**: left top corner of rectangle point's coordinate y
    **w**: rectangle width
    **h**: rectangle height
    **color**: rectangle color
    **thickness**: rectangle thickness(line width), by default(value is 1), 1 means fill rectangle
    **return** this image object self **static** False **C++ defination code**: ```cpp image::Image *draw_rect(int x, int y, int w, int h, const image::Color &color, int thickness 1) ``` #### draw\\_line item doc **type** func **brief** Draw line on image **param** **x1**: start point's coordinate x
    **y1**: start point's coordinate y
    **x2**: end point's coordinate x
    **y2**: end point's coordinate y
    **color**: line color @see image::Color
    **thickness**: line thickness(line width), by default(value is 1)
    **return** this image object self **static** False **C++ defination code**: ```cpp image::Image *draw_line(int x1, int y1, int x2, int y2, const image::Color &color, int thickness 1) ``` #### draw\\_circle item doc **type** func **brief** Draw circle on image **param** **x**: circle center point's coordinate x
    **y**: circle center point's coordinate y
    **radius**: circle radius
    **color**: circle color @see image::Color
    **thickness**: circle thickness(line width), by default(value is 1), 1 means fill circle
    **return** this image object self **static** False **C++ defination code**: ```cpp image::Image *draw_circle(int x, int y, int radius, const image::Color &color, int thickness 1) ``` #### draw\\_ellipse item doc **type** func **brief** Draw ellipse on image **param** **x**: ellipse center point's coordinate x
    **y**: ellipse center point's coordinate y
    **a**: ellipse major axis length
    **b**: ellipse minor axis length
    **angle**: ellipse rotation angle
    **start_angle**: ellipse start angle
    **end_angle**: ellipse end angle
    **color**: ellipse color @see image::Color
    **thickness**: ellipse thickness(line width), by default(value is 1), 1 means fill ellipse
    **return** this image object self **static** False **C++ defination code**: ```cpp image::Image *draw_ellipse(int x, int y, int a, int b, float angle, float start_angle, float end_angle, const image::Color &color, int thickness 1) ``` #### draw\\_string item doc **type** func **brief** Draw text on image **param** **x**: text left top point's coordinate x
    **y**: text left top point's coordinate y
    **string**: text content
    **color**: text color @see image::Color, default is white
    **scale**: font scale, by default(value is 1)
    **thickness**: text thickness(line width), if negative, the glyph is filled, by default(value is 1)
    **wrap**: if true, will auto wrap text to next line if text width > image width, by default(value is true)
    **return** this image object self **static** False **C++ defination code**: ```cpp image::Image *draw_string(int x, int y, const std::string &textstring, const image::Color &color image::COLOR_WHITE, float scale 1, int thickness 1, bool wrap true, int wrap_space 4, const std::string &font \"\") ``` #### draw\\_cross item doc **type** func **brief** Draw cross on image **param** **x**: cross center point's coordinate x
    **y**: cross center point's coordinate y
    **color**: cross color @see image::Color
    **size**: how long the lines of the cross extend, by default(value is 5). So the line length is `2 * size + thickness`
    **thickness**: cross thickness(line width), by default(value is 1)
    **static** False **C++ defination code**: ```cpp image::Image *draw_cross(int x, int y, const image::Color &color, int size 5, int thickness 1) ``` #### draw\\_arrow item doc **type** func **brief** Draw arrow on image **param** **x0**: start coordinate of the arrow x0
    **y0**: start coordinate of the arrow y0
    **x1**: end coordinate of the arrow x1
    **y1**: end coordinate of the arrow y1
    **color**: cross color @see image::Color
    **thickness**: cross thickness(line width), by default(value is 1)
    **return** this image object self **static** False **C++ defination code**: ```cpp image::Image *draw_arrow(int x0, int y0, int x1, int y1, const image::Color &color, int thickness 1) ``` #### draw\\_edges item doc **type** func **brief** Draw edges on image **param** **corners**: edges, [[x0, y0], [x1, y1], [x2, y2], [x3, y3]]
    **color**: edges color @see image::Color
    **size**: the circle of radius size. TODO: support in the feature
    **thickness**: edges thickness(line width), by default(value is 1)
    **fill**: if true, will fill edges, by default(value is false)
    **return** this image object self **static** False **C++ defination code**: ```cpp image::Image *draw_edges(std::vector> corners, const image::Color &color, int size 0, int thickness 1, bool fill false) ``` #### draw\\_keypoints item doc **type** func **brief** Draw keypoints on image **param** **keypoints**: keypoints, [x, y, rotation_andle_in_degrees], TODO: rotation_andle_in_degrees support in the feature
    **color**: keypoints color @see image::Color
    **size**: size of keypoints
    **thickness**: keypoints thickness(line width), by default(value is 1)
    **fill**: if true, will fill keypoints, by default(value is false)
    **return** this image object self **static** False **C++ defination code**: ```cpp image::Image *draw_keypoints(std::vector keypoints, const image::Color &color, int size 10, int thickness 1, bool fill false) ``` #### resize item doc **type** func **brief** Resize image, will create a new resized image object **param** **width**: new width, if value is 1, will use height to calculate aspect ratio
    **height**: new height, if value is 1, will use width to calculate aspect ratio
    **object_fit**: fill, contain, cover, by default is fill
    **method**: resize method, by default is bilinear
    **return** Always return a new resized image object even size not change, So in C++ you should take care of the return value to avoid memory leak.
    And it's better to judge whether the size has changed before calling this function to make the program more efficient.
    e.g.
    if img >width() ! width img >height() ! height:
    img img >resize(width, height); **static** False **C++ defination code**: ```cpp image::Image *resize(int width, int height, image::Fit object_fit image::Fit::FIT_FILL, image::ResizeMethod method image::ResizeMethod::NEAREST) ``` #### affine item doc **type** func **brief** Affine transform image, will create a new transformed image object **param** **src_points**: three source points, [x1, y1, x2, y2, x3, y3]
    **dst_points**: three destination points, [x1, y1, x2, y2, x3, y3]
    **width**: new width, if value is 1, will use height to calculate aspect ratio
    **height**: new height, if value is 1, will use width to calculate aspect ratio
    **method**: resize method, by default is bilinear
    **return** new transformed image object **static** False **C++ defination code**: ```cpp image::Image *affine(std::vector src_points, std::vector dst_points, int width 1, int height 1, image::ResizeMethod method image::ResizeMethod::BILINEAR) ``` #### copy item doc **type** func **brief** Copy image, will create a new copied image object **return** new copied image object **static** False **C++ defination code**: ```cpp image::Image *copy() ``` #### crop item doc **type** func **brief** Crop image, will create a new cropped image object **param** **x**: left top corner of crop rectangle point's coordinate x
    **y**: left top corner of crop rectangle point's coordinate y
    **w**: crop rectangle width
    **h**: crop rectangle height
    **return** new cropped image object **static** False **C++ defination code**: ```cpp image::Image *crop(int x, int y, int w, int h) ``` #### rotate item doc **type** func **brief** Rotate image, will create a new rotated image object **param** **angle**: anti clock wise rotate angle, if angle is 90 or 270, and width or height is 1, will swap width and height, or will throw exception
    **width**: new width, if value is 1, will use height to calculate aspect ratio
    **height**: new height, if value is 1, will use width to calculate aspect ratio
    **method**: resize method, by default is bilinear
    **return** new rotated image object **static** False **C++ defination code**: ```cpp image::Image *rotate(float angle, int width 1, int height 1, image::ResizeMethod method image::ResizeMethod::BILINEAR) ``` #### mean\\_pool item doc **type** func **brief** Finds the mean of x_div * y_div squares in the image and returns the modified image composed of the mean of each square. **param** **x_div**: The width of the squares.
    **y_div**: The height of the squares.
    **copy**: Select whether to return a new image or modify the original image. default is false.
    If true, returns a new image composed of the mean of each square; If false, returns the modified image composed of the mean of each square.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *mean_pool(int x_div, int y_div, bool copy false) ``` #### midpoint\\_pool item doc **type** func **brief** Finds the midpoint of x_div * y_div squares in the image and returns the modified image composed of the mean of each square. **param** **x_div**: The width of the squares.
    **y_div**: The height of the squares.
    **bias**: The bias of the midpoint. default is 0.5.
    midpoint value is equal to (max * bias + min * (1 bias))
    **copy**: Select whether to return a new image or modify the original image. default is false.
    If true, returns a new image composed of the midpoint of each square; If false, returns the modified image composed of the midpoint of each square.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *midpoint_pool(int x_div, int y_div, double bias 0.5, bool copy false) ``` #### compress item doc **type** func **brief** JPEG compresses the image in place, the same as to_jpeg functioin, it's recommend to use to_jpeg instead. **param** **quality**: The quality of the compressed image. default is 95.
    **return** Returns the compressed JPEG image **static** False **C++ defination code**: ```cpp image::Image *compress(int quality 95) ``` #### clear item doc **type** func **brief** Sets all pixels in the image to zero **param** **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *clear(image::Image *mask nullptr) ``` #### mask\\_rectange item doc **type** func **brief** Zeros a rectangular part of the image. If no arguments are supplied this method zeros the center of the image. **param** **x**: The x coordinate of the top left corner of the rectangle.
    **y**: The y coordinate of the top left corner of the rectangle.
    **w**: The width of the rectangle.
    **h**: The height of the rectangle.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *mask_rectange(int x 1, int y 1, int w 1, int h 1) ``` #### mask\\_circle item doc **type** func **brief** Zeros a circular part of the image. If no arguments are supplied this method zeros the center of the image. **param** **x**: The x coordinate of the center of the circle.
    **y**: The y coordinate of the center of the circle.
    **radius**: The radius of the circle.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *mask_circle(int x 1, int y 1, int radius 1) ``` #### mask\\_ellipse item doc **type** func **brief** Zeros a ellipse part of the image. If no arguments are supplied this method zeros the center of the image. **param** **x**: The x coordinate of the center of the ellipse.
    **y**: The y coordinate of the center of the ellipse.
    **radius_x**: The radius of the ellipse in the x direction.
    **radius_y**: The radius of the ellipse in the y direction.
    **rotation_angle_in_degrees**: The rotation angle of the ellipse in degrees.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *mask_ellipse(int x 1, int y 1, int radius_x 1, int radius_y 1, float rotation_angle_in_degrees 0) ``` #### binary item doc **type** func **brief** Sets all pixels in the image to black or white depending on if the pixel is inside of a threshold in the threshold list thresholds or not. **param** **thresholds**: You can define multiple thresholds.
    For GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.
    For RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.
    Where the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.
    **invert**: If true, the thresholds will be inverted before the operation. default is false.
    **zero**: If zero is true, the image will be set the pixels within the threshold to 0, other pixels remain unchanged. If zero is false, the image will be set to black or white. default is false.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **to_bitmap**: If true, the image will be converted to a bitmap image before thresholding. default is false. TODO: support in the feature
    **copy**: Select whether to return a new image or modify the original image. default is false.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *binary(std::vector> thresholds std::vector>(), bool invert false, bool zero false, image::Image *mask nullptr, bool to_bitmap false, bool copy false) ``` #### invert item doc **type** func **brief** Inverts the image in place. **return** Returns the image after the operation is completed **static** False **C++ defination code**: ```cpp image::Image *invert() ``` #### b\\_and item doc **type** func **brief** Performs a bitwise and operation between the image and the other image. **param** **other**: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *b_and(image::Image *other, image::Image *mask nullptr) ``` #### b\\_nand item doc **type** func **brief** Performs a bitwise nand operation between the image and the other image. **param** **other**: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *b_nand(image::Image *other, image::Image *mask nullptr) ``` #### b\\_or item doc **type** func **brief** Performs a bitwise or operation between the image and the other image. **param** **other**: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *b_or(image::Image *other, image::Image *mask nullptr) ``` #### b\\_nor item doc **type** func **brief** Performs a bitwise nor operation between the image and the other image. **param** **other**: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *b_nor(image::Image *other, image::Image *mask nullptr) ``` #### b\\_xor item doc **type** func **brief** Performs a bitwise xor operation between the image and the other image. **param** **other**: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *b_xor(image::Image *other, image::Image *mask nullptr) ``` #### b\\_xnor item doc **type** func **brief** Performs a bitwise xnor operation between the image and the other image. **param** **other**: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *b_xnor(image::Image *other, image::Image *mask nullptr) ``` #### awb item doc **type** func **brief** Performs an auto white balance operation on the image. TODO: support in the feature **param** **max**: if True uses the white patch algorithm instead. default is false.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *awb(bool max false) ``` #### ccm item doc **type** func **brief** Multiples the passed (3x3) or (4x3) floating point color correction matrix with the image.\\nnote: Grayscale format is not support. **param** **matrix**: The color correction matrix to use. 3x3 or 4x3 matrix.
    Weights may either be positive or negative, and the sum of each column in the 3x3 matrix should generally be 1.
    example:
    {
    1, 0, 0,
    0, 1, 0,
    0, 0, 1,
    }
    Where the last row of the 4x3 matrix is an offset per color channel. If you add an offset you may wish to make the
    weights sum to less than 1 to account for the offset.
    example:
    {
    1, 0, 0,
    0, 1, 0,
    0, 0, 1,
    0, 0, 0,
    }
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *ccm(std::vector &matrix) ``` #### gamma item doc **type** func **brief** Quickly changes the image gamma, contrast, and brightness. Create a array whose size is usually 255,\\nand use the parameters gamma, contrast, and brightness to calculate the value of the array, and then map the\\nimage pixel value through the value of the array.\\nThe calculation method for array is: array[array_idx] (powf((array_idx / 255.0), (1 / gamma)) * contrast + brightness) * scale,\\n`powf` is a function used to calculate floating point power.\\n`array` is the array used for mapping.\\n`array_idx` is the index of the array, the maximum value is determined according to the image format, usually 255.\\n`scale` is a constant, the value is determined by the image format, usually 255.\\nMapping method:\\nAssume that a pixel value in the image is 128, then map the pixel value to the value of array[128]\\nUsers can adjust the value of the array through the gamma, contrast, and brightness parameters. **param** **gamma**: The contrast gamma greater than 1.0 makes the image darker in a non linear manner while less than 1.0 makes the image brighter. default is 1.0.
    **contrast**: The contrast value greater than 1.0 makes the image brighter in a linear manner while less than 1.0 makes the image darker. default is 1.0.
    **brightness**: The brightness value greater than 0.0 makes the image brighter in a constant manner while less than 0.0 makes the image darker. default is 0.0.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *gamma(double gamma 1.0, double contrast 1.0, double brightness 0.0) ``` #### gamma\\_corr item doc **type** func **brief** Alias for Image.gamma. **param** **gamma**: The contrast gamma greater than 1.0 makes the image darker in a non linear manner while less than 1.0 makes the image brighter. default is 1.0.
    **contrast**: The contrast value greater than 1.0 makes the image brighter in a linear manner while less than 1.0 makes the image darker. default is 1.0.
    **brightness**: The brightness value greater than 0.0 makes the image brighter in a constant manner while less than 0.0 makes the image darker. default is 0.0.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *gamma_corr(double gamma, double contrast 1.0, double brightness 0.0) ``` #### negate item doc **type** func **brief** Flips (numerically inverts) all pixels values in an image **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *negate() ``` #### replace item doc **type** func **brief** Replaces all pixels in the image with the corresponding pixels in the other image. **param** **other**: The other image should be an image and should be the same size as the image being operated on.
    **hmirror**: If true, the image will be horizontally mirrored before the operation. default is false.
    **vflip**: If true, the image will be vertically flipped before the operation. default is false.
    **transpose**: If true, the image can be used to rotate 90 degrees or 270 degrees.
    hmirror false, vflip false, transpose false, the image will not be rotated.
    hmirror false, vflip true, transpose true, the image will be rotated 90 degrees.
    hmirror true, vflip true, transpose false, the image will be rotated 180 degrees.
    hmirror true, vflip false, transpose true, the image will be rotated 270 degrees.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *replace(image::Image *other nullptr, bool hmirror false, bool vflip false, bool transpose false, image::Image *mask nullptr) ``` #### set item doc **type** func **brief** Alias for Image::replace. **param** **other**: The other image should be an image and should be the same size as the image being operated on.
    **hmirror**: If true, the image will be horizontally mirrored before the operation. default is false.
    **vflip**: If true, the image will be vertically flipped before the operation. default is false.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *set(image::Image *other, bool hmirror false, bool vflip false, bool transpose false, image::Image *mask nullptr) ``` #### add item doc **type** func **brief** Adds the other image to the image. **param** **other**: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *add(image::Image *other, image::Image *mask nullptr) ``` #### sub item doc **type** func **brief** Subtracts the other image from the image. **param** **other**: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
    **reverse**: If true, the image will be reversed before the operation. default is false.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *sub(image::Image *other, bool reverse false, image::Image *mask nullptr) ``` #### mul item doc **type** func **brief** Multiplies the image by the other image.\\nNote: This method is meant for image blending and cannot multiply the pixels in the image by a scalar like 2. **param** **other**: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
    **invert**: If true, the image will be change the multiplication operation from a*b to 1/((1/a)*(1/b)).
    In particular, this lightens the image instead of darkening it (e.g. multiply versus burn operations). default is false.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *mul(image::Image *other, bool invert false, image::Image *mask nullptr) ``` #### div item doc **type** func **brief** Divides the image by the other image.\\nThis method is meant for image blending and cannot divide the pixels in the image by a scalar like 2. **param** **other**: The other image should be an image and should be the same size as the image being operated on. TODO: support path?
    **invert**: If true, the image will be change the division direction from a/b to b/a. default is false.
    **mod**: If true, the image will be change the division operation to the modulus operation. default is false.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *div(image::Image *other, bool invert false, bool mod false, image::Image *mask nullptr) ``` #### min item doc **type** func **brief** Caculate the minimum of each pixel in the image and the other image. **param** **other**: The other image should be an image and should be the same size as the image being operated on.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *min(image::Image *other, image::Image *mask nullptr) ``` #### max item doc **type** func **brief** Caculate the maximum of each pixel in the image and the other image. **param** **other**: The other image should be an image and should be the same size as the image being operated on.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *max(image::Image *other, image::Image *mask nullptr) ``` #### difference item doc **type** func **brief** Caculate the absolute value of the difference between each pixel in the image and the other image. **param** **other**: The other image should be an image and should be the same size as the image being operated on.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *difference(image::Image *other, image::Image *mask nullptr) ``` #### blend item doc **type** func **brief** Blends the image with the other image.\\nres alpha * this_img / 256 + (256 alpha) * other_img / 256 **param** **other**: The other image should be an image and should be the same size as the image being operated on.
    **alpha**: The alpha value of the blend, the value range is [0, 256],default is 128.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *blend(image::Image *other, int alpha 128, image::Image *mask nullptr) ``` #### histeq item doc **type** func **brief** Runs the histogram equalization algorithm on the image. **param** **adaptive**: If true, an adaptive histogram equalization method will be run on the image instead which as generally better results than non adaptive histogram qualization but a longer run time. default is false.
    **clip_limit**: Provides a way to limit the contrast of the adaptive histogram qualization. Use a small value for this, like 10, to produce good histogram equalized contrast limited images. default is 1.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *histeq(bool adaptive false, int clip_limit 1, image::Image *mask nullptr) ``` #### mean item doc **type** func **brief** Standard mean blurring filter using a box filter.\\nThe parameters offset and invert are valid when threshold is True. **param** **size**: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
    **threshold**: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel’s brightness in relation to the brightness of the kernel of pixels around them.
    default is false.
    **offset**: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.
    **invert**: If true, the image will be inverted before the operation. default is false.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *mean(int size, bool threshold false, int offset 0, bool invert false, image::Image *mask nullptr) ``` #### median item doc **type** func **brief** Runs the median filter on the image. The median filter is the best filter for smoothing surfaces while preserving edges but it is very slow. **param** **size**: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
    **percentile**: This parameter controls the percentile of the value used in the kernel. You can set this to 0 for a min filter, 0.25 for a lower quartile filter, 0.75 for an upper quartile filter, and 1.0 for a max filter. default is 0.5.
    **threshold**: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel’s brightness in relation to the brightness of the kernel of pixels around them.
    default is false.
    **offset**: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.
    **invert**: If true, the image will be inverted before the operation. default is false.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *median(int size, double percentile 0.5, bool threshold false, int offset 0, bool invert false, image::Image *mask nullptr) ``` #### mode item doc **type** func **brief** Runs the mode filter on the image by replacing each pixel with the mode of their neighbors. **param** **size**: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
    **threshold**: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel’s brightness in relation to the brightness of the kernel of pixels around them.
    default is false.
    **offset**: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.
    **invert**: If true, the image will be inverted before the operation. default is false.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *mode(int size, bool threshold false, int offset 0, bool invert false, image::Image *mask nullptr) ``` #### midpoint item doc **type** func **brief** Runs the midpoint filter on the image.This filter finds the midpoint (max * bias + min * (1 bias)) of each pixel neighborhood in the image. **param** **size**: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
    **bias**: The bias of the midpoint. default is 0.5.
    **threshold**: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel’s brightness in relation to the brightness of the kernel of pixels around them.
    default is false.
    **offset**: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.
    **invert**: If true, the image will be inverted before the operation. default is false.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *midpoint(int size, double bias 0.5, bool threshold false, int offset 0, bool invert false, image::Image *mask nullptr) ``` #### morph item doc **type** func **brief** Convolves the image by a filter kernel. This allows you to do general purpose convolutions on an image. **param** **size**: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
    **kernel**: The kernel used for convolution. The kernel should be a list of lists of numbers. The kernel should be the same size as the actual kernel size.
    **mul**: This parameter is used to multiply the convolved pixel results. default is auto.
    **add**: This parameter is the value to be added to each convolution pixel result. default is 0.0.
    **threshold**: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel’s brightness in relation to the brightness of the kernel of pixels around them.
    default is false.
    **offset**: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.
    **invert**: If true, the image will be inverted before the operation. default is false.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *morph(int size, std::vector kernel, float mul 1, float add 0.0, bool threshold false, int offset 0, bool invert false, image::Image *mask nullptr) ``` #### gaussian item doc **type** func **brief** Convolves the image by a smoothing guassian kernel. **param** **size**: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
    **unsharp**: If true, this method will perform an unsharp mask operation instead of gaussian filtering operation, this improves the clarity of image edges. default is false.
    **mul**: This parameter is used to multiply the convolved pixel results. default is auto.
    **add**: This parameter is the value to be added to each convolution pixel result. default is 0.0.
    **threshold**: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel’s brightness in relation to the brightness of the kernel of pixels around them.
    default is false.
    **offset**: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.
    **invert**: If true, the image will be inverted before the operation. default is false.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *gaussian(int size, bool unsharp false, float mul 1, float add 0.0, bool threshold false, int offset 0, bool invert false, image::Image *mask nullptr) ``` #### laplacian item doc **type** func **brief** Convolves the image by a edge detecting laplacian kernel. **param** **size**: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
    **sharpen**: If True, this method will sharpen the image instead of an unthresholded edge detection image. Then increase the kernel size to improve image clarity. default is false.
    **mul**: This parameter is used to multiply the convolved pixel results. default is auto.
    **add**: This parameter is the value to be added to each convolution pixel result. default is 0.0.
    **threshold**: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel’s brightness in relation to the brightness of the kernel of pixels around them.
    default is false.
    **offset**: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.
    **invert**: If true, the image will be inverted before the operation. default is false.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *laplacian(int size, bool sharpen false, float mul 1, float add 0.0, bool threshold false, int offset 0, bool invert false, image::Image *mask nullptr) ``` #### bilateral item doc **type** func **brief** Convolves the image by a bilateral filter. **param** **size**: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
    **color_sigma**: Controls how closely colors are matched using the bilateral filter. default is 0.1.
    **space_sigma**: Controls how closely pixels space wise are blurred with each other. default is 1.
    **threshold**: If true, which will enable adaptive thresholding of the image which sets pixels to white or black based on a pixel’s brightness in relation to the brightness of the kernel of pixels around them.
    default is false.
    **offset**: The larger the offset value, the lower brightness pixels on the original image will be set to white. default is 0.
    **invert**: If true, the image will be inverted before the operation. default is false.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *bilateral(int size, double color_sigma 0.1, double space_sigma 1, bool threshold false, int offset 0, bool invert false, image::Image *mask nullptr) ``` #### linpolar item doc **type** func **brief** Re project’s and image from cartessian coordinates to linear polar coordinates. **param** **reverse**: If true, the image will be reverse polar transformed. default is false.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *linpolar(bool reverse false) ``` #### logpolar item doc **type** func **brief** Re project’s and image from cartessian coordinates to log polar coordinates. **param** **reverse**: If true, the image will be reverse polar transformed. default is false.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *logpolar(bool reverse false) ``` #### lens\\_corr item doc **type** func **brief** Performs a lens correction operation on the image. TODO: support in the feature **param** **strength**: The strength of the lens correction. default is 1.8.
    **zoom**: The zoom of the lens correction. default is 1.0.
    **x_corr**: The x correction of the lens correction. default is 0.5.
    **y_corr**: The y correction of the lens correction. default is 0.5.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *lens_corr(double strength 1.8, double zoom 1.0, double x_corr 0.5, double y_corr 0.5) ``` #### rotation\\_corr item doc **type** func **brief** Performs a rotation correction operation on the image. TODO: support in the feature **param** **x_rotation**: The x rotation of the rotation correction. default is 0.0.
    **y_rotation**: The y rotation of the rotation correction. default is 0.0.
    **z_rotation**: The z rotation of the rotation correction. default is 0.0.
    **x_translation**: The x translation of the rotation correction. default is 0.0.
    **y_translation**: The y translation of the rotation correction. default is 0.0.
    **zoom**: The zoom of the rotation correction. default is 1.0.
    **fov**: The fov of the rotation correction. default is 60.0.
    **corners**: The corners of the rotation correction. default is None.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *rotation_corr(double x_rotation 0.0, double y_rotation 0.0, double z_rotation 0.0, double x_translation 0.0, double y_translation 0.0, double zoom 1.0, double fov 60.0, std::vector corners std::vector()) ``` #### get\\_histogram item doc **type** func **brief** Gets the histogram of the image. **param** **thresholds**: You can define multiple thresholds.
    For GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.
    For RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.
    Where the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.
    **invert**: If true, the thresholds will be inverted before the operation. default is false.
    **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **bins**: The number of bins to use for the histogram.
    In GRAYSCALE format, setting range is [2, 256], default is 100.
    In rgb888 format, setting range is [2, 100], default is 100.
    **l_bins**: The number of bins to use for the l channel of the histogram. Only valid in RGB888 format.
    If an invalid value is set, bins will be used instead. The setting range is [2, 100], default is 100.
    **a_bins**: The number of bins to use for the a channel of the histogram.
    Only valid in RGB888 format.The setting range is [2, 256], default is 256.
    **b_bins**: The number of bins to use for the b channel of the histogram.
    Only valid in RGB888 format. The setting range is [2, 256], default is 256.
    **difference**: difference may be set to an image object to cause this method to operate on the difference image between the current image and the difference image object.
    default is None.
    **return** Returns the histogram of the image **static** False **C++ defination code**: ```cpp std::map> get_histogram(std::vector> thresholds std::vector>(), bool invert false, std::vector roi std::vector(), int bins 1, int l_bins 100, int a_bins 256, int b_bins 256, image::Image *difference nullptr) ``` #### get\\_statistics item doc **type** func **brief** Gets the statistics of the image. TODO: support in the feature **param** **thresholds**: You can define multiple thresholds.
    For GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.
    For RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.
    Where the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.
    **invert**: If true, the image will be inverted before the operation. default is false.
    **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **bins**: The number of bins to use for the statistics. default is 1.
    **l_bins**: The number of bins to use for the l channel of the statistics. default is 1.
    **a_bins**: The number of bins to use for the a channel of the statistics. default is 1.
    **b_bins**: The number of bins to use for the b channel of the statistics. default is 1.
    **difference**: The difference image to use for the statistics. default is None.
    **return** Returns the statistics of the image **static** False **C++ defination code**: ```cpp image::Statistics get_statistics(std::vector> thresholds std::vector>(), bool invert false, std::vector roi std::vector(), int bins 1, int l_bins 1, int a_bins 1, int b_bins 1, image::Image *difference nullptr) ``` #### get\\_regression item doc **type** func **brief** Gets the regression of the image. **param** **thresholds**: You can define multiple thresholds.
    For GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.
    For RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.
    Where the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.
    **invert**: If true, the image will be inverted before the operation. default is false.
    **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **x_stride**: The x stride to use for the regression. default is 2.
    **y_stride**: The y stride to use for the regression. default is 1.
    **area_threshold**: The area threshold to use for the regression. default is 10.
    **pixels_threshold**: The pixels threshold to use for the regression. default is 10.
    **robust**: If true, the regression will be robust. default is false.
    **return** Returns the regression of the image **static** False **C++ defination code**: ```cpp std::vector get_regression(std::vector> thresholds std::vector>(), bool invert false, std::vector roi std::vector(), int x_stride 2, int y_stride 1, int area_threshold 10, int pixels_threshold 10, bool robust false) ``` #### save item doc **type** func **brief** Save image to file **param** **path**: file path
    **quality**: image quality, by default(value is 95), support jpeg and png format
    **return** error code, err::ERR_NONE is ok, other is error **static** False **C++ defination code**: ```cpp err::Err save(const char *path, int quality 95) ``` #### flood\\_fill item doc **type** func **brief** Flood fills a region of the image starting from location x, y. **param** **x**: The x coordinate of the seed point.
    **y**: The y coordinate of the seed point.
    **seed_threshold**: The seed_threshold value controls how different any pixel in the fill area may be from the original starting pixel. default is 0.05.
    **floating_threshold**: The floating_threshold value controls how different any pixel in the fill area may be from any neighbor pixels. default is 0.05.
    **color**: The color to fill the region with. default is white.
    **invert**: If true, the image will be inverted before the operation. default is false.
    **clear_background**: If true, the background will be cleared before the operation. default is false.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None. FIXME: the mask image works abnormally
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *flood_fill(int x, int y, float seed_threshold 0.05, float floating_threshold 0.05, image::Color color image::COLOR_WHITE, bool invert false, bool clear_background false, image::Image *mask nullptr) ``` #### erode item doc **type** func **brief** Erodes the image in place. **param** **size**: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
    **threshold**: The number of pixels in the kernel that are not 0. If it is less than or equal to the threshold, set the center pixel to black. default is (kernel_size 1).
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *erode(int size, int threshold 1, image::Image *mask nullptr) ``` #### dilate item doc **type** func **brief** Dilates the image in place. **param** **size**: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
    **threshold**: The number of pixels in the kernel that are not 0. If it is greater than or equal to the threshold, set the center pixel to white. default is 0.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *dilate(int size, int threshold 0, image::Image *mask nullptr) ``` #### open item doc **type** func **brief** Performs erosion and dilation on an image in order. **param** **size**: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
    **threshold**: As the threshold for erosion and dilation, the actual threshold for erosion is (kernel_size 1 threshold), the actual threshold for dialation is threshold. default is 0.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *open(int size, int threshold 0, image::Image *mask nullptr) ``` #### close item doc **type** func **brief** Performs dilation and erosion on an image in order. **param** **size**: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
    **threshold**: As the threshold for erosion and dilation, the actual threshold for erosion is (kernel_size 1 threshold), the actual threshold for dialation is threshold. default is 0.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *close(int size, int threshold 0, image::Image *mask nullptr) ``` #### top\\_hat item doc **type** func **brief** Returns the image difference of the image and Image.open()’ed image. **param** **size**: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
    **threshold**: As the threshold for open method. default is 0.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *top_hat(int size, int threshold 0, image::Image *mask nullptr) ``` #### black\\_hat item doc **type** func **brief** Returns the image difference of the image and Image.close()’ed image. **param** **size**: Kernel size. The actual kernel size is ((size * 2) + 1) * ((size * 2) + 1). Use 1(3x3 kernel), 2(5x5 kernel).
    **threshold**: As the threshold for close method. default is 0.
    **mask**: Mask is another image to use as a pixel level mask for the operation. The mask should be an image with just black or white pixels and should be the same size as the image being operated on.
    Only pixels set in the mask are modified. default is None.
    **return** Returns the image after the operation is completed. **static** False **C++ defination code**: ```cpp image::Image *black_hat(int size, int threshold 0, image::Image *mask nullptr) ``` #### find\\_blobs item doc **type** func **brief** Finds all blobs in the image and returns a list of image.Blob class which describe each Blob.\\nPlease see the image.Blob object more more information. **param** **thresholds**: You can define multiple thresholds.
    For GRAYSCALE format, you can use {{Lmin, Lmax}, ...} to define one or more thresholds.
    For RGB888 format, you can use {{Lmin, Lmax, Amin, Amax, Bmin, Bmax}, ...} to define one or more thresholds.
    Where the upper case L,A,B represent the L,A,B channels of the LAB image format, and min, max represent the minimum and maximum values of the corresponding channels.
    **invert**: if true, will invert thresholds before find blobs, default is false
    **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **x_stride**: x stride is the number of x pixels to skip when doing the hough transform. default is 2
    **y_stride**: y_stride is the number of y pixels to skip when doing the hough transform. default is 1
    **area_threshold**: area threshold, if the blob area is smaller than area_threshold, the blob is not returned, default is 10
    **pixels_threshold**: pixels threshold, if the blob pixels is smaller than area_threshold, the blob is not returned,, default is 10.
    when x_stride and y_stride is equal to 1, pixels_threshold is equivalent to area_threshold
    **merge**: if True merges all not filtered out blobs whos bounding rectangles intersect each other. default is false
    **margin**: margin can be used to increase or decrease the size of the bounding rectangles for blobs during the intersection test.
    For example, with a margin of 1 blobs whos bounding rectangles are 1 pixel away from each other will be merged. default is 0
    **x_hist_bins_max**: if set to non zero populates a histogram buffer in each blob object with an x_histogram projection of all columns in the object. This value then sets the number of bins for that projection.
    **y_hist_bins_max**: if set to non zero populates a histogram buffer in each blob object with an y_histogram projection of all rows in the object. This value then sets the number of bins for that projection.
    **return** Return the blob when found blobs, format is (blob1, blob2, ...), you can use blob class methods to do more operations. **static** False **C++ defination code**: ```cpp std::vector find_blobs(std::vector> thresholds std::vector>(), bool invert false, std::vector roi std::vector(), int x_stride 2, int y_stride 1, int area_threshold 10, int pixels_threshold 10, bool merge false, int margin 0, int x_hist_bins_max 0, int y_hist_bins_max 0) ``` #### find\\_lines item doc **type** func **brief** Find lines in image **param** **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **x_stride**: x stride is the number of x pixels to skip when doing the hough transform. default is 2
    **y_stride**: y_stride is the number of y pixels to skip when doing the hough transform. default is 1
    **threshold**: threshold threshold controls what lines are detected from the hough transform. Only lines with a magnitude greater than or equal to threshold are returned.
    The right value of threshold for your application is image dependent. default is 1000.
    **theta_margin**: theta_margin controls the merging of detected lines. default is 25.
    **rho_margin**: rho_margin controls the merging of detected lines. default is 25.
    **return** Return the line when found lines, format is (line1, line2, ...), you can use line class methods to do more operations **static** False **C++ defination code**: ```cpp std::vector find_lines(std::vector roi std::vector(), int x_stride 2, int y_stride 1, double threshold 1000, double theta_margin 25, double rho_margin 25) ``` #### find\\_line\\_segments item doc **type** func **brief** Finds all line segments in the image. **param** **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **merge_distance**: The maximum distance between two lines to merge them. default is 0.
    **max_theta_difference**: The maximum difference between two lines to merge them. default is 15.
    **return** Return the line when found lines, format is (line1, line2, ...), you can use line class methods to do more operations **static** False **C++ defination code**: ```cpp std::vector find_line_segments(std::vector roi std::vector(), int merge_distance 0, int max_theta_difference 15) ``` #### find\\_circles item doc **type** func **brief** Find circles in image **param** **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **x_stride**: x stride is the number of x pixels to skip when doing the hough transform. default is 2
    **y_stride**: y_stride is the number of y pixels to skip when doing the hough transform. default is 1
    **threshold**: threshold controls what circles are detected from the hough transform. Only circles with a magnitude greater than or equal to threshold are returned.
    The right value of threshold for your application is image dependent.
    **x_margin**: x_margin controls the merging of detected circles. Circles which are x_margin, y_margin, and r_margin pixels apart are merged. default is 10
    **y_margin**: y_margin controls the merging of detected circles. Circles which are x_margin, y_margin, and r_margin pixels apart are merged. default is 10
    **r_margin**: r_margin controls the merging of detected circles. Circles which are x_margin, y_margin, and r_margin pixels apart are merged. default is 10
    **r_min**: r_min controls the minimum circle radius detected. Increase this to speed up the algorithm. default is 2
    **r_max**: r_max controls the maximum circle radius detected. Decrease this to speed up the algorithm. default is min(roi.w / 2, roi.h / 2)
    **r_step**: r_step controls how to step the radius detection by. default is 2.
    **return** Return the circle when found circles, format is (circle1, circle2, ...), you can use circle class methods to do more operations **static** False **C++ defination code**: ```cpp std::vector find_circles(std::vector roi std::vector(), int x_stride 2, int y_stride 1, int threshold 2000, int x_margin 10, int y_margin 10, int r_margin 10, int r_min 2, int r_max 1, int r_step 2) ``` #### find\\_rects item doc **type** func **brief** Finds all rects in the image. **param** **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **threshold**: The threshold to use for the rects. default is 10000.
    **return** Returns the rects of the image **static** False **C++ defination code**: ```cpp std::vector find_rects(std::vector roi std::vector(), int threshold 10000) ``` #### find\\_qrcodes item doc **type** func **brief** Finds all qrcodes in the image. **param** **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **return** Returns the qrcodes of the image **static** False **C++ defination code**: ```cpp std::vector find_qrcodes(std::vector roi std::vector()) ``` #### find\\_apriltags item doc **type** func **brief** Finds all apriltags in the image. **param** **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **families**: The families to use for the apriltags. default is TAG36H11.
    **fx**: The camera X focal length in pixels, default is 1.
    **fy**: The camera Y focal length in pixels, default is 1.
    **cx**: The camera X center in pixels, default is image.width / 2.
    **cy**: The camera Y center in pixels, default is image.height / 2.
    **return** Returns the apriltags of the image **static** False **C++ defination code**: ```cpp std::vector find_apriltags(std::vector roi std::vector(), image::ApriltagFamilies families image::ApriltagFamilies::TAG36H11, float fx 1, float fy 1, int cx 1, int cy 1) ``` #### find\\_datamatrices item doc **type** func **brief** Finds all datamatrices in the image. **param** **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **effort**: Controls how much time to spend trying to find data matrix matches. default is 200.
    **return** Returns the datamatrices of the image **static** False **C++ defination code**: ```cpp std::vector find_datamatrices(std::vector roi std::vector(), int effort 200) ``` #### find\\_barcodes item doc **type** func **brief** Finds all barcodes in the image. **param** **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **return** Returns the barcodes of the image **static** False **C++ defination code**: ```cpp std::vector find_barcodes(std::vector roi std::vector()) ``` #### find\\_displacement item doc **type** func **brief** Finds the displacement between the image and the template. TODO: support in the feature\\nnote: this method must be used on power of 2 image sizes **param** **template_image**: The template image.
    **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **template_roi**: The region of interest rectangle (x, y, w, h) to work in. If not specified, it is equal to the image rectangle.
    **logpolar**: If true, it will instead find rotation and scale changes between the two images. default is false.
    **return** Returns the displacement of the image **static** False **C++ defination code**: ```cpp image::Displacement find_displacement(image::Image &template_image, std::vector roi std::vector(), std::vector template_roi std::vector(), bool logpolar false) ``` #### find\\_template item doc **type** func **brief** Finds the template in the image. **param** **template_image**: The template image.
    **threshold**: Threshold is floating point number (0.0 1.0) where a higher threshold prevents false positives while lowering the detection rate while a lower threshold does the opposite.
    **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image. Only valid in SEARCH_EX mode.
    **step**: The step size to use for the template. default is 2. Only valid in SEARCH_EX mode
    **search**: The search method to use for the template. default is SEARCH_EX.
    **return** Returns a bounding box tuple (x, y, w, h) for the matching location otherwise None. **static** False **C++ defination code**: ```cpp std::vector find_template(image::Image &template_image, float threshold, std::vector roi std::vector(), int step 2, image::TemplateMatch search image::TemplateMatch::SEARCH_EX) ``` #### find\\_features item doc **type** func **brief** Finds the features in the image. TODO: support in the feature **param** **cascade**: The cascade to use for the features. default is CASCADE_FRONTALFACE_ALT.
    **threshold**: The threshold to use for the features. default is 0.5.
    **scale**: The scale to use for the features. default is 1.5.
    **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **return** Returns the features of the image **static** False **C++ defination code**: ```cpp std::vector find_features(int cascade, float threshold 0.5, float scale 1.5, std::vector roi std::vector()) ``` #### find\\_lbp item doc **type** func **brief** Finds the lbp in the image. TODO: support in the feature. **param** **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **return** Returns the lbp of the image **static** False **C++ defination code**: ```cpp image::LBPKeyPoint find_lbp(std::vector roi std::vector()) ``` #### find\\_keypoints item doc **type** func **brief** Finds the keypoints in the image. TODO: support in the feature. **param** **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **threshold**: The threshold to use for the keypoints. default is 20.
    **normalized**: If true, the image will be normalized before the operation. default is false.
    **scale_factor**: The scale factor to use for the keypoints. default is 1.5.
    **max_keypoints**: The maximum number of keypoints to use for the keypoints. default is 100.
    **corner_detector**: The corner detector to use for the keypoints. default is CORNER_AGAST.
    **return** Returns the keypoints of the image **static** False **C++ defination code**: ```cpp image::ORBKeyPoint find_keypoints(std::vector roi std::vector(), int threshold 20, bool normalized false, float scale_factor 1.5, int max_keypoints 100, image::CornerDetector corner_detector image::CornerDetector::CORNER_AGAST) ``` #### find\\_edges item doc **type** func **brief** Finds the edges in the image. **param** **edge_type**: The edge type to use for the edges. default is EDGE_CANNY.
    **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **threshold**: The threshold to use for the edges. default is 20.
    **return** Returns the edges of the image **static** False **C++ defination code**: ```cpp image::Image* find_edges(image::EdgeDetector edge_type, std::vector roi std::vector(), std::vector threshold std::vector({100, 200})) ``` #### find\\_hog item doc **type** func **brief** Finds the hog in the image. TODO: support in the feature **param** **roi**: The region of interest, input in the format of (x, y, w, h), x and y are the coordinates of the upper left corner, w and h are the width and height of roi.
    default is None, means whole image.
    **size**: The size to use for the hog. default is 8.
    **return** Returns the hog of the image **static** False **C++ defination code**: ```cpp image::Image* find_hog(std::vector roi std::vector(), int size 8) ``` #### match\\_lbp\\_descriptor item doc **type** func **brief** Matches the lbp descriptor of the image. TODO: support in the feature **param** **desc1**: The descriptor to use for the match.
    **desc2**: The descriptor to use for the match.
    **return** Returns the match of the image **static** False **C++ defination code**: ```cpp int match_lbp_descriptor(image::LBPKeyPoint &desc1, image::LBPKeyPoint &desc2) ``` #### match\\_orb\\_descriptor item doc **type** func **brief** Matches the orb descriptor of the image. TODO: support in the feature **param** **desc1**: The descriptor to use for the match.
    **desc2**: The descriptor to use for the match.
    **threshold**: The threshold to use for the match. default is 95.
    **filter_outliers**: If true, the image will be filter_outliers before the operation. default is false.
    **return** Returns the match of the image **static** False **C++ defination code**: ```cpp image::KPTMatch match_orb_descriptor(image::ORBKeyPoint &desc1, image::ORBKeyPoint &desc2, int threshold 95, bool filter_outliers false) ```"},"/maixpy/api/maix/thread.html":{"title":"maix.thread","content":" title: maix.thread maix.thread module > You can use `maix.thread` to access this module with MaixPy > This module is generated from [MaixCDK](https://github.com/sipeed/MaixCDK) ## Module No module ## Enum ## Variable ## Function ## Class ### Thread item doc **brief** thread class **C++ defination code**: ```cpp class Thread ``` #### \\_\\_init\\_\\_ item doc **type** func **brief** create thread **param** **func**: direction [in], thread function, one `args` parameter, void* type, no return value
    **args**: direction [in], thread function parameter
    **static** False **C++ defination code**: ```cpp Thread(std::function func, void *args nullptr) ``` #### join item doc **type** func **brief** wait thread exit **static** False **C++ defination code**: ```cpp void join() ``` #### detach item doc **type** func **brief** detach thread **static** False **C++ defination code**: ```cpp void detach() ``` #### joinable item doc **type** func **brief** Check if thread is joinable **return** true if thread is joinable **static** False **C++ defination code**: ```cpp bool joinable() ```"},"/maixpy/api/maix/network/wifi.html":{"title":"maix.network.wifi","content":" title: maix.network.wifi maix.network.wifi module > You can use `maix.network.wifi` to access this module with MaixPy > This module is generated from [MaixCDK](https://github.com/sipeed/MaixCDK) ## Module No module ## Enum ## Variable ## Function ### list\\_devices ```python def list_devices() > list[str] ``` item doc **brief** List WiFi interfaces **return** WiFi interface list, string type **C++ defination code**: ```cpp std::vector list_devices() ``` ## Class ### AP\\_Info item doc **brief** WiFi AP info **C++ defination code**: ```cpp class AP_Info ``` #### ssid item doc **type** var **brief** WiFi AP info SSID **static** False **readonly** False **C++ defination code**: ```cpp std::vector ssid ``` #### bssid item doc **type** var **brief** WiFi AP info BSSID **static** False **readonly** False **C++ defination code**: ```cpp std::string bssid ``` #### security item doc **type** var **brief** WiFi AP info security **static** False **readonly** False **C++ defination code**: ```cpp std::string security ``` #### channel item doc **type** var **brief** WiFi AP info channel **static** False **readonly** False **C++ defination code**: ```cpp int channel ``` #### frequency item doc **type** var **brief** WiFi AP info frequency **static** False **readonly** False **C++ defination code**: ```cpp int frequency ``` #### rssi item doc **type** var **brief** WiFi AP info rssi **static** False **readonly** False **C++ defination code**: ```cpp int rssi ``` #### ssid\\_str ```python def ssid_str(self) > str ``` item doc **type** func **brief** WiFi AP info ssid_str **static** False **C++ defination code**: ```cpp std::string ssid_str() ``` ### Wifi item doc **brief** Wifi class **C++ defination code**: ```cpp class Wifi ``` #### \\_\\_init\\_\\_ item doc **type** func **brief** Wifi class **param** **iface**: wifi interface name, default is wlan0
    **static** False **C++ defination code**: ```cpp Wifi(std::string iface \"wlan0\") ``` #### get\\_ip item doc **type** func **brief** Get current WiFi ip **return** ip, string type, if network not connected, will return empty string. **static** False **C++ defination code**: ```cpp std::string get_ip() ``` #### get\\_mac item doc **type** func **brief** Get current WiFi MAC address **return** ip, string type. **static** False **C++ defination code**: ```cpp std::string get_mac() ``` #### get\\_gateway item doc **type** func **brief** Get current WiFi ip **return** ip, string type, if network not connected, will return empty string. **static** False **C++ defination code**: ```cpp std::string get_gateway() ``` #### start\\_scan item doc **type** func **brief** WiFi start scan AP info around in background. **return** If success, return err.Err.ERR_NONE, else means failed. **static** False **C++ defination code**: ```cpp err::Err start_scan() ``` #### get\\_scan\\_result item doc **type** func **brief** Get WiFi scan AP info. **return** wifi.AP_Info list. **static** False **C++ defination code**: ```cpp std::vector get_scan_result() ``` #### stop\\_scan item doc **type** func **brief** Stop WiFi scan AP info. **static** False **C++ defination code**: ```cpp void stop_scan() ``` #### connect item doc **type** func **brief** Connect to WiFi AP. **param** **ssid**: SSID of AP
    **password**: password of AP, if no password, leave it empty.
    **wait**: wait for got IP or failed or timeout.
    **timeout**: connect timeout internal, unit second.
    **return** If success, return err.Err.ERR_NONE, else means failed. **static** False **C++ defination code**: ```cpp err::Err connect(const std::string &ssid, const std::string &password, bool wait true, int timeout 60) ``` #### disconnect item doc **type** func **brief** Disconnect from WiFi AP. **return** If success, return err.Err.ERR_NONE, else means failed. **static** False **C++ defination code**: ```cpp err::Err disconnect() ``` #### is\\_connected item doc **type** func **brief** See if WiFi is connected to AP. **return** If connected return true, else false. **static** False **C++ defination code**: ```cpp bool is_connected() ```"},"/maixpy/api/maix/comm.html":{"title":"maix.comm","content":" title: maix.comm maix.comm module > You can use `maix.comm` to access this module with MaixPy > This module is generated from [MaixCDK](https://github.com/sipeed/MaixCDK) ## Module No module ## Enum ## Variable ## Function ## Class ### CommProtocol item doc **brief** Class for communication protocol **C++ defination code**: ```cpp class CommProtocol ``` #### \\_\\_init\\_\\_ item doc **type** func **brief** Construct a new CommProtocol object **param** **buff_size**: buffer size, default to 1024 bytes
    **static** False **C++ defination code**: ```cpp CommProtocol(int buff_size 1024) ``` #### get\\_msg item doc **type** func **brief** Read data to buffer, and try to decode it as maix.protocol.MSG object **return** decoded data, if nullptr, means no valid frame found.
    Attentioin, delete it after use in C++. **static** False **C++ defination code**: ```cpp protocol::MSG *get_msg() ``` #### resp\\_ok item doc **type** func **brief** Send response ok(success) message **param** **cmd**: CMD value
    **body**: response body, can be null
    **return** encoded data, if nullptr, means error, and the error code is err.Err.
    Attentioin, delete it after use in C++. **static** False **C++ defination code**: ```cpp err::Err resp_ok(uint8_t cmd, Bytes *body nullptr) ``` #### report item doc **type** func **brief** Send report message **param** **cmd**: CMD value
    **body**: report body, can be null
    **return** encoded data, if nullptr, means error, and the error code is err.Err.
    Attentioin, delete it after use in C++. **static** False **C++ defination code**: ```cpp err::Err report(uint8_t cmd, Bytes *body nullptr) ``` #### resp\\_err item doc **type** func **brief** Encode response error message to buffer **param** **cmd**: CMD value
    **code**: error code
    **msg**: error message
    **return** encoded data, if nullptr, means error, and the error code is err.Err.
    Attentioin, delete it after use in C++. **static** False **C++ defination code**: ```cpp err::Err resp_err(uint8_t cmd, err::Err code, const std::string &msg) ```"},"/maixpy/api/maix/protocol.html":{"title":"maix.protocol","content":" title: maix.protocol maix.protocol module > You can use `maix.protocol` to access this module with MaixPy > This module is generated from [MaixCDK](https://github.com/sipeed/MaixCDK) ## Module No module ## Enum ### CMD item doc **brief** protocol cmd, more doc see MaixCDK document's convention doc **note** max app custom CMD value should < CMD_APP_MAX **values** **CMD_APP_MAX**: 200, max app custom CMD value should < CMD_APP_MAX
    **CMD_SET_UPLOAD**: set auto upload data mode
    **CMD_APP_LIST**:
    **CMD_START_APP**:
    **CMD_EXIT_APP**:
    **CMD_CUR_APP_INFO**:
    **CMD_APP_INFO**:
    **CMD_KEY**:
    **CMD_TOUCH**:
    **C++ defination code**: ```cpp enum CMD { CMD_APP_MAX 0xC8, // 200, max app custom CMD value should < CMD_APP_MAX CMD_SET_UPLOAD 0xF8, // set auto upload data mode CMD_APP_LIST 0xF9, CMD_START_APP 0xFA, CMD_EXIT_APP 0xFB, CMD_CUR_APP_INFO 0xFC, CMD_APP_INFO 0xFD, CMD_KEY 0xFE, CMD_TOUCH 0xFF, } ``` ### FLAGS item doc **brief** protocol flags, more doc see MaixCDK document's convention doc **values** **FLAG_REQ**:
    **FLAG_RESP**:
    **FLAG_IS_RESP_MASK**:
    **FLAG_RESP_OK**:
    **FLAG_RESP_ERR**:
    **FLAG_RESP_OK_MASK**:
    **FLAG_REPORT**:
    **FLAG_REPORT_MASK**:
    **FLAG_VERSION_MASK**:
    **C++ defination code**: ```cpp enum FLAGS { FLAG_REQ 0x00, FLAG_RESP 0x80, FLAG_IS_RESP_MASK 0x80, FLAG_RESP_OK 0x40, FLAG_RESP_ERR 0x00, FLAG_RESP_OK_MASK 0x40, FLAG_REPORT 0x20, FLAG_REPORT_MASK 0x20, FLAG_VERSION_MASK 0x03 } ``` ## Variable ### VERSION item doc **brief** protocol version **value** **1** **readonly** True **C++ defination code**: ```cpp const uint8_t VERSION 1 ``` ### HEADER item doc **brief** protocol header **value** **0xBBACCAAA** **readonly** True **C++ defination code**: ```cpp const uint32_t HEADER 0xBBACCAAA ``` ## Function ### crc16\\_IBM ```python def crc16_IBM(data: maix.Bytes(bytes)) > int ``` item doc **brief** CRC16 IBM **param** **data**: data, bytes type.
    **return** CRC16 IBM value, uint16_t type. **C++ defination code**: ```cpp uint16_t crc16_IBM(const Bytes *data) ``` ## Class ### MSG item doc **brief** protocol msg **C++ defination code**: ```cpp class MSG ``` #### version item doc **type** var **brief** protocol version **static** False **readonly** False **C++ defination code**: ```cpp uint8_t version ``` #### resp\\_ok item doc **type** var **brief** Is success response or not, (only for response msg) **static** False **readonly** False **C++ defination code**: ```cpp uint8_t resp_ok ``` #### cmd item doc **type** var **brief** CMD value **static** False **readonly** False **C++ defination code**: ```cpp uint8_t cmd ``` #### is\\_resp item doc **type** var **brief** message is response or not, contrast with is_req **static** False **readonly** False **C++ defination code**: ```cpp bool is_resp ``` #### body\\_len item doc **type** var **brief** Message body length, read only, use set_body() to update **attention** DO NOT manually change this value **static** False **readonly** False **C++ defination code**: ```cpp int body_len ``` #### encode\\_resp\\_ok ```python def encode_resp_ok(*args, **kwargs) ``` item doc **type** func **brief** Encode response ok(success) message **param** **body**: response body, can be null
    **return** encoded data, if nullptr, means error, and the error code is err.Err **static** False **C++ defination code**: ```cpp Bytes *encode_resp_ok(Bytes *body nullptr) ``` #### encode\\_report ```python def encode_report(*args, **kwargs) ``` item doc **type** func **brief** Encode proactively report message **param** **body**: report body, can be null
    **return** encoded data, if nullptr, means error, and the error code is err.Err **static** False **C++ defination code**: ```cpp Bytes *encode_report(Bytes *body nullptr) ``` #### encode\\_resp\\_err ```python def encode_resp_err(*args, **kwargs) ``` item doc **type** func **brief** Encode response error message **param** **code**: error code
    **msg**: error message
    **return** encoded data, if nullptr, means error, and the error code is err.Err **static** False **C++ defination code**: ```cpp Bytes *encode_resp_err(err::Err code, const std::string &msg) ``` #### set\\_body ```python def set_body(self, body_new: maix.Bytes(bytes)) > None ``` item doc **type** func **brief** Update message body **param** **body_new**: new body data
    **static** False **C++ defination code**: ```cpp void set_body(Bytes *body_new) ``` #### get\\_body ```python def get_body(*args, **kwargs) ``` item doc **type** func **brief** Get message body **return** message body, bytes type **static** False **C++ defination code**: ```cpp Bytes *get_body() ``` ### Protocol item doc **brief** Communicate protocol **C++ defination code**: ```cpp class Protocol ``` #### \\_\\_init\\_\\_ item doc **type** func **brief** Construct a new Protocol object **param** **buff_size**: Data queue buffer size
    **static** False **C++ defination code**: ```cpp Protocol(int buff_size 1024) ``` #### buff\\_size item doc **type** func **brief** Data queue buffer size **static** False **C++ defination code**: ```cpp int buff_size() ``` #### push\\_data item doc **type** func **brief** Add data to data queue **param** **new_data**: new data
    **return** error code, maybe err.Err.ERR_BUFF_FULL **static** False **C++ defination code**: ```cpp err::Err push_data(const Bytes *new_data) ``` #### decode item doc **type** func **brief** Decode data in data queue and return a message **param** **new_data**: new data add to data queue, if null, only decode.
    **return** decoded message, if nullptr, means no message decoded. **static** False **C++ defination code**: ```cpp protocol::MSG *decode(const Bytes *new_data nullptr) ``` #### encode\\_resp\\_ok item doc **type** func **brief** Encode response ok(success) message to buffer **param** **cmd**: CMD value
    **body**: response body, can be null
    **return** encoded data, if nullptr, means error, and the error code is err.Err **static** False **C++ defination code**: ```cpp Bytes *encode_resp_ok(uint8_t cmd, Bytes *body nullptr) ``` #### encode\\_report item doc **type** func **brief** Encode proactively report message to buffer **param** **cmd**: CMD value
    **body**: report body, can be null
    **return** encoded data, if nullptr, means error, and the error code is err.Err **static** False **C++ defination code**: ```cpp Bytes *encode_report(uint8_t cmd, Bytes *body nullptr) ``` #### encode\\_resp\\_err item doc **type** func **brief** Encode response error message to buffer **param** **cmd**: CMD value
    **code**: error code
    **msg**: error message
    **return** encoded data, if nullptr, means error, and the error code is err.Err **static** False **C++ defination code**: ```cpp Bytes *encode_resp_err(uint8_t cmd, err::Err code, const std::string &msg) ```"},"/maixpy/api/maix/time.html":{"title":"maix.time","content":" title: maix.time maix.time module > You can use `maix.time` to access this module with MaixPy > This module is generated from [MaixCDK](https://github.com/sipeed/MaixCDK) ## Module No module ## Enum ## Variable ## Function ### time ```python def time() > float ``` item doc **brief** Get current time in s **return** current time in s, double type **C++ defination code**: ```cpp double time() ``` ### time\\_ms ```python def time_ms() > int ``` item doc **brief** Get current time in ms **return** current time in ms, uint64_t type **C++ defination code**: ```cpp uint64_t time_ms() ``` ### time\\_s ```python def time_s() > int ``` item doc **brief** Get current time in s **return** current time in s, uint64_t type **C++ defination code**: ```cpp uint64_t time_s() ``` ### time\\_us ```python def time_us() > int ``` item doc **brief** Get current time in us **return** current time in us, uint64_t type **C++ defination code**: ```cpp uint64_t time_us() ``` ### time\\_diff ```python def time_diff(last: float, now: float 1) > float ``` item doc **brief** Calculate time difference **param** **last**: last time
    **now**: current time
    **return** time difference **C++ defination code**: ```cpp double time_diff(double last, double now 1) ``` ### sleep ```python def sleep(s: float) > None ``` item doc **brief** Sleep seconds **param** **s**: seconds, double type
    **C++ defination code**: ```cpp void sleep(double s) ``` ### sleep\\_ms ```python def sleep_ms(ms: int) > None ``` item doc **brief** Sleep milliseconds **param** **ms**: milliseconds, uint64_t type
    **C++ defination code**: ```cpp void sleep_ms(uint64_t ms) ``` ### sleep\\_us ```python def sleep_us(us: int) > None ``` item doc **brief** Sleep microseconds **param** **us**: microseconds, uint64_t type
    **C++ defination code**: ```cpp void sleep_us(uint64_t us) ``` ### now ```python def now() > DateTime ``` item doc **brief** Get current UTC date and time **return** current date and time, DateTime type **C++ defination code**: ```cpp time::DateTime *now() ``` ### localtime ```python def localtime() > DateTime ``` item doc **brief** Get local time **return** local time, DateTime type **C++ defination code**: ```cpp time::DateTime *localtime() ``` ### strptime ```python def strptime(str: str, format: str) > DateTime ``` item doc **brief** DateTime from string **param** **str**: date time string
    **format**: date time format
    **return** DateTime **C++ defination code**: ```cpp time::DateTime *strptime(const std::string &str, const std::string &format) ``` ### gmtime item doc **brief** timestamp to DateTime(time zone is UTC (value 0)) **param** **timestamp**: double timestamp
    **return** DateTime **C++ defination code**: ```cpp time::DateTime *gmtime(double timestamp) ``` ## Class ### DateTime item doc **brief** Date and time class **C++ defination code**: ```cpp class DateTime ``` #### year item doc **type** var **brief** Year **static** False **readonly** False **C++ defination code**: ```cpp int year ``` #### month item doc **type** var **brief** Month, 1~12 **static** False **readonly** False **C++ defination code**: ```cpp int month ``` #### day item doc **type** var **brief** Day **static** False **readonly** False **C++ defination code**: ```cpp int day ``` #### hour item doc **type** var **brief** Hour **static** False **readonly** False **C++ defination code**: ```cpp int hour ``` #### minute item doc **type** var **brief** Minute **static** False **readonly** False **C++ defination code**: ```cpp int minute ``` #### second item doc **type** var **brief** Second **static** False **readonly** False **C++ defination code**: ```cpp int second ``` #### microsecond item doc **type** var **brief** Microsecond **static** False **readonly** False **C++ defination code**: ```cpp int microsecond ``` #### yearday item doc **type** var **brief** Year day **static** False **readonly** False **C++ defination code**: ```cpp int yearday ``` #### weekday item doc **type** var **brief** Weekday, 0 is Monday, 6 is Sunday **static** False **readonly** False **C++ defination code**: ```cpp int weekday ``` #### zone item doc **type** var **brief** Time zone **static** False **readonly** False **C++ defination code**: ```cpp float zone ``` #### zone\\_name item doc **type** var **brief** Time zone name **static** False **readonly** False **C++ defination code**: ```cpp std::string zone_name ``` #### \\_\\_init\\_\\_ ```python def __init__(self, year: int 0, month: int 0, day: int 0, hour: int 0, minute: int 0, second: int 0, microsecond: int 0, yearday: int 0, weekday: int 0, zone: int 0) > None ``` item doc **type** func **brief** Constructor **param** **year**: year
    **month**: month
    **day**: day
    **hour**: hour
    **minute**: minute
    **second**: second
    **microsecond**: microsecond
    **yearday**: year day
    **weekday**: weekday
    **zone**: time zone
    **static** False **C++ defination code**: ```cpp DateTime(int year 0, int month 0, int day 0, int hour 0, int minute 0, int second 0, int microsecond 0, int yearday 0, int weekday 0, int zone 0) ``` #### strftime ```python def strftime(self, format: str) > str ``` item doc **type** func **brief** Convert to string **return** date time string **static** False **C++ defination code**: ```cpp std::string strftime(const std::string &format) ``` #### timestamp ```python def timestamp(self) > float ``` item doc **type** func **brief** Convert to float timestamp **return** float timestamp **static** False **C++ defination code**: ```cpp double timestamp() ```"},"/maixpy/api/maix/app.html":{"title":"maix.app","content":" title: maix.app maix.app module > You can use `maix.app` to access this module with MaixPy > This module is generated from [MaixCDK](https://github.com/sipeed/MaixCDK) ## Module No module ## Enum ## Variable ## Function ### app\\_id ```python def app_id() > str ``` item doc **brief** Get current APP ID. **return** APP ID. **C++ defination code**: ```cpp string app_id() ``` ### set\\_app\\_id ```python def set_app_id(app_id: str) > str ``` item doc **brief** Set current APP ID. **param** **app_id**: APP ID.
    **C++ defination code**: ```cpp string set_app_id(const string &app_id) ``` ### get\\_apps\\_info\\_path ```python def get_apps_info_path() > str ``` item doc **brief** Get APP info file path. **C++ defination code**: ```cpp string get_apps_info_path() ``` ### get\\_apps\\_info ```python def get_apps_info(ignore_launcher: bool False, ignore_app_store: bool False) > list[APP_Info] ``` item doc **brief** Get APP info list. **param** **ignore_launcher**: if true, ignore launcher APP. default false.
    **ignore_app_store**: if true, ignore app store APP. default false.
    **return** APP info list. APP_Info object list. **C++ defination code**: ```cpp vector &get_apps_info(bool ignore_launcher false, bool ignore_app_store false) ``` ### get\\_app\\_data\\_path ```python def get_app_data_path() > str ``` item doc **brief** Get APP info, APP can store private data in this directory. **return** APP data path \"./data\", just return the data folder in current path because APP executed in app install path or project path.
    So, you must execute your program in you project path to use the project/data folder when you debug your APP. **C++ defination code**: ```cpp string get_app_data_path() ``` ### get\\_app\\_path ```python def get_app_path(app_id: str '') > str ``` item doc **brief** Get APP path. **param** **app_id**: APP ID, if empty, return current APP path, else return the APP path by app_id.
    **return** APP path, just return the current path because APP executed in app install path or project path.
    So, you must execute your program in you project path to use the project/data folder when you debug your APP. **C++ defination code**: ```cpp string get_app_path(const string &app_id \"\") ``` ### get\\_tmp\\_path ```python def get_tmp_path() > str ``` item doc **brief** Get global temporary data path, APPs can use this path as temporary data directory. **return** temporary data path. **C++ defination code**: ```cpp string get_tmp_path() ``` ### get\\_share\\_path ```python def get_share_path() > str ``` item doc **brief** Get data path of share, shared data like picture and video will put in this directory **return** share data path. **C++ defination code**: ```cpp string get_share_path() ``` ### get\\_picture\\_path ```python def get_picture_path() > str ``` item doc **brief** Get picture path of share, shared picture will put in this directory **return** share picture path. **C++ defination code**: ```cpp string get_picture_path() ``` ### get\\_video\\_path ```python def get_video_path() > str ``` item doc **brief** Get video path of share, shared video will put in this directory **return** share video path. **C++ defination code**: ```cpp string get_video_path() ``` ### get\\_font\\_path ```python def get_font_path() > str ``` item doc **brief** Get font path of share, shared font will put in this directory **return** share font path. **C++ defination code**: ```cpp string get_font_path() ``` ### get\\_icon\\_path ```python def get_icon_path() > str ``` item doc **brief** Get icon path of share, shared icon will put in this directory **return** share icon path. **C++ defination code**: ```cpp string get_icon_path() ``` ### get\\_sys\\_config\\_kv ```python def get_sys_config_kv(item: str, key: str, value: str '', from_cache: bool True) > str ``` item doc **brief** Get system config item value. **param** **item**: name of setting item, e.g. wifi, language. more see settings APP.
    **key**: config key, e.g. for wifi, key can be ssid, for language, key can be locale.
    **value**: default value, if not found, return this value.
    **from_cache**: if true, read from cache, if false, read from file.
    **return** config value, always string type, if not found, return empty string. **C++ defination code**: ```cpp string get_sys_config_kv(const string &item, const string &key, const string &value \"\", bool from_cache true) ``` ### get\\_app\\_config\\_kv ```python def get_app_config_kv(item: str, key: str, value: str '', from_cache: bool True) > str ``` item doc **brief** Get APP config item value. **param** **item**: name of setting item, e.g. user_info
    **key**: config key, e.g. for user_info, key can be name, age etc.
    **value**: default value, if not found, return this value.
    **from_cache**: if true, read from cache, if false, read from file.
    **return** config value, always string type, if not found, return empty string. **C++ defination code**: ```cpp string get_app_config_kv(const string &item, const string &key, const string &value \"\", bool from_cache true) ``` ### set\\_app\\_config\\_kv ```python def set_app_config_kv(item: str, key: str, value: str, write_file: bool True) > maix.err.Err ``` item doc **brief** Set APP config item value. **param** **item**: name of setting item, e.g. user_info
    **key**: config key, e.g. for user_info, key can be name, age etc.
    **value**: config value, always string type.
    **write_file**: if true, write to file, if false, just write to cache.
    **return** err::Err **C++ defination code**: ```cpp err::Err set_app_config_kv(const string &item, const string &key, const string &value, bool write_file true) ``` ### get\\_app\\_config\\_path ```python def get_app_config_path() > str ``` item doc **brief** Get APP config path, ini format, so you can use your own ini parser to parse it like `configparser` in Python.\\nAll APP config info is recommended to store in this file. **return** APP config path(ini format). **C++ defination code**: ```cpp string get_app_config_path() ``` ### set\\_exit\\_msg ```python def set_exit_msg(code: maix.err.Err, msg: str) > maix.err.Err ``` item doc **brief** Set APP exit code and exit message.\\nIf code ! 0, the launcher will show a dialog to user, and display the msg. **param** **code**: exit code, 0 means success, other means error, if code is 0, do nothing.
    **msg**: exit message, if code is 0, msg is not used.
    **return** exit code, the same as arg @code. **C++ defination code**: ```cpp err::Err set_exit_msg(err::Err code, const string &msg) ``` ### get\\_exit\\_msg ```python def get_exit_msg(cache: bool False) > tuple[str, maix.err.Err, str] ``` item doc **brief** Get APP exit code and exit message. **param** **cache**: if true, read from cache, if false, read from file. default false.
    **return** exit return app_id, exit code and exit message. **C++ defination code**: ```cpp tuple get_exit_msg(bool cache false) ``` ### have\\_exit\\_msg ```python def have_exit_msg(cache: bool False) > bool ``` item doc **brief** Check if have exit msg **param** **cache**: if true, just check from cache, if false, check from file. default false.
    **return** true if have exit msg, false if not. **C++ defination code**: ```cpp bool have_exit_msg(bool cache false) ``` ### switch\\_app ```python def switch_app(app_id: str, idx: int 1) > None ``` item doc **brief** Exit this APP and start another APP(by launcher).\\nCall this API will call set_exit_flag(true), you should check app::need_exit() in your code.\\nAnd exit this APP if app::need_exit() return true. **param** **app_id**: APP ID which will be started. app_id and idx must have one is valid.
    **idx**: APP index. app_id and idx must have one is valid.
    **C++ defination code**: ```cpp void switch_app(const string &app_id, int idx 1) ``` ### need\\_exit ```python def need_exit() > bool ``` item doc **brief** Shoule this APP exit? **return** true if this APP should exit, false if not. **attention** This API is a function, not a variable. **C++ defination code**: ```cpp bool need_exit() ``` ### running ```python def running() > bool ``` item doc **brief** App should running? The same as !app::need_exit() (not app::need_exit() in MaixPy). **return** true if this APP should running, false if not. **attention** This API is a function, not a variable. **C++ defination code**: ```cpp bool running() ``` ### set\\_exit\\_flag ```python def set_exit_flag(exit: bool) > None ``` item doc **brief** Set exit flag. You can get exit flag by app.need_exit(). **param** **exit**: true if this APP should exit, false if not.
    **C++ defination code**: ```cpp void set_exit_flag(bool exit) ``` ## Class ### Version item doc **brief** APP version **C++ defination code**: ```cpp class Version ``` #### \\_\\_str\\_\\_ item doc **type** func **brief** Convert to string, e.g. 1.0.0 **static** False **C++ defination code**: ```cpp std::string __str__() ``` #### from\\_str item doc **type** func **brief** Convert from string, e.g. \\\"1.0.0\\\" **static** True **C++ defination code**: ```cpp static app::Version from_str(const string &version_str) ``` ### APP\\_Info item doc **brief** APP info **C++ defination code**: ```cpp class APP_Info ``` #### id item doc **type** var **brief** APP id **static** False **readonly** False **C++ defination code**: ```cpp string id ``` #### name item doc **type** var **brief** APP name **static** False **readonly** False **C++ defination code**: ```cpp string name ``` #### icon item doc **type** var **brief** APP icon **static** False **readonly** False **C++ defination code**: ```cpp string icon ``` #### version item doc **type** var **brief** APP version **static** False **readonly** False **C++ defination code**: ```cpp Version version ``` #### exec item doc **type** var **brief** APP exec **static** False **readonly** False **C++ defination code**: ```cpp string exec ``` #### author item doc **type** var **brief** APP author **static** False **readonly** False **C++ defination code**: ```cpp string author ``` #### desc item doc **type** var **brief** APP desc **static** False **readonly** False **C++ defination code**: ```cpp string desc ``` #### names item doc **type** var **brief** APP names **static** False **readonly** False **C++ defination code**: ```cpp map names ``` #### descs item doc **type** var **brief** APP descs **static** False **readonly** False **C++ defination code**: ```cpp map descs ```"},"/maixpy/api/maix/camera.html":{"title":"maix.camera","content":" title: maix.camera maix.camera module, access camera device and get image from it > You can use `maix.camera` to access this module with MaixPy > This module is generated from [MaixCDK](https://github.com/sipeed/MaixCDK) ## Module No module ## Enum ## Variable ## Function ### list\\_devices item doc **brief** List all supported camera devices. **return** Returns the path to the camera device. **C++ defination code**: ```cpp std::vector list_devices() ``` ### set\\_regs\\_enable ```python def set_regs_enable(enable: bool True) > None ``` item doc **brief** Enable set camera registers, default is false, if set to true, will not set camera registers, you can manually set registers by write_reg API. **param** **enable**: enable/disable set camera registers
    **C++ defination code**: ```cpp void set_regs_enable(bool enable true) ``` ## Class ### Camera item doc **brief** Camera class **C++ defination code**: ```cpp class Camera ``` #### \\_\\_init\\_\\_ ```python def __init__(self, width: int 1, height: int 1, format: maix.image.Format ..., device: str None, fps: int 1, buff_num: int 3, open: bool True) > None ``` item doc **type** func **brief** Construct a new Camera object **param** **width**: camera width, default is 1, means auto, mostly means max width of camera support
    **height**: camera height, default is 1, means auto, mostly means max height of camera support
    **format**: camera output format, default is image.Format.FMT_RGB888
    **device**: camera device path, you can get devices by list_devices method, by default(value is NULL(None in MaixPy)) means the first device
    **fps**: camera fps, default is 1, means auto, mostly means max fps of camera support
    **buff_num**: camera buffer number, default is 3, means 3 buffer, one used by user, one used for cache the next frame,
    more than one buffer will accelerate image read speed, but will cost more memory.
    **open**: If true, camera will automatically call open() after creation. default is true.
    **static** False **C++ defination code**: ```cpp Camera(int width 1, int height 1, image::Format format image::FMT_RGB888, const char *device nullptr, int fps 1, int buff_num 3, bool open true) ``` #### get\\_ch\\_nums ```python def get_ch_nums(self) > int ``` item doc **type** func **brief** Get the number of channels supported by the camera. **return** Returns the maximum number of channels. **static** False **C++ defination code**: ```cpp int get_ch_nums() ``` #### open ```python def open(self, width: int 1, height: int 1, format: maix.image.Format ..., fps: int 1, buff_num: int 1) > maix.err.Err ``` item doc **type** func **brief** Open camera and run **param** **width**: camera width, default is 1, means auto, mostly means max width of camera support
    **height**: camera height, default is 1, means auto, mostly means max height of camera support
    **format**: camera output format, default same as the constructor's format argument
    **fps**: camera fps, default is 1, means auto, mostly means max fps of camera support
    **buff_num**: camera buffer number, default is 3, means 3 buffer, one used by user, one used for cache the next frame,
    more than one buffer will accelerate image read speed, but will cost more memory.
    **return** error code, err::ERR_NONE means success, others means failed **static** False **C++ defination code**: ```cpp err::Err open(int width 1, int height 1, image::Format format image::FMT_INVALID, int fps 1, int buff_num 1) ``` #### read ```python def read(self, buff: capsule None, buff_size: int 0, block: bool True) > maix.image.Image ``` item doc **type** func **brief** Get one frame image from camera buffer, must call open method before read.\\nIf open method not called, will call it automatically, if open failed, will throw exception!\\nSo call open method before read is recommended. **param** **buff**: buffer to store image data, if buff is nullptr, will alloc memory automatically.
    In MaixPy, default to None, you can create a image.Image object, then pass img.data() to buff.
    **block**: block read, default is true, means block util read image successfully,
    if set to false, will return nullptr if no image in buffer
    **return** image::Image object, if failed, return nullptr, you should delete if manually in C++ **static** False **C++ defination code**: ```cpp image::Image *read(void *buff nullptr, size_t buff_size 0, bool block true) ``` #### clear\\_buff ```python def clear_buff(self) > None ``` item doc **type** func **brief** Clear buff to ensure the next read image is the latest image **static** False **C++ defination code**: ```cpp void clear_buff() ``` #### skip\\_frames ```python def skip_frames(self, num: int) > None ``` item doc **type** func **brief** Read some frames and drop, this is usually used avoid read not stable image when camera just opened. **param** **num**: number of frames to read and drop
    **static** False **C++ defination code**: ```cpp void skip_frames(int num) ``` #### close ```python def close(self) > None ``` item doc **type** func **brief** Close camera **static** False **C++ defination code**: ```cpp void close() ``` #### add\\_channel ```python def add_channel(self, width: int 1, height: int 1, format: maix.image.Format ..., fps: int 1, buff_num: int 3, open: bool True) > Camera ``` item doc **type** func **brief** Add a new channel and return a new Camera object, you can use close() to close this channel. **param** **width**: camera width, default is 1, means auto, mostly means max width of camera support
    **height**: camera height, default is 1, means auto, mostly means max height of camera support
    **format**: camera output format, default is RGB888
    **fps**: camera fps, default is 1, means auto, mostly means max fps of camera support
    **buff_num**: camera buffer number, default is 3, means 3 buffer, one used by user, one used for cache the next frame,
    more than one buffer will accelerate image read speed, but will cost more memory.
    **open**: If true, camera will automatically call open() after creation. default is true.
    **return** new Camera object **static** False **C++ defination code**: ```cpp camera::Camera *add_channel(int width 1, int height 1, image::Format format image::FMT_RGB888, int fps 1, int buff_num 3, bool open true) ``` #### is\\_opened ```python def is_opened(self) > bool ``` item doc **type** func **brief** Check if camera is opened **return** true if camera is opened, false if not **static** False **C++ defination code**: ```cpp bool is_opened() ``` #### is\\_closed ```python def is_closed(self) > bool ``` item doc **type** func **brief** check camera device is closed or not **return** closed or not, bool type **static** False **C++ defination code**: ```cpp bool is_closed() ``` #### width ```python def width(self) > int ``` item doc **type** func **brief** Get camera width **return** camera width **static** False **C++ defination code**: ```cpp int width() ``` #### height ```python def height(self) > int ``` item doc **type** func **brief** Get camera height **return** camera height **static** False **C++ defination code**: ```cpp int height() ``` #### fps ```python def fps(self) > int ``` item doc **type** func **brief** Get camera fps **return** camera fps **static** False **C++ defination code**: ```cpp int fps() ``` #### format ```python def format(self) > maix.image.Format ``` item doc **type** func **brief** Get camera output format **return** camera output format, image::Format object **static** False **C++ defination code**: ```cpp image::Format format() ``` #### buff\\_num ```python def buff_num(self) > int ``` item doc **type** func **brief** Get camera buffer number **return** camera buffer number **static** False **C++ defination code**: ```cpp int buff_num() ``` #### hmirror ```python def hmirror(self, value: int 1) > int ``` item doc **type** func **brief** Set/Get camera horizontal mirror **return** camera horizontal mirror **static** False **C++ defination code**: ```cpp int hmirror(int value 1) ``` #### vflip ```python def vflip(self, value: int 1) > int ``` item doc **type** func **brief** Set/Get camera vertical flip **return** camera vertical flip **static** False **C++ defination code**: ```cpp int vflip(int value 1) ``` #### device ```python def device(self) > str ``` item doc **type** func **brief** Get camera device path **return** camera device path **static** False **C++ defination code**: ```cpp std::string device() ``` #### write\\_reg ```python def write_reg(self, addr: int, data: int, bit_width: int 8) > maix.err.Err ``` item doc **type** func **brief** Write camera register **param** **addr**: register address
    **data**: register data
    **bit_width**: register data bit width, default is 8
    **return** error code, err::ERR_NONE means success, others means failed **static** False **C++ defination code**: ```cpp err::Err write_reg(int addr, int data, int bit_width 8) ``` #### read\\_reg ```python def read_reg(self, addr: int, bit_width: int 8) > int ``` item doc **type** func **brief** Read camera register **param** **addr**: register address
    **bit_width**: register data bit width, default is 8
    **return** register data, 1 means failed **static** False **C++ defination code**: ```cpp int read_reg(int addr, int bit_width 8) ``` #### show\\_colorbar ```python def show_colorbar(self, enable: bool) > maix.err.Err ``` item doc **type** func **brief** Camera output color bar image for test **param** **enable**: enable/disable color bar
    **return** error code, err::ERR_NONE means success, others means failed **static** False **C++ defination code**: ```cpp err::Err show_colorbar(bool enable) ``` #### get\\_channel ```python def get_channel(self) > int ``` item doc **type** func **brief** Get channel of camera **return** channel number **static** False **C++ defination code**: ```cpp int get_channel() ``` #### set\\_resolution ```python def set_resolution(self, width: int, height: int) > maix.err.Err ``` item doc **type** func **brief** Set camera resolution **param** **width**: new width
    **height**: new height
    **return** error code, err::ERR_NONE means success, others means failed **static** False **C++ defination code**: ```cpp err::Err set_resolution(int width, int height) ``` #### exposure ```python def exposure(self, value: int 1) > int ``` item doc **type** func **brief** Set/Get camera exposure **attention** This method will affect the isp and thus the image, so please be careful with it. **param** **value**: exposure time. unit: us
    If value 1, return exposure time.
    If value ! 0, set and return exposure time.
    **return** camera exposure time **static** False **C++ defination code**: ```cpp uint64_t exposure(uint64_t value 1) ``` #### gain ```python def gain(self, value: int 1) > int ``` item doc **type** func **brief** Set/Get camera gain **attention** This method will affect the isp and thus the image, so please be careful with it. **param** **value**: camera gain.
    If value 1, returns camera gain.
    If value ! 0, set and return camera gain.
    **return** camera gain **static** False **C++ defination code**: ```cpp uint32_t gain(uint32_t value 1) ``` #### luma ```python def luma(self, value: int 1) > int ``` item doc **type** func **brief** Set/Get camera luma **attention** This method will affect the isp and thus the image, so please be careful with it. **param** **value**: luma value, range is [0, 100]
    If value 1, returns luma value.
    If value ! 0, set and return luma value.
    **return** returns luma value **static** False **C++ defination code**: ```cpp uint32_t luma(uint32_t value 1) ``` #### constrast ```python def constrast(self, value: int 1) > int ``` item doc **type** func **brief** Set/Get camera constrast **attention** This method will affect the isp and thus the image, so please be careful with it. **param** **value**: constrast value, range is [0, 100]
    If value 1, returns constrast value.
    If value ! 0, set and return constrast value.
    **return** returns constrast value **static** False **C++ defination code**: ```cpp uint32_t constrast(uint32_t value 1) ``` #### saturation ```python def saturation(self, value: int 1) > int ``` item doc **type** func **brief** Set/Get camera saturation **attention** This method will affect the isp and thus the image, so please be careful with it. **param** **value**: saturation value, range is [0, 100]
    If value 1, returns saturation value.
    If value ! 0, set and return saturation value.
    **return** returns saturation value **static** False **C++ defination code**: ```cpp uint32_t saturation(uint32_t value 1) ```"}} \ No newline at end of file diff --git a/maixpy/static/search_index/index_1.json b/maixpy/static/search_index/index_1.json new file mode 100644 index 00000000..ae127c2d --- /dev/null +++ b/maixpy/static/search_index/index_1.json @@ -0,0 +1 @@ +{"/maixpy/doc/zh/vision/qrcode.html":{"title":"MaixPy 二维码识别","content":" title: MaixPy 二维码识别 update: date: 2024 04 03 author: lxowalle version: 1.0.0 content: 初版文档 阅读本文前,确保已经知晓如何开发MaixCAM,详情请阅读[快速开始](../index.html) ## 简介 本文介绍如何使用MaixPy来识别二维码 ## 使用 MaixPy 识别二维码 MaixPy的 `maix.image.Image`中提供了`find_qrcodes`方法,用来识别二维码。 ### 如何识别二维码 一个简单的示例,实现识别二维码并画框 ```python from maix import image, camera, display cam camera.Camera(320, 240) disp display.Display() while 1: img cam.read() qrcodes img.find_qrcodes() for qr in qrcodes: corners qr.corners() for i in range(4): img.draw_line(corners[i][0], corners[i][1], corners[(i + 1) % 4][0], corners[(i + 1) % 4][1], image.COLOR_RED) img.draw_string(qr.x(), qr.y() 15, qr.payload(), image.COLOR_RED) disp.show(img) ``` 步骤: 1. 导入image、camera、display模块 ```python from maix import image, camera, display ``` 2. 初始化摄像头和显示 ```python cam camera.Camera(320, 240) # 初始化摄像头,输出分辨率320x240 RGB格式 disp display.Display() ``` 3. 从摄像头获取图片并显示 ```python while 1: img cam.read() disp.show(img) ``` 4. 调用`find_qrcodes`方法识别摄像头中的二维码 ```python qrcodes img.find_qrcodes() ``` `img`是通过`cam.read()`读取到的摄像头图像,当初始化的方式为`cam camera.Camera(320, 240)`时,`img`对象是一张分辨率为320x240的RGB图。 `img.find_qrcodes`用来寻找二维码,并将查询结果保存到`qrocdes`,以供后续处理 5. 处理识别二维码的结果并显示到屏幕上 ```python for qr in qrcodes: corners qr.corners() for i in range(4): img.draw_line(corners[i][0], corners[i][1], corners[(i + 1) % 4][0], corners[(i + 1) % 4][1], image.COLOR_RED) img.draw_string(qr.x(), qr.y() 15, qr.payload(), image.COLOR_RED) ``` `qrcodes`是通过`img.find_qrcodes()`查询二维码的结果,如果找不到二维码则`qrcodes`内部为空 `qr.corners()`用来获取已扫描到的二维码的四个顶点坐标,`img.draw_line()`利用这四个顶点坐标画出二维码的形状 `img.draw_string`用来显示二维码的内容和位置等信息,其中`qr.x()`和`qr.y()`用来获取二维码左上角坐标x和坐标y,`qr.payload()`用来获取二维码的内容 ### 常用参数说明 列举常用参数说明,如果没有找到可以实现应用的参数,则需要考虑是否使用其他算法实现,或者基于目前算法的结果扩展所需的功能 参数 说明 示例 roi 设置算法计算的矩形区域,roi [x, y, w, h],x,y表示矩形区域左上角坐标,w,h表示矩形区域的宽度和高度,默认为整张图片 计算坐标为(50,50),宽和高为100的区域
    ```img.find_qrcodes(roi [50, 50, 100, 100])``` 本文介绍常用方法,更多 API 请看 API 文档的 [image](../../../api/maix/image.html) 部分。"},"/maixpy/doc/zh/vision/self_learn_classifier.html":{"title":"MaixPy 自学习分类器","content":" title: MaixPy 自学习分类器 ## MaixPy 自学习分类器介绍 一般情况下我们要识别新的类别,需要在电脑端重新采集数据集并训练,步骤很麻烦,难度较高,这里提供一种不需要电脑端训练,而是直接在设备端就能秒学习新的物体,适合场景不太复杂的使用场景。 比如眼前有饮料瓶和手机,使用设备分别拍一张它们的照片作为两个分类的依据,然后再采集几张他们各个角度的照片,提取它们的特征保存,然后识别时根据图像的特征值分别和保存的特征值进行对比,和保存的哪个更相近就认为是对应的分类。 ## MaixPy 中使用自学习分类器 步骤: * 采集 n 张分类图。 * 采集 n*m 张图,每个分类采集 m 张,顺序无所谓。 * 启动学习。 * 识别图像输出结果。 简洁版本代码,完整版本请看例程里面的完整代码。 ```python from maix import nn, image classifier nn.SelfLearnClassifier(model \"/root/models/mobilenetv2.mud\", feature_layer None) img1 image.load(\"/root/1.jpg\") img2 image.load(\"/root/2.jpg\") img3 image.load(\"/root/3.jpg\") sample_1 image.load(\"/root/sample_1.jpg\") sample_2 image.load(\"/root/sample_2.jpg\") sample_3 image.load(\"/root/sample_3.jpg\") sample_4 image.load(\"/root/sample_4.jpg\") sample_5 image.load(\"/root/sample_5.jpg\") sample_6 image.load(\"/root/sample_6.jpg\") classifier.add_class(img1) classifier.add_class(img2) classifier.add_class(img3) classifier.add_sample(sample_1) classifier.add_sample(sample_2) classifier.add_sample(sample_3) classifier.add_sample(sample_4) classifier.add_sample(sample_5) classifier.add_sample(sample_6) classifier.learn() img image.load(\"/root/test.jpg\") max_idx, max_score classifier.classify(img) print(maix_idx, max_score) ```"},"/maixpy/doc/zh/vision/line_tracking.html":{"title":"MaixPy 寻找直线","content":" title: MaixPy 寻找直线 update: date: 2024 05 09 author: lxowalle version: 1.0.0 content: 初版文档 阅读本文前,确保已经知晓如何开发MaixCAM,详情请阅读[快速开始](../index.html) ## 简介 在视觉应用中,在巡迹小车、巡线机器人等应用中经常需要寻找线条的功能。本文将介绍: 如何使用MaixPy来实现巡线功能 如何使用MaixCam的默认应用程序巡线 ## 如何使用MaixPy来寻找直线 MaixPy的 `maix.image.Image`中提供了`get_regression`方法来寻找直线 ### 代码示例 一个简单的示例,实现寻找并画出直线 ```python from maix import camera, display, image cam camera.Camera(320, 240) disp display.Display() # thresholds [[0, 80, 40, 80, 10, 80]] # red thresholds [[0, 80, 120, 10, 0, 30]] # green # thresholds [[0, 80, 30, 100, 120, 60]] # blue while 1: img cam.read() lines img.get_regression(thresholds, area_threshold 100) for a in lines: img.draw_line(a.x1(), a.y1(), a.x2(), a.y2(), image.COLOR_GREEN, 2) theta a.theta() rho a.rho() if theta > 90: theta 270 theta else: theta 90 theta img.draw_string(0, 0, \"theta: \" + str(theta) + \", rho: \" + str(rho), image.COLOR_BLUE) disp.show(img) ``` 步骤: 1. 导入image、camera、display模块 ```python from maix import image, camera, display ``` 2. 初始化摄像头和显示 ```python cam camera.Camera(320, 240)\t# 初始化摄像头,输出分辨率320x240 RGB格式 disp display.Display() ``` 3. 从摄像头获取图片并显示 ```python while 1: img cam.read() disp.show(img) ``` 4. 调用`get_regression`方法寻找摄像头图片中的直线,并画到屏幕上 ```python lines img.get_regression(thresholds, area_threshold 100) for a in lines: img.draw_line(a.x1(), a.y1(), a.x2(), a.y2(), image.COLOR_GREEN, 2) theta a.theta() rho a.rho() if theta > 90: theta 270 theta else: theta 90 theta img.draw_string(0, 0, \"theta: \" + str(theta) + \", rho: \" + str(rho), image.COLOR_BLUE) ``` `img`是通过`cam.read()`读取到的摄像头图像,当初始化的方式为`cam camera.Camera(320, 240)`时,`img`对象是一张分辨率为320x240的RGB图。 `img.get_regression`用来寻找直线, `thresholds` 是一个颜色阈值列表,每个元素是一个颜色阈值,同时找到多个阈值就传入多个,每个颜色阈值的格式为 `[L_MIN, L_MAX, A_MIN, A_MAX, B_MIN, B_MAX]`,这里的 `L`、`A`、`B` 是`LAB`颜色空间的三个通道,`L` 通道是亮度,`A` 通道是红绿通道,`B` 通道是蓝黄通道。`pixels_threshold`是一个像素面积的阈值,用来过滤一些不需要直线。 `for a in lines`用来遍历返回的`Line`对象, 其中`a`就是当前的`Line`对象。通常`get_regression`函数只会返回一个`Line`对象,如果需要寻找多条直线,可以尝试使用`find_line`方法 使用`img.draw_line`来画出找到的线条,`a.x1(), a.y1(), a.x2(), a.y2()`分别代表直线两端的坐标 使用`img.draw_string`在左上角显示直线与x轴的夹角, `a.theta()`是直线与y轴的夹角, 这里为了方便理解转换成直线与x轴的夹角`theta`,`a.rho()`是原点与直线的垂线的长度. 5. 通过maixvision运行代码,就可以寻线啦,看看效果吧 ![image 20240509110204007](../../../static/image/line_tracking_demo.jpg) ### 常用参数说明 列举常用参数说明,如果没有找到可以实现应用的参数,则需要考虑是否使用其他算法实现,或者基于目前算法的结果扩展所需的功能 参数 说明 示例 thresholds 基于lab颜色空间的阈值,threshold [[l_min, l_max, a_min, a_max, b_min, b_max]],分别表示:
    亮度范围为[l_min, l_max]\\
    绿色到红色的分量范围为[l_min, l_max]
    蓝色到黄色的分量范围为[b_min, b_max]
    可同时设置多个阈值 设置两个阈值来检测红色和绿色
    ```img.find_blobs(threshold [[0, 80, 40, 80, 10, 80], [0, 80, 120, 10, 0, 30]])```
    红色阈值为[0, 80, 40, 80, 10, 80]
    绿色阈值为[0, 80, 120, 10, 0, 30] invert 使能阈值反转,使能后传入阈值与实际阈值相反,默认为False 使能阈值反转
    ```img.find_blobs(invert True)``` roi 设置算法计算的矩形区域,roi [x, y, w, h],x,y表示矩形区域左上角坐标,w,h表示矩形区域的宽度和高度,默认为整张图片 计算坐标为(50,50),宽和高为100的区域
    ```img.find_blobs(roi [50, 50, 100, 100])``` area_threshold 过滤像素面积小于area_threshold的直线,单位为像素点,默认为10。该参数可用于过滤一些无用的小直线 过滤面积小于1000的直线
    ```img.find_blobs(area_threshold 1000)``` pixels_threshold 过滤有效像素点小于pixels_threshold的直线,默认为10。该参数可用于过滤一些无用的小直线 过滤有效像素点小于1000的直线
    ```img.find_blobs(pixels_threshold 1000)``` 本文介绍常用方法,更多 API 请看 API 文档的 [image](../../../api/maix/image.html) 部分。 ## 如何使用MaixCam的默认应用程序寻找直线 为了快速验证寻找直线的功能,可以先使用MaixCam提供的`line_tracking`应用程序来体验寻找直线的效果。 ### 使用方法 1. 选择并打开`Line tracking`应用 2. 点击屏幕中需要识别的直线,左侧会显示该直线的颜色 3. 点击左侧(界面中`L A B`下方的颜色)需要检测的颜色 4. 此时就可以识别到对应的直线了,同时串口也会输出直线的坐标和角度信息。 ### 演示 ### 进阶操作 #### 手动设置LAB阈值寻找直线 APP提供手动设置LAB阈值来精确的寻找直线 操作方法: 1. `点击`左下角`选项图标`,进入配置模式 2. 将`摄像头对准`需要`寻找的物体`,`点击`屏幕上的`目标直线`,此时界面中`L A B`下方会显示该物体对应颜色的`矩形框`,并显示该物体颜色的`LAB值`。 3. 点击下方选项`L Min,L Max,A Min,A Max,B Min,B Max`,点击后右侧会出现滑动条来设置该选项值。这些值分别对应LAB颜色格式的L通道、A通道和B通道的最小值和最大值 4. 参考步骤2计算的物体颜色的`LAB值`,将`L Min,L Max,A Min,A Max,B Min,B Max`调整到合适的值,即可识别到对应的直线。 例如`LAB (20, 50, 80)`,由于`L 20`,为了适配一定范围让`L Min 10`,`L Max 30`;同理,由于`A 50`,让`A Min 40`,`A Max 60`; 由于`B 80`,让`B Min 70`,`B Max 90`。 #### 通过串口协议获取检测数据 寻找直线应用支持通过串口(默认波特率为115200)上报检测到的直线信息。 由于上报信息只有一条,这里直接用示例来说明上报信息的内容。 例如上报信息为: ```shell AA CA AC BB 0E 00 00 00 E1 09 FC 01 01 00 E9 01 6F 01 57 00 C1 C6 ``` `AA CA AC BB`:协议头部,内容固定 `0E 00 00 00`:数据长度,除了协议头部和数据长度外的总长度,这里表示长度为14 `E1`:标志位,用来标识串口消息标志 `09`:命令类型,对于寻找直线APP应用该值固定为0x09 `FC 01 01 00 E9 01 6F 01 57 00`:直线的两端坐标和角度信息,每个值用小端格式的2字节表示。`FC 01`和`01 00`表示第一个端点坐标为(508, 1),`E9 01`和`6F 01`表示第二个端点坐标为(489, 367),`57 00`表示直线与x轴的角度为87度 ` C1 C6`:CRC 校验值,用以校验帧数据在传输过程中是否出错"},"/maixpy/doc/zh/vision/ai.html":{"title":"AI 视觉基本知识","content":" title: AI 视觉基本知识 update: date: 2024 04 03 author: neucrack version: 1.0.0 content: 初版文档 ## 简介 如果没有 AI 基础,在学习 AI 前可以先看[什么是人工智能(AI)和机器学习](https://wiki.sipeed.com/ai/zh/basic/what_is_ai.html) 了解一下 AI 的基本概念。 然后我们使用的视觉 AI 一般都是基于`深度神经网络学习`这个方法,有兴趣可以看看[深度神经网络(DNN)基础知识](https://wiki.sipeed.com/ai/zh/basic/dnn_basic.html) ## MaixPy 中使用视觉 AI 在 MaixPy 中使用视觉 AI 很简单,默认提供了常用的 AI 模型,不需要自己训练模型就可以直接使用,在[MaixHub 模型库](https://maixhub.com/model/zoo) 中选择`maixcam` 就可以找到。 并且在底层已经封装好的 API,只需要简单的调用就可以实现。 如果你想训练自己的模型,也可以先从[MaixHub 在线训练](https://maixhub.com/model/training/project) 开始,在线平台只需要点点点就能训练出模型,不需要购买昂贵的机器,不需要搭建复杂的开发环境,也不需要写代码,非常适合入门,也适合懒得翻代码的老手。 一般训练得到了模型文件,直接传输到设备上,调用 MaixPy 的 API 就可以使用了,具体的调用方法看后文。"},"/maixpy/doc/zh/vision/camera.html":{"title":"MaixPy 摄像头使用","content":" title: MaixPy 摄像头使用 update: date: 2024 04 03 author: neucrack version: 1.0.0 content: 初版文档 ## 简介 对于 MaixCAM 默认搭载了 GC4653 摄像头,或者可选的 OS04A10 摄像头或者全局快门摄像头,甚至是 HDMI 转 MIPI 模块,都可以直接用简单的 API 调用。 ## API 文档 本文介绍常用方法,更多 API 使用参考 [maix.camera](/api/maix/camera.html) 模块的文档。 ## 摄像头切换 不同的摄像头使用不同的驱动,需要在系统中选择正确的驱动。 TODO:如何切换摄像头,比如 GC4653 和 OS04A10 之间的切换。 ## 从摄像头获取图像 使用 MaixPy 轻松获取: ```python from maix import camera cam camera.Camera(640, 480) while 1: img cam.read() print(img) ``` 这里我们从`maix`模块导入`camera`模块,然后创建一个`Camera`对象,指定图像的宽度和高度。然后在一个循环中不断读取图像, 默认出的图为`RGB`格式,如果需要`BGR`格式,其它格式请看 API 文档。 ## 跳过 开头的帧 摄像头初始化的一小段时间,可能图像采集还没稳定出现奇怪的画面,可以通过`skip_frames`函数跳过开头的几帧: ```python cam camera.Camera(640, 480) cam.skip_frames(30) # 跳过开头的30帧 ``` ## 显示图像 MaixPy 提供了`display`模块,可以方便的显示图像: ```python from maix import camera, display cam camera.Camera(640, 480) disp display.Display() while 1: img cam.read() disp.show(img) ```"},"/maixpy/doc/zh/vision/custmize_model.html":{"title":"MaixPy 自定义(离线训练) AI 模型和运行","content":" title: MaixPy 自定义(离线训练) AI 模型和运行 update: date: 2024 4 23 version: v1.0 author: dragonforward content: 加入了YOLOv5s部署 > 本文来自社区用户 dragonforward 的贡献 > 本博客将向你展示零基础一步步的部署好自己的yolov5s模型(博主展示的是安全帽模型),训练就引用我自己之前写过的,已经训练好的可以跳过该部分,其中有部分不一样。 ## 获得自定义训练得到的yolov5s onnx模型 ### 准备自定义数据集(博主用的是VOC数据集) `数据集目录结构`如下: ``` └─VOC2028:\t\t自定义数据集 ├─Annotations\t存放的是数据集标签文件,xml格式 ├─ImageSets\t\t数据集的划分文件 │ └─Main ├─JPEGImages\t存放的是数据集图片 ``` `分割数据集` 在split_train_val.py文件路径下执行`python3 split_train_val.py`会得到一下目录结构: ``` └─VOC2028:\t\t自定义数据集 ├─Annotations\t存放的是数据集标签文件,xml格式 ├─ImageSets\t\t数据集的划分文件 │ └─Main test.txt └─test.txt └─train.txt └─val.txt ├─JPEGImages\t存放的是数据集图片 ├─split_train_val.py\t分割数据集的py文件 ``` `split_train_val.py文件代码如下`: ``` # * coding: utf 8 * \"\"\" Author:dragonforward 简介:分训练集、验证集和测试集,按照 8:1:1 的比例来分,训练集8,验证集1,测试集1 \"\"\" import os import random import argparse parser argparse.ArgumentParser() # xml文件的地址,根据自己的数据进行修改 xml一般存放在Annotations下 parser.add_argument(' xml_path', default 'Annotations/', type str, help 'input xml label path') # 数据集的划分,地址选择自己数据下的ImageSets/Main parser.add_argument(' txt_path', default 'ImageSets/Main/', type str, help 'output txt label path') opt parser.parse_args() train_percent 0.8 # 训练集所占比例 val_percent 0.1 # 验证集所占比例 test_persent 0.1 # 测试集所占比例 xmlfilepath opt.xml_path txtsavepath opt.txt_path total_xml os.listdir(xmlfilepath) if not os.path.exists(txtsavepath): os.makedirs(txtsavepath) num len(total_xml) list list(range(num)) t_train int(num * train_percent) t_val int(num * val_percent) train random.sample(list, t_train) num1 len(train) for i in range(num1): list.remove(train[i]) val_test [i for i in list if not i in train] val random.sample(val_test, t_val) num2 len(val) for i in range(num2): list.remove(val[i]) file_train open(txtsavepath + '/train.txt', 'w') file_val open(txtsavepath + '/val.txt', 'w') file_test open(txtsavepath + '/test.txt', 'w') for i in train: name total_xml[i][: 4] + '\\n' file_train.write(name) for i in val: name total_xml[i][: 4] + '\\n' file_val.write(name) for i in list: name total_xml[i][: 4] + '\\n' file_test.write(name) file_train.close() file_val.close() file_test.close() ``` `voc转label得到label文件` 目录结构如下: ``` └─VOC2028:\t\t自定义数据集 ├─Annotations\t存放的是数据集标签文件,xml格式 ├─ImageSets\t\t数据集的划分文件 │ └─Main ├─JPEGImages\t存放的是数据集图片 └─labels\t\tyolov5将此文件夹当作训练的标注文件夹 └─voc_label.py ``` `voc_label.py文件代码如下`: ``` # * coding: utf 8 * import xml.etree.ElementTree as ET import os sets ['train', 'val', 'test'] # 如果你的Main文件夹没有test.txt,就删掉'test' classes [\"hat\", \"people\"] # 改成自己的类别,VOC数据集有以下20类别 # classes [\"brickwork\", \"coil\",\"rebar\"] # 改成自己的类别,VOC数据集有以下20类别 # classes [\"aeroplane\", 'bicycle', 'bird', 'boat', 'bottle', 'bus', 'car', 'cat', 'chair', 'cow', 'diningtable', 'dog', # 'horse', 'motorbike', 'person', 'pottedplant', 'sheep', 'sofa', 'train', 'tvmonitor'] # class names # abs_path os.getcwd() /root/yolov5/data/voc_label.py abs_path '/root/yolov5/data/' def convert(size, box): dw 1. / (size[0]) dh 1. / (size[1]) x (box[0] + box[1]) / 2.0 1 y (box[2] + box[3]) / 2.0 1 w box[1] box[0] h box[3] box[2] x x * dw w w * dw y y * dh h h * dh return x, y, w, h def convert_annotation(image_id): in_file open(abs_path + '/VOC2028/Annotations/%s.xml' % (image_id), encoding 'UTF 8') out_file open(abs_path + '/VOC2028/labels/%s.txt' % (image_id), 'w') tree ET.parse(in_file) root tree.getroot() size root.find('size') w int(size.find('width').text) h int(size.find('height').text) for obj in root.iter('object'): difficult obj.find('difficult').text # difficult obj.find('Difficult').text cls obj.find('name').text if cls not in classes or int(difficult) 1: continue cls_id classes.index(cls) xmlbox obj.find('bndbox') b (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text), float(xmlbox.find('ymax').text)) b1, b2, b3, b4 b # 标注越界修正 if b2 > w: b2 w if b4 > h: b4 h b (b1, b2, b3, b4) bb convert((w, h), b) out_file.write(str(cls_id) + \" \" + \" \".join([str(a) for a in bb]) + '\\n') for image_set in sets: if not os.path.exists(abs_path + '/VOC2028/labels/'): os.makedirs(abs_path + '/VOC2028/labels/') image_ids open(abs_path + '/VOC2028/ImageSets/Main/%s.txt' % (image_set)).read().strip().split() list_file open(abs_path + '/VOC2028/%s.txt' % (image_set), 'w') for image_id in image_ids: list_file.write(abs_path + '/VOC2028/JPEGImages/%s.jpg\\n' % (image_id)) # 要么自己补全路径,只写一半可能会报错 convert_annotation(image_id) list_file.close() ``` ![picture 0](./assets/custmize_model8.png) ### 训练模型 配置环境 ``` git clone https://github.com/ultralytics/yolov5 cd yolov5 pip install r requirements.txt pip install onnx ``` 下载预训练权重(博主尝试了v7.0的和v6.0的pt都可以) ``` https://github.com/ultralytics/yolov5/releases/download/v7.0/yolov5s.pt ``` ![picture 1](./assets/custmize_model11.png) 训练(博主使用的是学校的集群进行训练) ``` python3 train.py weights weights/yolov5s.pt cfg models/yolov5s.yaml data data/safthat.yaml epochs 150 batch size 16 multi scale device 0 ``` ![picture 2](./assets/custmize_model9.png) ``` python3 detect.py source /root/yolov5/data/images/000000.jpg weights /root/yolov5/runs/train/exp13/weights/best.pt conf thres 0.25 ``` ![picture 3](./assets/custmize_model10.png) 导出onnx模型,由于学校服务器目前去教学上课去了,他们上完课才能分配我就用电脑本机的conda环境导出 下面为啥使用` imgsz 224 320`,原因就是比较适配屏幕,加上我尝试640*640的,摄像头报错,提示是640*480这样,然后我就看到sipeed那个yolov5s是320*224的,我也就和他保持一致吧 ``` python export.py weights yolov5s_hat.pt include onnx opset 16 imgsz 224 320 ``` ![picture 4](./assets/custmize_model5.png) 模型查看通过网址输入netron.app查看三个输出: ![picture 5](./assets/custmize_model2.png) 下面是博主的三个输出 ``` onnx::Shape_329 onnx::Shape_384 onnx::Shape_439 ``` ## 模型转化(关键) ### 安装docker环境(已安装过的可以跳过) ``` 安装docker依赖的基础软件 sudo apt get update sudo apt get install apt transport https ca certificates curl gnupg agent software properties common 添加官方来源 curl fsSL https://download.docker.com/linux/ubuntu/gpg sudo apt key add sudo add apt repository \"deb [arch amd64] https://download.docker.com/linux/ubuntu $(lsb_release cs) stable\" 安装 docker sudo apt get update sudo apt get install docker ce docker ce cli containerd.io ``` ### 开始量化模型实操(!!!) ### 准备工作 ``` https://github.com/sophgo/tpu mlir/releases/tag/v1.7 上面网址下载 tpu mlir resource.tar 和 tpu_mlir 1.7 py3 none any.whl ``` ![picture 6](./assets/custmize_model3.png) 为什么拉取最新版,因为我用3.1版本失败了,工具在一直更新,最好保持最新,可以看下面图片我使用3.1版本也试过 ![picture 7](./assets/custmize_model7.png) ``` docker pull sophgo/tpuc_dev:latest 进入容器后将上面的准备的两个文件拷贝到workspace目录 root@3d517bc7f51f:/workspace/model_yolov5s# cd .. root@3d517bc7f51f:/workspace# ls model_yolov5s tpu mlir resource tpu mlir resource.tar tpu_mlir 1.7 py3 none any.whl root@3d517bc7f51f:/workspace# 下面两个二选一,我建议是第二个,离线安装 pip install tpu_mlir[all]或者pip install tpu_mlir * py3 none any.whl[all] 博主是选的第二个 pip install tpu_mlir 1.7 py3 none any.whl 以及安装它的全部依赖 pip install tpu_mlir 1.7 py3 none any.whl[all] 解压 tar xvf tpu mlir resource.tar 修改文件夹名字 mv regression/ tpu mlir resource/ mkdir model_yolov5s && cd model_yolov5s cp rf ../tpu_mlir_resource/dataset/COCO2017 . cp rf ../tpu_mlir_resource/image . 把之前准备好的图片100张一集一张测试图片和onnx模型传递到如下 root@3d517bc7f51f:/workspace# cd model_yolov5s/ root@3d517bc7f51f:/workspace/model_yolov5s# ls COCO2017 image workspace yolov5n_hat.onnx yolov5s_hat.onnx root@3d517bc7f51f:/workspace/model_yolov5s# cd COCO2017/ root@3d517bc7f51f:/workspace/model_yolov5s/COCO2017# ls 000000.jpg 000011.jpg 000022.jpg 000032.jpg 000042.jpg 000053.jpg 000066.jpg 000076.jpg 000086.jpg 000096.jpg 000002.jpg 000012.jpg 000023.jpg 000033.jpg 000043.jpg 000054.jpg 000067.jpg 000077.jpg 000087.jpg 000101.jpg 000003.jpg 000013.jpg 000024.jpg 000034.jpg 000044.jpg 000055.jpg 000068.jpg 000078.jpg 000088.jpg 000102.jpg 000004.jpg 000014.jpg 000025.jpg 000035.jpg 000045.jpg 000058.jpg 000069.jpg 000079.jpg 000089.jpg 000103.jpg 000005.jpg 000015.jpg 000026.jpg 000036.jpg 000046.jpg 000059.jpg 000070.jpg 000080.jpg 000090.jpg 000104.jpg 000006.jpg 000016.jpg 000027.jpg 000037.jpg 000048.jpg 000061.jpg 000071.jpg 000081.jpg 000091.jpg 000105.jpg 000007.jpg 000017.jpg 000028.jpg 000038.jpg 000049.jpg 000062.jpg 000072.jpg 000082.jpg 000092.jpg 000106.jpg 000008.jpg 000019.jpg 000029.jpg 000039.jpg 000050.jpg 000063.jpg 000073.jpg 000083.jpg 000093.jpg 000107.jpg 000009.jpg 000020.jpg 000030.jpg 000040.jpg 000051.jpg 000064.jpg 000074.jpg 000084.jpg 000094.jpg 000108.jpg 000010.jpg 000021.jpg 000031.jpg 000041.jpg 000052.jpg 000065.jpg 000075.jpg 000085.jpg 000095.jpg 000109.jpg root@3d517bc7f51f:/workspace/model_yolov5s/COCO2017# ls l grep \"^ \" wc l 100 root@3d517bc7f51f:/workspace/model_yolov5s/COCO2017# ls l grep \"^ \" wc l可以查看一下图片多少个,COCO2017文件下的图片博主替换了安全帽的100张图片以及测试图片同样 回到 model_yolov5s root@3d517bc7f51f:/workspace/model_yolov5s/COCO2017# cd .. root@3d517bc7f51f:/workspace/model_yolov5s# ls COCO2017 image workspace yolov5n_hat.onnx yolov5s_hat.onnx root@3d517bc7f51f:/workspace/model_yolov5s# 接着 mkdir workspace && cd workspace 执行下面命令ONNX 转 MLIR(记得output_names换为自己的) model_transform \\ model_name yolov5s \\ model_def ../yolov5s_hat.onnx \\ input_shapes [[1,3,224,320]] \\ mean 0.0,0.0,0.0 \\ scale 0.0039216,0.0039216,0.0039216 \\ keep_aspect_ratio \\ pixel_format rgb \\ output_names onnx::Shape_329,onnx::Shape_439,onnx::Shape_384 \\ test_input ../image/hat.jpg \\ test_result yolov5s_top_outputs.npz \\ mlir yolov5s.mlir 执行下面命令MLIR 转 INT8 模型,转 INT8 模型前需要跑 calibration, 得到校准表 run_calibration yolov5s.mlir \\ dataset ../COCO2017 \\ input_num 100 \\ o yolov5s_cali_table 接着执行下面 model_deploy \\ mlir yolov5s.mlir \\ quantize INT8 \\ calibration_table yolov5s_cali_table \\ processor cv181x \\ test_input yolov5s_in_f32.npz \\ test_reference yolov5s_top_outputs.npz \\ tolerance 0.85,0.45 \\ model yolov5s_cv181x_int8_sym.cvimodel 最后你会得到如下: root@3d517bc7f51f:/workspace/model_yolov5s/workspace# ls _weight_map.csv yolov5s_cv181x_int8_sym.cvimodel yolov5s_origin.mlir build_flag.json yolov5s_cv181x_int8_sym_final.mlir yolov5s_top_f32_all_origin_weight.npz final_opt.onnx yolov5s_cv181x_int8_sym_tensor_info.txt yolov5s_top_f32_all_weight.npz yolov5s.mlir yolov5s_cv181x_int8_sym_tpu.mlir yolov5s_top_outputs.npz yolov5s_cali_table yolov5s_in_f32.npz yolov5s_tpu_addressed_cv181x_int8_sym_weight.npz yolov5s_cv181x_int8_sym yolov5s_opt.onnx.prototxt yolov5s_tpu_addressed_cv181x_int8_sym_weight_fix.npz root@3d517bc7f51f:/workspace/model_yolov5s/workspace# ``` 通过上述步骤,你就可以得到量化后的可以部署到开发板上的模型的 解答: 上面为什么会是cv181x,因为我自己先用了一个实验了一下,然后报错如下: ``` [I] load cvimodel from: /root/models/yolov5n.cvimodel cvimodel built for cv180x CANNOT run on platform cv181x failed to parse cvimodel ``` ### 实机运行 `yolov5s_hat.mud内容如下`如下: ``` [basic] type cvimodel model yolov5s_hat_cv181x_int8_sym.cvimodel [extra] model_type yolov5 input_type rgb mean 0, 0, 0 scale 0.00392156862745098, 0.00392156862745098, 0.00392156862745098 anchors 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326 labels hat,person ``` 运行代码 ``` from maix import camera, display, image, nn, app detector nn.YOLOv5(model \"/root/models/yolov5s_hat.mud\") cam camera.Camera(detector.input_width(), detector.input_height(), detector.input_format()) dis display.Display() print(\"www\") print(detector.input_width(),detector.input_height(), detector.input_format()) while not app.need_exit(): img cam.read() objs detector.detect(img, conf_th 0.5, iou_th 0.45) for obj in objs: img.draw_rect(obj.x, obj.y, obj.w, obj.h, color image.COLOR_RED) msg f'{detector.labels[obj.class_id]}: {obj.score:.2f}' img.draw_string(obj.x, obj.y, msg, color image.COLOR_RED) dis.show(img) ``` ![picture 8](./assets/custmize_model4.png) 其中10.84.117.1就是ip地址,将cvmodel和mud上传到`/root/models/` 路径下 ![picture 9](./assets/custmize_model1.png) 打包完成后安装应用然后运行就行,也可以ide运行 ![picture 10](./assets/custmize_model6.png) 视频链接: ``` https://www.bilibili.com/video/BV1xz421S7Rx/?spm_id_from 333.999.0.0&vd_source b1fff0f773136d7d05331087929c7739 ``` ## 感谢 感谢`谁说现在是冬天呢 `一些思路"},"/maixpy/doc/zh/vision/object_track.html":{"title":"","content":""},"/maixpy/doc/zh/vision/maixhub_train.html":{"title":"使用 MaixHub 在线训练 AI 模型给 MaixPy 使用","content":" title: 使用 MaixHub 在线训练 AI 模型给 MaixPy 使用 update: date: 2024 04 03 author: neucrack version: 1.0.0 content: 初版文档 ## 简介 MaixHub 提供了在线训练 AI 模型的功能,可以直接在浏览器中训练模型,不需要购买昂贵的机器,不需要搭建复杂的开发环境,也不需要写代码,非常适合入门,也适合懒得翻代码的老手。 ## 使用 MaixHub 训练模型的基本步骤 ### 确认要识别的数据类型和模型类型 要训练一个 AI 模型,需要先确定是什么数据和模型,目前 MaixHub(2024.4)提供了图像数据的`物体分类模型`和`物体检测模型`,都是图像识别模型, `物体分类模型` 比 `物体检测模型` 更简单,因为物体检测需要标注物体在图中的位置,会比较麻烦,物体分类则只需要给出图像中是什么,不需要坐标,所以更简单, 如果是初学者建议先从物体分类开始。 ### 采集数据 如前面的 AI 基础所说,要训练模型,必须准备训练用的数据集让 AI 学习,对于图像训练,我们需要创建一个数据集,并且上传图片到数据集。 保证设备已经连接网络(WiFi)。 打开设备上的 MaixHub 应用选择 采集数据 来拍照并一键上传到 MaixHub。需要先在 MaixHub 创建数据集,然后点击 设备 上传数据,会出现一个 二维码,设备扫描二维码来与MaixHub 建立连接。 注意要分清训练集和验证集的区别,要想实机运行的效果和训练效果相当,验证集的数据一定要和实机运行拍摄的图像质量一样,训练集也建议用设备拍摄的,如果要用网上的图片,一定只能用在训练集,不要用在验证集,因为数据量小,数据集与实机运行越接近越好。 ### 标注数据 对于分类模型,在上传的时候就顺便已经标注好了,即上传时选择好了图片属于那个分类。 对于目标检测模型,上传完成后需要进行手动标注,即在每一张图中框出要被识别物体的坐标大小和分类。 这个标注过程你也可以选择自己在自己的电脑中离线用比如 labelimg 这样的软件标注完毕后使用数据集中的导入功能导入到 MaixHub。 标注时善用快捷键标注起来会更快,后面MaixHub 也会增加更多辅助标注和自动标注工具(目前在上传视频处有自动标注工具也可以尝试使用)。 ### 训练模型 选择训练参数训练,选择对应的设备平台,选择 maixcam,等待排队训练,可以实时看到训练进度,等待完成即可。 ### 部署模型 训练完成后,可以设备的 MaixHub 应用中选择 部署 功能,扫码进行部署。 设备开会自动下载模型并且运行起来,模型会被存在本地,后面也能选择再次运行。 如果你觉得识别效果很不错,可以一键分享到模型库让更多人使用。 ## 使用方法 请到 [MaixHub](https://maixhub.com) 注册账号,然后登录,主页有视频教程,学习即可。 注意教程如果是使用了 M2dock 这个开发板,和 MaixCAM也是类似的,只是设备(板子)上使用的 MaixHub 应用可能稍微有点区别,大体上是相同的,请注意举一反三。"},"/maixpy/doc/zh/basic/app_usage.html":{"title":"应用使用说明","content":" title: 应用使用说明 开机后会自动进入应用选择界面,内置各种应用均发布在 [MaixHub 应用商店](https://maixhub.com/app), 可以在这里找到对应应用的介绍和使用说明。 上手用得比较多的是 `设置 > 语言`, 以及 `设置 > WiFi`,`应用商店`应用可以用来升级和安装应用,连接上可以连接互联网的 WiFi 后即可在[MaixHub 应用商店](https://maixhub.com/app)扫码安装应用。 另外,你编写的应用也可以上传到[MaixHub 应用商店](https://maixhub.com/app)分享给其他人使用,质量合格和优秀的应用都会得到官方红包打赏,优秀应用也会得到大家的赞同和支持。 无论是小到一个采集传感器的数据小应用还是功能复杂的应用,让我们一起来创造更多有趣的东西吧!"},"/maixpy/doc/zh/basic/maixpy_upgrade.html":{"title":"更新 MaixPy","content":" title: 更新 MaixPy 有两种方法,如果第一次上手使用,为了降低难度,可以直接使用出厂 TF 卡自带的 MaixPy 固件尝试,以后再考虑更新。 不过因为不知道你拿到手的是什么时候出厂的 TF 卡,所以建议都更新一下系统。 ## 直接更新系统 按照 [升级和烧录系统](./os.html) 中的操作升级到最新的系统,里面就包含了最新的 MaixPy 固件。 ## 只更新 MaixPy 固件 在 [MaixPy 仓库 release 页面](https://github.com/sipeed/MaixPy/releases) 看到最新的版本信息和更新日志,其中包含了 MaixPy 固件信息,以及对应版本使用的系统信息。 如果不想更新系统(因为一般系统变动不大,可以看 MaixPy 更新日志中是否有系统改动相关,再决定是否更新系统),则可以只更新 MaixPy 固件。 * 在设置中设置 WiFi, 让系统联网。 * 点击设置应用中的 `更新 MaixPy` 进行更新。 > 如果你会使用终端, 也可以在终端中使用 `pip install MaixPy U` 来更新 MaixPy。"},"/maixpy/doc/zh/basic/os.html":{"title":"升级和烧录系统","content":" title: 升级和烧录系统 ## 介绍 如果你购买了官方(Sipeed)的带 TF 卡的套餐,一般来说出厂已经烧录好了系统,可以跳过这一步直接使用。 但是为了防止出厂烧录的系统版本过旧,强烈建议先按照教程升级到最新的系统。 ## 如何确认系统是否需要升级 * 在开机后的功能选择界面,点击`设置`,然后点击`设备信息`,可以看到系统的版本号。 * 到[MaixPy 发布历史页面](https://github.com/sipeed/MaixPy/releases)查看更新日志,里面有 MaixPy 固件和系统镜像的更新说明,如果在你的版本后有重要更新,建议升级。 > 如果最新系统和当前系统对比只是 MaixPy 固件的常规更新,也可以不升级,在 `设置` 中的 `更新 MaixPy` 中单独更新 `MaixPy` 即可。 ## 获得最新系统 在 [MaixPy 发布页面](https://github.com/sipeed/MaixPy/releases) 找到最新的系统镜像文件,比如`maixcam_os_20240401_maixpy_v4.1.0.xz`。 备用地址: * [Sourceforge](https://sourceforge.net/projects/maixpy/files/) ## 烧录系统到 MaixCAM 参考 [MaixCAM 系统烧录](https://wiki.sipeed.com/hardware/zh/maixcam/os.html) 教程。"},"/maixpy/doc/zh/faq.html":{"title":"MaixPy FAQ(常见问题)","content":" title: MaixPy FAQ(常见问题) 此页面列出了 MaixPy 相关的常见问题和解决方案,如果你遇到了问题,请先在这里找寻答案。 如果这个页面找不到答案,可以到 [MaixHub 讨论版块](https://maixhub.com/discussion) 将问题的详细步骤发贴提问。 如果你使用的是 MaixCAM, 也可以参考 [MaixCAM FAQ](https://wiki.sipeed.com/hardware/zh/maixcam/faq.html) ## MaixVision 无法搜索到设备? 先确认连接方式是 WiFi 还是 USB 线, **WiFi**: * 确认 WiFi 是否正确连接上并且获取到 IP 地址, 可以在 `设置 >设备信息` 或者`设置 >WiFi` 里面看到 `ip`。 **USB线**: * 确保设备通过 Type C 数据线连接到电脑,设备处于开机状态并且进入了功能选择界面。 * 确保设备驱动已经安装: * Windows 下可以在`设备管理器`中查看是否有 USB 虚拟网卡设备,如果有感叹号则是去动没有安装好,按照[快速开始](./index.html) 中的方法安装驱动即可。 * Linux 下可以通过`ifconfig`或者`ip addr`查看是否有`usb0`设备或者`lsusb`查看所有 USB 设备。 Linux 已经自带去动,所以识别不到检查硬件连接,设备系统是否是最新,以及设备是否已经正常启动即可。 * Mac OS 同 Linux 方法。 * 另外 检查 USB 线缆的质量,换一个高质量的线缆。 * 另外 检查电脑 USB 口的质量,比如实测某些小主机 USB 口 EMI 设计太糟糕,外接一个质量好点的 USB HUB 反而可以使用了,也可以换 USB 口 或者直接换台电脑。 ## MaixVision 运行摄像头例程显示图像卡顿 默认配的 GC4653 摄像头最高帧率为 30 帧,摄像头例程正常情况下 MaixVision 的显示肉眼不会有卡顿感,如果卡顿,首先考虑传输问题: * 检查网络连接质量,比如 WiFi。 * 如果用的 USB 连接,检查 USB 线质量, 电脑 USB 口质量,可以尝试换台电脑或者 USB 口 或者 USB 线缆尝试对比。 ## MaixPy v4 和 v1 v3 有什么区别? * MaixPy v4 使用 Python 语言,是吸取了 v1 v3 经验的集大成之作,有更好的配套软件和生态,更多的功能,更简单的使用方式和更完善的文档;硬件有很大提升的同时加个和另外两者的硬件价格想当甚至更便宜;另外也做了兼容 K210 的使用体验和 API,方便用户从 v1 快速迁移到 v4。 * v1 使用了 Micropython 语言,有很多局限性,比如第三方库支持有限;同时受限于 Maix I (K210) 的硬件性能,内存不够用,AI 模型支持有限,很多编解码不支持硬件加速等缺点。 * v3 也是使用了 Python 语言,基于 Maix II Dock (v831) 硬件,硬件 AI 模型支持有限,而且全志的基础生态不够开放,API 也不够完善,此版本仅作为 Maix II Dock (v831)上面使用,不会继续更新。 ## MaixPy 目前只支持 MaixCAM 吗,用其它同款芯片的板子行不行? MaixPy 目前仅支持 MaixCAM 系列板子,其它同款芯片的板子也不支持(包括 Sipeed 的同款芯片板子 比如 LicheeRV Nano),强烈不建议尝试,导致设备损坏(比如冒烟烧屏等)后果自负。 未来 Sipeed 出的 Maix 系列的产品都将继续得到 MaixPy 支持,目前如果 MaixCAM 有什么无法满足的需求,可以到 [MaixHub 讨论版块](https://maixhub.com/discussion) 提出需求或者发送邮件到 support@sipeed.com. ## 可以用除了官方搭配的摄像头或者屏幕以外的自己的摄像头或者屏幕吗? 不建议这样操作,除非你有够丰富的软硬件知识和经验,否则可能导致设备损坏。 官方搭配的配件对应的软硬件是调教过的,表现效果是最好的,上手即可使用,其它配件可能接口不同,驱动不同,软件不同,需要自己去调教,这是一个非常复杂的过程,不建议尝试。 当然,如果你是大佬,我们也欢迎你提交 PR! ## 运行模型报错 cvimodel built for xxxcv181x CANNOT run on platform cv181x 解析模型文件失败了,一般情况是模型文件损坏造成的,确保你的模型文件是没有损坏的。 比如: * 如果是从网上下载的,保证下载没有出问题,一般网上的文件提供 sha256sum/md5 校验值,下载下来后可以对比一下,具体方法请自行搜索或者问 ChatGPT。 * 如果是来自压缩包,请确认解压过程没有出错,可以从压缩包重新解压一遍保证中间没有出错。 * 保证传输到设备的过程没有造成文件损坏,可以对比一下设备中的文件和电脑中的文件 sha256sum 值,具体方法请自性搜索或者问 ChatGPT。 ## 上电启动黑屏,屏幕无显示 * 检查是否安装了 TF(micro SD)卡。 * 检查 TF 卡里面是否烧录了最新的系统镜像(强烈推荐烧录到最新的系统镜像),具体烧录方法看文档。 * 检查 TF 卡是否完全插进到了 TF 卡口,确保没有缝隙和松动。 * 检查屏幕和摄像头排线是否正确扣紧了,不能出现松动现象。 * 检查板子上的电源灯(红灯)以及系统运行状态灯(蓝灯)是否亮起,如果红灯不亮则考虑硬件问题,比如无供电或者供电不足或者板子烧坏了。 * 用 USB 转 TTL 连接电脑和板子的串口,电脑打开串口助手,让板子重启,查看启动日志里面是否有报错。 > 如果没有日志输出,可以尝试交换一下 TX 和 RX 接线, 对于 MaixCAM, Type C 转 串口小板插的方向不一样 TX RX 可能反向,即不支持正反插。"},"/maixpy/doc/zh/source_code/faq.html":{"title":"MaixPy 源代码常见问题","content":"MaixPy 源代码常见问题 ## subprocess.CalledProcessError: Command '('lsb_release', ' a')' returned non zero exit status 1. 以 root 身份编辑 `/usr/bin/lsb_release`,将第一行从 `#!/usr/bin/python3` 更改为 `python3`。 然后重新编译,应该就可以工作了。 ## ImportError: arg(): could not convert default argument 'format: maix::image::Format' in method '.**init**' into a Python object (type not registered yet?) Pybind11 需要你先注册 `image::Format`,然后才能在 `camera::Camera` 中使用它,所以我们必须先在生成的 `build/maixpy_wrapper.cpp` 源文件中定义 `image::Format`。 要实现这一点,请编辑 `components/maix/headers_priority.txt`,被依赖的应该放在依赖它的前面。 例如: ``` maix_image.hpp maix_camera.hpp ``` ## /usr/bin/ld: /lib/libgdal.so.30: undefined reference to `std::condition_variable::wait(std::unique_lock&)@GLIBCXX_3.4.30' collect2: error: ld returned 1 exit status 一般在为 Linux 构建时并且使用 conda 环境时容易出现,conda 环境中的一些库编译参数问题,解决方法就是不用 conda 即可, 或者单独找到 conda 中的那个库,替换成系统的或者直接删掉(会从系统找)"},"/maixpy/doc/zh/source_code/add_c_module.html":{"title":"给 MaixPy 添加一个 C/C++ 模块","content":" title: 给 MaixPy 添加一个 C/C++ 模块 ## 简介 有时候需要高效地执行某个函数, Python 的速度无法满足时,就可以使用 C/C++ 或者其它编译型语言来实现。 ## 通用函数封装 如果你想封装的函数实现的功能不依赖 MaixPy 的其它功能,直接使用 Python 使用 C/C++ 添加模块的通用方法,具体方法可以自行百度,比如 ffi, ctype 等 > 欢迎 PR 添加方法 ## 如果你的模块还想依赖 MaixPy 的其它基础 API 你需要先学会编译使用 [MaixCDK](https://github.com/sipeed/MaixCDK), 因为 MaixPy 就是从 MaixCDK 生成的 API, MaixPy 里面有的功能 MaixCDK 里面也有, 然后 。。。TODO"},"/maixpy/doc/zh/source_code/maixcdk.html":{"title":"切换到 MaixCDK 使用 C/C++ 开发应用","content":" title: 切换到 MaixCDK 使用 C/C++ 开发应用 除了使用 MaixPy 开发,还有对应的 C/C++ SDK 可以使用,项目名称为 [MaixCDK](https://github.com/sipeed/MaixCDK)。 ## MaixCDK 介绍 MaixPy 基于 MaixCDK 构建,MaixPy 的大多数 API 都是基于 MaixCDK 的 API 自动生成的,所以 MaixPy 有的功能 MaixCDK 都包含。 如果你更熟悉 C/C++ 编程,或者需要更高的性能,可以使用 MaixCDK 进行开发。 ## MaixCDK 使用 MaixCDK 代码仓库地址:[github.com/sipeed/MaixCDK](https://github.com/sipeed/MaixCDK), 你可以在这里找到 MaixCDK 的代码和文档。"},"/maixpy/doc/zh/source_code/build.html":{"title":"MaixPy 开发源代码指南","content":" title: MaixPy 开发源代码指南 ## 获取源代码 ```shell mkdir p ~/maix cd ~/maix git clone https://github.com/sipeed/MaixPy ``` ## 获取 MaixCDK 源码 MaixPy 项目依赖于 MaixCDK,需要先克隆它,放到电脑的某个目录(勿放在 MaixPy 目录下) ```shell cd ~/maix git clone https://github.com/sipeed/MaixCDK ``` 然后需要设置环境变量 `MAIXCAK_PATH` 指定 MaixCDK 的路径,可以在 `~/.bashrc` 或者`~/.zshrc`(根据你使用的shell决定)添加: ```shell export MAIXCAK_PATH ~/maix/MaixCDK ``` 只有在成功设置环境变量后, MaixPy 才能找到 MaixCDK 源码。 ## 构建并打包成 wheel 文件 ```shell cd ~/maix/MaixPy python setup.py bdist_wheel maixcam ``` `maixcam` 可以被替换为其他板卡配置, 请查看 `MaixPy/platforms` 目录。 构建成功后, 你会在 `dist` 目录中找到 wheel 文件, 传输到设备(开发板),在设备终端中使用 `pip install U MaixPy****.wheel` 在你的设备上安装或升级。 > `python setup.py bdist_wheel maixcam skip build` 不会执行构建命令, 只会打包 wheel 文件, 因此你可以先使用 `maixcdk menuconfig` 和 `maixcdk build` 来自定义构建。 > 另外如果你是在调试 API,需要频繁安装,使用 pip 安装会比较慢,可以直接编译后拷贝 `maix` 目录到设备的 `/usr/lib/python3.11/site packages`目录下覆盖旧的文件即可。 ## 手动构建 ```shell maixcdk build ``` ## 修改源代码后运行测试 * 首先, 构建源代码 ```shell maixcdk build ``` * 如果为 PC 自身构建(平台 `linux`): 然后执行 `./run.sh your_test_file_name.py` 来运行 Python 脚本。 ```shell cd test ./run.sh examples/hello_maix.py ``` * 如果为板卡交叉编译: * 最快的方式是将 `maix` 目录复制到设备的 `/usr/lib/python3.11/site packages/` 目录, 然后在设备上运行脚本。 * 或者打包 wheel 文件并在设备上使用 `pip install U MaixPy****.wheel` 安装, 然后在设备上运行脚本。 ## 本地预览文档 文档位于 [docs](https://github.com/sipeed/MaixPy/tree/main/docs) 目录, 使用 `Markdown` 格式, 你可以使用 [teedoc](https://github.com/teedoc/teedoc) 来生成网页版本的文档。 API 文档会在构建 MaixPy 固件时生成, **如果你没有构建 MaixPy, API 文档将会是空的**。 ```shell pip install teedoc U cd docs teedoc install i https://pypi.tuna.tsinghua.edu.cn/simple teedoc serve ``` 然后访问 `http://127.0.0.1:2333` 在网页浏览器中预览文档。 ## 对于想要贡献的开发者 请查看 [MaixPy 开发源代码指南](./contribute.html) 如果在使用源代码时遇到任何问题, 请先参考 [FAQ](./faq.html)。"},"/maixpy/doc/zh/source_code/contribute.html":{"title":"参与 MaixPy 文档修改和贡献代码","content":" title: 参与 MaixPy 文档修改和贡献代码 ## 参与 MaixPy 文档修改 * 点击要修改的文档右上角的`编辑本页`按钮,进入 github 源文档页面。 * 保证已经登录了 GitHub 账号。 * 在 github 预案文档页面点击右上角铅笔按钮修改文档内容。 * github 会提示需要 fork 一份到自己的仓库,点击 fork 按钮。 > 这一步就是将 MaixPy 源码仓库复刻一份到你自己的账号下,这样你就可以自由修改了。 * 修改文档内容,然后在页面底部填写修改说明,点击提交修改。 * 然后在你的仓库中找到 Pull requests 按钮,点击创建一个 Pull requests。 * 然后在弹出的页面中填写修改说明,点击提交 Pull requests,其它人和管理员就可以在[Pull requests 页面](https://github.com/sipeed/MaixPy/pulls)看到你的修改了。 * 等待管理员审核通过后,你的修改就会合并到 MaixPy 源码仓库中了。 * 合并成功后,文档会自动更新到 [MaixPy 官方文档](https://wiki.sipeed.com/maixpy)。 > 文档经过 CDN 缓存了的,可能需要等待一段时间才能看到更新,紧急更新可以联系管理员手动刷新。 > 也可以访问 [en.wiki.sipeed.com/maixpy](https://en.wiki.sipeed.com/maixpy) 查看 github pages 服务版本,这个是没有缓存实时更新的。 ## 参与 MaixPy 代码贡献 * 访问 MaixPy 代码仓库地址:[github.com/sipeed/MaixPy](https://github.com/sipeed/MaixPy) * 在修改代码前最好先创建一个 [issue](https://github.com/sipeed/MaixPy/issues) ,描述你要修改的内容让大家知道你的想法和计划,这样大家可以参与修改讨论,以免重复劳动。 * 点击右上角的 fork 按钮,将 MaixPy 代码仓库复刻一份到你自己的账号下。 * 然后在你的账号下 clone 一份代码到本地。 * 修改代码后提交到你的仓库中。 * 然后在你的仓库中找到 Pull requests 按钮,点击创建一个 Pull requests。 * 然后在弹出的页面中填写修改说明,点击提交 Pull requests,其它人和管理员就可以在[Pull requests 页面](https://github.com/sipeed/MaixPy/pulls)看到你的修改了。 * 等待管理员审核通过后,你的修改就会合并到 MaixPy 源码仓库中了。 > 需要注意的是 MaixPy 的代码大多数是从 [MaixCDK](https://github.com/sipeed/MaixCDK) 自动生成的,所以如果你修改 C/C++ 源码,很有可能你需要先修改这个仓库。"},"/maixpy/doc/zh/projects/index.html":{"title":"MaixPy 项目实战 介绍和汇总","content":" title: MaixPy 项目实战 介绍和汇总 ## 简介 这里提供一些常见的项目实战示例,方便社区成员可以参考复现使用,也方便激发大家的灵感做出更多更好的应用和项目出来。 要找到用 MaixPy 实现的相关的项目,有几种方式: ## MaixPy 官方文档 也就是本文档左边目录可以找到的项目实战,比如`小车巡线`。 如果你有好的项目,或者好的项目推荐,也可以贡献文档添加进来。 ## MaixHub 项目分享广场 在[MaixHub 项目分享](https://maixhub.com/share?type project) 栏目可以找到项目分享。 有高质量的分享也会被链接到 MaixPy 官方文档。 你也可以分享你的项目制作方法,会获得官方(必获得)以及社区成员的现金打赏(通常高质量能解决急需需求的更容易被打赏)。 推荐项目: * maixcam部署yolov5s 自定义模型: https://maixhub.com/share/23 ## MaixHub 应用分享 除了项目分享以外,还可以在[MaixHub 应用商店](https://maixhub.com/app) 找到可以直接运行的应用,有部分应用可能是用 MaixPy 编写的,如果作者提供了源码或者写了详细的教程也都可以参考。 推荐项目: * 简易HTTP串流服务器: https://maixhub.com/app/19 * 桌面电脑性能监视器: https://maixhub.com/app/13 * 安全帽检测模型应用: https://maixhub.com/app/10"},"/maixpy/doc/zh/projects/line_tracking_robot.html":{"title":"MaixPy 小车巡线","content":" title: MaixPy 小车巡线 update: date: 2024 05 09 author: lxowalle version: 1.0.0 content: 初版文档 阅读本文前,确保已经知晓如何开发MaixCAM,详情请阅读[快速开始](../index.html) ## 简介 本文将介绍如何使用MaixPy实现寻线小车 ## 如何使用MaixPy实现寻线小车 1. 准备MaixCAM与小车 2. 实现寻线功能 3. 实现小车控制功能 ### 准备MaixCAM与小车 TODO ### 实现寻线功能 使用`image`模块的`get_regression`可以快速寻找到直线,详情见[寻找直线](./line_tracking.html) 代码实现: ```python from maix import camera, display, image cam camera.Camera(320, 240) disp display.Display() # thresholds [[0, 80, 40, 80, 10, 80]] # red thresholds [[0, 80, 120, 10, 0, 30]] # green # thresholds [[0, 80, 30, 100, 120, 60]] # blue while 1: img cam.read() lines img.get_regression(thresholds, area_threshold 100) for a in lines: img.draw_line(a.x1(), a.y1(), a.x2(), a.y2(), image.COLOR_GREEN, 2) theta a.theta() rho a.rho() if theta > 90: theta 270 theta else: theta 90 theta img.draw_string(0, 0, \"theta: \" + str(theta) + \", rho: \" + str(rho), image.COLOR_BLUE) disp.show(img) ``` 上述代码实现了寻线功能, 上述参数中需注意: 设置合适的thresholds值来寻找到对应的直线 设置合适的area_threshold值来过滤环境干扰,可以过滤一些面积小的直线 使用`a.theta()`获取直线的角度 使用`a.rho()`获取直线与原点(原点在左上角)的距离 根据实际环境调试好寻线参数后, 就可以利用`a.theta()`和`a.rho()`控制小车方向了。 ### 实现小车控制功能 TODO"},"/maixpy/doc/zh/pro/compile_os.html":{"title":"","content":""},"/maixpy/doc/zh/modules/acc.html":{"title":"","content":""},"/maixpy/doc/zh/modules/tof.html":{"title":"","content":""},"/maixpy/doc/zh/peripheral/i2c.html":{"title":"MaixPy 使用 I2C","content":" title: MaixPy 使用 I2C 对于 MaixCAM,由于引脚资源比较紧张,引出的 I2C 引脚和 WiFi 模块(SDIO1)重合了,所以 WiFi 和硬件 I2C 只能二选一使用。 所以推荐使用 IO 模拟 I2C。 > 注意需要 MaixPy 镜像和固件 > 4.1.2(不包含) ## IO 模拟 I2C 模拟 `I2C` 只需要引脚使用 `GPIO` 功能即可,在 `MaixCAM` 上,模拟 `I2C` 被固定在引脚`A15`(`SCL`),`A27`(`SDA`),并且`i2c`编号为`5`, 要使用,只需要: ```python from maix import i2c, pinmap # pinmap.set_pin_function(\"A15\", \"GPIOA23\") # pinmap.set_pin_function(\"A27\", \"GPIOA24\") bus1 i2c.I2C(5, i2c.Mode.MASTER) slaves bus1.scan() print(\"find slaves:\", slaves) ``` 更多 API 看 [i2c API 文档](https://wiki.sipeed.com/maixpy/api/maix/peripheral/i2c.html) ## 硬件 I2C 如上面所说, 对于 `MaixCAM` 硬件 `I2C` 和 `WiFi` 只能二选一,如果一定要用,需要禁用`WiFi`,使用`pinmap`模块设置引脚功能为 `I2C`,在使用`maix.i2c`模块操作。 > TODO: 提供禁用 WiFi 的方法(需要系统里面禁用掉 WiFi 驱动,比较复杂) 硬件`I2C`及对应的引脚看图: ![](http://wiki.sipeed.com/hardware/zh/lichee/assets/RV_Nano/intro/RV_Nano_3.jpg) ```python from maix import i2c, pinmap pinmap.set_pin_function(\"P18\", \"I2C1_SCL\") pinmap.set_pin_function(\"P21\", \"I2C1_SDA\") bus1 i2c.I2C(1, i2c.Mode.MASTER) slaves bus1.scan() print(\"find slaves:\", slaves) ```"},"/maixpy/doc/zh/peripheral/pwm.html":{"title":"MaixPy 使用 PWM","content":" title: MaixPy 使用 PWM ## 简介 在 MaixPy (v4) 中使用 `PWM`,先使用`pinmap`设置引脚的功能为 `PWM`,在使用。 以及每个 `PWM` 有对应的引脚,根据 MaixCAM 的引脚图可以看到: ![](http://wiki.sipeed.com/hardware/zh/lichee/assets/RV_Nano/intro/RV_Nano_3.jpg) 这里我们推荐使用`PWM6` 和 `PWM7`。 对于 `MaixCAM` 因为`WiFi` 使用了`SDIO1`的所有引脚,所以`PWM4~9`只能和`WiFi`二选一使用。 > TODO: 提供禁用 WiFi 的方法(需要系统里面禁用掉 WiFi 驱动,比较复杂) ## MaixPy 使用 PWM 控制舵机 这里我们以控制舵机为例, 使用`MaixCAM`的`PWM7`和`A19`引脚: ```python from maix import pwm, time, pinmap SERVO_PERIOD 50 # 50Hz 20ms SERVO_MIN_DUTY 2.5 # 2.5% > 0.5ms SERVO_MAX_DUTY 12.5 # 12.5% > 2.5ms # Use PWM7 pwm_id 7 # !! set pinmap to use PWM7 pinmap.set_pin_function(\"A19\", \"PWM7\") def angle_to_duty(percent): return (SERVO_MAX_DUTY SERVO_MIN_DUTY) * percent / 100.0 + SERVO_MIN_DUTY out pwm.PWM(pwm_id, freq SERVO_PERIOD, duty angle_to_duty(0), enable True) for i in range(100): out.duty(angle_to_duty(i)) time.sleep_ms(100) for i in range(100): out.duty(angle_to_duty(100 i)) time.sleep_ms(100) ``` 这里的功能是控制舵机从最小角度旋转到最大角度再旋转回最小角度。"},"/maixpy/doc/zh/peripheral/spi.html":{"title":"MaixPy 使用 SPI","content":" title: MaixPy 使用 SPI TODO:"},"/maixpy/doc/zh/peripheral/uart.html":{"title":"MaixPy UART 串口使用介绍","content":" title: MaixPy UART 串口使用介绍 ## 串口简介 串口是一种通信方式,包含了硬件和通信协议的定义。 * 硬件包括: * 3 个引脚: `GND`, `RX`, `TX`,通信双发交叉连接 RX TX, 即一方 TX 发送到另一方的 RX, 双方 GND 连接到一起。 * 控制器,一般在芯片内部,也叫 UART 外设,一般一个芯片有一个或者多个 UART 控制器,每个控制器有相对应的引脚。 * 通信协议: 为了让双方能顺利通信,规定了一套协议,具体可以自行学习,常见的参数有 波特率 校验位等,波特率是我们用得最多的参数。 通过板子的串口,可以和其它单片机或者 SOC 进行数据通信,比如可以在 MaixCAM 上实现人体检测功能,检测到坐标后通过串口发送给 STM32 单片机。 ## MaixPy 中使用串口 对于 MaixCAM 默认从 USB 口引出了一个串口,可以插上配套的 Type C 转接小板,就能直接使用上面的串口引脚, 也可以不用转接板,直接使用板子上的 `A16(TX)` 和 `A17(RX)`引脚, 和 USB 口引出的是同样的引脚,是等效的。 对于 MaixCAM 使用 USB 引出的串口时需要**注意**,Typc C 正插和反插,转接小板上的 `RX` 和 `TX`会交换,所以当你发现无法通信时,有可能就是 RX TX 反了,可以尝试将 Type C 翻转一面插再看看通信是否正常。这个算是设计缺陷,不过一般也不会经常拔插所以适应一下也能接受。 将两个通信的板子双方连接好后(通信双发交叉连接 RX TX, 即一方 TX 发送到另一方的 RX, 双方 GND 连接到一起),就可以使用软件了。 通过 MaixPy 使用串口很简单: ```python from maix import uart devices uart.list_devices() serial uart.UART(devices[0], 115200) serial.write_str(\"hello world\") print(\"received:\", serial.read(timeout 2000)) ``` 先列出了系统的所有串口设备,然后这里使用了第一个,也就是上面说的 Type C 出 引出的串口。 更多串口的 API 请看 [UART API 文档](../../../api/maix/peripheral/uart.html) ## 其它写法,以及使用其它串口 ```python from maix import app, uart, pinmap, time import sys # pinmap.set_pin_function(\"A16\", \"UART0_TX\") # pinmap.set_pin_function(\"A17\", \"UART0_RX\") device \"/dev/ttyS0\" serial0 uart.UART(device, 115200) serial0.write(\"hello 1\\r\\n\".encode()) serial0.write_str(\"hello 2\\r\\n\") while not app.need_exit(): data serial0.read() if data: print(\"Received, type: {}, len: {}, data: {}\".format(type(data), len(data), data)) serial0.write(data) time.sleep_ms(1) # sleep 1ms to make CPU free ``` 这里先设置了引脚映射,特别是如果你要使用除了 UART0 以外的串口,根据图中的引脚号和 UART 使用`pinmap.set_pin_function`来设置 ![](http://wiki.sipeed.com/hardware/zh/lichee/assets/RV_Nano/intro/RV_Nano_3.jpg) 另外,这里循环里面加了一个 `sleep_ms` 是简单地释放一下 CPU,以达到程序不会占满 CPU 的效果,当然也有其它方式,这种方式最简单粗暴。"},"/maixpy/doc/zh/peripheral/gpio.html":{"title":"MaixPy 使用 GPIO","content":" title: MaixPy 使用 GPIO ## 简介 使用 GPIO 可以控制引脚输入或者输出高低电平,用来读取信号或者输出控制信号,十分常用。 ## MaixPy 中使用 GPIO > MaixPy 固件版本应该 > 4.1.2(不包含) 首先我们需要知道设备有哪些引脚和 GPIO,对于 MaixCAM 每个引脚都对应了一个 GPIO 控制器,如图: ![](http://wiki.sipeed.com/hardware/zh/lichee/assets/RV_Nano/intro/RV_Nano_3.jpg) 需要注意的是,引脚除了作为 GPIO 使用,还能用作其它功能比如 PWM 使用,使用前我们需要设置一下引脚的功能为 GPIO。 比如在 MaixCAM 上有些引脚默认已经被其它功能占用,比如 UART0, WiFi(SDIO1 + A26), 不建议使用它们,其它的可以使用,另外 A14 引脚连接到了板载的 LED,默认是作为系统的负载提示灯,如果初始化它会自动取消系统提示灯功能作为普通 GPIO 被使用(注意`A14`只能作为输出),这样你就能控制这颗 LED 的亮灭了。 ```python from maix import gpio, pinmap, time pinmap.set_pin_function(\"A14\", \"GPIOA14\") led gpio.GPIO(\"A14\", gpio.Mode.OUT) led.value(0) while 1: led.toggle() time.sleep_ms(500) ``` 这里先使用`pinmap`设置了`A14`引脚的功能为`GPIO`,当然,对于`A14`因为只有`GPIO`功能,可以不设置,为了程序通用起见,其它引脚可能需要设置,所以这里例程设置了。 更多 API 请看 [GPIO API 文档](https://wiki.sipeed.com/maixpy/api/maix/peripheral/gpio.html) ## GPIO 作为输入模式 ```python from maix import gpio, pinmap, time pinmap.set_pin_function(\"A19\", \"GPIOA19\") led gpio.GPIO(\"A19\", gpio.Mode.IN) while 1: print(led.value()) time.sleep_ms(1) # sleep to make cpu free ```"},"/maixpy/doc/zh/peripheral/wdt.html":{"title":"MaixPy 使用看门狗定时器","content":" title: MaixPy 使用看门狗定时器 ## 简介 为了防止程序出现问题,常常会用到看门狗定时器(WDT), 在程序出问题时自动重启系统。 原理就是有一个倒计时计数器,我们需要在程序的逻辑中定期地去设置这个倒计时时间(也叫喂狗),如果我们的程序在哪儿卡住了导致没有定期去设置倒计时,倒计时到 0 后硬件就会出发系统重启。 ## MaixPy 中使用 WDT ```python from maix import wdt, app, time w wdt.WDT(0, 1000) while not app.need_exit(): w.feed() # here sleep op is our operation # 200 ms is normal, if > 1000ms will cause system reset time.sleep_ms(200) ```"},"/maixpy/doc/zh/video/jpeg_streaming.html":{"title":"MaixPy 视频流 JPEG 推流 / 发送图片到服务器","content":" title: MaixPy 视频流 JPEG 推流 / 发送图片到服务器 update: date: 2024 04 03 author: neucrack version: 1.0.0 content: 初版文档 ## 简介 有时需要将图像发送到服务器,或者将摄像头的视频推送到服务器,这里提供一个最简单的方法,即压缩成 `JPEG` 图片,然后一张一张地发送到服务器。 注意,这是一种最简单的方法,不算很正规的视频推流方法,也不适合高分辨率高帧率的视频流,因为这只是一张一张发送图片,如果要高效推送视频流,请使用后文的 `RTSP` 或者 `RTMP` 模块。 ## 使用方法 ```python from maix import image import requests # create image img image.Image(640, 480, image.Format.FMT_RGB) # draw something img.draw_rect(60, 60, 80, 80, image.Color.from_rgb(255, 0, 0)) # convert to jpeg jpeg img.to_format(image.Format.FMT_JPEG) # image.Format.FMT_PNG # get jpeg bytes jpeg_bytes jpeg.to_bytes() # faster way, borrow memory from jpeg object, # but be carefully, when jpeg object is deleted, jpeg_bytes object MUST NOT be used, or program will crash # jpeg_bytes jpeg.to_bytes(copy False) # send image binary bytes to server url \"http://192.168.0.123:8080/upload\" res requests.post(url, data jpeg_bytes) print(res.status_code) print(res.text) ``` 可以看到,先将图片转换成了 `JPEG` 格式,然后将 `JPEG` 图片的二进制数据通过`TCP`发送到服务器。"},"/maixpy/doc/zh/audio/recognize.html":{"title":"","content":""},"/maixpy/doc/zh/basic/python.html":{"title":"Python 基础知识","content":" title: Python 基础知识 MaixPy 的教程文档里面就不涉及具体的 Python 语法教程了,因为 Python 的教程实在是太多了,都做得很好,这里只介绍需要学什么,方向和线路指导即可。 ## Python 简介 Python 是一门解释性、面向对象、动态类型的高级编程语言。 * 解释性:不需要编译,直接运行,优点是开发快速,缺点是因为每次运行都要解释一遍代码,运行速度慢一点点,但是往往瓶颈还是开发者写的代码而不是语言本身。 * 面向对象:支持面向对象编程,可以定义类和对象,相比面向过程语言,更容易组织代码。更多自行搜索。 * 动态类型:变量不需要声明类型,可以直接赋值,类型会根据赋值自动确定,这样可以减少代码量,但是也容易出现类型错误,需要开发者自己注意。 总之,对于没有接触过 Python 的开发者来说,Python 非常容易上手,有大量现成的库,开发者群体巨大,开发应用周期短,非常值得学习! ## Python 环境安装 你可以按照你学习的 Python 教程在电脑上安装 Python; 也可以在 MaixVisioin 上连接设备后使用 MaixVision 编程然后在开发板运行。 ## 使用 MaixPy 需要的 Python 基础有哪些? * Python 的基本概念。 * 面向对象编程的基本概念。 * Python 的基本语法,包括: * tab 缩进对齐语法 * 变量、函数、类、对象、注释等 * 控制语句比如 if、for、while 等等 * 模块和导入模块 * 基本数据类型比如 int、float、str、list、dict、tuple 等等 * bytes 和 str 的区别和转换 * 异常处理,try except * 常用的内置函数,比如 print、open、len、range 等等 * 常用的内置模块,比如 os、sys、time、random、math 等等 掌握以上的基础知识就可以顺畅使用 MaixPy 编程了,配合后面的教程和例程,在不懂的时候查询搜索引擎或者官方文档,或者问 ChatGPT 就能顺利完成开发。 ## 对于已经有一门面向对象编程语言经验的开发者 如果你已经会一门面向对象语言比如 C++/Java/C# 等等,那只需要快速浏览一下 Python 的语法,就可以开始使用了。 比如 [菜鸟教程](https://www.runoob.com/python3/python3 tutorial.html) 或者 [Python 官方教程](https://docs.python.org/3/tutorial/index.html)。 或者个人开发者的博客,比如 [哇!是 Python](https://neucrack.com/p/59)。 ## 对于没有面向对象编程经验但是有 C 语言经验的开发者 如果只学了 C,缺乏对面向对象的理解,那么可以先学习一下面向对象的概念,然后再学习 Python,也是比较快的,可以自行搜索视频教程入门。 跟着视频教程入门之后可以看看文档教程,比如 [菜鸟教程](https://www.runoob.com/python3/python3 tutorial.html) 或者 [Python 官方教程](https://docs.python.org/3/tutorial/index.html) 就可以开动了! 在学了入门知识后,就可以按照 MaixPy 的文档和例程开始使用 MaixPy 编程了。 ## 对于编程新手 如果你从未接触过编程,那么你需要重头开始学习 Python,Python 作为入门语言也是比较合适的,具体可以搜一搜视频教程。 在学会了基础语法后,就能按照例程使用 MaixPy 编程了。"},"/maixpy/doc/zh/basic/linux_basic.html":{"title":"Linux 基础知识","content":" title: Linux 基础知识 ## 简介 本章内容对于刚入门的同学来说,可以先跳过此章节,在学会 MaixPy 基础开发后再来学习也是可以的。 最新的 MaixPy 支持的 MaixCAM 硬件支持跑 Linux 系统,所以 MaixPy 底层都是基于 Linux 系统进行开发的。 虽然 Sipeed 开发的 MaixPy 已经为开发者们做了很多工作,即使不知道 Linux 系统知识也能愉快使用,但是以防在某些情况下需要一些底层操作,以及方便未接触过 Linux 的开发者学习,这里写一些 Linux 基础知识。 ## 为什么需要 Linux 系统 具体的原因大家可以自行查阅,这里用通俗的看起来不太专业的话语简单举几个例子方便初学者理解: * 在单片机中,我们的程序是一个死循环程序,用上 Linux 后我们可以同时跑很多程序,每个程序看起来都独立在同时运行,每个程序具体怎么执行的由操作系统实现。 * 基于 Linux 的开发者众多,需要功能和驱动可以很方便地找到,不需要自己再实现一遍。 * 基于 Linux 配套的软件工具丰富,可以很方便地进行开发和调试,比如在本教程没有提到的一些 Linux 通用工具理论上也是可以使用的。 ## 文件系统 什么是文件系统? * 就像电脑的文件系统一样,Linux 上会将硬件磁盘用文件系统进行管理,这样我们可以很方便地向磁盘读写数据。 * 对于学过单片机没有接触过文件系统开发的同学来讲,可以理解为我们有一个 Flash 或者 TF 卡,我们可以通过 API 读写 Flash 存取数据,断电后也能保存数据,但是 Flash 具有读写寿命,我们往往需要写一套程序去保证 Flash 读写寿命,而文件系统就可以理解成这样一套成熟的程序,文件系统帮我们完成了具体如何管理 Flash 空间和读写,我们只需调用文件系统的 API 即可,大大减少了我们的开发工作量并且用成熟的程序保证了稳定性和安全性。 ## 在电脑和设备(开发板)之间传输文件 既然设备有 Linux 和文件系统,那我们怎么发送文件到设备呢? 对于 MaixPy 我们配套了 MaixVision, 在后面的版本也会支持文件管理功能,在此之前可以用下面的方法: 这里我们主要介绍通过网络传输的方式,其它方式可自行探索`传输文件到 Linux`: * 确保设备和电脑连接到了同一个局域网,比如: * MaixCAM 的 USB 口连接到电脑会创建一个虚拟网卡,在电脑端的设备管理器就能看到,设备的 IP 可以在设备的`设置 >设备信息`中看到设备名和 IP。 * 也可以在设备`设置 >WiFi`中连接到和电脑相同的局域网。 * 电脑使用 SCP 或者 SFTP 协议传输文件到设备,具体的软件有很多,具体的软件和使用方法可以自行搜索,比如: * 在 Windows 上可以使用 WinSCP 或者 FileZilla,或者 scp 命令等。 * 在 Linux 上可以使用 FileZilla 或者 scp 命令 等。 * 在 Mac 上可以使用 FileZilla 或者 scp 命令 等。 ## 终端和命令行 终端就是通过`终端`这个软件与 Linux 系统进行通信和操作的工具,类似于 Windows 的`cmd`或者`PowerShell`。 比如我们可以在电脑的 Window 系统中的 powershell 或者 Linux系统中的 终端 工具中输入`ssh root@maixcam xxxx.local` 这里具体的名字在设备的`设置 >设备信息`中可以看到,这样我们就可以通过终端连接到设备了(用户名和密码都是`root`)。 然后我们通过输入命令来操作设备,比如`ls`命令可以列出设备文件系统中当前目录下的文件, `cd` 用来切换当前所在的目录(就像电脑文件管理中点击文件夹切换目录一样), ```shell cd / # 切换到根目录 ls # 显示当前目录(根目录)下的所有文件 ``` 然后会显示类似下面的内容: ```shell bin lib media root tmp boot lib64 mnt run usr dev linuxrc opt sbin var etc lost+found proc sys ``` 更多命令学习请自行搜索`Linux 命令行使用教程`,这里只是为了让初学者知道基本概念,这样有开发者提到时可以知道是什么意思。"},"/maixpy/doc/zh/basic/maixvision.html":{"title":"MaixVision -- MaixPy 编程 IDE + 图形化积木编程","content":" title: MaixVision MaixPy 编程 IDE + 图形化积木编程 ## 简介 [MaixVision](https://wiki.sipeed.com/maixvision) 是专为 Maix 生态打造的一款开发者编程工具,支持 MaixPy 编程和图形化积木编程,同时支持在线运行和调试,以及实时预览图像,可以同步设备显示屏的图像,方便调试和开发。 以及支持打包应用和安装应用到设备,方便用户一键生成、安装应用。 同时还集成一些方便开发的小工具,比如文件管理,阈值编辑器,二维码生成等等。 ## 下载 访问 [MaixVision 主页](https://wiki.sipeed.com/maixvision) 下载。 ## 使用 MaixPy 编程和在线运行 按照[快速开始](../index.html)的步骤连接设备,我们可以很方便地使用 MaixPy 编程和在线运行。 ## 实时预览图像 MaixPy 提供`display`模块,可以将图像显示到屏幕上,同时,在调用`display`模块的`show`方法时,会将图像发送到 MaixVision 显示,比如代码: ```python from maix import display, camera cam camera.Camera(640, 480) disp display.Display() while 1: disp.show(cam.read()) ``` 这里我们用摄像头读取了图像,然后通过`disp.show()`方法将图像显示到屏幕上,同时也会发送到 MaixVision 显示。 当我们点击了右上角的`暂停`按钮,就会停止发送图像到 MaixVision 显示。 ## 代码自动补全 代码提示依赖电脑本地的 Python 包,为了实现代码提示,我们需要在电脑中安装 Python,并且安装需要提示的 Python 包。 * 安装 Python 请访问 [Python 官网](https://python.org/)安装。 * 安装需要提示的包,比如对于 MaixPy, 你需要在电脑也安装一份 MaixPy 包,在电脑使用`pip install MaixPy`即可安装好,如果`MaixPy`更新了,你也需要在电脑和设备更新到`MaixPy`,电脑手动在终端执行`pip install MaixPy U`即可,设备更新直接在`设置`应用中更新即可。 > 中国国内用户可以使用国内镜像`pip install i https://pypi.tuna.tsinghua.edu.cn/simple MaixPy`。 * 重启 MaixVision 就能够看到代码提示了。 > 如果仍然不能提示,可以手动在设置中设置 python 可执行文件的路径后重启。 >! 注意在电脑安装 Python 包这里只是为了用作代码提示,实际代码运行还是在设备(开发板)上,设备上也要有对应的包才能正常运行。 > 另外,虽然你在电脑上安装了 MaixPy 包,但是由于我们精力有限,我们不确保你能直接在电脑的 Python 导入 maix 包进行使用,请在支持的设备上运行。 ## 计算图像的直方图 在上一步中我们可以在 MaixVision 中实时看到图像,我们用鼠标框选一个区域,图像下方就能看到这个区域的直方图了,选择不同的颜色表示方法,可以看到不同的颜色通道的直方图。 这个功能方便我们在做某些图像处理算法时找到一些合适的参数。 ## 区分`设备文件系统`和`电脑文件系统` 这里我们有一个比较重要的概念需要掌握:**分清楚`设备文件系统`和`电脑文件系统`**。 * **电脑文件系统**:运行在电脑上,在 MaixVision 中打开文件或者工程都是打开的电脑里面的文件,保存也是自动保存到电脑的文件系统。 * **设备文件系统**:程序运行时会将程序发送到设备上运行,所以代码里面使用的文件都是从设备文件系统读取。 所以常见的问题是有同学在电脑上保存了文件`D:\\data\\a.jpg`,然后在设备上使用这个文件`img image.load(\"D:\\data\\a.jpg\")`,这样当然是找不到文件的,因为设备上没有`D:\\data\\a.jpg`这个文件。 具体如何将电脑的文件发送到设备上,参考下面的章节。 ## 传输文件到设备 先连接设备,然后点击浏览设备文件系统的按钮,有两个入口,如下图,然后就能上传文件到设备,或者从设备下载文件到电脑了。 ![maixvision_browser2](../../assets/maixvision_browser2.jpg) ![maixvision_browser](../../assets/maixvision_browser.jpg) .. details::也可以用其它工具代替,点击展开 先知道设备的 ip 地址或者设备名称,MaixVision 就可以搜索到, 或者在设备`设置 >系统信息`中看到,比如类似 `maixcam xxxx.local` 或者 `192.168.0.123`。 用户名和密码都是 `root`, 使用 `SFTP` 协议传输文件,端口号是 `22`。 然后不同系统下都有很多好用的软件: ### Windows 下 使用 [WinSCP](https://winscp.net/eng/index.php) 或者 [FileZilla](https://filezilla project.org/) 等工具连接设备,将文件传输到设备上,选择 `SFTP` 协议填写设备和账号信息连接即可。 具体不懂的可以自行搜索。 ### Linux 下 终端使用 `scp` 命令传输文件到设备上,比如: ```bash scp /path/to/your/file.py root@maixcam xxxx.local:/root ``` ### Mac 下 * **方法一**:终端使用 `scp` 命令传输文件到设备上,比如: ```bash scp /path/to/your/file.py root@maixcam xxxx.local:/root ``` * **方法二**:使用 [FileZilla](https://filezilla project.org/) 等工具连接设备,将文件传输到设备上,选择 `SFTP` 协议填写设备和账号信息连接即可。 ## 使用图形化积木编程 开发中,敬请期待。"},"/maixpy/doc/zh/basic/python_pkgs.html":{"title":"添加额外的 Python 软件包","content":" title: 添加额外的 Python 软件包 ## 简介 MaixPy 基于 Python 语言,提供了大量方便嵌入式应用开发的功能和 API,除此之外,你也可以使用其它的 Python 包来扩展功能。 ## 安装额外的 Python 包 > 注意可能不是所有 Python 包都支持,一般只支持纯 Python 包,不支持 C 扩展包, C 扩展包可能需要你手动在电脑交叉编译(比较复杂,这里就不介绍了)。 ### 方法一: 使用 Python 代码来安装 在 MaixVision 中使用 Python 代码来安装你需要的包,比如: ```python import os os.system(\"pip install 包名\") ``` 要更新一个包,可以使用: ```python import os os.system(\"pip install upgrade 包名\") ``` ### 方法二: 终端使用 pip 命令安装 使用[Linux 基础](./linux_basic.html)中介绍的终端使用方法,使用 `pip install 包名` 安装你需要的包。"},"/maixpy/doc/zh/basic/app.html":{"title":"应用开发和应用商店","content":" title: 应用开发和应用商店 ## 应用生态简介 为了让开发板做到开箱即用,以及方便用户无门槛地使用,以及方便开发者分享自己的有趣应用,并且能有有效的渠道获取到反馈甚至是收益,我们推出了一个简易的应用框架,包括: * **[应用商店](https://maixhub.com/app)**: 开发者上传分享应用,用户无需开发直接下载使用,开发者可以获取到一定的现金收益(来自 MaixHub 官方以及用户打赏)。 * **出厂内置大量应用**: 官方提供了一些常用的应用,比如找色块、AI 物体检测追踪、找二维码、人脸识别等等,用户可以直接使用,也可以作为串口模块直接使用。 * **MaixPy + MaixCDK** 软件开发包:使用 [MaixPy](https://github.com/sipeed/maixpy) 或者 [MaixCDK](https://github.com/sipeed/MaixCDK) 可以用 Python 或者 C/C++ 语言快速开发嵌入式 AI 视觉听觉应用,超高效率实现你的有趣想法。 * **MaixVision** 配套电脑端开发工具: 全新的电脑端代码开发工具,快速上手、调试、运行、上传代码、安装应用到设备,一键式开发,甚至支持图像化积木式编程,小学生也能轻松上手。 大家可以多多关注应用商店,也可以在应用商店中分享自己的应用,大家一起共建活跃的社区。 ## 打包应用 使用 MaixPy + MaixVison 可以方便地开发、打包、安装应用: * 在 MaixVision 中使用 MaixPy 开发应用程序,可以是单个文件,也可以是一个工程目录。 * 连接设备。 * 点点击 MaixVision 左下角的 安装 按钮,会弹出一个界面填写应用的基本信息,id 是用来判别应用的 id,一个设备不能同时安装相同 id 的不同应用,所以 id 应该与 MaixHub 上面已经有的应用 id 不同,应用名字可以重复。以及图标等。 * 点击打包应用,会将应用打包成一个安装包,如果你要上传到 [MaixHub 应用商店](https://maixhub./com/app),用这个打包好的文件即可。 * 点击 安装应用,这会将打包好的应用安装到设备。 * 断开与设备的连接,就能看到设备功能选择界面多了一个你的应用,直接点进去就能运行。 > 如果你用 MaixCDK 开发,使用 `maixcdk relrease` 就能打包出来一个应用,具体看 MaixCDK 的文档。 ## 退出应用 如果你只是写了比较简单的应用,没有做界面和返回按钮,默认可以按设备上的功能按键(一般是 USER 或者 FUNC 或者 OK 按钮)或者返回按钮(如果有这个按键,MaixCAM 默认没有这个按键)来退出应用。 ## 应用开发基本准则 * 因为默认都配了触摸屏幕,推荐都写一个简单的界面显示,最好有触摸交互。实现方法可以在例子里面找找参考。 * 界面和按钮不要太小,因为 MaixCAM 默认的屏幕是 2.3寸 552x368分辨率,PPI 比较高屏幕比较小,要让手指能很容易戳到并且不会点错。 * 每个应用实现的主要功能实现一个简单的串口交互,基于[串口协议](https://github.com/sipeed/MaixCDK/blob/master/docs/doc/convention/protocol.md) ([例程](https://github.com/sipeed/MaixPy/tree/main/examples/communication/protocol)),这样用户可以直接当成串口模块使用,比如人脸检测应用,可以在检测到人脸后通过串口输出坐标。"},"/maixpy/doc/zh/vision/image_ops.html":{"title":"MaixPy 图像基础操作","content":" title: MaixPy 图像基础操作 update: date: 2024 04 03 author: neucrack version: 1.0.0 content: 初版文档 ## 简介 视觉应用中图像占据非常重要的位置,不管是图片还是视频,因为视频本质上就是一帧帧的图像,所以图像处理是视觉应用的基础。 ## API 文档 本文介绍常用方法, 更多 API 参考 [maix.image](/api/maix/image.html) 模块的文档。 ## 图像格式 MaixPy 提供基础图像模块`image`,里面最重要的就是`image.Image`类,用于图像的创建以及各种图像基础操作,以及图像加载和保存等。 图像格式有很多,一般我们用`image.Format.FMT_RGB888` 或者 `image.Format.FMT_RGBA8888` 或者 `image.Format.FMT_GRAYSCALE`或者`image.Format.FMT_BGR888`等。 大家知道 `RGB` 三色可以合成任意颜色,所以一般情况下我们使用 `image.Format.FMT_RGB888`就足够, `RGB888` 在内存中是 `RGB packed` 排列,即在内存中的排列: `像素1_红色, 像素1_绿色, 像素1_蓝色, 像素2_红色, 像素2_绿色, 像素2_蓝色, ...` 依次排列。 ## 创建图像 创建图像很简单,只需要指定图像的宽度和高度以及图像格式即可: ```python from maix import image img image.Image(320, 240, image.Format.FMT_RGB888) print(img) print(img.width(), img.height(), img.format()) ``` `320` 是图像的宽度,`240` 是图像的高度,`image.Format.FMT_RGB888` 是图像的格式,格式参数可以省略,默认是`image.Format.FMT_RGB888`。 这里通过`img.width()`、`img.height()`、`img.format()`可以获取图像的宽度、高度和格式。 ## 显示到屏幕 MaixPy 提供了`maix.display.Display`类,可以方便的显示图像: ```python from maix import image, display disp display.Display() img image.Image(320, 240, image.Format.FMT_RGB888) disp.show(img) ``` 注意这里因为没有图像数据,所以显示的是黑色的图像,修改画面看后文。 ## 从文件系统读取图像 MaixPy 提供了`maix.image.load`方法,可以从文件系统读取图像: ```python from maix import image img image.load(\"/root/image.jpg\") print(img) ``` 注意这里`/root/image.jpg` 是提前传输到了板子上的,方法可以看前面的教程。 可以支持 `jpg` 和 `png` 格式的图像。 ## 保存图像到文件系统 MaixPy 的`maix.image.Image`提供了`save`方法,可以保存图像到文件系统: ```python from maix import image img image.Image(320, 240, image.Format.FMT_RGB888) # do something with img img.save(\"/root/image.jpg\") ``` ## 画框 `image.Image`提供了`draw_rect`方法,可以在图像上画框: ```python from maix import image img image.Image(320, 240, image.Format.FMT_RGB888) img.draw_rect(10, 10, 100, 100, image.Color.from_rgb(255, 0, 0)) ``` 这里的参数依次是:`x`, `y`, `w`, `h`, `color`,`x` 和 `y` 是框的左上角坐标,`w` 和 `h` 是框的宽度和高度,`color` 是框的颜色,可以使用`image.Color.from_rgb`方法创建颜色。 可以用`thickness`指定框的线宽,默认是`1`, 也可以画实心框,传参 `thickness 1` 即可: ```python from maix import image img image.Image(320, 240, image.Format.FMT_RGB888) img.draw_rect(10, 10, 100, 100, (255, 0, 0), thickness 1) ``` ## 写字符串 `image.Image`提供了`draw_string`方法,可以在图像上写字: ```python from maix import image img image.Image(320, 240, image.Format.FMT_RGB888) img.draw_string(10, 10, \"Hello MaixPy\", image.Color.from_rgb(255, 0, 0)) ``` 这里的参数依次是:`x`, `y`, `text`, `color`,`x` 和 `y` 是文字的左上角坐标,`text` 是要写的文字,`color` 是文字的颜色,可以使用`image.Color.from_rgb`方法创建颜色。 还可以放大字体,传参 `scale` 即可: ```python img.draw_string(10, 10, \"Hello MaixPy\", image.Color.from_rgb(255, 0, 0), scale 2) ``` 获取字体的宽度和高度: ```python w, h img.string_size(\"Hello MaixPy\", scale 2) print(w, h) ``` **注意**这里`scale`是放大倍数,默认是`1`,和`draw_string`应该保持一致。 ## 画线 `image.Image`提供了`draw_line`方法,可以在图像上画线: ```python from maix import image img image.Image(320, 240, image.Format.FMT_RGB888) img.draw_line(10, 10, 100, 100, image.Color.from_rgb(255, 0, 0)) ``` 这里的参数依次是:`x1`, `y1`, `x2`, `y2`, `color`,`x1` 和 `y1` 是线的起点坐标,`x2` 和 `y2` 是线的终点坐标,`color` 是线的颜色,可以使用`image.Color.from_rgb`方法创建颜色。 ## 画圆 `image.Image`提供了`draw_circle`方法,可以在图像上画圆: ```python from maix import image img image.Image(320, 240, image.Format.FMT_RGB888) img.draw_circle(100, 100, 50, image.Color.from_rgb(255, 0, 0)) ``` 这里的参数依次是:`x`, `y`, `r`, `color`,`x` 和 `y` 是圆心坐标,`r` 是半径,`color` 是圆的颜色,可以使用`image.Color.from_rgb`方法创建颜色。 ## 缩放图像 `image.Image`提供了`resize`方法,可以缩放图像: ```python from maix import image img image.Image(320, 240, image.Format.FMT_RGB888) img_new img.resize(160, 120) print(img, img_new) ``` 注意这里`resize`方法返回一个新的图像对象,原图像不变。 ## 剪裁图像 `image.Image`提供了`crop`方法,可以剪裁图像: ```python from maix import image img image.Image(320, 240, image.Format.FMT_RGB888) img_new img.crop(10, 10, 100, 100) print(img, img_new) ``` 注意这里`crop`方法返回一个新的图像对象,原图像不变。 ## 旋转图像 `image.Image`提供了`rotate`方法,可以旋转图像: ```python from maix import image img image.Image(320, 240, image.Format.FMT_RGB888) img_new img.rotate(90) print(img, img_new) ``` 注意这里`rotate`方法返回一个新的图像对象,原图像不变。 ## 拷贝图像 `image.Image`提供了`copy`方法,可以拷贝一份独立的图像: ```python from maix import image img image.Image(320, 240, image.Format.FMT_RGB888) img_new img.copy() print(img, img_new) ``` ## 仿射变换 `image.Image`提供了`affine`方法,可以进行仿射变换,即提供当前图中三个及以上的点坐标,以及目标图中对应的点坐标,可以自动进行图像的旋转、缩放、平移等操作变换到目标图像: ```python from maix import image img image.Image(320, 240, image.Format.FMT_RGB888) img_new img.affine([(10, 10), (100, 10), (10, 100)], [(10, 10), (100, 20), (20, 100)]) print(img, img_new) ``` 更多参数和用法请参考 API 文档。 ## 画关键点 `image.Image`提供了`draw_keypoints`方法,可以在图像上画关键点: ```python from maix import image img image.Image(320, 240, image.Format.FMT_RGB888) keypoints [(10, 10), (100, 10), (10, 100)] img.draw_keypoints(keypoints, image.Color.from_rgb(255, 0, 0), size 10, thickness 1, fill False) ``` 在坐标`(10, 10)`、`(100, 10)`、`(10, 100)`画三个红色的关键点,关键点的大小是`10`,线宽是`1`,不填充。 ## 画十字 `image.Image`提供了`draw_cross`方法,可以在图像上画十字: ```python from maix import image img image.Image(320, 240, image.Format.FMT_RGB888) img.draw_cross(100, 100, image.Color.from_rgb(255, 0, 0), size 5, thickness 1) ``` 在坐标`(100, 100)`画一个红色的十字,十字的延长大小是`5`,所以线段长度为`2 * size + thickness`, 线宽是`1`。 ## 画箭头 `image.Image`提供了`draw_arrow`方法,可以在图像上画箭头: ```python from maix import image img image.Image(320, 240, image.Format.FMT_RGB888) img.draw_arrow(10, 10, 100, 100, image.Color.from_rgb(255, 0, 0), thickness 1) ``` 在坐标`(10, 10)`画一个红色的箭头,箭头的终点是`(100, 100)`,线宽是`1`。 ## 画图 `image.Image`提供了`draw_image`方法,可以在图像上画图: ```python from maix import image img image.Image(320, 240, image.Format.FMT_RGB888) img2 image.Image(100, 100, image.Format.FMT_RGB888) img2.draw_rect(10, 10, 90, 90, image.Color.from_rgb(255, 0, 0)) img.draw_image(10, 10, img2) ``` ## 转换格式 `image.Image`提供了`to_format`方法,可以转换图像格式: ```python from maix import image img image.Image(320, 240, image.Format.FMT_RGB888) img_new img.to_format(image.Format.FMT_BGR888) print(img, img_new) img_jpg img.to_format(image.Format.FMT_JPEG) print(img, img_new) ``` 注意这里`to_format`方法返回一个新的图像对象,原图像不变。 ## 和 Numpy/OpenCV 格式互相转换 另外还可以转换成`numpy`数组,这样就能给`numpy`和`opencv`等库使用: ```python from maix import image img image.Image(320, 240, image.Format.FMT_RGB888) img_np image.image2cv(img) img2 image.cv2image(img_np) print(type(img_np), img_np, img_np.shape) print(type(img2), img2) ``` ## 和 bytes 数据互相转换 `image.Image`提供了`to_bytes`方法,可以转换图像为`bytes`数据: ```python from maix import image img image.Image(320, 240, image.Format.FMT_RGB888) data img.to_bytes() print(type(data), len(data), img.data_size()) img2 image.Image(320, 240, image.Format.FMT_RGB888, data) print(img2) ``` 这里`to_bytes`获得一个新的`bytes`对象,是独立的内存,不会影响原图。 `image.Image`构造函数中传入`data`参数可以直接从`bytes`数据构造图像对象,注意新的图像也是独立的内存,不会影响到`data`。 因为涉及到内存拷贝,所以这个方法比较耗时,不建议频繁使用。 > 如果你想用不拷贝的方式优化程序(不建议轻易使用,写不好代码会导致程序容易崩溃,),请看 API 文档。 ## 更多基础 API 使用方法 更多 API 使用方法请参考 [maix.image](/api/maix/image.html) 模块的文档。"},"/maixpy/doc/zh/vision/find_blobs.html":{"title":"MaixPy 寻找色块","content":" title: MaixPy 寻找色块 update: date: 2024 04 03 author: neucrack version: 1.0.0 content: 初版文档 date: 2024 04 03 author: lxowalle version: 1.0.1 content: 添加寻找色块的详细用法 阅读本文前,确保已经知晓如何开发MaixCAM,详情请阅读[快速开始](../index.html) ## 简介 本文将介绍如何使用MaixPy来寻找色块,以及如何使用MaixCam的默认应用程序寻找色块。 在视觉应用中,寻找色块是一个非常常见的需求,比如机器人找色块,自动化生产线找色块等等,即需要识别画面中的特定的颜色区域,获取这个区域的位置和大小等信息。 ## 使用 MaixPy 寻找色块 MaixPy的 `maix.image.Image`中提供了`find_blobs`方法,可以方便的找色块。 ### 如何寻找色块 一个简单的示例,实现寻找色块并画框 ```python from maix import image, camera, display cam camera.Camera(320, 240) disp display.Display() # 根据色块颜色选择对应配置 thresholds [[0, 80, 40, 80, 10, 80]] # red # thresholds [[0, 80, 120, 10, 0, 30]] # green # thresholds [[0, 80, 30, 100, 120, 60]] # blue while 1: img cam.read() blobs img.find_blobs(thresholds, pixels_threshold 500) for blob in blobs: img.draw_rect(blob[0], blob[1], blob[2], blob[3], image.COLOR_GREEN) disp.show(img) ``` 步骤: 1. 导入image、camera、display模块 ```python from maix import image, camera, display ``` 2. 初始化摄像头和显示 ```python cam camera.Camera(320, 240)\t# 初始化摄像头,输出分辨率320x240 RGB格式 disp display.Display() ``` 3. 从摄像头获取图片并显示 ```python while 1: img cam.read() disp.show(img) ``` 4. 调用`find_blobs`方法寻找摄像头图片中的色块,并画到屏幕上 ```python blobs img.find_blobs(thresholds, pixels_threshold 500) for blob in blobs: img.draw_rect(blob[0], blob[1], blob[2], blob[3], image.COLOR_GREEN) ``` `img`是通过`cam.read()`读取到的摄像头图像,当初始化的方式为`cam camera.Camera(320, 240)`时,`img`对象是一张分辨率为320x240的RGB图。 `img.find_blobs`用来寻找色块, `thresholds` 是一个颜色阈值列表,每个元素是一个颜色阈值,同时找到多个阈值就传入多个,每个颜色阈值的格式为 `[L_MIN, L_MAX, A_MIN, A_MAX, B_MIN, B_MAX]`,这里的 `L`、`A`、`B` 是`LAB`颜色空间的三个通道,`L` 通道是亮度,`A` 通道是红绿通道,`B` 通道是蓝黄通道。`pixels_threshold`是一个像素点数量的阈值,用来过滤一些不需要的小色块。 `img.draw_rect`用来画色块框,`blob[0]`、`blob[1]`、`blob[1]`、`blob[1]`分别代表色块左上角坐标x,色块左上角坐标y,色块宽度w和色块高度h ### 常用参数说明 列举常用参数说明,如果没有找到可以实现应用的参数,则需要考虑是否使用其他算法实现,或者基于目前算法的结果扩展所需的功能 参数 说明 示例 thresholds 基于lab颜色空间的阈值,threshold [[l_min, l_max, a_min, a_max, b_min, b_max]],分别表示:
    亮度范围为[l_min, l_max]\\
    绿色到红色的分量范围为[l_min, l_max]
    蓝色到黄色的分量范围为[b_min, b_max]
    可同时设置多个阈值 设置两个阈值来检测红色和绿色
    ```img.find_blobs(threshold [[0, 80, 40, 80, 10, 80], [0, 80, 120, 10, 0, 30]])```
    红色阈值为[0, 80, 40, 80, 10, 80]
    绿色阈值为[0, 80, 120, 10, 0, 30] invert 使能阈值反转,使能后传入阈值与实际阈值相反,默认为False 使能阈值反转
    ```img.find_blobs(invert True)``` roi 设置算法计算的矩形区域,roi [x, y, w, h],x,y表示矩形区域左上角坐标,w,h表示矩形区域的宽度和高度,默认为整张图片 计算坐标为(50,50),宽和高为100的区域
    ```img.find_blobs(roi [50, 50, 100, 100])``` area_threshold 过滤像素面积小于area_threshold的色块,单位为像素点,默认为10。该参数可用于过滤一些无用的小色块 过滤面积小于1000的色块
    ```img.find_blobs(area_threshold 1000)``` pixels_threshold 过滤有效像素点小于pixels_threshold的色块,默认为10。该参数可用于过滤一些无用的小色块 过滤有效像素点小于1000的色块
    ```img.find_blobs(pixels_threshold 1000)``` 本文介绍常用方法,更多 API 请看 API 文档的 [image](../../../api/maix/image.html) 部分。 ## 使用寻找色块APP 为了快速验证寻找色块的功能,可以先使用MaixCam提供的寻找色块应用程序来体验寻找色块的效果。 ### 使用方法 打开设备,选择`找色块`应用,然后在下方选择要识别的颜色,或者自定义颜色,即可以识别到对应的颜色了,同时串口也会输出识别到的坐标和颜色信息。 ### 详细说明 APP界面参考如下: ![](../../../static/image/find_blobs_app.jpg) #### 使用默认配置 寻找色块APP默认提供了`red、green、blue、user`四种配置,其中`red、green和blue`用来`寻找红色、绿色和蓝色的色块`,`user`主要提供给`用户自定义寻找色块`,自定义配置的方法见下文。快速体验时通过`点击`界面下方`按钮`即可切换到对应配置, #### 寻找自定义色块 APP提供两种方式来寻找自定义的色块:通过自适应LAB阈值寻找和手动设置LAB阈值寻找 ##### 1. 自适应LAB阈值寻找色块 操作方法: 1. `点击`左下角`选项图标`,进入配置模式 2. 将`摄像头对准`需要`寻找的物体`,`点击`屏幕上的`目标物体`,此时`左侧`会显示该物体对应颜色的`矩形框`,并显示该物体颜色的LAB值。 3. 点击出现的`矩形框`,系统将会`自动设置`LAB阈值,此时画面将会画出该物体边缘。 ##### 2. 手动设置LAB阈值寻找色块 手动设置可以更精确的找到目标色块。 操作方法: 1. `点击`左下角`选项图标`,进入配置模式 2. 将`摄像头对准`需要`寻找的物体`,`点击`屏幕上的`目标物体`,此时`左侧`会显示该物体对应颜色的`矩形框`,并显示该物体颜色的`LAB值`。 3. 点击下方选项`L Min,L Max,A Min,A Max,B Min,B Max`,点击后右侧会出现滑动条来设置该选项值。这些值分别对应LAB颜色格式的L通道、A通道和B通道的最小值和最大值 4. 参考步骤2计算的物体颜色的`LAB值`,将`L Min,L Max,A Min,A Max,B Min,B Max`调整到合适的值,即可识别到对应的色块。 例如`LAB (20, 50, 80)`,由于`L 20`,为了适配一定范围让`L Min 10`,`L Max 30`;同理,由于`A 50`,让`A Min 40`,`A Max 60`; 由于`B 80`,让`B Min 70`,`B Max 90`。 #### 通过串口协议获取检测数据 寻找色块APP支持通过串口(默认波特率为115200)上报检测到的色块信息。 由于上报信息只有一条,这里直接用示例来说明上报信息的内容。 例如上报信息为: ```shell AA CA AC BB 14 00 00 00 E1 08 EE 00 37 00 15 01 F7 FF 4E 01 19 00 27 01 5A 00 A7 20 ``` `AA CA AC BB`:协议头部,内容固定 `14 00 00 00`:数据长度,除了协议头部和数据长度外的总长度 `E1`:标志位,用来标识串口消息标志 `08`:命令类型,对于寻找色块APP应用该值固定为0x08 `EE 00 37 00 15 01 F7 FF 4E 01 19 00 27 01 5A 00`:已找到色块的四个顶点坐标,每个值用小端格式的2字节表示。`EE 00`和`37 00`表示第一个顶点坐标为(238, 55),`15 01`和`F7 FF`表示第二个顶点坐标为(277, 9),`4E 01`和`19 00`表示第三个顶点坐标为(334, 25),`27 01`和`5A 00`表示第四个顶点坐标为(295, 90)。 `A7 20`:CRC 校验值,用以校验帧数据在传输过程中是否出错 ## 关于LAB颜色空间 LAB颜色空间和RGB颜色空间一样是一种表示颜色的方法,LAB可以表示人眼能看到的所有颜色。如果需要了解LAB可以去网络上搜索相关文章,那样更详细,而对于你应该只需要了解为什么选用LAB对于MaixPy的优势。 LAB对于MaixPy的优势: 1. LAB颜色空间的色域比RGB都要大,因此完全可以替换RGB。 2. LAB颜色空间下,由于L通道是亮度通道,我们常常设置到较大的范围即可(常用[0,80]),而编写代码时主要关注是A通道和B通道,这样可以减少大量的时间在纠结颜色阈值如何选择的问题上。 3. LAB颜色空间的颜色感知更均匀,更容易用代码调试。例如,对于只需要寻找红色色块,可以固定L通道和B通道值,只需要调整A通道的值即可(这是在颜色精度要求不高的情况下);如果是RGB通道则基本需要R、G、B三个通道同时变动才能找到合适的阈值。"},"/maixpy/doc/zh/vision/display.html":{"title":"MaixPy 屏幕使用","content":" title: MaixPy 屏幕使用 update: date: 2024 03 31 author: neucrack version: 1.0.0 content: 初版文档 ## 简介 MaixPy 提供了`display`模块,可以将图像显示到屏幕上,同时,也可以将图像发送到 MaixVision 显示,方便调试和开发。 ## API 文档 本文介绍常用方法,更多 API 请看 API 文档的 [display](/api/maix/display.html) 部分。 ## 使用屏幕 * 导入`display`模块: ```python from maix import display ``` * 创建一个`Display`对象: ```python disp display.Display() ``` * 显示图像: ```python disp.show(img) ``` 这里`img`对象是`maix.image.Image`对象,可以通过`camera`模块的`read`方法获取,也可以通过`image`模块的`load`方法加载文件系统中的图像,也可以通过`image`模块的`Image`类创建一个空白图像。 比如: ```python from maix import image, display disp display.Display() img image.load(\"/root/dog.jpg\") disp.show(img) ``` 这里需要先把`dog.jpg`文件传到设备的`/root`目录下。 显示文字: ```python from maix import image, display disp display.Display() img image.Image(320, 240) img.draw_rectangle(0, 0, disp.width(), disp.height(), color image.Color.from_rgb(255, 0, 0), thickness 1) img.draw_rectangle(10, 10, 100, 100, color image.Color.from_rgb(255, 0, 0)) img.draw_string(10, 10, \"Hello MaixPy!\", color image.Color.from_rgb(255, 255, 255)) disp.show(img) ``` 从摄像头读取图像并显示: ```python from maix import camera, display, app disp display.Display() cam camera.Camera(320, 240) while not app.need_exit(): img cam.read() disp.show(img) ``` > 这里用了一个`while not app.need_exit():` 是方便程序在其它地方调用`app.set_exit_flag()`方法后退出循环。 ## 调整背光亮度 在系统的`设置`应用中可以手动调整背光亮度,如果你想在程序中调整背光亮度,可以使用`set_backlight`方法,参数就是亮度百分比,取值范围是 0 100: ```python disp.set_backlight(50) ``` 注意,程序退出回到应用选择界面后会自动恢复到系统设置的背光亮度。 ## 显示到 MaixVision 在使用 MaixVision 运行代码时,能够将图像显示到 MaixVision 上,方便调试和开发。 在调用`show`方法时,会自动压缩图像并发送到 MaixVision 显示。 当然,如果你没有屏幕,或者为了节省内存不想初始化屏幕,也可以直接调用`image.Image`对象的`send_to_maixvision`方法发送图像到 MaixVision 显示。 ```python from maix import image img image.Image(320, 240) img.draw_rectangle(0, 0, img.width(), img.height(), color image.Color.from_rgb(255, 0, 0), thickness 1) img.draw_rectangle(10, 10, 100, 100, color image.Color.from_rgb(255, 0, 0)) img.draw_string(10, 10, \"Hello MaixPy!\", color image.Color.from_rgb(255, 255, 255)) img.send_to_maixvision() ```"},"/maixpy/doc/zh/vision/body_key_points.html":{"title":"MaixPy 检测人体关键点姿态检测","content":" title: MaixPy 检测人体关键点姿态检测 ## 简介 使用 MaixPy 可以轻松检测人体关节的关键点的坐标,用在姿态检测比如坐姿检测,体感游戏输入等。 ## 使用 使用 MaixPy 的 maix.nn.BodyKeyPoints 类可以轻松实现: ```python from maix import nn, image, display detector nn.BodyKeyPoints(model \"/root/models/body_key_points.mud\") cam camera.Camera(recognizer.input_width(), recognizer.input_height(), recognizer.input_format()) dis display.Display() while 1: img cam.read() points detector.detect(img) for point in points: img.draw_circle(point[0], point[1], 3, color image.COLOR_RED, thickness 1) dis.show(img) ```"},"/maixpy/doc/zh/vision/self_learn_detector.html":{"title":"MaixPy 自学习检测器","content":" title: MaixPy 自学习检测器 ## MaixPy 自学习检测器 和自学习分类器类似,不需要训练,直接拍摄几张要检测的物体照片即可实现检测,在简单检测场景下十分好用。 和自学习分类器不同的是因为是检测器,会有物体的坐标和大小。 ## MaixPy 中使用自学习检测器 TODO:"},"/maixpy/doc/zh/vision/face_recognition.html":{"title":"MaixPy 人脸识别","content":" title: MaixPy 人脸识别 ## 人脸识别简介 人脸识别就是识别当前画面中的人脸的位置以及是谁。 所以人脸识别除了要检测到人脸,一般会有一个库来保存认识的人和不认识的人。 ## 识别原理 * 使用 AI 模型检测人脸,获得坐标和五官的坐标。 * 利用五官的坐标仿射变换将图中的脸拉正对其到标准脸的样子,方便模型提取脸的特征。 * 使用特征提取模型提取脸的特征值。 * 与库中记录的人脸特征值进行对比(计算保存的和当前画面中的脸的特征值的余弦距离,得出最小的距离的库中的人脸,小于设定的阈值就认为当前画面中就是这个库中的人) ## MaixPy 使用 MaixPy maix.nn 模块中提供了人脸识别的 API, 可以直接使用,模型也内置了,也可以到 [MaixHub 模型库](https://maixhub.com/model/zoo) 下载(筛选选则对应的硬件平台,比如 maixcam)。 识别: ```python from maix import nn recognizer nn.Face_Recognizer(model \"/root/models/face_recognizer.mud\") if os.path.exists(\"/root/faces.bin\"): recognizer.load_faces(\"/root/faces.bin\") cam camera.Camera(recognizer.input_width(), recognizer.input_height(), recognizer.input_format()) dis display.Display() while 1: img cam.read() faces recognizer.recognize(img) for obj in faces: img.draw_rect(obj.x, obj.y, obj.w, obj.h, color image.COLOR_RED) msg f'{recognizer.labels[obj.class_id]}: {obj.score:.2f}' img.draw_string(obj.x, obj.y, msg, color image.COLOR_RED) dis.show(img) ``` 第一次运行这个代码会发现能检测到人脸,但是都不认识,需要我们进入添加人脸模式学习人脸才行。 比如可以在用户按下按键的时候学习人脸: ```python faces recognizer.detect_faces(img) for face in faces: print(face) # 这里考虑到了一个画面中有多个人脸的情况 # 可以在这里根据 face 的坐标决定要不要添加到库里面 recognizer.add_face(face) recognizer.save_(faces)(\"/too/faces.bin\") ```"},"/maixpy/doc/zh/vision/classify.html":{"title":"MaixPy 使用 AI 模型进行物体分类","content":" title: MaixPy 使用 AI 模型进行物体分类 ## 物体分类概念 比如眼前有两张图片,一张图里面是苹果,另一张是飞机,物体分类的任务就是把两张图分别依次输入给 AI 模型,模型会依次输出两个结果,一个是苹果,一个是飞机。 ## MaixPy 中使用物体分类 MaixPy 默认提供了 `imagenet` 数据集训练得到的 `1000`分类模型,可以直接使用: ```python from maix import camera, display, image, nn classifier nn.Classifier(model \"/root/models/mobilenetv2.mud\") cam camera.Camera(classifier.input_width(), classifier.input_height(), classifier.input_format()) dis display.Display() while 1: img cam.read() res classifier.classify(img) max_idx, max_prob res[0] msg f\"{max_prob:5.2f}: {classifier.labels[max_idx]}\" img.draw_string(10, 10, msg, image.COLOR_RED) dis.show(img) ``` 效果视频: 这里使用了摄像头拍摄图像,然后传给 `classifier`进行识别,得出结果后,将结果显示在屏幕上。 更多 API 使用参考 [maix.nn](/api/maix/nn.html) 模块的文档。 ## 训练自己的分类模型 请到[MaixHub](https://maixhub.com) 学习并训练分类模型,创建项目时选择`分类模型`即可。"},"/maixpy/doc/zh/vision/yolov5.html":{"title":"MaixPy 使用 YOLOv5 模型进行目标检测","content":" title: MaixPy 使用 YOLOv5 模型进行目标检测 ## 目标检测概念 目标检测是指在图像或视频中检测出目标的位置和类别,比如在一张图中检测出苹果、飞机等物体,并且标出物体的位置。 和分类不同的是多了一个位置信息,所以目标检测的结果一般是一个矩形框,框出物体的位置。 ## MaixPy 中使用目标检测 MaixPy 默认提供了 `YOLOv5` 模型,可以直接使用: ```python from maix import camera, display, image, nn, app detector nn.YOLOv5(model \"/root/models/yolov5s.mud\") cam camera.Camera(detector.input_width(), detector.input_height(), detector.input_format()) dis display.Display() while not app.need_exit(): img cam.read() objs detector.detect(img, conf_th 0.5, iou_th 0.45) for obj in objs: img.draw_rect(obj.x, obj.y, obj.w, obj.h, color image.COLOR_RED) msg f'{detector.labels[obj.class_id]}: {obj.score:.2f}' img.draw_string(obj.x, obj.y, msg, color image.COLOR_RED) dis.show(img) ``` 效果视频: